@alis-build/opencode-plugin 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alis Build
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,160 @@
1
+ # Alis Build opencode Plugin
2
+
3
+ **Connect [opencode](https://opencode.ai) to Alis Build.**
4
+
5
+ Use this plugin to let opencode inspect Alis Build landing zones, products, neurons,
6
+ builds, deploys, and related workspace context — the opencode counterpart of the
7
+ [Alis Build Claude Code plugin](https://github.com/alis-build/claude-plugin).
8
+
9
+ ## What You Get
10
+
11
+ - A preconfigured opencode MCP server for `https://mcp.alis.build`
12
+ - OAuth sign-in through Alis Build identity (handled by opencode)
13
+ - Alis Build tools available inside opencode after sign-in
14
+ - A standing Define → Build → Deploy primer loaded into every session via opencode
15
+ `instructions`, so the agent knows the workflow, how to route requests, and to run
16
+ the `alis` CLI — no trigger word required
17
+ - `/build-it` and `/fix-it` workflow commands
18
+ - The `alis` CLI auto-approved via opencode `permission.bash`, so command-line calls
19
+ run without a permission prompt each time
20
+
21
+ ## How this maps from the Claude Code plugin
22
+
23
+ opencode and Claude Code expose the same capabilities through different mechanisms.
24
+ Most of the Claude plugin is **config** in opencode; only the session-id injection
25
+ needs plugin code.
26
+
27
+ | Claude Code plugin | opencode equivalent | Lives in |
28
+ | --- | --- | --- |
29
+ | `.mcp.json` (HTTP MCP + OAuth) | `mcp.api` (`type: "remote"`) | `opencode.json` |
30
+ | `commands/*.md` | `command/*.md` or `command` config key | this repo / config |
31
+ | `context/dbd-primer.md` via `SessionStart` hook | `instructions` array | `opencode.json` |
32
+ | `allow-alis-cli.sh` (`PreToolUse` Bash hook) | `permission.bash` patterns | `opencode.json` |
33
+ | `inject-skill-session-id.sh` (`PreToolUse` hook) | `tool.execute.before` plugin hook | `src/index.ts` |
34
+ | `.claude-plugin/marketplace.json` | npm package + config snippet | `package.json` |
35
+
36
+ > opencode has **no `config` hook**, so a plugin cannot register MCP servers,
37
+ > instructions, or commands programmatically. That is why those are config, and why
38
+ > install is a config snippet plus an npm package rather than a single command.
39
+
40
+ ## Before You Start
41
+
42
+ You need:
43
+
44
+ - opencode installed
45
+ - An Alis Build account with access to the landing zones and products you want to use
46
+ - Network access to `https://mcp.alis.build` and the Alis Build identity provider
47
+
48
+ ## Install
49
+
50
+ ### 1. Add the config
51
+
52
+ Merge the contents of [`opencode.example.json`](./opencode.example.json) into your
53
+ opencode config — `~/.config/opencode/opencode.json` for a global install, or
54
+ `.opencode/opencode.json` (or `opencode.json` at the repo root) for a project install.
55
+
56
+ It wires up four things: the `@alis-build/opencode-plugin` npm plugin, the `api` MCP
57
+ server, the `/build-it` + `/fix-it` commands, and the `alis` CLI permission allow.
58
+ opencode installs the npm plugin automatically with Bun on next start.
59
+
60
+ ### 2. Install the primer file
61
+
62
+ The DBD primer loads via the `instructions` array, which references a file path.
63
+ Copy the bundled primer to the path used in the config:
64
+
65
+ ```sh
66
+ mkdir -p ~/.config/opencode/alis-build
67
+ curl -fsSL https://raw.githubusercontent.com/alis-build/opencode-plugin/main/instructions/dbd-primer.md \
68
+ -o ~/.config/opencode/alis-build/dbd-primer.md
69
+ ```
70
+
71
+ (Or clone this repo and point the `instructions` path at `instructions/dbd-primer.md`.)
72
+
73
+ ### 3. (Optional) Install the commands as files
74
+
75
+ The `command` block in the config defines `/build-it` and `/fix-it` inline, so this
76
+ step is optional. If you prefer file-based commands, copy `command/build-it.md` and
77
+ `command/fix-it.md` into `~/.config/opencode/command/` (global) or `.opencode/command/`
78
+ (project) and drop the `command` block from your config.
79
+
80
+ ### 4. Start opencode
81
+
82
+ ```sh
83
+ opencode
84
+ ```
85
+
86
+ ## Sign In
87
+
88
+ opencode handles the MCP OAuth flow. On first use of an Alis tool it will prompt you to
89
+ authenticate, or you can trigger it explicitly:
90
+
91
+ ```sh
92
+ opencode mcp auth api
93
+ ```
94
+
95
+ ## Use It
96
+
97
+ After sign-in, ask opencode to use Alis Build:
98
+
99
+ ```text
100
+ build it
101
+ ```
102
+
103
+ ```text
104
+ fix it
105
+ ```
106
+
107
+ ```text
108
+ Use Alis Build to list the landing zones I can access.
109
+ ```
110
+
111
+ ```text
112
+ Show recent builds for product os in landing zone alis.
113
+ ```
114
+
115
+ The `/build-it` and `/fix-it` commands run the same skill-discovery router.
116
+
117
+ ### `alis` CLI auto-approval
118
+
119
+ The `permission.bash` block approves `alis ...` invocations so the CLI runs without a
120
+ prompt. opencode's bash permission matching is glob-based and **less strict than the
121
+ Claude plugin's shell hook**, which explicitly rejected chained/redirected commands
122
+ (`alis define && rm -rf`). If you want that stricter guarantee, tighten the pattern to
123
+ specific subcommands (e.g. `"alis define *": "allow"`, `"alis build *": "allow"`) and
124
+ leave everything else at the default `ask`.
125
+
126
+ ## Verify before relying on this
127
+
128
+ opencode's plugin hook surface is newer and less documented than Claude Code's. Two
129
+ things should be confirmed against your installed opencode / `@opencode-ai/plugin`
130
+ version before treating this as production-ready:
131
+
132
+ 1. **Session-id injection** (`src/index.ts`) — the exact hook field names (`input.tool`,
133
+ `output.args`, and where the session id is exposed) need verifying. The handler fails
134
+ safe: if it can't find the session id it leaves the call untouched, and the skill
135
+ falls back to its own in-markdown discovery.
136
+ 2. **Command directory name** — opencode versions have used both `command/` and
137
+ `commands/`. The inline `command` config block avoids this ambiguity; prefer it if the
138
+ file-based commands don't register.
139
+
140
+ ## Repository layout
141
+
142
+ ```
143
+ opencode-plugin/
144
+ ├── README.md
145
+ ├── LICENSE
146
+ ├── package.json # @alis-build/opencode-plugin (npm)
147
+ ├── tsconfig.json
148
+ ├── opencode.example.json # config snippet to merge into opencode.json
149
+ ├── src/
150
+ │ └── index.ts # plugin: session-id injection hook
151
+ ├── instructions/
152
+ │ └── dbd-primer.md # always-loaded DBD primer
153
+ └── command/
154
+ ├── build-it.md
155
+ └── fix-it.md
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT © Alis Build
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Find the right Alis Build skill for what you want to build.
3
+ ---
4
+
5
+ Run the Alis Build "build it" router as described in the Alis Build MCP server instructions: infer what I want built from the current request and workspace context (ask exactly one concise clarification only if the goal is ambiguous), call SearchSkills with the clarified goal, present the matching skills, and load the one I choose. Do not run Define, Build, Deploy, commits, or code edits from this router step — only the loaded skill does that, and only when its workflow requires it.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Alias for build-it: find the right Alis Build skill to fix or build something.
3
+ ---
4
+
5
+ Run the Alis Build "fix it" router (the fix-it alias of "build it") as described in the Alis Build MCP server instructions: infer what I want fixed or built from the current request, visible errors, and workspace context (ask exactly one concise clarification only if the goal is ambiguous), call SearchSkills with the clarified goal, present the matching skills, and load the one I choose. Do not run Define, Build, Deploy, commits, or code edits from this router step — only the loaded skill does that, and only when its workflow requires it.
@@ -0,0 +1,123 @@
1
+ # Alis Build — Define, Build, Deploy (DBD)
2
+
3
+ The core workflow on the Alis Build platform is **Define, Build, Deploy (DBD)**. Most
4
+ development flows touch one or more of these steps — use this framing when helping with any
5
+ Alis Build task, and walk the user through DBD rather than handing over a disconnected checklist.
6
+
7
+ This primer is the standing how-to guide for Alis Build work. It carries three things:
8
+
9
+ 1. The **mental model** — what DBD is and where things live on disk.
10
+ 2. The **routing contract** — when to discover a skill, when to run a command directly.
11
+ 3. The **execution contract** — how to actually run Define / Build / Deploy.
12
+
13
+ > The Alis Build MCP provides the *tools*; this primer provides *how to operate*. When a
14
+ > specific tool description is more precise than this primer (exact arguments, hard
15
+ > constraints), follow the tool description.
16
+
17
+ ## Define — lock the API / platform contract
18
+
19
+ - Edit protobuf files in the landing zone `define` repo: `~/alis.build/<organisation-id>/define`.
20
+ - Commit and push, then Define against a specific, reviewed commit — the contract pins to that
21
+ exact commit, so it has to be deliberate.
22
+ - Define pins the definition to that commit and generates consumable language packages
23
+ (Go, JavaScript, Python, Dart, .NET, public ECMAScript when configured) and may sync platform
24
+ artifacts such as Spanner protobundles or Pub/Sub topics.
25
+ - This is the source-of-truth step: it makes the contract reviewable, repeatable, and consumable.
26
+
27
+ ## Build — implement the service and produce a deployable artifact
28
+
29
+ - Work in the product build repo: `~/alis.build/<organisation-id>/build/<product-id>`.
30
+ - Install/update the generated packages from Define, then write or edit the business logic
31
+ (usually Go).
32
+ - Build a container image from a product repo commit. Docker build paths are relative to the
33
+ neuron folder (e.g. a top-level Dockerfile uses `.`, not `demo/v1`).
34
+ - This connects the locked contract to real behavior.
35
+
36
+ ## Deploy — provision and update the runtime
37
+
38
+ - Review the neuron's Terraform under its `infra/` folder.
39
+ - Deploy the successful build version to a real environment (e.g. DEV). The environment comes
40
+ from the product context, not a guess.
41
+ - Deploy makes the service reachable infrastructure (commonly Cloud Run plus supporting resources).
42
+ - Validate end-to-end via the generated playground, usually `<neuron>/.playground/main_test.go`.
43
+
44
+ ## Routing — discover a skill vs run a command directly
45
+
46
+ Not every Alis Build request is the same kind of work. Classify first, then act.
47
+
48
+ - **Routers — discover a skill before acting.** For an ambiguous *functional* request — the
49
+ user wants to build, fix, add, or change something and the agent needs to know *how* — treat
50
+ it as a router, not a direct task. Triggers: "build it", "fix it", "add X", "change Y", and
51
+ capability questions ("can you help with tracing?", "are you able to add X?").
52
+ - Work out the intended outcome (ask ONE concise question only if it is genuinely ambiguous),
53
+ then call the Alis Build MCP `SearchSkills` tool FIRST with that outcome as the query (fall
54
+ back to `ListSkills` if it returns nothing).
55
+ - Present the matching skills (id, what each does, when to choose it), ask which to use, and
56
+ only then call `LoadSkill` and follow that skill's workflow — the loaded skill owns
57
+ execution.
58
+ - **Do NOT inspect, write, or edit code, run Define / Build / Deploy, or make commits before
59
+ a skill is loaded.** If no skill fits, say so and offer `RequestSkill`.
60
+ - For a capability question, briefly confirm it is Alis Build work, then ask the user to name
61
+ the specific change so you can route it through `SearchSkills`. Do not dive into the
62
+ codebase or give a generic how-to before they name the concrete change.
63
+
64
+ - **Direct DBD commands — run the CLI, no skill needed.** When the user asks to run a *DBD
65
+ step* on an already-known target service, just run it (see **Executing DBD**). Triggers:
66
+ "define it", "deploy it", "ship it", "run define/build/deploy", "define and install". These
67
+ are deterministic; they do not need skill reasoning.
68
+
69
+ - **Spec it — call `SpecIt` directly.** "spec it" / "spec it up", or a request to turn the
70
+ current session into a build specification → call the `SpecIt` tool DIRECTLY (do not route
71
+ through `SearchSkills`). It needs no arguments (session context is resolved server-side);
72
+ pass `build_spec` only when the user names an existing one to append to. Report the returned
73
+ BuildSpec back to the user.
74
+
75
+ - **"alis" (vocative) / "dbd"** engage Alis Build context generally — then disambiguate with
76
+ the cases above.
77
+
78
+ - **"build it" is overloaded.** It can mean "construct this feature" (a router) or "run the
79
+ Build step" (the `alis build` command). If a build target/context is already established and
80
+ the user means the DBD step, run `alis build`; if it is a functional request, route via
81
+ `SearchSkills`; when genuinely unclear, ask one concise question.
82
+
83
+ Whenever a later request in the session would benefit from an Alis Build skill, use
84
+ `SearchSkills` to discover one before doing the work yourself.
85
+
86
+ ## Executing DBD — prefer the `alis` CLI
87
+
88
+ When you have a shell and the `alis` CLI is on `PATH`, **execute DBD through the CLI**, not the
89
+ MCP `RunDefine` / `RunBuild` / `RunDeploy` tools. The CLI is deterministic, auto-detects
90
+ context, and chains deterministic steps into one call:
91
+
92
+ - **Define** (and publish packages): `alis define <pkg> --json --install`
93
+ - **Build** (optionally deploy): `alis build <pkg> --json --deploy -e <env>`
94
+ - **Deploy**: `alis deploy <pkg> --json` (add `--version` / `-e <env>` as needed)
95
+
96
+ `<pkg>` is the package id, e.g. `alis.os.cli.v1`; it may be omitted when you are inside the
97
+ service's directory.
98
+
99
+ - **Pass `--json` for agent-driven calls.** `stdout` then carries the operation as a single
100
+ structured JSON object — parse `version`, `state` / `done`, `logs_uri`, and `error` from it
101
+ rather than scraping prose. Progress streams on `stderr`; the human one-liner (no `--json`)
102
+ is only for narrating to the user.
103
+ - **Let the CLI resolve context.** It auto-detects the latest commit, Dockerfile build/retag
104
+ paths, and a single-environment target. Don't hand-orchestrate these or ask the user for a
105
+ commit SHA the CLI will pick.
106
+ - **Long-running operations** stream to completion by default. Use `--async` to start one and
107
+ print its name, then re-attach with `alis operations wait <name> --json`. Never use shell
108
+ `sleep` / `git ls-remote` loops to pass time.
109
+ - **The CLI is self-documenting — consult it, don't memorise it.** This primer names only the
110
+ DBD core. For the full command surface (e.g. `service new`, `packages`, `product`,
111
+ `environment`, `operations`, `login`) run `alis -h`; for a command's flags run
112
+ `alis <cmd> --help`. Treat that output as the source of truth; this primer and the skills
113
+ deliberately do not restate it.
114
+
115
+ **Fallback.** Use the MCP `RunDefine` / `RunBuild` / `RunDeploy` tools only when there is no
116
+ shell available (remote / headless agents). They run the same operation server-side; `RunDefine`
117
+ needs an explicit commit (never `HEAD`).
118
+
119
+ ## Getting deeper
120
+
121
+ For onboarding or the full step-by-step Simple API quickstart, load the `getting-started` skill
122
+ via `LoadSkill`. For an ambiguous "build it" / "fix it" request, route through skill discovery
123
+ (`SearchSkills`) before executing any DBD step.
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+
4
+ "plugin": ["@alis-build/opencode-plugin"],
5
+
6
+ "mcp": {
7
+ "api": {
8
+ "type": "remote",
9
+ "url": "https://mcp.alis.build",
10
+ "enabled": true
11
+ }
12
+ },
13
+
14
+ "instructions": ["~/.config/opencode/alis-build/dbd-primer.md"],
15
+
16
+ "command": {
17
+ "build-it": {
18
+ "description": "Find the right Alis Build skill for what you want to build.",
19
+ "template": "Run the Alis Build \"build it\" router as described in the Alis Build MCP server instructions: infer what I want built from the current request and workspace context (ask exactly one concise clarification only if the goal is ambiguous), call SearchSkills with the clarified goal, present the matching skills, and load the one I choose. Do not run Define, Build, Deploy, commits, or code edits from this router step — only the loaded skill does that, and only when its workflow requires it."
20
+ },
21
+ "fix-it": {
22
+ "description": "Alias for build-it: find the right Alis Build skill to fix or build something.",
23
+ "template": "Run the Alis Build \"fix it\" router (the fix-it alias of \"build it\") as described in the Alis Build MCP server instructions: infer what I want fixed or built from the current request, visible errors, and workspace context (ask exactly one concise clarification only if the goal is ambiguous), call SearchSkills with the clarified goal, present the matching skills, and load the one I choose. Do not run Define, Build, Deploy, commits, or code edits from this router step — only the loaded skill does that, and only when its workflow requires it."
24
+ }
25
+ },
26
+
27
+ "permission": {
28
+ "bash": {
29
+ "alis *": "allow",
30
+ "alis": "allow"
31
+ }
32
+ }
33
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@alis-build/opencode-plugin",
3
+ "version": "0.1.0",
4
+ "description": "Connect opencode to Alis Build through MCP, workflow commands, and the Define-Build-Deploy primer.",
5
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts"
9
+ },
10
+ "files": [
11
+ "src",
12
+ "instructions",
13
+ "command",
14
+ "opencode.example.json"
15
+ ],
16
+ "keywords": [
17
+ "opencode",
18
+ "alis",
19
+ "build",
20
+ "mcp",
21
+ "dbd",
22
+ "deploys",
23
+ "workspaces"
24
+ ],
25
+ "author": {
26
+ "name": "Alis Build"
27
+ },
28
+ "license": "MIT",
29
+ "homepage": "https://github.com/alis-build/opencode-plugin",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/alis-build/opencode-plugin.git"
33
+ },
34
+ "peerDependencies": {
35
+ "@opencode-ai/plugin": "*"
36
+ }
37
+ }
package/src/index.ts ADDED
@@ -0,0 +1,56 @@
1
+ import type { Plugin } from "@opencode-ai/plugin"
2
+
3
+ /**
4
+ * Alis Build plugin for opencode.
5
+ *
6
+ * This file ships the one piece of behaviour that genuinely needs code: injecting
7
+ * the opencode session id into Alis MCP calls. Everything else the Claude Code
8
+ * plugin did is config in opencode (see opencode.example.json and the README):
9
+ *
10
+ * - the MCP server -> `mcp.api` in opencode.json
11
+ * - the always-loaded primer -> `instructions` in opencode.json
12
+ * - the build-it / fix-it cmds -> `command/*.md` (or the `command` config key)
13
+ * - auto-approving `alis ...` -> `permission.bash` in opencode.json
14
+ *
15
+ * opencode has no "config" hook, so a plugin cannot register MCP servers,
16
+ * instructions, or commands programmatically — that is why those live in config.
17
+ *
18
+ * ---------------------------------------------------------------------------
19
+ * Session-id injection (mirror of the Claude `inject-skill-session-id` hook)
20
+ * ---------------------------------------------------------------------------
21
+ * The Alis MCP server uses the caller's session id to resolve the active Context
22
+ * and prepend an <alis-runtime-context> block to LoadSkill / SpecIt results. The
23
+ * model never supplies it; we merge it into the outgoing tool arguments here.
24
+ *
25
+ * NOTE: opencode's plugin hook surface is younger and less documented than Claude
26
+ * Code's. The exact field names below (`input.tool`, `output.args`, and where the
27
+ * session id is exposed) MUST be verified against the installed @opencode-ai/plugin
28
+ * version before relying on this in production — see the README "Verify" section.
29
+ */
30
+
31
+ // Matches the Alis MCP tools that resolve server-side Context from the session id.
32
+ // MCP tools are exposed to opencode with a server-name prefix, so match the suffix.
33
+ const SESSION_AWARE_TOOL = /(?:^|[._-])(LoadSkill|SpecIt)$/
34
+
35
+ export const AlisBuildPlugin: Plugin = async ({ client }) => {
36
+ return {
37
+ "tool.execute.before": async (input: any, output: any) => {
38
+ const toolName: string = input?.tool ?? ""
39
+ if (!SESSION_AWARE_TOOL.test(toolName)) return
40
+
41
+ // Resolve the current session id. The precise accessor depends on the
42
+ // opencode plugin API version; try the documented shapes in order.
43
+ const sessionID: string | undefined =
44
+ input?.sessionID ?? input?.sessionId ?? output?.sessionID
45
+
46
+ if (!sessionID) return
47
+
48
+ // Merge session_id into the outgoing MCP arguments without clobbering
49
+ // anything the model already set.
50
+ const args = (output.args ??= {})
51
+ if (args.session_id == null) args.session_id = sessionID
52
+ },
53
+ }
54
+ }
55
+
56
+ export default AlisBuildPlugin