act-cli 0.8.0__tar.gz → 0.8.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.
Files changed (40) hide show
  1. {act_cli-0.8.0 → act_cli-0.8.2}/Cargo.lock +81 -51
  2. {act_cli-0.8.0 → act_cli-0.8.2}/Cargo.toml +1 -1
  3. {act_cli-0.8.0 → act_cli-0.8.2}/PKG-INFO +1 -1
  4. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/Cargo.toml +1 -0
  5. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/main.rs +42 -1
  6. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/mod.rs +19 -3
  7. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/Cargo.toml +2 -2
  8. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/lock.rs +6 -5
  9. {act_cli-0.8.0 → act_cli-0.8.2}/README.md +0 -0
  10. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/README.md +0 -0
  11. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/build.rs +0 -0
  12. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/config.rs +0 -0
  13. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/format.rs +0 -0
  14. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/http.rs +0 -0
  15. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/resolve.rs +0 -0
  16. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/rmcp_bridge.rs +0 -0
  17. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/bindings/mod.rs +0 -0
  18. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/effective.rs +0 -0
  19. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/fs_matcher.rs +0 -0
  20. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/fs_policy.rs +0 -0
  21. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/http_client.rs +0 -0
  22. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/http_policy.rs +0 -0
  23. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/network.rs +0 -0
  24. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/sessions.rs +0 -0
  25. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/src/runtime/sockets_policy.rs +0 -0
  26. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/wit/deps/act-core/act-core.wit +0 -0
  27. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/wit/deps/act-tools/act-tools.wit +0 -0
  28. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/wit/deps.lock +0 -0
  29. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/wit/deps.toml +0 -0
  30. {act_cli-0.8.0 → act_cli-0.8.2}/act-cli/wit/world.wit +0 -0
  31. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/README.md +0 -0
  32. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/fetch.rs +0 -0
  33. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/index.rs +0 -0
  34. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/layout.rs +0 -0
  35. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/lib.rs +0 -0
  36. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/provenance.rs +0 -0
  37. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/reference.rs +0 -0
  38. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/referrer.rs +0 -0
  39. {act_cli-0.8.0 → act_cli-0.8.2}/crates/act-store/src/store.rs +0 -0
  40. {act_cli-0.8.0 → act_cli-0.8.2}/pyproject.toml +0 -0
@@ -4,7 +4,7 @@ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "act-build"
7
- version = "0.8.0"
7
+ version = "0.8.2"
8
8
  dependencies = [
9
9
  "act-types",
10
10
  "anyhow",
@@ -14,11 +14,13 @@ dependencies = [
14
14
  "dirs",
15
15
  "flate2",
16
16
  "globset",
17
+ "http",
17
18
  "include_dir",
18
19
  "json-patch",
19
20
  "minijinja",
20
21
  "oci-client",
21
- "reqwest 0.13.3",
22
+ "olpc-cjson",
23
+ "reqwest 0.13.4",
22
24
  "serde",
23
25
  "serde_json",
24
26
  "sha2 0.11.0",
@@ -35,7 +37,7 @@ dependencies = [
35
37
 
36
38
  [[package]]
37
39
  name = "act-cli"
38
- version = "0.8.0"
40
+ version = "0.8.2"
39
41
  dependencies = [
40
42
  "act-store",
41
43
  "act-types",
@@ -43,6 +45,7 @@ dependencies = [
43
45
  "axum",
44
46
  "base64",
45
47
  "bytes",
48
+ "bytesize",
46
49
  "ciborium",
47
50
  "cidr",
48
51
  "clap",
@@ -58,7 +61,7 @@ dependencies = [
58
61
  "owo-colors",
59
62
  "path-clean",
60
63
  "regex",
61
- "reqwest 0.13.3",
64
+ "reqwest 0.13.4",
62
65
  "rmcp",
63
66
  "serde",
64
67
  "serde_json",
@@ -81,11 +84,11 @@ dependencies = [
81
84
 
82
85
  [[package]]
83
86
  name = "act-store"
84
- version = "0.1.0"
87
+ version = "0.1.1"
85
88
  dependencies = [
86
89
  "chrono",
87
90
  "dirs",
88
- "fs2",
91
+ "fs4",
89
92
  "oci-client",
90
93
  "oci-spec",
91
94
  "regex",
@@ -326,9 +329,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
326
329
 
327
330
  [[package]]
328
331
  name = "bitflags"
329
- version = "2.11.1"
332
+ version = "2.12.1"
330
333
  source = "registry+https://github.com/rust-lang/crates.io-index"
331
- checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
334
+ checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a"
332
335
 
333
336
  [[package]]
334
337
  name = "block-buffer"
@@ -382,6 +385,12 @@ version = "1.11.1"
382
385
  source = "registry+https://github.com/rust-lang/crates.io-index"
383
386
  checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
384
387
 
388
+ [[package]]
389
+ name = "bytesize"
390
+ version = "2.3.1"
391
+ source = "registry+https://github.com/rust-lang/crates.io-index"
392
+ checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3"
393
+
385
394
  [[package]]
386
395
  name = "cap-fs-ext"
387
396
  version = "3.4.5"
@@ -452,9 +461,9 @@ dependencies = [
452
461
 
453
462
  [[package]]
454
463
  name = "cc"
455
- version = "1.2.62"
464
+ version = "1.2.63"
456
465
  source = "registry+https://github.com/rust-lang/crates.io-index"
457
- checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
466
+ checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f"
458
467
  dependencies = [
459
468
  "find-msvc-tools",
460
469
  "jobserver",
@@ -1073,9 +1082,9 @@ dependencies = [
1073
1082
 
1074
1083
  [[package]]
1075
1084
  name = "displaydoc"
1076
- version = "0.2.5"
1085
+ version = "0.2.6"
1077
1086
  source = "registry+https://github.com/rust-lang/crates.io-index"
1078
- checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
1087
+ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
1079
1088
  dependencies = [
1080
1089
  "proc-macro2",
1081
1090
  "quote",
@@ -1226,13 +1235,13 @@ dependencies = [
1226
1235
  ]
1227
1236
 
1228
1237
  [[package]]
1229
- name = "fs2"
1230
- version = "0.4.3"
1238
+ name = "fs4"
1239
+ version = "1.1.0"
1231
1240
  source = "registry+https://github.com/rust-lang/crates.io-index"
1232
- checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
1241
+ checksum = "7e72ed92b67c146290f88e9c89d60ca163ea417a446f61ffd7b72df3e7f1dfd5"
1233
1242
  dependencies = [
1234
- "libc",
1235
- "winapi",
1243
+ "rustix",
1244
+ "windows-sys 0.61.2",
1236
1245
  ]
1237
1246
 
1238
1247
  [[package]]
@@ -1513,9 +1522,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
1513
1522
 
1514
1523
  [[package]]
1515
1524
  name = "http"
1516
- version = "1.4.0"
1525
+ version = "1.4.1"
1517
1526
  source = "registry+https://github.com/rust-lang/crates.io-index"
1518
- checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
1527
+ checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0"
1519
1528
  dependencies = [
1520
1529
  "bytes",
1521
1530
  "itoa",
@@ -1576,9 +1585,9 @@ dependencies = [
1576
1585
 
1577
1586
  [[package]]
1578
1587
  name = "hyper"
1579
- version = "1.9.0"
1588
+ version = "1.10.1"
1580
1589
  source = "registry+https://github.com/rust-lang/crates.io-index"
1581
- checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
1590
+ checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
1582
1591
  dependencies = [
1583
1592
  "atomic-waker",
1584
1593
  "bytes",
@@ -2059,9 +2068,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
2059
2068
 
2060
2069
  [[package]]
2061
2070
  name = "libredox"
2062
- version = "0.1.16"
2071
+ version = "0.1.17"
2063
2072
  source = "registry+https://github.com/rust-lang/crates.io-index"
2064
- checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
2073
+ checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
2065
2074
  dependencies = [
2066
2075
  "libc",
2067
2076
  ]
@@ -2089,9 +2098,9 @@ dependencies = [
2089
2098
 
2090
2099
  [[package]]
2091
2100
  name = "log"
2092
- version = "0.4.29"
2101
+ version = "0.4.31"
2093
2102
  source = "registry+https://github.com/rust-lang/crates.io-index"
2094
- checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
2103
+ checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f"
2095
2104
 
2096
2105
  [[package]]
2097
2106
  name = "lru-slab"
@@ -2131,9 +2140,9 @@ checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4"
2131
2140
 
2132
2141
  [[package]]
2133
2142
  name = "memchr"
2134
- version = "2.8.0"
2143
+ version = "2.8.1"
2135
2144
  source = "registry+https://github.com/rust-lang/crates.io-index"
2136
- checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
2145
+ checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
2137
2146
 
2138
2147
  [[package]]
2139
2148
  name = "memfd"
@@ -2178,9 +2187,9 @@ dependencies = [
2178
2187
 
2179
2188
  [[package]]
2180
2189
  name = "mio"
2181
- version = "1.2.0"
2190
+ version = "1.2.1"
2182
2191
  source = "registry+https://github.com/rust-lang/crates.io-index"
2183
- checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
2192
+ checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
2184
2193
  dependencies = [
2185
2194
  "libc",
2186
2195
  "wasi",
@@ -2252,7 +2261,7 @@ dependencies = [
2252
2261
  "oci-spec",
2253
2262
  "olpc-cjson",
2254
2263
  "regex",
2255
- "reqwest 0.13.3",
2264
+ "reqwest 0.13.4",
2256
2265
  "serde",
2257
2266
  "serde_json",
2258
2267
  "sha2 0.11.0",
@@ -2793,9 +2802,9 @@ dependencies = [
2793
2802
 
2794
2803
  [[package]]
2795
2804
  name = "reqwest"
2796
- version = "0.13.3"
2805
+ version = "0.13.4"
2797
2806
  source = "registry+https://github.com/rust-lang/crates.io-index"
2798
- checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0"
2807
+ checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
2799
2808
  dependencies = [
2800
2809
  "base64",
2801
2810
  "bytes",
@@ -2953,9 +2962,9 @@ dependencies = [
2953
2962
 
2954
2963
  [[package]]
2955
2964
  name = "rustls-native-certs"
2956
- version = "0.8.3"
2965
+ version = "0.8.4"
2957
2966
  source = "registry+https://github.com/rust-lang/crates.io-index"
2958
- checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
2967
+ checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d"
2959
2968
  dependencies = [
2960
2969
  "openssl-probe",
2961
2970
  "rustls-pki-types",
@@ -3279,9 +3288,9 @@ dependencies = [
3279
3288
 
3280
3289
  [[package]]
3281
3290
  name = "shlex"
3282
- version = "1.3.0"
3291
+ version = "2.0.1"
3283
3292
  source = "registry+https://github.com/rust-lang/crates.io-index"
3284
- checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
3293
+ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
3285
3294
 
3286
3295
  [[package]]
3287
3296
  name = "signal-hook-registry"
@@ -3341,9 +3350,9 @@ dependencies = [
3341
3350
 
3342
3351
  [[package]]
3343
3352
  name = "socket2"
3344
- version = "0.6.3"
3353
+ version = "0.6.4"
3345
3354
  source = "registry+https://github.com/rust-lang/crates.io-index"
3346
- checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
3355
+ checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
3347
3356
  dependencies = [
3348
3357
  "libc",
3349
3358
  "windows-sys 0.61.2",
@@ -3833,9 +3842,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
3833
3842
 
3834
3843
  [[package]]
3835
3844
  name = "typenum"
3836
- version = "1.20.0"
3845
+ version = "1.20.1"
3837
3846
  source = "registry+https://github.com/rust-lang/crates.io-index"
3838
- checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
3847
+ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
3839
3848
 
3840
3849
  [[package]]
3841
3850
  name = "unicase"
@@ -3914,9 +3923,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
3914
3923
 
3915
3924
  [[package]]
3916
3925
  name = "uuid"
3917
- version = "1.23.1"
3926
+ version = "1.23.2"
3918
3927
  source = "registry+https://github.com/rust-lang/crates.io-index"
3919
- checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
3928
+ checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7"
3920
3929
  dependencies = [
3921
3930
  "getrandom 0.4.2",
3922
3931
  "js-sys",
@@ -4080,6 +4089,16 @@ dependencies = [
4080
4089
  "wasmparser 0.250.0",
4081
4090
  ]
4082
4091
 
4092
+ [[package]]
4093
+ name = "wasm-encoder"
4094
+ version = "0.251.0"
4095
+ source = "registry+https://github.com/rust-lang/crates.io-index"
4096
+ checksum = "5a879a421bd17c528b74721b2abf4c62e8f1d1889c2ba8c3c50d02deaf2ce395"
4097
+ dependencies = [
4098
+ "leb128fmt",
4099
+ "wasmparser 0.251.0",
4100
+ ]
4101
+
4083
4102
  [[package]]
4084
4103
  name = "wasm-metadata"
4085
4104
  version = "0.244.0"
@@ -4143,6 +4162,17 @@ dependencies = [
4143
4162
  "serde",
4144
4163
  ]
4145
4164
 
4165
+ [[package]]
4166
+ name = "wasmparser"
4167
+ version = "0.251.0"
4168
+ source = "registry+https://github.com/rust-lang/crates.io-index"
4169
+ checksum = "437970b35b1a85cfde9c74b2398352d8d653f3bd8e3a3db0c063ea8f5b4b36ff"
4170
+ dependencies = [
4171
+ "bitflags",
4172
+ "indexmap 2.14.0",
4173
+ "semver",
4174
+ ]
4175
+
4146
4176
  [[package]]
4147
4177
  name = "wasmprinter"
4148
4178
  version = "0.248.0"
@@ -4477,22 +4507,22 @@ dependencies = [
4477
4507
 
4478
4508
  [[package]]
4479
4509
  name = "wast"
4480
- version = "250.0.0"
4510
+ version = "251.0.0"
4481
4511
  source = "registry+https://github.com/rust-lang/crates.io-index"
4482
- checksum = "69e9294a1f0204aeb5c47e95165517f43ef3cc895918c4f3e939380d4c290f4a"
4512
+ checksum = "5cc7467dda0a96142eb2c980329dfb62480b1e1d3622fdeb1a44e2bca6ceed74"
4483
4513
  dependencies = [
4484
4514
  "bumpalo",
4485
4515
  "leb128fmt",
4486
4516
  "memchr",
4487
4517
  "unicode-width",
4488
- "wasm-encoder 0.250.0",
4518
+ "wasm-encoder 0.251.0",
4489
4519
  ]
4490
4520
 
4491
4521
  [[package]]
4492
4522
  name = "wat"
4493
- version = "1.250.0"
4523
+ version = "1.251.0"
4494
4524
  source = "registry+https://github.com/rust-lang/crates.io-index"
4495
- checksum = "0a549ed329a70e444e0f7796391ab2a87d0aef30ddde9f60e16e429224fafd02"
4525
+ checksum = "81b1086c9e85b95bd6a229a928bc6c6d0662e42af0250c88d067b418831ea4d4"
4496
4526
  dependencies = [
4497
4527
  "wast",
4498
4528
  ]
@@ -5036,18 +5066,18 @@ dependencies = [
5036
5066
 
5037
5067
  [[package]]
5038
5068
  name = "zerocopy"
5039
- version = "0.8.48"
5069
+ version = "0.8.50"
5040
5070
  source = "registry+https://github.com/rust-lang/crates.io-index"
5041
- checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
5071
+ checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1"
5042
5072
  dependencies = [
5043
5073
  "zerocopy-derive",
5044
5074
  ]
5045
5075
 
5046
5076
  [[package]]
5047
5077
  name = "zerocopy-derive"
5048
- version = "0.8.48"
5078
+ version = "0.8.50"
5049
5079
  source = "registry+https://github.com/rust-lang/crates.io-index"
5050
- checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
5080
+ checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639"
5051
5081
  dependencies = [
5052
5082
  "proc-macro2",
5053
5083
  "quote",
@@ -3,7 +3,7 @@ members = ["act-cli", "crates/act-store"]
3
3
  resolver = "3"
4
4
 
5
5
  [workspace.package]
6
- version = "0.8.0"
6
+ version = "0.8.2"
7
7
  edition = "2024"
8
8
  license = "MIT OR Apache-2.0"
9
9
  repository = "https://github.com/actcore/act-cli"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: act-cli
3
- Version: 0.8.0
3
+ Version: 0.8.2
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -57,6 +57,7 @@ globset = "0.4"
57
57
  path-clean = "1"
58
58
  owo-colors = { version = "4.3.0", features = ["supports-colors"] }
59
59
  act-store = { version = "0.1.0", path = "../crates/act-store" }
60
+ bytesize = "2.3.1"
60
61
 
61
62
  [dev-dependencies]
62
63
  tempfile = "3"
@@ -55,6 +55,12 @@ struct CommonOpts {
55
55
  #[arg(long = "deny-socket")]
56
56
  sockets_deny: Vec<String>,
57
57
 
58
+ /// Cap the component's wasm linear memory. Accepts a byte count or a size
59
+ /// with a unit — binary (`512MiB`) or decimal (`512MB`). Growth past the cap
60
+ /// fails inside the guest instead of ballooning the host process.
61
+ #[arg(long = "max-memory", value_parser = parse_max_memory)]
62
+ max_memory: Option<usize>,
63
+
58
64
  /// Use a named profile from the config file
59
65
  #[arg(long)]
60
66
  profile: Option<String>,
@@ -318,6 +324,22 @@ fn parse_cli_metadata(
318
324
  }
319
325
  }
320
326
 
327
+ /// Parse a `--max-memory` value via the `bytesize` crate: a byte count or a
328
+ /// size with a unit, decimal (`512MB` = 512·10⁶) or binary (`512MiB` = 512·2²⁰).
329
+ fn parse_max_memory(s: &str) -> Result<usize, String> {
330
+ let bytes = s
331
+ .trim()
332
+ .parse::<bytesize::ByteSize>()
333
+ .map_err(|e| format!("invalid --max-memory value '{s}': {e}"))?
334
+ .as_u64();
335
+ let bytes =
336
+ usize::try_from(bytes).map_err(|_| format!("--max-memory value too large: '{s}'"))?;
337
+ if bytes == 0 {
338
+ return Err(format!("--max-memory must be greater than 0: '{s}'"));
339
+ }
340
+ Ok(bytes)
341
+ }
342
+
321
343
  struct ResolvedOpts {
322
344
  #[allow(dead_code)]
323
345
  config_file: config::ConfigFile,
@@ -325,6 +347,7 @@ struct ResolvedOpts {
325
347
  http: config::HttpConfig,
326
348
  sockets: config::SocketsConfig,
327
349
  metadata: Option<serde_json::Value>,
350
+ max_memory: Option<usize>,
328
351
  }
329
352
 
330
353
  fn resolve_opts(opts: &CommonOpts) -> Result<ResolvedOpts> {
@@ -360,6 +383,7 @@ fn resolve_opts(opts: &CommonOpts) -> Result<ResolvedOpts> {
360
383
  http,
361
384
  sockets,
362
385
  metadata,
386
+ max_memory: opts.max_memory,
363
387
  })
364
388
  }
365
389
 
@@ -388,6 +412,7 @@ async fn prepare_component(
388
412
  let fs = resolved.fs;
389
413
  let http = resolved.http;
390
414
  let sockets = resolved.sockets;
415
+ let max_memory = resolved.max_memory;
391
416
 
392
417
  let mut preopens = runtime::fs_policy::derive_preopens(&fs);
393
418
  let mount_root = info.std.capabilities.fs_mount_root().unwrap_or("/");
@@ -410,7 +435,7 @@ async fn prepare_component(
410
435
  let wasm = runtime::load_component(&engine, &component_path)?;
411
436
  let linker = runtime::create_linker(&engine)?;
412
437
  let (instance, session_provider, store) = runtime::instantiate_component(
413
- &engine, &wasm, &linker, &preopens, &http, &fs, &sockets, &info,
438
+ &engine, &wasm, &linker, &preopens, &http, &fs, &sockets, &info, max_memory,
414
439
  )
415
440
  .await?;
416
441
  let has_sessions = session_provider.is_some();
@@ -969,6 +994,22 @@ mod tests {
969
994
  assert_eq!(result, Some(serde_json::json!({"key": "value"})));
970
995
  }
971
996
 
997
+ #[test]
998
+ fn parse_max_memory_units_and_bytes() {
999
+ assert_eq!(parse_max_memory("268435456").unwrap(), 256 << 20); // bare = bytes
1000
+ assert_eq!(parse_max_memory("256MiB").unwrap(), 256 << 20); // binary
1001
+ assert_eq!(parse_max_memory("1GiB").unwrap(), 1 << 30);
1002
+ assert_eq!(parse_max_memory("512KiB").unwrap(), 512 << 10);
1003
+ assert_eq!(parse_max_memory("256MB").unwrap(), 256_000_000); // decimal
1004
+ }
1005
+
1006
+ #[test]
1007
+ fn parse_max_memory_rejects_garbage_and_zero() {
1008
+ assert!(parse_max_memory("12xyz").is_err());
1009
+ assert!(parse_max_memory("").is_err());
1010
+ assert!(parse_max_memory("0").is_err());
1011
+ }
1012
+
972
1013
  #[test]
973
1014
  fn parse_cli_metadata_from_file() {
974
1015
  let mut file = NamedTempFile::new().unwrap();
@@ -5,7 +5,9 @@ use std::pin::Pin;
5
5
  use std::task::{Context, Poll};
6
6
  use tokio::sync::{mpsc, oneshot};
7
7
  use wasmtime::component::{Component, Linker, ResourceTable, Source, StreamConsumer, StreamResult};
8
- use wasmtime::{AsContextMut, Config, Engine, Store, StoreContextMut};
8
+ use wasmtime::{
9
+ AsContextMut, Config, Engine, Store, StoreContextMut, StoreLimits, StoreLimitsBuilder,
10
+ };
9
11
  use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView};
10
12
  use wasmtime_wasi_http::WasiHttpCtx;
11
13
  use wasmtime_wasi_http::p3::WasiHttpCtxView;
@@ -36,6 +38,9 @@ pub struct HostState {
36
38
  fs_matcher: crate::runtime::fs_matcher::FsMatcher,
37
39
  fs_mode: crate::config::PolicyMode,
38
40
  fd_paths: crate::runtime::fs_policy::FdPathMap,
41
+ /// Caps the component's wasm linear memory growth (via `store.limiter`).
42
+ /// Default `StoreLimits` is unlimited.
43
+ limits: StoreLimits,
39
44
  }
40
45
 
41
46
  impl HostState {
@@ -153,6 +158,7 @@ pub async fn create_store(
153
158
  fs: &crate::config::FsConfig,
154
159
  sockets: &crate::config::SocketsConfig,
155
160
  info: &ComponentInfo,
161
+ max_memory: Option<usize>,
156
162
  ) -> Result<Store<HostState>> {
157
163
  // Intersect user policy with the component's declared capabilities.
158
164
  let effective_fs = crate::runtime::effective::effective_fs(fs, &info.std.capabilities).config;
@@ -208,8 +214,17 @@ pub async fn create_store(
208
214
  preopens: preopen_pairs,
209
215
  by_rep: Default::default(),
210
216
  },
217
+ limits: match max_memory {
218
+ Some(bytes) => StoreLimitsBuilder::new().memory_size(bytes).build(),
219
+ None => StoreLimits::default(),
220
+ },
211
221
  };
212
- Ok(Store::new(engine, state))
222
+ let mut store = Store::new(engine, state);
223
+ // Enforce the linear-memory cap: when the guest grows memory past the limit,
224
+ // `memory.grow` fails (the guest typically traps OOM) instead of letting the
225
+ // host process balloon. No-op when `max_memory` is None (default limits).
226
+ store.limiter(|state| &mut state.limits);
227
+ Ok(store)
213
228
  }
214
229
 
215
230
  // ── Component info from custom section ──
@@ -346,12 +361,13 @@ pub async fn instantiate_component(
346
361
  fs: &crate::config::FsConfig,
347
362
  sockets: &crate::config::SocketsConfig,
348
363
  info: &ComponentInfo,
364
+ max_memory: Option<usize>,
349
365
  ) -> Result<(
350
366
  ActWorld,
351
367
  Option<sessions::SessionProvider>,
352
368
  Store<HostState>,
353
369
  )> {
354
- let mut store = create_store(engine, preopens, http, fs, sockets, info).await?;
370
+ let mut store = create_store(engine, preopens, http, fs, sockets, info, max_memory).await?;
355
371
 
356
372
  // Manual instantiation flow (replicates ActWorld::instantiate_async)
357
373
  // so we keep access to the raw `Instance` for session-provider lookup.
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "act-store"
3
3
  description = "Local OCI-layout component store for ACT (act-cli, act-toolserver)"
4
- version = "0.1.0"
4
+ version = "0.1.1"
5
5
  edition.workspace = true
6
6
  license.workspace = true
7
7
  repository.workspace = true
@@ -14,7 +14,7 @@ serde = { version = "1", features = ["derive"] }
14
14
  serde_json = "1"
15
15
  sha2 = "0.11"
16
16
  thiserror = "2"
17
- fs2 = "0.4"
17
+ fs4 = { version = "1", features = ["sync"] }
18
18
  oci-spec = "0.9.0"
19
19
  dirs = "6.0.0"
20
20
  tokio = { version = "1.52.3", features = ["rt", "macros", "fs", "io-util"] }
@@ -4,7 +4,7 @@ use std::fs::{File, OpenOptions};
4
4
  use std::io;
5
5
  use std::path::Path;
6
6
 
7
- use fs2::FileExt;
7
+ use fs4::FileExt;
8
8
 
9
9
  /// RAII advisory lock. The lock is released when dropped.
10
10
  #[derive(Debug)]
@@ -26,28 +26,29 @@ impl StoreLock {
26
26
  /// Block until an exclusive (writer) lock is held.
27
27
  pub fn exclusive(root: &Path) -> io::Result<Self> {
28
28
  let file = open_lockfile(root)?;
29
- FileExt::lock_exclusive(&file)?;
29
+ <File as FileExt>::lock(&file)?;
30
30
  Ok(Self { file })
31
31
  }
32
32
 
33
33
  /// Block until a shared (reader) lock is held.
34
34
  pub fn shared(root: &Path) -> io::Result<Self> {
35
35
  let file = open_lockfile(root)?;
36
- FileExt::lock_shared(&file)?;
36
+ <File as FileExt>::lock_shared(&file)?;
37
37
  Ok(Self { file })
38
38
  }
39
39
 
40
40
  /// Non-blocking exclusive lock; errors if it cannot be acquired now.
41
41
  pub fn try_exclusive(root: &Path) -> io::Result<Self> {
42
42
  let file = open_lockfile(root)?;
43
- FileExt::try_lock_exclusive(&file)?;
43
+ <File as FileExt>::try_lock(&file)
44
+ .map_err(|e| io::Error::other(format!("lock not acquired: {e}")))?;
44
45
  Ok(Self { file })
45
46
  }
46
47
  }
47
48
 
48
49
  impl Drop for StoreLock {
49
50
  fn drop(&mut self) {
50
- let _ = FileExt::unlock(&self.file);
51
+ let _ = <File as FileExt>::unlock(&self.file);
51
52
  }
52
53
  }
53
54
 
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