Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ registry/native/target/
registry/native/vendor/
registry/native/c/build/
registry/native/c/vendor/
registry/native/go/vendor/
registry/native/c/libs/
registry/native/c/.cache/
registry/native/c/sysroot/
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@rivet-dev/agent-os-ripgrep": "link:../../registry/software/ripgrep",
"@rivet-dev/agent-os-sed": "link:../../registry/software/sed",
"@rivet-dev/agent-os-tar": "link:../../registry/software/tar",
"@rivet-dev/agent-os-slack-cli": "link:../../registry/software/slack-cli",
"@rivet-dev/agent-os-tree": "link:../../registry/software/tree",
"@rivet-dev/agent-os-yq": "link:../../registry/software/yq",
"@types/node": "^22.10.2",
Expand Down
31 changes: 31 additions & 0 deletions packages/core/tests/wasm-commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { existsSync } from "node:fs";
import { join } from "node:path";
import { AgentOs } from "../src/index.js";
import curlPackage from "@rivet-dev/agent-os-curl";
import slackCliPackage from "@rivet-dev/agent-os-slack-cli";
import {
REGISTRY_SOFTWARE,
registrySkipReason,
Expand Down Expand Up @@ -804,3 +805,33 @@ server.listen(0, "0.0.0.0", () => {
});
});
});

// ── slack-cli (Go WASM, separate build) ──────────────────────────────

const slackCliSkipReason = existsSync(slackCliPackage.commandDir)
? false
: "slack-cli WASM binary not available (run: cd registry && make build-wasm-go copy-wasm)";

describe.skipIf(slackCliSkipReason)("slack-cli", () => {
let vm: AgentOs;

beforeEach(async () => {
vm = await AgentOs.create({ software: [...REGISTRY_SOFTWARE, slackCliPackage] });
});

afterEach(async () => {
await vm.dispose();
});

test("slack version prints version info", async () => {
const r = await vm.exec("slack version");
expect(r.exitCode).toBe(0);
expect(r.stdout).toMatch(/slack/i);
});

test("slack help prints usage", async () => {
const r = await vm.exec("slack help");
expect(r.exitCode).toBe(0);
expect(r.stdout).toContain("slack");
});
});
4 changes: 2 additions & 2 deletions packages/registry-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export interface WasmCommandPackage {
aptName: string;
/** Human-readable description. */
description: string;
/** Build source: "rust" or "c". */
source: "rust" | "c";
/** Build source: "rust", "c", or "go". */
source: "rust" | "c" | "go";
/** Commands provided by this package. */
commands: WasmCommandEntry[];
/** Absolute path to the directory containing WASM command binaries. */
Expand Down
15 changes: 15 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions registry/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ COMMANDS_DIR := $(NATIVE_DIR)/target/wasm32-wasip1/release/commands
MARKER_DIR := .build-markers
RUST_MARKER := $(MARKER_DIR)/rust-wasm-built
C_MARKER := $(MARKER_DIR)/c-wasm-built
GO_MARKER := $(MARKER_DIR)/go-wasm-built
COPY_MARKER := $(MARKER_DIR)/wasm-copied
META_MARKER := $(MARKER_DIR)/meta-generated
TS_MARKER := $(MARKER_DIR)/ts-built

# Command packages (excludes _types and meta-packages)
CMD_PACKAGES := coreutils sed grep gawk findutils diffutils tar gzip \
curl http-get wget zip unzip jq ripgrep fd tree file sqlite3 duckdb yq codex git
curl http-get wget zip unzip jq ripgrep fd tree file sqlite3 duckdb yq codex git slack-cli

# Meta-packages
META_PACKAGES := common build-essential everything

# All publishable packages
ALL_PACKAGES := $(CMD_PACKAGES) $(META_PACKAGES)

.PHONY: all build-wasm build-wasm-rust build-wasm-c copy-wasm generate-meta build test \
.PHONY: all build-wasm build-wasm-rust build-wasm-c build-wasm-go copy-wasm generate-meta build test \
publish publish-dry publish-force publish-clean clean rebuild

all: build
Expand All @@ -36,7 +37,7 @@ $(MARKER_DIR):
# ---------------------------------------------------------------------------
# Build WASM binaries from source (in native/)
# ---------------------------------------------------------------------------
build-wasm: build-wasm-rust build-wasm-c
build-wasm: build-wasm-rust build-wasm-c build-wasm-go

build-wasm-rust: $(RUST_MARKER)
$(RUST_MARKER): $(MARKER_DIR)
Expand All @@ -51,11 +52,17 @@ $(C_MARKER): $(MARKER_DIR)
cd $(NATIVE_DIR)/c && make install COMMANDS_DIR=../target/wasm32-wasip1/release/commands
@touch $(C_MARKER)

build-wasm-go: $(GO_MARKER)
$(GO_MARKER): $(MARKER_DIR)
@echo "=== Building Go WASM commands ==="
cd $(NATIVE_DIR)/go && make wasm
@touch $(GO_MARKER)

# ---------------------------------------------------------------------------
# Copy WASM binaries from native build output into per-package wasm/ dirs
# ---------------------------------------------------------------------------
copy-wasm: $(COPY_MARKER)
$(COPY_MARKER): $(RUST_MARKER) $(C_MARKER)
$(COPY_MARKER): $(RUST_MARKER) $(C_MARKER) $(GO_MARKER)
@echo "=== Copying WASM binaries to packages ==="

@# --- coreutils ---
Expand Down Expand Up @@ -186,6 +193,10 @@ $(COPY_MARKER): $(RUST_MARKER) $(C_MARKER)
@mkdir -p software/git/wasm
@[ -f "$(COMMANDS_DIR)/git" ] && cp -f "$(COMMANDS_DIR)/git" software/git/wasm/ || echo " WARN: git not found"

@# --- slack-cli (Go build, GOOS=wasip1) ---
@mkdir -p software/slack-cli/wasm
@[ -f "$(COMMANDS_DIR)/slack" ] && cp -f "$(COMMANDS_DIR)/slack" software/slack-cli/wasm/ || echo " WARN: slack not found (Go WASI build)"

@echo "=== Copy complete ==="
@touch $(COPY_MARKER)

Expand Down Expand Up @@ -321,6 +332,7 @@ clean-native:
@rm -rf $(NATIVE_DIR)/target
@rm -rf $(NATIVE_DIR)/vendor
@rm -rf $(NATIVE_DIR)/c/build $(NATIVE_DIR)/c/vendor $(NATIVE_DIR)/c/libs $(NATIVE_DIR)/c/.cache
@rm -rf $(NATIVE_DIR)/go/vendor
@rm -rf $(MARKER_DIR)
@echo "Cleaned native build artifacts"

Expand Down
66 changes: 66 additions & 0 deletions registry/native/go/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
SHELL := /bin/bash

# Output directory (shared with Rust/C builds)
COMMANDS_DIR ?= ../target/wasm32-wasip1/release/commands

# Vendor directory for upstream Go sources
VENDOR_DIR := vendor

# --- slack-cli ---
SLACK_CLI_REPO := https://github.com/slackapi/slack-cli.git
SLACK_CLI_COMMIT := 24c1d2c50b7f438700596c4d1902e0838a42fab0
SLACK_CLI_DIR := $(VENDOR_DIR)/slack-cli
SLACK_CLI_PATCHES := $(sort $(wildcard patches/slack-cli/*.patch))

.PHONY: wasm clean install

# ---------------------------------------------------------------------------
# Build all Go WASM commands
# ---------------------------------------------------------------------------
wasm: $(COMMANDS_DIR)/slack

# ---------------------------------------------------------------------------
# slack-cli
# ---------------------------------------------------------------------------

# Fetch upstream source at pinned commit
$(SLACK_CLI_DIR)/go.mod:
@echo "=== Fetching slack-cli ==="
@mkdir -p $(VENDOR_DIR)
git clone $(SLACK_CLI_REPO) $(SLACK_CLI_DIR)
git -C $(SLACK_CLI_DIR) checkout $(SLACK_CLI_COMMIT)

# Vendor Go dependencies
$(SLACK_CLI_DIR)/vendor/modules.txt: $(SLACK_CLI_DIR)/go.mod
@echo "=== Vendoring slack-cli dependencies ==="
cd $(SLACK_CLI_DIR) && go mod vendor

# Apply WASI patches to vendored dependencies
.PHONY: patch-slack-cli
patch-slack-cli: $(SLACK_CLI_DIR)/vendor/modules.txt
@echo "=== Applying WASI patches to slack-cli ==="
@for patch in $(SLACK_CLI_PATCHES); do \
echo " PATCH: $$patch"; \
patch --forward -p1 -d $(SLACK_CLI_DIR) < "$$patch" || \
echo " (already applied)"; \
done

# Build WASM binary
$(COMMANDS_DIR)/slack: $(SLACK_CLI_DIR)/vendor/modules.txt $(SLACK_CLI_PATCHES) | patch-slack-cli
@echo "=== Building slack-cli WASM ==="
@mkdir -p $(COMMANDS_DIR)
cd $(SLACK_CLI_DIR) && GOOS=wasip1 GOARCH=wasm go build -mod=vendor -o $(abspath $@) .
@echo " Built: $@ ($$(du -h $@ | cut -f1))"

# ---------------------------------------------------------------------------
# Install (copy to COMMANDS_DIR, for parity with C Makefile)
# ---------------------------------------------------------------------------
install:
@echo "Go binaries already output directly to COMMANDS_DIR"

# ---------------------------------------------------------------------------
# Clean
# ---------------------------------------------------------------------------
clean:
rm -rf $(VENDOR_DIR)
rm -f $(COMMANDS_DIR)/slack
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--- /dev/null
+++ b/vendor/github.com/atotto/clipboard/clipboard_wasip1.go
@@ -0,0 +1,13 @@
+//go:build wasip1
+
+package clipboard
+
+import "errors"
+
+func readAll() (string, error) {
+ return "", errors.New("clipboard not supported in WASM")
+}
+
+func writeAll(text string) error {
+ return errors.New("clipboard not supported in WASM")
+}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--- /dev/null
+++ b/vendor/charm.land/bubbletea/v2/signals_wasip1.go
@@ -0,0 +1,7 @@
+//go:build wasip1
+
+package tea
+
+func (p *Program) listenForResize(done chan struct{}) {
+ close(done)
+}
--- /dev/null
+++ b/vendor/charm.land/bubbletea/v2/tty_wasip1.go
@@ -0,0 +1,11 @@
+//go:build wasip1
+
+package tea
+
+const suspendSupported = false
+
+func suspendProcess() {}
+
+func (p *Program) initInput() error {
+ return nil
+}
10 changes: 10 additions & 0 deletions registry/native/go/patches/slack-cli/0003-go-git-wasip1-stub.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_wasip1.go
@@ -0,0 +1,7 @@
+//go:build wasip1
+
+package git
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ return false
+}
7 changes: 7 additions & 0 deletions registry/software/slack-cli/agent-os-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@rivet-dev/agent-os-slack-cli",
"type": "wasm",
"description": "Slack CLI for building apps on the Slack Platform",
"aptName": "slack-cli",
"source": "go"
}
28 changes: 28 additions & 0 deletions registry/software/slack-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@rivet-dev/agent-os-slack-cli",
"version": "0.0.0",
"type": "module",
"license": "Apache-2.0",
"description": "Slack CLI for building apps on the Slack Platform for agentOS",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist",
"wasm"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"scripts": {
"build": "tsc",
"check-types": "tsc --noEmit"
},
"devDependencies": {
"@rivet-dev/agent-os-registry-types": "link:../../../packages/registry-types",
"@types/node": "^22.10.2",
"typescript": "^5.9.2"
}
}
18 changes: 18 additions & 0 deletions registry/software/slack-cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { WasmCommandPackage } from "@rivet-dev/agent-os-registry-types";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));

const pkg = {
name: "slack-cli",
aptName: "slack-cli",
description: "Slack CLI for building apps on the Slack Platform",
source: "go" as const,
commands: [{ name: "slack", permissionTier: "full" as const }],
get commandDir() {
return resolve(__dirname, "..", "wasm");
},
} satisfies WasmCommandPackage;

export default pkg;
8 changes: 8 additions & 0 deletions registry/software/slack-cli/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}