act-cli 0.3.0__tar.gz → 0.3.2__tar.gz

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.
@@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.2] - 2026-03-29
9
+
10
+ ### Added
11
+
12
+ - `--http` flag for `act run` — explicit HTTP transport selection, `--listen` now accepts port number or full address
13
+ - Universal agent skill (`skills/act/SKILL.md`) — works with Claude Code, Cursor, OpenCode, Codex, OpenClaw via `npx skills add actcore/act-cli`
14
+ - SECURITY.md with trusted publishing, SBOM, and sandbox policies
15
+ - Snap packaging (experimental)
16
+
17
+ ### Changed
18
+
19
+ - npm root package moved to `@actcore/act`
20
+ - README rewritten with current CLI commands and platform support matrix
21
+
22
+ ### Fixed
23
+
24
+ - OCI refs with numeric tags (e.g. `ghcr.io/actpkg/sqlite:0.1.0`) now resolved correctly
25
+ - Tracing filter uses `act=info` instead of `act_cli=info` to match binary name
26
+
27
+ ## [0.3.1] - 2026-03-26
28
+
29
+ ### Changed
30
+
31
+ - Publish workflow uses crates.io trusted publishing (OIDC) instead of long-lived API token
32
+
33
+ ### Fixed
34
+
35
+ - SBOM artifact path in release workflow
36
+ - npm publish no longer misinterprets tarball paths as git URLs
37
+
8
38
  ## [0.3.0] - 2026-03-26
9
39
 
10
40
  ### Added
