@ship-cli/opencode 0.0.4 → 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.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @ship-cli/opencode
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@ship-cli/opencode)](https://www.npmjs.com/package/@ship-cli/opencode)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)
5
+
6
+ OpenCode plugin for [Ship](https://github.com/EduSantosBrito/ship-cli) - Linear task management and stacked changes for AI coding agents.
7
+
8
+ ## Installation
9
+
10
+ Add to your `opencode.json`:
11
+
12
+ ```json
13
+ {
14
+ "plugins": ["@ship-cli/opencode"]
15
+ }
16
+ ```
17
+
18
+ ## Prerequisites
19
+
20
+ - [Ship CLI](https://www.npmjs.com/package/@ship-cli/core) installed and configured (`ship init`)
21
+ - [jj](https://martinvonz.github.io/jj) for VCS operations
22
+ - [Linear](https://linear.app) account
23
+
24
+ ## What It Provides
25
+
26
+ This plugin exposes the `ship` tool to OpenCode, enabling AI agents to:
27
+
28
+ ### Task Management
29
+
30
+ | Action | Description |
31
+ |--------|-------------|
32
+ | `ready` | Find tasks with no blockers |
33
+ | `list` | List all tasks with optional filters |
34
+ | `blocked` | List tasks waiting on dependencies |
35
+ | `show` | View task details |
36
+ | `start` | Mark task as in progress |
37
+ | `done` | Mark task as complete |
38
+ | `create` | Create new tasks |
39
+ | `update` | Modify task properties |
40
+ | `block` | Add task dependency |
41
+ | `unblock` | Remove task dependency |
42
+ | `relate` | Link related tasks |
43
+ | `status` | Check ship configuration status |
44
+
45
+ ### Stacked Changes (jj)
46
+
47
+ | Action | Description |
48
+ |--------|-------------|
49
+ | `stack-create` | Create isolated workspace for a task |
50
+ | `stack-describe` | Update commit message (use `title` + `description` params for multi-line) |
51
+ | `stack-sync` | Fetch and rebase onto trunk |
52
+ | `stack-restack` | Rebase stack onto trunk (no fetch) |
53
+ | `stack-submit` | Push and create/update PR |
54
+ | `stack-status` | View current change info |
55
+ | `stack-log` | View stack of changes |
56
+ | `stack-squash` | Squash change into parent |
57
+ | `stack-abandon` | Abandon a change |
58
+ | `stack-up` | Navigate to parent change |
59
+ | `stack-down` | Navigate to child change |
60
+ | `stack-undo` | Undo last jj operation |
61
+ | `stack-update-stale` | Fix stale working copy |
62
+ | `stack-bookmark` | Create or move bookmark |
63
+ | `stack-workspaces` | List all workspaces |
64
+ | `stack-remove-workspace` | Remove a workspace |
65
+
66
+ ### PR Reviews
67
+
68
+ | Action | Description |
69
+ |--------|-------------|
70
+ | `pr-reviews` | Fetch PR reviews in AI-friendly format |
71
+
72
+ ### Webhooks
73
+
74
+ | Action | Description |
75
+ |--------|-------------|
76
+ | `webhook-daemon-status` | Check webhook daemon status |
77
+ | `webhook-subscribe` | Subscribe to PR events |
78
+ | `webhook-unsubscribe` | Unsubscribe from events |
79
+ | `webhook-cleanup` | Remove stale subscriptions |
80
+
81
+ ### Milestones
82
+
83
+ | Action | Description |
84
+ |--------|-------------|
85
+ | `milestone-list` | List project milestones |
86
+ | `milestone-show` | View milestone details |
87
+ | `milestone-create` | Create new milestone |
88
+ | `milestone-update` | Modify milestone |
89
+ | `milestone-delete` | Delete milestone |
90
+ | `task-set-milestone` | Assign task to milestone |
91
+ | `task-unset-milestone` | Remove task from milestone |
92
+
93
+ ## Skill Integration
94
+
95
+ For best results, pair this plugin with the ship-cli skill which provides workflow guidance:
96
+
97
+ ```
98
+ .opencode/skill/ship-cli/SKILL.md
99
+ ```
100
+
101
+ The skill teaches the agent the proper workflow:
102
+ 1. Find ready tasks
103
+ 2. Create isolated workspaces
104
+ 3. Make changes and sync
105
+ 4. Submit PRs with proper context
106
+
107
+ ## Links
108
+
109
+ - [Ship CLI Documentation](https://github.com/EduSantosBrito/ship-cli#readme)
110
+ - [OpenCode](https://opencode.ai)
111
+ - [Linear](https://linear.app)
112
+ - [jj (Jujutsu)](https://martinvonz.github.io/jj)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ship-cli/opencode",
3
- "version": "0.0.4",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Ship - Linear task management integration",
6
6
  "license": "MIT",
@@ -19,25 +19,42 @@
19
19
  ],
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "https://github.com/user/ship",
22
+ "url": "https://github.com/EduSantosBrito/ship-cli.git",
23
23
  "directory": "packages/opencode-plugin"
24
24
  },
25
+ "homepage": "https://github.com/EduSantosBrito/ship-cli#readme",
26
+ "bugs": {
27
+ "url": "https://github.com/EduSantosBrito/ship-cli/issues"
28
+ },
29
+ "author": "Eduardo Santos de Brito",
25
30
  "publishConfig": {
26
31
  "access": "public"
27
32
  },
33
+ "scripts": {
34
+ "check": "tsc --noEmit",
35
+ "lint": "oxlint",
36
+ "format": "oxfmt --write src/",
37
+ "format:check": "oxfmt src/",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest",
40
+ "prepare": "effect-language-service patch --module typescript"
41
+ },
28
42
  "dependencies": {
29
- "@opencode-ai/plugin": "^1.0.143",
30
- "@opencode-ai/sdk": "^1.0.143"
43
+ "@opencode-ai/plugin": "^1.0.208",
44
+ "@opencode-ai/sdk": "^1.0.208",
45
+ "effect": "^3.19.13"
31
46
  },
32
47
  "devDependencies": {
48
+ "@effect/language-service": "^0.62.4",
49
+ "@effect/vitest": "^0.25.1",
33
50
  "@types/bun": "latest",
34
- "@types/node": "^22.0.0",
35
- "typescript": "~5.6.2"
51
+ "@types/node": "^25.0.3",
52
+ "oxfmt": "^0.21.0",
53
+ "oxlint": "^1.36.0",
54
+ "typescript": "~5.9.3",
55
+ "vitest": "^4.0.16"
36
56
  },
37
57
  "engines": {
38
58
  "bun": ">=1.0.0"
39
- },
40
- "scripts": {
41
- "typecheck": "tsc --noEmit"
42
59
  }
43
- }
60
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Compaction context preservation module.
3
+ *
4
+ * This module provides utilities for tracking task state across sessions
5
+ * and preserving context during OpenCode session compaction.
6
+ */
7
+
8
+ import * as Option from "effect/Option";
9
+ import * as Schema from "effect/Schema";
10
+
11
+ // =============================================================================
12
+ // Types
13
+ // =============================================================================
14
+
15
+ /**
16
+ * Session task state for compaction context preservation.
17
+ */
18
+ export interface SessionTaskState {
19
+ taskId: string;
20
+ workdir?: string;
21
+ }
22
+
23
+ // =============================================================================
24
+ // State Management
25
+ // =============================================================================
26
+
27
+ /**
28
+ * Module-level state for tracking the current task per session.
29
+ *
30
+ * This is populated when tasks are started via the ship tool (action=start)
31
+ * and updated when workspaces are created (action=stack-create).
32
+ * Used during compaction to preserve task context.
33
+ */
34
+ export const sessionTaskMap = new Map<string, SessionTaskState>();
35
+
36
+ /**
37
+ * Track when a task is started or updated for a session.
38
+ */
39
+ export const trackTask = (sessionId: string, state: Partial<SessionTaskState>): void => {
40
+ const existing = sessionTaskMap.get(sessionId);
41
+ if (existing) {
42
+ // Update existing state
43
+ sessionTaskMap.set(sessionId, { ...existing, ...state });
44
+ } else if (state.taskId) {
45
+ // New task started
46
+ sessionTaskMap.set(sessionId, { taskId: state.taskId, workdir: state.workdir });
47
+ }
48
+ };
49
+
50
+ /**
51
+ * Get the tracked task for a session.
52
+ */
53
+ export const getTrackedTask = (sessionId: string): Option.Option<SessionTaskState> => {
54
+ const task = sessionTaskMap.get(sessionId);
55
+ return task ? Option.some(task) : Option.none();
56
+ };
57
+
58
+ /**
59
+ * Clear tracked task for a session. Used for cleanup or when task is completed.
60
+ */
61
+ export const clearTrackedTask = (sessionId: string): void => {
62
+ sessionTaskMap.delete(sessionId);
63
+ };
64
+
65
+ // =============================================================================
66
+ // Schema Validation
67
+ // =============================================================================
68
+
69
+ /**
70
+ * Schema for parsing ship tool args from metadata.
71
+ * Only includes fields needed for task tracking.
72
+ */
73
+ export const ShipToolArgsSchema = Schema.Struct({
74
+ action: Schema.String,
75
+ taskId: Schema.optional(Schema.String),
76
+ });
77
+
78
+ export const decodeShipToolArgs = Schema.decodeUnknownOption(ShipToolArgsSchema);