@@ -4,7 +4,7 @@ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "act-cli"
7
- version = "0.3.0"
7
+ version = "0.3.2"
8
8
  dependencies = [
9
9
  "act-types",
10
10
  "anyhow",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "act-cli"
3
- version = "0.3.0"
3
+ version = "0.3.2"
4
4
  edition = "2024"
5
5
  description = "CLI host for ACT (Agent Component Tools) WebAssembly components"
6
6
  license = "MIT OR Apache-2.0"
act_cli-0.3.2/PKG-INFO ADDED
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: act-cli
3
+ Version: 0.3.2
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Environment :: Console
6
+ Classifier: Intended Audience :: Developers
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: License :: OSI Approved :: Apache Software License
9
+ Classifier: Topic :: Software Development :: Libraries
10
+ License-File: LICENSE-APACHE
11
+ License-File: LICENSE-MIT
12
+ Summary: CLI host for ACT (Agent Component Tools) WebAssembly components
13
+ Keywords: act,wasm,component-model,mcp,agent
14
+ Home-Page: https://actcore.dev
15
+ License: MIT OR Apache-2.0
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
18
+ Project-URL: Homepage, https://actcore.dev
19
+ Project-URL: Repository, https://github.com/actcore/act-cli
20
+
21
+ # ACT CLI
22
+
23
+ CLI host for [ACT](https://actcore.dev) (Agent Component Tools) — run WebAssembly component tools from local files, HTTP URLs, or OCI registries.
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ npm i -g @actcore/act # npm
29
+ pip install act-cli # PyPI
30
+ cargo install act-cli # crates.io
31
+ ```
32
+
33
+ Pre-built binaries available on [GitHub Releases](https://github.com/actcore/act-cli/releases) and Docker (`ghcr.io/actcore/act`).
34
+
35
+ ## Quick Start
36
+
37
+ ```bash
38
+ # Discover tools in a component
39
+ act info --tools ghcr.io/actpkg/sqlite:0.1.0
40
+
41
+ # Call a tool
42
+ act call ghcr.io/actpkg/sqlite:0.1.0 query \
43
+ --args '{"sql":"SELECT sqlite_version()"}' \
44
+ --metadata '{"database_path":"/data/app.db"}' \
45
+ --allow-dir /data:./data
46
+
47
+ # Serve over HTTP
48
+ act run -l ghcr.io/actpkg/sqlite:0.1.0
49
+
50
+ # Serve over MCP stdio
51
+ act run --mcp ghcr.io/actpkg/sqlite:0.1.0
52
+ ```
53
+
54
+ Components can be referenced as:
55
+ - **OCI refs:** `ghcr.io/actpkg/sqlite:0.1.0`
56
+ - **HTTP URLs:** `https://example.com/component.wasm`
57
+ - **Local paths:** `./component.wasm`
58
+
59
+ Remote components are cached in `~/.cache/act/components/`.
60
+
61
+ ## Commands
62
+
63
+ | Command | Description |
64
+ |---------|-------------|
65
+ | `run` | Serve a component over ACT-HTTP (`-l`) or MCP stdio (`--mcp`) |
66
+ | `call` | Call a tool directly, print result to stdout |
67
+ | `info` | Show component metadata, tools, and schemas (`--tools`, `--format text\|json`) |
68
+ | `pull` | Download a component from OCI or HTTP to local file |
69
+
70
+ ## HTTP Endpoints (`run -l`)
71
+
72
+ | Method | Path | Description |
73
+ |--------|------|-------------|
74
+ | `GET` | `/info` | Component metadata |
75
+ | `POST` | `/metadata-schema` | JSON Schema for metadata |
76
+ | `POST/QUERY` | `/tools` | List tools |
77
+ | `POST/QUERY` | `/tools/{name}` | Call a tool (SSE with `Accept: text/event-stream`) |
78
+
79
+ ## Platform Support
80
+
81
+ | Architecture | Linux (GNU) | Linux (musl) | macOS | Windows | Docker |
82
+ |-------------|:-----------:|:------------:|:-----:|:-------:|:------:|
83
+ | x86_64 | ✓ | ✓ | ✓ | ✓ | ✓ |
84
+ | aarch64 | ✓ | ✓ | ✓ | ✓ | ✓ |
85
+ | riscv64 | ✓ | ✓ | — | — | ✓ |
86
+
87
+ RISC-V (`riscv64`) is a first-class target. Regressions on RISC-V are release-blocking.
88
+
89
+ ## Building
90
+
91
+ ```bash
92
+ cargo build --release
93
+ ```
94
+
95
+ Set `RUST_LOG=act=debug` for verbose output.
96
+
97
+ ## License
98
+
99
+ MIT OR Apache-2.0
100
+
@@ -0,0 +1,79 @@
1
+ # ACT CLI
2
+
3
+ CLI host for [ACT](https://actcore.dev) (Agent Component Tools) — run WebAssembly component tools from local files, HTTP URLs, or OCI registries.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i -g @actcore/act # npm
9
+ pip install act-cli # PyPI
10
+ cargo install act-cli # crates.io
11
+ ```
12
+
13
+ Pre-built binaries available on [GitHub Releases](https://github.com/actcore/act-cli/releases) and Docker (`ghcr.io/actcore/act`).
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ # Discover tools in a component
19
+ act info --tools ghcr.io/actpkg/sqlite:0.1.0
20
+
21
+ # Call a tool
22
+ act call ghcr.io/actpkg/sqlite:0.1.0 query \
23
+ --args '{"sql":"SELECT sqlite_version()"}' \
24
+ --metadata '{"database_path":"/data/app.db"}' \
25
+ --allow-dir /data:./data
26
+
27
+ # Serve over HTTP
28
+ act run -l ghcr.io/actpkg/sqlite:0.1.0
29
+
30
+ # Serve over MCP stdio
31
+ act run --mcp ghcr.io/actpkg/sqlite:0.1.0
32
+ ```
33
+
34
+ Components can be referenced as:
35
+ - **OCI refs:** `ghcr.io/actpkg/sqlite:0.1.0`
36
+ - **HTTP URLs:** `https://example.com/component.wasm`
37
+ - **Local paths:** `./component.wasm`
38
+
39
+ Remote components are cached in `~/.cache/act/components/`.
40
+
41
+ ## Commands
42
+
43
+ | Command | Description |
44
+ |---------|-------------|
45
+ | `run` | Serve a component over ACT-HTTP (`-l`) or MCP stdio (`--mcp`) |
46
+ | `call` | Call a tool directly, print result to stdout |
47
+ | `info` | Show component metadata, tools, and schemas (`--tools`, `--format text\|json`) |
48
+ | `pull` | Download a component from OCI or HTTP to local file |
49
+
50
+ ## HTTP Endpoints (`run -l`)
51
+
52
+ | Method | Path | Description |
53
+ |--------|------|-------------|
54
+ | `GET` | `/info` | Component metadata |
55
+ | `POST` | `/metadata-schema` | JSON Schema for metadata |
56
+ | `POST/QUERY` | `/tools` | List tools |
57
+ | `POST/QUERY` | `/tools/{name}` | Call a tool (SSE with `Accept: text/event-stream`) |
58
+
59
+ ## Platform Support
60
+
61
+ | Architecture | Linux (GNU) | Linux (musl) | macOS | Windows | Docker |
62
+ |-------------|:-----------:|:------------:|:-----:|:-------:|:------:|
63
+ | x86_64 | ✓ | ✓ | ✓ | ✓ | ✓ |
64
+ | aarch64 | ✓ | ✓ | ✓ | ✓ | ✓ |
65
+ | riscv64 | ✓ | ✓ | — | — | ✓ |
66
+
67
+ RISC-V (`riscv64`) is a first-class target. Regressions on RISC-V are release-blocking.
68
+
69
+ ## Building
70
+
71
+ ```bash
72
+ cargo build --release
73
+ ```
74
+
75
+ Set `RUST_LOG=act=debug` for verbose output.
76
+
77
+ ## License
78
+
79
+ MIT OR Apache-2.0
@@ -50,13 +50,17 @@ enum Cli {
50
50
  /// Component reference (path, URL, OCI ref, or name)
51
51
  component: String,
52
52
 
53
- /// Serve over MCP stdio instead of HTTP
53
+ /// Serve over MCP stdio
54
54
  #[arg(long)]
55
55
  mcp: bool,
56
56
 
57
- /// Address to listen on (host:port). Default: [::1]:3000
58
- #[arg(short, long, num_args = 0..=1, default_missing_value = "[::1]:3000")]
59
- listen: Option<SocketAddr>,
57
+ /// Serve over ACT-HTTP
58
+ #[arg(long)]
59
+ http: bool,
60
+
61
+ /// Listen address: [host]:port or just port (default: [::1]:3000)
62
+ #[arg(short, long)]
63
+ listen: Option<String>,
60
64
 
61
65
  #[command(flatten)]
62
66
  opts: CommonOpts,
@@ -127,8 +131,8 @@ async fn main() -> Result<()> {
127
131
  .ok()
128
132
  .and_then(|c| c.log_level);
129
133
  let directive = match log_level.as_deref() {
130
- Some(level) => format!("act_cli={level}"),
131
- None => "act_cli=info".to_string(),
134
+ Some(level) => format!("act={level}"),
135
+ None => "act=info".to_string(),
132
136
  };
133
137
  directive.parse().expect("valid log filter")
134
138
  };
@@ -142,9 +146,10 @@ async fn main() -> Result<()> {
142
146
  Cli::Run {
143
147
  component,
144
148
  mcp,
149
+ http,
145
150
  listen,
146
151
  opts,
147
- } => cmd_run(component, mcp, listen, opts).await,
152
+ } => cmd_run(component, mcp, http, listen, opts).await,
148
153
  Cli::Call {
149
154
  component,
150
155
  tool,
@@ -242,6 +247,13 @@ async fn prepare_component(component: &str, opts: &CommonOpts) -> Result<Prepare
242
247
  .map(|v| runtime::Metadata::from(v.clone()))
243
248
  .unwrap_or_default();
244
249
 
250
+ tracing::info!(
251
+ name = %info.name,
252
+ version = %info.version,
253
+ path = %component_path.display(),
254
+ "Loading component"
255
+ );
256
+
245
257
  let engine = runtime::create_engine()?;
246
258
  let wasm = runtime::load_component(&engine, &component_path)?;
247
259
  let linker = runtime::create_linker(&engine)?;
@@ -249,7 +261,7 @@ async fn prepare_component(component: &str, opts: &CommonOpts) -> Result<Prepare
249
261
  runtime::instantiate_component(&engine, &wasm, &linker, &fs_config).await?;
250
262
  let handle = runtime::spawn_component_actor(instance, store);
251
263
 
252
- tracing::info!(name = %info.name, version = %info.version, "Loaded component");
264
+ tracing::info!(name = %info.name, version = %info.version, "Component ready");
253
265
 
254
266
  Ok(PreparedComponent {
255
267
  info,
@@ -260,14 +272,28 @@ async fn prepare_component(component: &str, opts: &CommonOpts) -> Result<Prepare
260
272
 
261
273
  // ── Commands ─────────────────────────────────────────────────────────────────
262
274
 
275
+ /// Parse a listen address: either `[host]:port` or just a port number.
276
+ fn parse_listen_addr(s: &str) -> Result<SocketAddr> {
277
+ // Try as full socket address first
278
+ if let Ok(addr) = s.parse::<SocketAddr>() {
279
+ return Ok(addr);
280
+ }
281
+ // Try as port number
282
+ if let Ok(port) = s.parse::<u16>() {
283
+ return Ok(SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], port)));
284
+ }
285
+ anyhow::bail!("invalid listen address: {s} (expected [host]:port or port number)")
286
+ }
287
+
263
288
  async fn cmd_run(
264
289
  component: String,
265
290
  mcp: bool,
266
- listen: Option<SocketAddr>,
291
+ http: bool,
292
+ listen: Option<String>,
267
293
  opts: CommonOpts,
268
294
  ) -> Result<()> {
269
- if mcp && listen.is_some() {
270
- anyhow::bail!("MCP over HTTP not yet supported");
295
+ if mcp && http {
296
+ anyhow::bail!("--mcp and --http are mutually exclusive");
271
297
  }
272
298
 
273
299
  if mcp {
@@ -275,7 +301,12 @@ async fn cmd_run(
275
301
  return mcp::run_stdio(pc.info, pc.handle, pc.metadata).await;
276
302
  }
277
303
 
278
- if let Some(addr) = listen {
304
+ if http || listen.is_some() {
305
+ let addr = match &listen {
306
+ Some(s) => parse_listen_addr(s)?,
307
+ None => "[::1]:3000".parse().unwrap(),
308
+ };
309
+
279
310
  let pc = prepare_component(&component, &opts).await?;
280
311
 
281
312
  let state = Arc::new(http::AppState {
@@ -293,9 +324,7 @@ async fn cmd_run(
293
324
  return Ok(());
294
325
  }
295
326
 
296
- anyhow::bail!(
297
- "ACT stdio not yet implemented. Use --listen to serve over HTTP or --mcp for MCP stdio."
298
- )
327
+ anyhow::bail!("Specify a transport: --http (ACT-HTTP server) or --mcp (MCP stdio)")
299
328
  }
300
329
 
301
330
  async fn cmd_call(component: String, tool: String, args: String, opts: CommonOpts) -> Result<()> {
@@ -31,7 +31,7 @@ pub enum ComponentRef {
31
31
  /// Registry host must contain a dot or be `localhost`.
32
32
  static OCI_RE: LazyLock<Regex> = LazyLock::new(|| {
33
33
  Regex::new(
34
- r"^(?:localhost(?::\d+)?|[a-zA-Z0-9][\w.-]*\.[a-zA-Z]{2,}(?::\d+)?)/[a-zA-Z0-9][\w./-]*(?::[a-zA-Z][\w.-]*|@sha256:[a-fA-F0-9]+)?$"
34
+ r"^(?:localhost(?::\d+)?|[a-zA-Z0-9][\w.-]*\.[a-zA-Z]{2,}(?::\d+)?)/[a-zA-Z0-9][\w./-]*(?::[\w][\w.-]*|@sha256:[a-fA-F0-9]+)?$"
35
35
  ).unwrap()
36
36
  });
37
37
 
@@ -112,6 +112,7 @@ async fn cache_path(input: &str) -> Result<PathBuf> {
112
112
  /// If `fresh` is true, bypass cache and re-download.
113
113
  /// Returns the path to the .wasm file.
114
114
  pub async fn resolve(component_ref: &ComponentRef, fresh: bool) -> Result<PathBuf> {
115
+ tracing::info!(ref = %component_ref, "Resolving component");
115
116
  match component_ref {
116
117
  ComponentRef::Local(path) => {
117
118
  anyhow::ensure!(
@@ -119,6 +120,7 @@ pub async fn resolve(component_ref: &ComponentRef, fresh: bool) -> Result<PathBu
119
120
  "component not found: {}",
120
121
  path.display()
121
122
  );
123
+ tracing::debug!(path = %path.display(), "Using local component");
122
124
  Ok(path.clone())
123
125
  }
124
126
  ComponentRef::Http(url) => resolve_http(url.as_str(), fresh).await,
@@ -162,7 +164,7 @@ fn make_progress_bar(total: Option<u64>, message: &str) -> ProgressBar {
162
164
  async fn resolve_http(url: &str, fresh: bool) -> Result<PathBuf> {
163
165
  let cached = cache_path(url).await?;
164
166
  if !fresh && tokio::fs::try_exists(&cached).await.unwrap_or(false) {
165
- tracing::debug!(%url, path = %cached.display(), "Using cached component");
167
+ tracing::info!(%url, path = %cached.display(), "Using cached component");
166
168
  return Ok(cached);
167
169
  }
168
170
 
@@ -196,7 +198,7 @@ async fn resolve_http(url: &str, fresh: bool) -> Result<PathBuf> {
196
198
  async fn resolve_oci(reference: &str, fresh: bool) -> Result<PathBuf> {
197
199
  let cached = cache_path(reference).await?;
198
200
  if !fresh && tokio::fs::try_exists(&cached).await.unwrap_or(false) {
199
- tracing::debug!(%reference, path = %cached.display(), "Using cached component");
201
+ tracing::info!(%reference, path = %cached.display(), "Using cached component");
200
202
  return Ok(cached);
201
203
  }
202
204
 
@@ -309,6 +311,14 @@ mod tests {
309
311
  ));
310
312
  }
311
313
 
314
+ #[test]
315
+ fn parse_oci_semver_tag() {
316
+ assert!(matches!(
317
+ parse("ghcr.io/actpkg/sqlite:0.1.0"),
318
+ ComponentRef::Oci(_)
319
+ ));
320
+ }
321
+
312
322
  #[test]
313
323
  fn parse_local_relative() {
314
324
  assert!(matches!(parse("./component.wasm"), ComponentRef::Local(_)));
act_cli-0.3.0/PKG-INFO DELETED
@@ -1,72 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: act-cli
3
- Version: 0.3.0
4
- Classifier: Development Status :: 4 - Beta
5
- Classifier: Environment :: Console
6
- Classifier: Intended Audience :: Developers
7
- Classifier: License :: OSI Approved :: MIT License
8
- Classifier: License :: OSI Approved :: Apache Software License
9
- Classifier: Topic :: Software Development :: Libraries
10
- License-File: LICENSE-APACHE
11
- License-File: LICENSE-MIT
12
- Summary: CLI host for ACT (Agent Component Tools) WebAssembly components
13
- Keywords: act,wasm,component-model,mcp,agent
14
- Home-Page: https://actcore.dev
15
- License: MIT OR Apache-2.0
16
- Requires-Python: >=3.8
17
- Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
18
- Project-URL: Homepage, https://actcore.dev
19
- Project-URL: Repository, https://github.com/actcore/act-cli
20
-
21
- # act-cli
22
-
23
- CLI and reference host for [ACT](../act-spec/) — loads `.wasm` ACT components and serves them over HTTP or MCP (stdio).
24
-
25
- ## Usage
26
-
27
- ```
28
- act serve <component.wasm> [-l [::1]:3000]
29
- act call <component.wasm> <tool-name> [--args '{}'] [-c '{}']
30
- act mcp <component.wasm> [-c '{}'] [--config-file config.json]
31
- act info <component.wasm>
32
- act tools <component.wasm> [-c '{}']
33
- ```
34
-
35
- Set `RUST_LOG=act_cli=debug` for verbose output.
36
-
37
- ## Commands
38
-
39
- | Command | Description |
40
- |---------|-------------|
41
- | `serve` | Start ACT-HTTP server for a component |
42
- | `call` | Call a tool directly, print result to stdout |
43
- | `mcp` | Serve component as MCP server over stdio |
44
- | `info` | Show component name, version, description, capabilities |
45
- | `tools` | List tools exposed by a component |
46
-
47
- ## HTTP Endpoints (`serve`)
48
-
49
- | Method | Path | Description |
50
- |--------|------|-------------|
51
- | `GET` | `/info` | Component metadata |
52
- | `GET` | `/config-schema` | JSON Schema for config (204 if none) |
53
- | `GET` | `/tools` | List tools |
54
- | `POST` | `/tools/{name}` | Call a tool |
55
-
56
- ## Building
57
-
58
- ```
59
- cargo build --release
60
- ```
61
-
62
- ## Architecture
63
-
64
- ```
65
- main.rs CLI (clap) → subcommands (serve, call, mcp, info, tools)
66
- runtime.rs wasmtime engine, component instantiation, actor pattern
67
- http.rs axum routes, ACT-HTTP request/response handling
68
- mcp.rs MCP JSON-RPC over stdio
69
- ```
70
-
71
- The host uses an actor pattern: a single tokio task owns the wasmtime `Store` and component instance, receiving requests over an mpsc channel. This ensures single-threaded access to the Wasm component while allowing concurrent HTTP handling.
72
-
act_cli-0.3.0/README.md DELETED
@@ -1,51 +0,0 @@
1
- # act-cli
2
-
3
- CLI and reference host for [ACT](../act-spec/) — loads `.wasm` ACT components and serves them over HTTP or MCP (stdio).
4
-
5
- ## Usage
6
-
7
- ```
8
- act serve <component.wasm> [-l [::1]:3000]
9
- act call <component.wasm> <tool-name> [--args '{}'] [-c '{}']
10
- act mcp <component.wasm> [-c '{}'] [--config-file config.json]
11
- act info <component.wasm>
12
- act tools <component.wasm> [-c '{}']
13
- ```
14
-
15
- Set `RUST_LOG=act_cli=debug` for verbose output.
16
-
17
- ## Commands
18
-
19
- | Command | Description |
20
- |---------|-------------|
21
- | `serve` | Start ACT-HTTP server for a component |
22
- | `call` | Call a tool directly, print result to stdout |
23
- | `mcp` | Serve component as MCP server over stdio |
24
- | `info` | Show component name, version, description, capabilities |
25
- | `tools` | List tools exposed by a component |
26
-
27
- ## HTTP Endpoints (`serve`)
28
-
29
- | Method | Path | Description |
30
- |--------|------|-------------|
31
- | `GET` | `/info` | Component metadata |
32
- | `GET` | `/config-schema` | JSON Schema for config (204 if none) |
33
- | `GET` | `/tools` | List tools |
34
- | `POST` | `/tools/{name}` | Call a tool |
35
-
36
- ## Building
37
-
38
- ```
39
- cargo build --release
40
- ```
41
-
42
- ## Architecture
43
-
44
- ```
45
- main.rs CLI (clap) → subcommands (serve, call, mcp, info, tools)
46
- runtime.rs wasmtime engine, component instantiation, actor pattern
47
- http.rs axum routes, ACT-HTTP request/response handling
48
- mcp.rs MCP JSON-RPC over stdio
49
- ```
50
-
51
- The host uses an actor pattern: a single tokio task owns the wasmtime `Store` and component instance, receiving requests over an mpsc channel. This ensures single-threaded access to the Wasm component while allowing concurrent HTTP handling.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes