functionalscript 0.37.0 → 0.39.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 +1 -1
- package/{fs → fjs}/asn.1/proof.f.js +32 -94
- package/fjs/asserts/module.f.d.ts +36 -0
- package/fjs/asserts/module.f.js +39 -0
- package/fjs/asserts/proof.f.d.ts +11 -0
- package/fjs/asserts/proof.f.js +18 -0
- package/{fs → fjs}/base_n/proof.f.js +12 -36
- package/{fs → fjs}/basen/base64/proof.f.d.ts +1 -0
- package/{fs → fjs}/basen/base64/proof.f.js +15 -1
- package/{fs → fjs}/basen/cbase32/proof.f.js +15 -42
- package/fjs/bnf/data/module.f.d.ts +52 -0
- package/{fs → fjs}/bnf/data/module.f.js +53 -3
- package/{fs → fjs}/bnf/data/proof.f.d.ts +1 -0
- package/{fs → fjs}/bnf/data/proof.f.js +54 -19
- package/{fs → fjs}/bnf/descent/module.f.d.ts +4 -14
- package/fjs/bnf/descent/module.f.js +124 -0
- package/{fs → fjs}/bnf/descent/proof.f.d.ts +1 -0
- package/{fs → fjs}/bnf/descent/proof.f.js +55 -24
- package/{fs → fjs}/bnf/ll1/module.f.d.ts +4 -4
- package/{fs → fjs}/bnf/ll1/module.f.js +7 -5
- package/{fs → fjs}/bnf/ll1/proof.f.d.ts +1 -0
- package/{fs → fjs}/bnf/ll1/proof.f.js +27 -10
- package/{fs → fjs}/bnf/module.f.d.ts +19 -5
- package/{fs → fjs}/bnf/module.f.js +10 -11
- package/fjs/bnf/proof.f.js +69 -0
- package/{fs → fjs}/bnf/testlib.f.js +2 -2
- package/fjs/bnf/token_symbol/module.f.d.ts +38 -0
- package/fjs/bnf/token_symbol/module.f.js +48 -0
- package/fjs/bnf/token_symbol/proof.f.d.ts +10 -0
- package/fjs/bnf/token_symbol/proof.f.js +37 -0
- package/{fs → fjs}/cas/cli/module.f.js +6 -9
- package/{fs → fjs}/cas/cli/proof.f.d.ts +4 -1
- package/{fs → fjs}/cas/cli/proof.f.js +29 -66
- package/fjs/cas/evo/mcp/module.f.d.ts +27 -0
- package/fjs/cas/evo/mcp/module.f.js +94 -0
- package/fjs/cas/evo/mcp/proof.f.d.ts +11 -0
- package/fjs/cas/evo/mcp/proof.f.js +126 -0
- package/fjs/cas/evo/module.f.d.ts +202 -0
- package/fjs/cas/evo/module.f.js +421 -0
- package/fjs/cas/evo/proof.f.d.ts +39 -0
- package/fjs/cas/evo/proof.f.js +572 -0
- package/fjs/cas/mcp/module.f.d.ts +49 -0
- package/{fs → fjs}/cas/mcp/module.f.js +61 -81
- package/{fs → fjs}/cas/mcp/proof.f.d.ts +4 -1
- package/{fs → fjs}/cas/mcp/proof.f.js +45 -17
- package/{fs → fjs}/cas/module.f.d.ts +10 -0
- package/{fs → fjs}/cas/module.f.js +89 -36
- package/fjs/cas/proof.f.d.ts +18 -0
- package/fjs/cas/proof.f.js +305 -0
- package/{fs → fjs}/ci/bun/module.f.js +3 -3
- package/{fs → fjs}/ci/common/module.f.d.ts +1 -2
- package/{fs → fjs}/ci/common/module.f.js +1 -5
- package/{fs → fjs}/ci/config/module.f.d.ts +8 -8
- package/{fs → fjs}/ci/config/module.f.js +8 -8
- package/{fs → fjs}/ci/deno/module.f.js +3 -3
- package/{fs → fjs}/ci/module.f.js +3 -4
- package/{fs → fjs}/ci/node/module.f.js +11 -9
- package/{fs → fjs}/ci/proof.f.js +16 -9
- package/{fs → fjs}/ci/rust/module.f.js +9 -1
- package/{fs → fjs}/cli/module.f.js +2 -2
- package/{fs → fjs}/cli/proof.f.js +22 -63
- package/{fs → fjs}/common/monoid/module.f.d.ts +46 -2
- package/fjs/common/monoid/module.f.js +88 -0
- package/fjs/common/monoid/proof.f.d.ts +9 -0
- package/fjs/common/monoid/proof.f.js +48 -0
- package/{fs → fjs}/crypto/hmac/proof.f.js +4 -12
- package/fjs/crypto/pow/proof.f.js +111 -0
- package/{fs → fjs}/crypto/secp/proof.f.js +12 -33
- package/{fs → fjs}/crypto/sha2/proof.f.js +18 -49
- package/{fs → fjs}/crypto/sign/module.f.d.ts +0 -5
- package/{fs → fjs}/crypto/sign/module.f.js +7 -4
- package/{fs → fjs}/crypto/sign/proof.f.js +36 -105
- package/{fs → fjs}/crypto/vdf/proof.f.js +22 -63
- package/{fs → fjs}/dev/module.f.js +25 -25
- package/{fs → fjs}/dev/package_json/proof.f.js +7 -7
- package/{fs → fjs}/dev/proof.f.js +2 -4
- package/{fs → fjs}/djs/ast/proof.f.js +4 -12
- package/{fs → fjs}/djs/module.f.js +5 -8
- package/{fs → fjs}/djs/parser/module.f.d.ts +8 -0
- package/{fs → fjs}/djs/parser/module.f.js +37 -0
- package/{fs → fjs}/djs/parser/proof.f.js +138 -400
- package/{fs → fjs}/djs/proof.f.js +13 -36
- package/{fs → fjs}/djs/serializer/proof.f.js +14 -39
- package/fjs/djs/tokenizer/module.f.d.ts +24 -0
- package/fjs/djs/tokenizer/module.f.js +472 -0
- package/{fs/djs/tokenizer-new → fjs/djs/tokenizer}/proof.f.d.ts +4 -3
- package/{fs/djs/tokenizer-new → fjs/djs/tokenizer}/proof.f.js +446 -445
- package/{fs → fjs}/djs/transpiler/module.f.js +6 -6
- package/{fs → fjs}/djs/transpiler/proof.f.d.ts +3 -0
- package/{fs → fjs}/djs/transpiler/proof.f.js +29 -30
- package/fjs/effects/eff/module.f.d.ts +72 -0
- package/fjs/effects/eff/module.f.js +46 -0
- package/fjs/effects/eff/proof.f.d.ts +11 -0
- package/fjs/effects/eff/proof.f.js +58 -0
- package/{fs → fjs}/effects/list/module.f.d.ts +11 -5
- package/{fs → fjs}/effects/list/module.f.js +2 -1
- package/{fs → fjs}/effects/memory/proof.f.js +15 -29
- package/fjs/effects/module.f.d.ts +388 -0
- package/fjs/effects/module.f.js +288 -0
- package/{fs → fjs}/effects/node/memory/proof.js +7 -13
- package/{fs → fjs}/effects/node/module.d.ts +1 -1
- package/{fs → fjs}/effects/node/module.f.d.ts +2 -2
- package/{fs → fjs}/effects/node/module.f.js +9 -11
- package/{fs → fjs}/effects/node/module.js +3 -3
- package/{fs → fjs}/effects/node/proof.f.d.ts +1 -0
- package/{fs → fjs}/effects/node/proof.f.js +121 -299
- package/{fs → fjs}/effects/node/virtual/proof.f.d.ts +1 -0
- package/{fs → fjs}/effects/node/virtual/proof.f.js +36 -29
- package/fjs/effects/proof.f.d.ts +51 -0
- package/fjs/effects/proof.f.js +178 -0
- package/{fs → fjs}/emergent_testing/module.f.js +55 -39
- package/{fs → fjs}/emergent_testing/proof.f.d.ts +4 -0
- package/{fs → fjs}/emergent_testing/proof.f.js +60 -27
- package/{fs → fjs}/fsc/proof.f.js +12 -34
- package/{fs → fjs}/fsm/proof.f.js +5 -12
- package/{fs → fjs}/mcp/module.f.d.ts +7 -0
- package/{fs → fjs}/mcp/module.f.js +17 -10
- package/{fs → fjs}/mcp/proof.f.js +17 -16
- package/{fs → fjs}/mcp/stdio/module.f.d.ts +4 -4
- package/{fs → fjs}/mcp/stdio/module.f.js +14 -14
- package/{fs → fjs}/media/html/proof.f.js +12 -33
- package/{fs → fjs}/media/json/parser/module.f.d.ts +5 -0
- package/{fs → fjs}/media/json/parser/module.f.js +14 -0
- package/{fs → fjs}/media/json/parser/proof.f.js +39 -114
- package/{fs → fjs}/media/json/rpc/module.f.js +1 -1
- package/{fs → fjs}/media/json/schema/module.f.d.ts +2 -2
- package/{fs → fjs}/media/json/schema/module.f.js +23 -39
- package/{fs → fjs}/media/json/schema/proof.f.js +3 -6
- package/{fs → fjs}/media/json/serializer/proof.f.js +10 -27
- package/{fs → fjs}/media/module.f.d.ts +6 -6
- package/{fs → fjs}/media/module.f.js +3 -4
- package/{fs → fjs}/media/proof.f.js +5 -4
- package/{fs → fjs}/media/revision/module.f.d.ts +31 -4
- package/{fs → fjs}/media/revision/module.f.js +35 -23
- package/{fs → fjs}/media/revision/proof.f.d.ts +10 -8
- package/fjs/media/revision/proof.f.js +140 -0
- package/{fs → fjs}/media/type/module.f.js +2 -2
- package/{fs → fjs}/media/type/proof.f.js +8 -15
- package/{fs → fjs}/module.f.js +5 -9
- package/{fs → fjs}/path/proof.f.js +27 -78
- package/{fs → fjs}/proof.f.js +2 -0
- package/{fs → fjs}/sul/id/proof.f.js +7 -21
- package/{fs → fjs}/sul/level/hash/proof.f.js +5 -5
- package/{fs → fjs}/sul/level/literal/proof.f.js +12 -26
- package/fjs/text/ascii/proof.f.d.ts +6 -0
- package/{fs → fjs}/text/ascii/proof.f.js +4 -14
- package/{fs → fjs}/text/code_point/module.f.js +10 -10
- package/{fs → fjs}/text/proof.f.js +4 -9
- package/{fs → fjs}/text/sgr/proof.f.js +6 -15
- package/{fs → fjs}/text/utf16/module.f.js +1 -1
- package/{fs → fjs}/text/utf16/proof.f.js +23 -66
- package/{fs → fjs}/text/utf8/proof.f.js +56 -125
- package/{fs → fjs}/types/array/proof.f.js +18 -52
- package/fjs/types/bigfloat/proof.f.js +217 -0
- package/{fs → fjs}/types/bigint/module.f.js +4 -3
- package/{fs → fjs}/types/bigint/proof.f.js +49 -145
- package/{fs → fjs}/types/bit_vec/module.f.js +5 -15
- package/{fs → fjs}/types/bit_vec/proof.f.js +72 -214
- package/{fs → fjs}/types/btree/find/proof.f.js +23 -66
- package/{fs → fjs}/types/btree/proof.f.js +5 -12
- package/{fs → fjs}/types/btree/remove/module.f.d.ts +5 -0
- package/{fs → fjs}/types/btree/remove/module.f.js +12 -0
- package/{fs → fjs}/types/btree/remove/proof.f.d.ts +2 -0
- package/{fs → fjs}/types/btree/remove/proof.f.js +83 -230
- package/{fs → fjs}/types/btree/set/module.f.js +5 -2
- package/{fs → fjs}/types/btree/set/proof.f.js +35 -24
- package/{fs → fjs}/types/byte_set/proof.f.js +22 -63
- package/{fs → fjs}/types/function/compare/proof.f.js +13 -36
- package/{fs → fjs}/types/function/operator/proof.f.js +17 -48
- package/{fs → fjs}/types/function/proof.f.js +2 -3
- package/{fs → fjs}/types/list/module.f.d.ts +21 -0
- package/{fs → fjs}/types/list/module.f.js +17 -0
- package/{fs → fjs}/types/list/proof.f.d.ts +1 -0
- package/{fs → fjs}/types/list/proof.f.js +79 -164
- package/{fs → fjs}/types/map/proof.f.js +4 -12
- package/{fs → fjs}/types/nibble_set/proof.f.js +16 -45
- package/{fs → fjs}/types/nominal/proof.f.js +5 -10
- package/fjs/types/nullable/proof.f.js +29 -0
- package/{fs → fjs}/types/number/module.f.js +2 -1
- package/{fs → fjs}/types/number/proof.f.js +9 -24
- package/{fs → fjs}/types/object/proof.f.js +3 -6
- package/{fs → fjs}/types/patricia_trie/proof.f.js +21 -21
- package/{fs → fjs}/types/prime_field/module.f.js +2 -7
- package/{fs → fjs}/types/range/module.f.d.ts +1 -1
- package/fjs/types/range/module.f.js +2 -0
- package/fjs/types/range/proof.f.js +9 -0
- package/{fs → fjs}/types/range_map/proof.f.js +28 -81
- package/{fs → fjs}/types/result/proof.f.d.ts +3 -2
- package/fjs/types/result/proof.f.js +31 -0
- package/{fs → fjs}/types/rtti/common/module.f.d.ts +36 -1
- package/{fs → fjs}/types/rtti/common/module.f.js +44 -0
- package/fjs/types/rtti/common/proof.f.d.ts +8 -0
- package/fjs/types/rtti/common/proof.f.js +51 -0
- package/{fs → fjs}/types/rtti/parse/module.f.js +13 -22
- package/{fs → fjs}/types/rtti/parse/proof.f.js +7 -18
- package/{fs → fjs}/types/rtti/ts/module.f.d.ts +10 -4
- package/{fs → fjs}/types/rtti/validate/module.f.js +8 -29
- package/{fs → fjs}/types/rtti/validate/proof.f.js +4 -9
- package/{fs → fjs}/types/sorted_list/proof.f.js +8 -21
- package/{fs → fjs}/types/sorted_set/proof.f.js +14 -39
- package/{fs → fjs}/types/string/module.f.js +10 -2
- package/fjs/types/string/proof.f.js +77 -0
- package/fjs/types/string_set/proof.f.js +43 -0
- package/{fs → fjs}/types/ts/proof.f.js +15 -42
- package/{fs → fjs}/types/uint8array/module.f.js +7 -7
- package/{fs → fjs}/types/uint8array/proof.f.d.ts +4 -1
- package/{fs → fjs}/types/uint8array/proof.f.js +7 -7
- package/{fs → fjs}/website/module.f.js +2 -3
- package/{fs → fjs}/website/proof.f.js +3 -6
- package/package.json +8 -8
- package/fs/asserts/module.f.d.ts +0 -4
- package/fs/asserts/module.f.js +0 -9
- package/fs/asserts/proof.f.d.ts +0 -8
- package/fs/asserts/proof.f.js +0 -51
- package/fs/bnf/data/module.f.d.ts +0 -30
- package/fs/bnf/descent/module.f.js +0 -119
- package/fs/bnf/proof.f.js +0 -104
- package/fs/cas/mcp/module.f.d.ts +0 -36
- package/fs/cas/proof.f.d.ts +0 -20
- package/fs/cas/proof.f.js +0 -294
- package/fs/common/monoid/module.f.js +0 -44
- package/fs/common/monoid/proof.f.d.ts +0 -4
- package/fs/common/monoid/proof.f.js +0 -27
- package/fs/crypto/pow/proof.f.js +0 -161
- package/fs/djs/tokenizer/module.f.d.ts +0 -12
- package/fs/djs/tokenizer/module.f.js +0 -62
- package/fs/djs/tokenizer/proof.f.d.ts +0 -7
- package/fs/djs/tokenizer/proof.f.js +0 -543
- package/fs/djs/tokenizer-new/module.f.d.ts +0 -3
- package/fs/djs/tokenizer-new/module.f.js +0 -155
- package/fs/effects/module.f.d.ts +0 -106
- package/fs/effects/module.f.js +0 -80
- package/fs/effects/proof.f.d.ts +0 -25
- package/fs/effects/proof.f.js +0 -115
- package/fs/media/revision/proof.f.js +0 -119
- package/fs/text/ascii/proof.f.d.ts +0 -4
- package/fs/types/bigfloat/proof.f.js +0 -348
- package/fs/types/nullable/proof.f.js +0 -50
- package/fs/types/range/module.f.js +0 -2
- package/fs/types/range/proof.f.js +0 -18
- package/fs/types/result/proof.f.js +0 -52
- package/fs/types/string/proof.f.js +0 -118
- package/fs/types/string_set/proof.f.js +0 -82
- /package/{fs → fjs}/asn.1/module.f.d.ts +0 -0
- /package/{fs → fjs}/asn.1/module.f.js +0 -0
- /package/{fs → fjs}/asn.1/proof.f.d.ts +0 -0
- /package/{fs → fjs}/base_n/module.f.d.ts +0 -0
- /package/{fs → fjs}/base_n/module.f.js +0 -0
- /package/{fs → fjs}/base_n/proof.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base128/module.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base128/module.f.js +0 -0
- /package/{fs → fjs}/basen/base128/proof.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base128/proof.f.js +0 -0
- /package/{fs → fjs}/basen/base64/module.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base64/module.f.js +0 -0
- /package/{fs → fjs}/basen/cbase32/module.f.d.ts +0 -0
- /package/{fs → fjs}/basen/cbase32/module.f.js +0 -0
- /package/{fs → fjs}/basen/cbase32/proof.f.d.ts +0 -0
- /package/{fs → fjs}/bnf/proof.f.d.ts +0 -0
- /package/{fs → fjs}/bnf/testlib.f.d.ts +0 -0
- /package/{fs → fjs}/cas/cli/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/bun/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/deno/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/node/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/playwright/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/playwright/module.f.js +0 -0
- /package/{fs → fjs}/ci/proof.f.d.ts +0 -0
- /package/{fs → fjs}/ci/rust/module.f.d.ts +0 -0
- /package/{fs → fjs}/cli/module.f.d.ts +0 -0
- /package/{fs → fjs}/cli/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/hmac/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/hmac/module.f.js +0 -0
- /package/{fs → fjs}/crypto/hmac/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/pow/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/pow/module.f.js +0 -0
- /package/{fs → fjs}/crypto/pow/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/secp/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/secp/module.f.js +0 -0
- /package/{fs → fjs}/crypto/secp/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/sha2/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/sha2/module.f.js +0 -0
- /package/{fs → fjs}/crypto/sha2/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/sign/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/vdf/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/vdf/module.f.js +0 -0
- /package/{fs → fjs}/crypto/vdf/proof.f.d.ts +0 -0
- /package/{fs → fjs}/dev/module.f.d.ts +0 -0
- /package/{fs → fjs}/dev/package_json/module.f.d.ts +0 -0
- /package/{fs → fjs}/dev/package_json/module.f.js +0 -0
- /package/{fs → fjs}/dev/package_json/proof.f.d.ts +0 -0
- /package/{fs → fjs}/dev/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/ast/module.f.d.ts +0 -0
- /package/{fs → fjs}/djs/ast/module.f.js +0 -0
- /package/{fs → fjs}/djs/ast/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/examples/input.f.d.ts +0 -0
- /package/{fs → fjs}/djs/examples/input.f.js +0 -0
- /package/{fs → fjs}/djs/examples/m.f.d.ts +0 -0
- /package/{fs → fjs}/djs/examples/m.f.js +0 -0
- /package/{fs → fjs}/djs/module.f.d.ts +0 -0
- /package/{fs → fjs}/djs/parser/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/serializer/module.f.d.ts +0 -0
- /package/{fs → fjs}/djs/serializer/module.f.js +0 -0
- /package/{fs → fjs}/djs/serializer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/transpiler/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/memory/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/memory/module.f.js +0 -0
- /package/{fs → fjs}/effects/memory/proof.f.d.ts +0 -0
- /package/{fs → fjs}/effects/mock/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/mock/module.f.js +0 -0
- /package/{fs → fjs}/effects/module.d.ts +0 -0
- /package/{fs → fjs}/effects/module.js +0 -0
- /package/{fs → fjs}/effects/node/memory/module.d.ts +0 -0
- /package/{fs → fjs}/effects/node/memory/module.js +0 -0
- /package/{fs → fjs}/effects/node/memory/proof.d.ts +0 -0
- /package/{fs → fjs}/effects/node/virtual/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/node/virtual/module.f.js +0 -0
- /package/{fs → fjs}/emergent_testing/all.test.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/all.test.js +0 -0
- /package/{fs → fjs}/emergent_testing/example.f.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/example.f.js +0 -0
- /package/{fs → fjs}/emergent_testing/module.f.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/all.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/all.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.fail.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.fail.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.fail.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/fail.fail.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/fail.fail.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/return-value.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/return-value.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable2.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable2.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/throw.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/throw.pass.js +0 -0
- /package/{fs → fjs}/fsc/bnf.f.d.ts +0 -0
- /package/{fs → fjs}/fsc/bnf.f.js +0 -0
- /package/{fs → fjs}/fsc/json.f.d.ts +0 -0
- /package/{fs → fjs}/fsc/json.f.js +0 -0
- /package/{fs → fjs}/fsc/module.f.d.ts +0 -0
- /package/{fs → fjs}/fsc/module.f.js +0 -0
- /package/{fs → fjs}/fsc/proof.f.d.ts +0 -0
- /package/{fs → fjs}/fsm/module.f.d.ts +0 -0
- /package/{fs → fjs}/fsm/module.f.js +0 -0
- /package/{fs → fjs}/fsm/proof.f.d.ts +0 -0
- /package/{fs → fjs}/js/tokenizer/module.f.d.ts +0 -0
- /package/{fs → fjs}/js/tokenizer/module.f.js +0 -0
- /package/{fs → fjs}/js/tokenizer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/js/tokenizer/proof.f.js +0 -0
- /package/{fs → fjs}/mcp/proof.f.d.ts +0 -0
- /package/{fs → fjs}/mcp/stdio/proof.f.d.ts +0 -0
- /package/{fs → fjs}/mcp/stdio/proof.f.js +0 -0
- /package/{fs → fjs}/media/html/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/html/module.f.js +0 -0
- /package/{fs → fjs}/media/html/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/module.f.js +0 -0
- /package/{fs → fjs}/media/json/parser/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/proof.f.js +0 -0
- /package/{fs → fjs}/media/json/rpc/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/rpc/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/rpc/proof.f.js +0 -0
- /package/{fs → fjs}/media/json/schema/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/serializer/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/serializer/module.f.js +0 -0
- /package/{fs → fjs}/media/json/serializer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/tokenizer/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/tokenizer/module.f.js +0 -0
- /package/{fs → fjs}/media/json/tokenizer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/tokenizer/proof.f.js +0 -0
- /package/{fs → fjs}/media/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/type/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/type/proof.f.d.ts +0 -0
- /package/{fs → fjs}/module.d.ts +0 -0
- /package/{fs → fjs}/module.f.d.ts +0 -0
- /package/{fs → fjs}/module.js +0 -0
- /package/{fs → fjs}/path/module.f.d.ts +0 -0
- /package/{fs → fjs}/path/module.f.js +0 -0
- /package/{fs → fjs}/path/proof.f.d.ts +0 -0
- /package/{fs → fjs}/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/id/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/id/module.f.js +0 -0
- /package/{fs → fjs}/sul/id/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/hash/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/hash/module.f.js +0 -0
- /package/{fs → fjs}/sul/level/hash/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/literal/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/literal/module.f.js +0 -0
- /package/{fs → fjs}/sul/level/literal/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/module.f.js +0 -0
- /package/{fs → fjs}/sul/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/proof.f.js +0 -0
- /package/{fs → fjs}/text/ascii/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/ascii/module.f.js +0 -0
- /package/{fs → fjs}/text/code_point/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/code_point/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/code_point/proof.f.js +0 -0
- /package/{fs → fjs}/text/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/module.f.js +0 -0
- /package/{fs → fjs}/text/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/sgr/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/sgr/module.f.js +0 -0
- /package/{fs → fjs}/text/sgr/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf16/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf16/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf8/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf8/module.f.js +0 -0
- /package/{fs → fjs}/text/utf8/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/array/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/array/module.f.js +0 -0
- /package/{fs → fjs}/types/array/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigfloat/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigfloat/module.f.js +0 -0
- /package/{fs → fjs}/types/bigfloat/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigint/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigint/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/bit_vec/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/bit_vec/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/find/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/find/module.f.js +0 -0
- /package/{fs → fjs}/types/btree/find/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/module.f.js +0 -0
- /package/{fs → fjs}/types/btree/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/types/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/types/module.f.js +0 -0
- /package/{fs → fjs}/types/byte_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/byte_set/module.f.js +0 -0
- /package/{fs → fjs}/types/byte_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/compare/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/compare/module.f.js +0 -0
- /package/{fs → fjs}/types/function/compare/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/module.f.js +0 -0
- /package/{fs → fjs}/types/function/operator/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/operator/module.f.js +0 -0
- /package/{fs → fjs}/types/function/operator/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/map/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/map/module.f.js +0 -0
- /package/{fs → fjs}/types/map/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/nibble_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/nibble_set/module.f.js +0 -0
- /package/{fs → fjs}/types/nibble_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/nominal/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/nominal/module.f.js +0 -0
- /package/{fs → fjs}/types/nominal/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/nullable/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/nullable/module.f.js +0 -0
- /package/{fs → fjs}/types/nullable/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/number/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/number/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/object/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/object/module.f.js +0 -0
- /package/{fs → fjs}/types/object/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/option/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/option/module.f.js +0 -0
- /package/{fs → fjs}/types/ordered_map/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/ordered_map/module.f.js +0 -0
- /package/{fs → fjs}/types/ordered_map/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/ordered_map/proof.f.js +0 -0
- /package/{fs → fjs}/types/patricia_trie/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/patricia_trie/module.f.js +0 -0
- /package/{fs → fjs}/types/patricia_trie/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/phantom/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/phantom/module.f.js +0 -0
- /package/{fs → fjs}/types/prime_field/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/prime_field/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/prime_field/proof.f.js +0 -0
- /package/{fs → fjs}/types/range/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/range_map/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/range_map/module.f.js +0 -0
- /package/{fs → fjs}/types/range_map/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/result/module.d.ts +0 -0
- /package/{fs → fjs}/types/result/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/result/module.f.js +0 -0
- /package/{fs → fjs}/types/result/module.js +0 -0
- /package/{fs → fjs}/types/rtti/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/module.f.js +0 -0
- /package/{fs → fjs}/types/rtti/parse/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/parse/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/proof.f.js +0 -0
- /package/{fs → fjs}/types/rtti/ts/module.f.js +0 -0
- /package/{fs → fjs}/types/rtti/ts/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/ts/proof.f.js +0 -0
- /package/{fs → fjs}/types/rtti/validate/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/validate/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_list/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_list/module.f.js +0 -0
- /package/{fs → fjs}/types/sorted_list/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_set/module.f.js +0 -0
- /package/{fs → fjs}/types/sorted_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/string/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/string/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/string_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/string_set/module.f.js +0 -0
- /package/{fs → fjs}/types/string_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/ts/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/ts/module.f.js +0 -0
- /package/{fs → fjs}/types/ts/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/uint8array/module.f.d.ts +0 -0
- /package/{fs → fjs}/website/module.f.d.ts +0 -0
- /package/{fs → fjs}/website/proof.f.d.ts +0 -0
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP adapter for the content-addressable store
|
|
2
|
+
* MCP adapter for the content-addressable store and the Evo API layered on
|
|
3
|
+
* top of it.
|
|
3
4
|
*
|
|
4
5
|
* Maps `Cas<O>` operations onto MCP tools, so an agent that speaks MCP can
|
|
5
6
|
* store a blob and get back its hash, fetch a blob by hash, and enumerate
|
|
6
7
|
* what is stored — without shelling out to the `cas` CLI. The store itself
|
|
7
|
-
* (`
|
|
8
|
-
* front end alongside the CLI `main`.
|
|
8
|
+
* (`fjs/cas/module.f.ts`) stays transport-agnostic; this is an additional
|
|
9
|
+
* front end alongside the CLI `main`. The same server also exposes
|
|
10
|
+
* `fjs/cas/evo`'s subject/head API
|
|
11
|
+
* (`evo_list`/`evo_head`/`evo_revision`/`evo_add`, `fjs/cas/evo/mcp`) — one
|
|
12
|
+
* process, one `~/.cas/` store, one in-memory Evo cache scanned once at
|
|
13
|
+
* startup (`initEvo`).
|
|
9
14
|
*
|
|
10
15
|
* ## Tools
|
|
11
16
|
*
|
|
12
|
-
* | Tool
|
|
13
|
-
*
|
|
14
|
-
* | `cas_add`
|
|
15
|
-
* | `cas_get`
|
|
16
|
-
* | `cas_list`
|
|
17
|
+
* | Tool | args | action | result |
|
|
18
|
+
* |----------------|----------------------------------------------|------------------|--------------------------------------|
|
|
19
|
+
* | `cas_add` | `{ content, type? }` | `c.write(...)` | hash (cBase32) |
|
|
20
|
+
* | `cas_get` | `{ hash, content?: boolean }` | `c.read(key)` | JSON `{length,mimeType,type[,uri][,text\|blob]}` |
|
|
21
|
+
* | `cas_list` | `{}` | `c.list()` | hashes, one per line |
|
|
22
|
+
* | `evo_list` | `{}` | `e.list()` | subjects, one per line |
|
|
23
|
+
* | `evo_head` | `{ subject }` | `e.head(...)` | head hashes, one per line |
|
|
24
|
+
* | `evo_revision` | `{ hash }` | `e.revision(...)`| the revision, as JSON |
|
|
25
|
+
* | `evo_add` | `{ parents, snapshot?, subject?, archived? }` | `e.add(...)` | hash (cBase32) |
|
|
17
26
|
*
|
|
18
27
|
* ## `cas_add` input encoding
|
|
19
28
|
*
|
|
@@ -26,7 +35,7 @@
|
|
|
26
35
|
*
|
|
27
36
|
* Inline content (either encoding) is capped at 128 KiB (`maxLength`). There is
|
|
28
37
|
* no MCP route for larger content — the server never opens a local path named by
|
|
29
|
-
* the client (see the invariant in `
|
|
38
|
+
* the client (see the invariant in `fjs/cas/mcp/README.md`); large files go
|
|
30
39
|
* through the `cas` CLI (`cas add <path>`) instead, run directly by the user.
|
|
31
40
|
*
|
|
32
41
|
* ## `cas_get` output
|
|
@@ -40,7 +49,7 @@
|
|
|
40
49
|
* present (`'text'` or `'base64'`) as the discriminator for which of `text` /
|
|
41
50
|
* `blob` a later `content: true` fetch would populate — MCP allows extra fields,
|
|
42
51
|
* so `type` and `length` simply stay alongside the required resource-contents
|
|
43
|
-
* fields. A single classifier — the `
|
|
52
|
+
* fields. A single classifier — the `fjs/media/type` detector state machine (length ×
|
|
44
53
|
* magic-byte eliminator × UTF-8 DFA) — produces the same three-way verdict on
|
|
45
54
|
* both paths, so there is no second, divergent copy of the rules:
|
|
46
55
|
*
|
|
@@ -51,12 +60,12 @@
|
|
|
51
60
|
*
|
|
52
61
|
* **Metadata-only (`content: false`, the default) is size-independent for
|
|
53
62
|
* non-text and oversized blobs.** It folds the read stream through
|
|
54
|
-
* `
|
|
63
|
+
* `fjs/media/type` `detectStream` and never buffers the blob. Because a single
|
|
55
64
|
* `Vec` caps at `maxLength` bits (128 KiB), the old drain-into-one-`Vec`
|
|
56
65
|
* approach failed on any blob larger than one chunk even when only metadata
|
|
57
66
|
* was asked for; streaming detection returns correct
|
|
58
67
|
* `{ length, mimeType, type[, uri] }` regardless of size. A dialect (e.g.
|
|
59
|
-
* `vnd.fjs.revision`, see `
|
|
68
|
+
* `vnd.fjs.revision`, see `fjs/media/module.f.ts`) can only be recognized by
|
|
60
69
|
* parsing the whole blob as JSON, so when the streaming verdict is
|
|
61
70
|
* whole-blob-valid text within the same bounded inline cap as `content: true`
|
|
62
71
|
* (`maxLengthBytes`), one extra bounded read materializes the blob purely to
|
|
@@ -65,12 +74,12 @@
|
|
|
65
74
|
* alone, unbuffered.
|
|
66
75
|
*
|
|
67
76
|
* **`content: true`** first derives `{ length, mimeType, type }` with the same
|
|
68
|
-
* size-independent `
|
|
77
|
+
* size-independent `fjs/media/type` `detectStream` machine (to decide whether the
|
|
69
78
|
* blob even fits inline), then materializes the bytes (via `collectRead`, bounded
|
|
70
79
|
* by `maxLength`) and re-derives the verdict from the dialect-aware detector
|
|
71
|
-
* (`
|
|
80
|
+
* (`fjs/media/module.f.ts` `detect`) — now that the whole blob is in hand, a
|
|
72
81
|
* dialect match is reflected in the result — before encoding the inline payload
|
|
73
|
-
* by `type` — a `
|
|
82
|
+
* by `type` — a `fjs/text/utf8` `fromVec` string on `text` (for `type: 'text'`),
|
|
74
83
|
* base64 on `blob` (for `type: 'base64'`). A blob larger than `maxLength` (128
|
|
75
84
|
* KiB) cannot be buffered into one `Vec`, so it is rejected here with a
|
|
76
85
|
* descriptive *"too large"* error (carrying the byte size and `uri`) rather than
|
|
@@ -80,7 +89,7 @@
|
|
|
80
89
|
* ## Encoding split: hashes vs. content
|
|
81
90
|
*
|
|
82
91
|
* `Cas<O>` deals in `Vec` (bit vectors); MCP models only `textContent` today.
|
|
83
|
-
* **Hashes** travel as cBase32 (`
|
|
92
|
+
* **Hashes** travel as cBase32 (`fjs/basen/cbase32`) — the canonical CAS hash format,
|
|
84
93
|
* shared with the CLI and the on-disk store layout. **Content** encoding is
|
|
85
94
|
* determined at read time as described above.
|
|
86
95
|
*
|
|
@@ -101,23 +110,25 @@
|
|
|
101
110
|
*/
|
|
102
111
|
import { string, option, or, boolean } from '../../types/rtti/module.f.js';
|
|
103
112
|
import { stringify } from '../../media/json/module.f.js';
|
|
104
|
-
import { pure,
|
|
113
|
+
import { pure, step } from '../../effects/module.f.js';
|
|
105
114
|
import { create } from '../../effects/memory/module.f.js';
|
|
106
115
|
import { cBase32ToVec, vecToCBase32 } from '../../basen/cbase32/module.f.js';
|
|
107
116
|
import { decode as base64Decode, encode as base64Encode } from '../../basen/base64/module.f.js';
|
|
108
117
|
import { tryUtf8 } from '../../text/module.f.js';
|
|
109
118
|
import { detectStream } from '../../media/type/module.f.js';
|
|
110
119
|
import { detect as detectDialect } from '../../media/module.f.js';
|
|
111
|
-
import {
|
|
112
|
-
import { ok
|
|
120
|
+
import { maxLengthBytes } from '../../types/bit_vec/module.f.js';
|
|
121
|
+
import { ok } from '../../types/result/module.f.js';
|
|
113
122
|
import {} from '../../effects/node/module.f.js';
|
|
114
123
|
import { stdioTransport } from '../../mcp/stdio/module.f.js';
|
|
115
|
-
import { mcpStep, uninitializedState, toolEntry, fromRegistry, errorResult, } from '../../mcp/module.f.js';
|
|
116
|
-
import { fileCas } from '../module.f.js';
|
|
124
|
+
import { mcpStep, uninitializedState, toolEntry, fromRegistry, errorResult, okResult, } from '../../mcp/module.f.js';
|
|
125
|
+
import { collectRead, fileCas } from '../module.f.js';
|
|
117
126
|
import { fromVec } from '../../text/utf8/module.f.js';
|
|
118
127
|
import { identity } from '../../types/function/module.f.js';
|
|
119
128
|
import { sha256 } from '../../crypto/sha2/module.f.js';
|
|
120
129
|
import { nonEmpty, empty as elEmpty } from '../../effects/list/module.f.js';
|
|
130
|
+
import { initEvo, evo, syncRevision } from '../evo/module.f.js';
|
|
131
|
+
import { evoToolRegistry } from '../evo/mcp/module.f.js';
|
|
121
132
|
// ── Argument schemas (declared once, used for both inputSchema and validate) ─────
|
|
122
133
|
/** Arguments for `cas_add`: content to store, with optional encoding type. */
|
|
123
134
|
export const casAddArgs = {
|
|
@@ -131,38 +142,18 @@ export const casGetArgs = {
|
|
|
131
142
|
};
|
|
132
143
|
/** Arguments for `cas_list`: none. */
|
|
133
144
|
export const casListArgs = {};
|
|
134
|
-
// ── Stream helper ────────────────────────────────────────────────────────────────
|
|
135
|
-
/**
|
|
136
|
-
* Drains a CAS read stream into a single `Vec`. Used only on the `content: true`
|
|
137
|
-
* path, where the whole blob is needed for inline base64 / UTF-8 transfer; the
|
|
138
|
-
* chunk stream is concatenated and an error item is surfaced as the result.
|
|
139
|
-
* Metadata-only `cas_get` avoids this entirely via `fs/media/type` `detectStream`,
|
|
140
|
-
* which is why it is not bound by the `maxLength` ceiling below.
|
|
141
|
-
*/
|
|
142
|
-
const collectRead = (stream) => {
|
|
143
|
-
const loop = (acc) => (s) => s.step((node) => {
|
|
144
|
-
if (node === undefined) {
|
|
145
|
-
return pure(ok(acc));
|
|
146
|
-
}
|
|
147
|
-
const { first, tail } = node;
|
|
148
|
-
const [t, v] = first;
|
|
149
|
-
if (t === 'error') {
|
|
150
|
-
return pure(first);
|
|
151
|
-
}
|
|
152
|
-
// A single `Vec` cannot exceed `maxLength` bits; concatenating past it would
|
|
153
|
-
// overflow the runtime's `bigint` constraint. Surface that as an error item
|
|
154
|
-
// so the tool reports a failure rather than crashing the process.
|
|
155
|
-
if (bitVecLength(acc) + bitVecLength(v) > maxLength) {
|
|
156
|
-
return pure(error(`cas blob exceeds maximum vector length of ${maxLength} bits`));
|
|
157
|
-
}
|
|
158
|
-
return loop(msb.concat(acc)(v))(tail);
|
|
159
|
-
});
|
|
160
|
-
return loop(empty)(stream);
|
|
161
|
-
};
|
|
162
145
|
// ── Tool registry ──────────────────────────────────────────────────────────────
|
|
163
146
|
const toJson = stringify(identity);
|
|
164
|
-
/**
|
|
165
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Registry of all CAS tools, bound to `home` and the Evo cache at
|
|
149
|
+
* `cacheKey`. `cas_add` is the only tool that writes, so it is the only one
|
|
150
|
+
* that needs `cacheKey`: a successfully stored blob is folded into the Evo
|
|
151
|
+
* cache via `syncRevision` when it happens to be a `vnd.fjs.revision` — a
|
|
152
|
+
* plain `cas_add` and `evo_add` are two ways to reach the same store, and
|
|
153
|
+
* this keeps `evo_list`/`evo_head` honest about either one without a
|
|
154
|
+
* rescan.
|
|
155
|
+
*/
|
|
156
|
+
export const casToolRegistry = (home) => (cacheKey) => {
|
|
166
157
|
const c = fileCas(sha256)(home);
|
|
167
158
|
return [
|
|
168
159
|
toolEntry('cas_add', 'Store content and return its hash (cBase32). Pass type:"base64" for binary; omit or pass type:"text" for UTF-8 text (default). Inline content is capped at 128 KiB (131072 bytes) — larger content is rejected. For larger content, store the file with the `cas` CLI instead: run `npx functionalscript cas add <path>` yourself if you have shell access, or give the user that exact command to run — it prints the resulting hash on stdout.', casAddArgs, ({ type, content }) => {
|
|
@@ -173,9 +164,13 @@ const casToolRegistry = (home) => {
|
|
|
173
164
|
return x === null
|
|
174
165
|
? pure(errorResult('too large or malformed — for large content, run `npx functionalscript cas add <path>` (or have the user run it) instead'))
|
|
175
166
|
// The resolved content fits in one chunk; feed it as a single-item stream.
|
|
176
|
-
: c.write(nonEmpty(ok(x), elEmpty()))
|
|
177
|
-
|
|
178
|
-
|
|
167
|
+
: step(c.write(nonEmpty(ok(x), elEmpty())), (writeResult) => {
|
|
168
|
+
if (writeResult[0] === 'error') {
|
|
169
|
+
return pure(errorResult('write'));
|
|
170
|
+
}
|
|
171
|
+
const hash = writeResult[1];
|
|
172
|
+
return step(syncRevision(cacheKey)(hash)(x), () => pure(okResult(vecToCBase32(hash))));
|
|
173
|
+
});
|
|
179
174
|
}),
|
|
180
175
|
toolEntry('cas_get', 'Inspect a blob by hash. Always returns JSON {length,mimeType,type[,uri]} where type is "text" or "base64". Pass content:true to also include the inline payload as text (type:"text") or blob (type:"base64"), but content is capped at 128 KiB (131072 bytes) — a larger blob is rejected with an error. To download a blob, prefer the uri field returned in the result instead of requesting inline content.', casGetArgs, r => {
|
|
181
176
|
const key = cBase32ToVec(r.hash);
|
|
@@ -183,7 +178,7 @@ const casToolRegistry = (home) => {
|
|
|
183
178
|
return pure(errorResult(`invalid cBase32 hash: ${r.hash}`));
|
|
184
179
|
}
|
|
185
180
|
const uri = c.url(key);
|
|
186
|
-
return detectStream(c.read(key))
|
|
181
|
+
return step(detectStream(c.read(key)), ([tag, detected]) => {
|
|
187
182
|
if (tag === 'error') {
|
|
188
183
|
return pure(errorResult(`no such hash: ${r.hash}`));
|
|
189
184
|
}
|
|
@@ -196,7 +191,7 @@ const casToolRegistry = (home) => {
|
|
|
196
191
|
if (type !== 'text' || length > maxLengthBytes) {
|
|
197
192
|
return pure(okResult(toJson(meta)));
|
|
198
193
|
}
|
|
199
|
-
return collectRead(c.read(key))
|
|
194
|
+
return step(collectRead(c.read(key)), ([collectTag, value]) => {
|
|
200
195
|
// Already known to fit from the streaming pass above, so an
|
|
201
196
|
// error here means the hash vanished between reads; fall back
|
|
202
197
|
// to the streaming verdict rather than fail the whole request.
|
|
@@ -214,7 +209,7 @@ const casToolRegistry = (home) => {
|
|
|
214
209
|
if (length > maxLengthBytes) {
|
|
215
210
|
return pure(errorResult(`blob too large to fetch inline (${length} bytes, limit ${maxLengthBytes} bytes); use the uri field (${uri}) or omit content for metadata`));
|
|
216
211
|
}
|
|
217
|
-
return collectRead(c.read(key))
|
|
212
|
+
return step(collectRead(c.read(key)), ([collectTag, value]) => {
|
|
218
213
|
if (collectTag === 'error') {
|
|
219
214
|
return pure(errorResult(`no such hash: ${r.hash}`));
|
|
220
215
|
}
|
|
@@ -239,17 +234,15 @@ const casToolRegistry = (home) => {
|
|
|
239
234
|
});
|
|
240
235
|
});
|
|
241
236
|
}),
|
|
242
|
-
toolEntry('cas_list', 'List all stored content hashes (cBase32), one per line.', casListArgs, () => c.list()
|
|
237
|
+
toolEntry('cas_list', 'List all stored content hashes (cBase32), one per line.', casListArgs, () => step(c.list(), hashes => pure(okResult(hashes.map(vecToCBase32).join('\n'))))),
|
|
243
238
|
];
|
|
244
239
|
};
|
|
245
|
-
// ── Result helpers ──────────────────────────────────────────────────────────────
|
|
246
|
-
/** A successful single-text-block tool result. */
|
|
247
|
-
const okResult = (text) => ({ content: [{ type: 'text', text }] });
|
|
248
240
|
// ── Handlers ────────────────────────────────────────────────────────────────────
|
|
249
241
|
/**
|
|
250
|
-
* MCP handlers for `FileCas
|
|
242
|
+
* MCP handlers for `FileCas` plus the Evo API (`fjs/cas/evo`) layered on it,
|
|
243
|
+
* bound to `home` and an already-built Evo cache slot (see `initEvo`).
|
|
251
244
|
*/
|
|
252
|
-
export const casMcpHandlers = (home) => fromRegistry(casToolRegistry(home));
|
|
245
|
+
export const casMcpHandlers = (home) => (cacheKey) => fromRegistry([...casToolRegistry(home)(cacheKey), ...evoToolRegistry(evo(fileCas(sha256)(home))(cacheKey))]);
|
|
253
246
|
// ── Session configuration ───────────────────────────────────────────────────────
|
|
254
247
|
/**
|
|
255
248
|
* Static MCP configuration for the CAS server: advertises the `tools`
|
|
@@ -262,28 +255,15 @@ export const casConfig = {
|
|
|
262
255
|
};
|
|
263
256
|
// ── Server ──────────────────────────────────────────────────────────────────────
|
|
264
257
|
/**
|
|
265
|
-
* Runs the
|
|
266
|
-
* the
|
|
267
|
-
*
|
|
258
|
+
* Runs the combined CAS + Evo MCP server over stdio: scans `~/.cas/` once to
|
|
259
|
+
* build the Evo subject/head cache (`initEvo`), allocates the session-state
|
|
260
|
+
* slot, builds the `mcpStep` for the merged tool registry, and drives the
|
|
261
|
+
* read → parse → dispatch → write loop until stdin EOF.
|
|
268
262
|
*/
|
|
269
|
-
export const casMcpServer = (home) => create(uninitializedState)
|
|
263
|
+
export const casMcpServer = (home) => step(initEvo(fileCas(sha256)(home)), cacheKey => step(create(uninitializedState), sessionKey => stdioTransport(mcpStep(casConfig)(casMcpHandlers(home)(cacheKey))(sessionKey))));
|
|
270
264
|
// ── Tests ────────────────────────────────────────────────────────────────────
|
|
271
265
|
export const proof = {
|
|
272
266
|
// casMcpServer is never called in integration tests because it drives a
|
|
273
267
|
// real stdio server; call it here to cover its Effect-building body.
|
|
274
268
|
casMcpServer: () => { casMcpServer('/'); },
|
|
275
|
-
// The overflow guard in collectRead (lines 125-126) is only reached when
|
|
276
|
-
// the running total of two stream chunks would exceed maxLength. Feed a
|
|
277
|
-
// pure stream whose second chunk pushes it just over the limit so the
|
|
278
|
-
// error branch executes without any real I/O.
|
|
279
|
-
collectReadOverflow: () => {
|
|
280
|
-
const half = maxLength / 2n;
|
|
281
|
-
const v1 = vec(half)(0n);
|
|
282
|
-
const v2 = vec(half + 1n)(0n);
|
|
283
|
-
const stream = nonEmpty(ok(v1), nonEmpty(ok(v2), elEmpty()));
|
|
284
|
-
const d = decode(collectRead(stream));
|
|
285
|
-
if (!d.done || d.result[0] !== 'error') {
|
|
286
|
-
throw 'expected overflow error';
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
269
|
};
|
|
@@ -7,7 +7,10 @@ export declare const proof: {
|
|
|
7
7
|
getContentBase64InflationOverflowWritesInternalError: () => void;
|
|
8
8
|
getContentBase64NearBoundarySucceeds: () => void;
|
|
9
9
|
getContentDoubleEscapedOverflowWritesInternalError: () => void;
|
|
10
|
-
|
|
10
|
+
toolsListAdvertisesSevenTools: () => void;
|
|
11
|
+
evoAddListHeadRoundTripsThroughCasServer: () => void;
|
|
12
|
+
evoAddDomainErrorIsErrorThroughCasServer: () => void;
|
|
13
|
+
casAddSyncsEvoCacheForRevisionContent: () => void;
|
|
11
14
|
addReturnsHash: () => void;
|
|
12
15
|
textAddGetMetaRoundTrips: () => void;
|
|
13
16
|
textAddGetContentRoundTrips: () => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assert, assertEq } from '../../asserts/module.f.js';
|
|
2
|
-
import { pure } from '../../effects/module.f.js';
|
|
2
|
+
import { pure, step } from '../../effects/module.f.js';
|
|
3
3
|
import { run } from '../../effects/mock/module.f.js';
|
|
4
4
|
import { asBase, asNominal, create } from '../../effects/memory/module.f.js';
|
|
5
5
|
import { msb, u8ListToVec, vec8, repeat, length, maxLengthBytes } from '../../types/bit_vec/module.f.js';
|
|
@@ -16,6 +16,7 @@ import { casConfig, casMcpHandlers } from './module.f.js';
|
|
|
16
16
|
import { ok as resultOk } from '../../types/result/module.f.js';
|
|
17
17
|
import { stdioTransport } from '../../mcp/stdio/module.f.js';
|
|
18
18
|
import { fromVec } from '../../types/uint8array/module.f.js';
|
|
19
|
+
import { initEvo } from '../evo/module.f.js';
|
|
19
20
|
const initialTestState = { memory: { next: 0, values: {} } };
|
|
20
21
|
const mock = {
|
|
21
22
|
memCreate: value => state => {
|
|
@@ -45,21 +46,21 @@ const mock = {
|
|
|
45
46
|
};
|
|
46
47
|
const runMem = (effect) => run(mock)(initialTestState)(effect)[1];
|
|
47
48
|
// ── Session driver ──────────────────────────────────────────────────────────────
|
|
48
|
-
// Feeds each message to `
|
|
49
|
-
const feed = (
|
|
49
|
+
// Feeds each message to `handler` in order, collecting every response.
|
|
50
|
+
const feed = (handler) => (msgs) => {
|
|
50
51
|
const go = (i, acc) => i === msgs.length
|
|
51
52
|
? pure(acc)
|
|
52
|
-
: step(msgs[i])
|
|
53
|
+
: step(handler(msgs[i]), r => go(i + 1, [...acc, r]));
|
|
53
54
|
return go(0, []);
|
|
54
55
|
};
|
|
55
56
|
// Runs a session backed by the virtual node runner (for cas_upload which uses
|
|
56
57
|
// Rename/ReadBytes/RandomInt/Mkdir). Uses fileKvStore so upload and get share
|
|
57
58
|
// the same filesystem-backed CAS.
|
|
58
59
|
const runSessionVirtual = (root, home = '/home/user') => (msgs) => {
|
|
59
|
-
const effect = create(uninitializedState)
|
|
60
|
-
const step = mcpStep(casConfig)(casMcpHandlers(home))(sessionKey);
|
|
60
|
+
const effect = step(initEvo(fileCas(sha256)(home)), cacheKey => step(create(uninitializedState), sessionKey => {
|
|
61
|
+
const step = mcpStep(casConfig)(casMcpHandlers(home)(cacheKey))(sessionKey);
|
|
61
62
|
return feed(step)(msgs);
|
|
62
|
-
});
|
|
63
|
+
}));
|
|
63
64
|
return virtual({ ...emptyState, root })(effect)[1];
|
|
64
65
|
};
|
|
65
66
|
// Seeds a blob directly into the virtual store via `c.write`, bypassing the
|
|
@@ -91,10 +92,10 @@ const toBytes = (s) => [...fromVec(utf8(s))];
|
|
|
91
92
|
// `session`/`runSessionVirtual`, which collect `mcpStep`'s `Response` values
|
|
92
93
|
// as plain JS objects and never serialize/encode them, this is the only
|
|
93
94
|
// helper that can observe the transport's oversized-response fallback (see
|
|
94
|
-
// `
|
|
95
|
+
// `fjs/mcp/stdio/module.f.ts` `writeResponse`).
|
|
95
96
|
const runStdio = (root, home = '/home/user') => (msgs) => {
|
|
96
97
|
const input = [init, initialized, ...msgs].map(m => JSON.stringify(m)).join('\n') + '\n';
|
|
97
|
-
const effect = create(uninitializedState)
|
|
98
|
+
const effect = step(initEvo(fileCas(sha256)(home)), cacheKey => step(create(uninitializedState), sessionKey => stdioTransport(mcpStep(casConfig)(casMcpHandlers(home)(cacheKey))(sessionKey))));
|
|
98
99
|
const stdout = virtual({ ...emptyState, root, stdin: toBytes(input) })(effect)[0].stdout;
|
|
99
100
|
// Only requests get a written line (notifications, like `initialized`,
|
|
100
101
|
// write nothing) — drop the `init` response, keep one line per `msgs` entry.
|
|
@@ -105,9 +106,9 @@ const item0 = (resp) => resultOf(resp).content[0];
|
|
|
105
106
|
const textOf = (resp) => item0(resp).text;
|
|
106
107
|
// A plain text sample for text add→get round-trips.
|
|
107
108
|
const textSample = 'hello, world!';
|
|
108
|
-
// A valid `vnd.fjs.revision` blob:
|
|
109
|
-
//
|
|
110
|
-
const revisionSample = `{"dialect":"${revisionDialect}","subject":"8","parents":[]}`;
|
|
109
|
+
// A valid `vnd.fjs.revision` blob: every required field present, including the
|
|
110
|
+
// explicit `snapshot` and `generation` the format now mandates.
|
|
111
|
+
const revisionSample = `{"dialect":"${revisionDialect}","subject":"8","parents":[],"snapshot":"8","generation":0}`;
|
|
111
112
|
// A base64-encoded binary payload for binary add→get round-trips.
|
|
112
113
|
const binarySample = base64Encode(vec8(0x2an));
|
|
113
114
|
// A base64 blob whose leading bytes are the PNG magic-byte signature, so
|
|
@@ -207,12 +208,12 @@ export const proof = {
|
|
|
207
208
|
// the JSON-RPC envelope is even added. The transport's `writeResponse`
|
|
208
209
|
// (`tryUtf8`) must catch this and write a JSON-RPC internal-error response —
|
|
209
210
|
// carrying the *original request's* `id` — instead of crashing the process.
|
|
210
|
-
// See `
|
|
211
|
+
// See `fjs/mcp/stdio/module.f.ts` `writeResponse`.
|
|
211
212
|
//
|
|
212
213
|
// This test originally timed out under `bun test`'s native 5s per-test
|
|
213
214
|
// limit (12-14s observed in CI on PR #1201) — the cost was in
|
|
214
215
|
// `base64Encode`, quadratic before the `baseN.vecToString` fix (see
|
|
215
|
-
// `
|
|
216
|
+
// `fjs/basen/base64/proof.f.ts` `encodeLargeVecIsSlow`). Now well under budget on
|
|
216
217
|
// both engines.
|
|
217
218
|
getContentBase64InflationOverflowWritesInternalError: () => {
|
|
218
219
|
const [root, hash] = seedBlob({})([oversizedBase64Chunk]);
|
|
@@ -256,14 +257,41 @@ export const proof = {
|
|
|
256
257
|
assertEq(err.error?.code, -32603);
|
|
257
258
|
assertEq(err.id, 2);
|
|
258
259
|
},
|
|
259
|
-
|
|
260
|
+
toolsListAdvertisesSevenTools: () => {
|
|
260
261
|
const [resp] = runSessionVirtual({})([init, initialized, list(2)]).slice(2);
|
|
261
262
|
const tools = resp.result.tools;
|
|
262
|
-
assertEq(tools.length,
|
|
263
|
-
assertEq(tools.map(t => t.name).join(','), 'cas_add,cas_get,cas_list');
|
|
263
|
+
assertEq(tools.length, 7);
|
|
264
|
+
assertEq(tools.map(t => t.name).join(','), 'cas_add,cas_get,cas_list,evo_list,evo_head,evo_revision,evo_add');
|
|
264
265
|
const add = resp.result.tools[0];
|
|
265
266
|
assertEq(add.inputSchema.type, 'object');
|
|
266
267
|
},
|
|
268
|
+
// The same server also exposes Evo (fjs/cas/evo): add a revision, then
|
|
269
|
+
// find it via evo_list/evo_head — one process, one store, one cache.
|
|
270
|
+
evoAddListHeadRoundTripsThroughCasServer: () => {
|
|
271
|
+
const [addResp, listResp, headResp] = session(call(2, 'evo_add', { parents: [], subject: 'doc', snapshot: vecToCBase32(vec8(0x1n)) }), call(3, 'evo_list', {}), call(4, 'evo_head', { subject: 'doc' }));
|
|
272
|
+
assert(!resultOf(addResp).isError);
|
|
273
|
+
const hash = textOf(addResp);
|
|
274
|
+
assert(hash.length > 0);
|
|
275
|
+
assertEq(textOf(listResp), '["doc"]');
|
|
276
|
+
assertEq(textOf(headResp), hash);
|
|
277
|
+
},
|
|
278
|
+
evoAddDomainErrorIsErrorThroughCasServer: () => {
|
|
279
|
+
// Valid arguments, but the domain rule fails: `subject` is required
|
|
280
|
+
// unless there is exactly one parent.
|
|
281
|
+
const [resp] = session(call(2, 'evo_add', { parents: [] }));
|
|
282
|
+
assertEq(resultOf(resp).isError, true);
|
|
283
|
+
assert(textOf(resp).includes('subject is required'));
|
|
284
|
+
},
|
|
285
|
+
// A plain `cas_add` of `vnd.fjs.revision` content is folded into the Evo
|
|
286
|
+
// cache too (`syncRevision`), not just `evo_add` — `cas_add`/`evo_add`
|
|
287
|
+
// are two ways to reach the same store and cache.
|
|
288
|
+
casAddSyncsEvoCacheForRevisionContent: () => {
|
|
289
|
+
const [addResp, listResp, headResp] = session(call(2, 'cas_add', { content: revisionSample }), call(3, 'evo_list', {}), call(4, 'evo_head', { subject: '8' }));
|
|
290
|
+
assert(!resultOf(addResp).isError);
|
|
291
|
+
const hash = textOf(addResp);
|
|
292
|
+
assertEq(textOf(listResp), '["8"]');
|
|
293
|
+
assertEq(textOf(headResp), hash);
|
|
294
|
+
},
|
|
267
295
|
addReturnsHash: () => {
|
|
268
296
|
const [resp] = session(call(2, 'cas_add', { content: textSample }));
|
|
269
297
|
assert(!resultOf(resp).isError);
|
|
@@ -33,6 +33,16 @@ export type Cas<O extends Operation> = {
|
|
|
33
33
|
/** Lists all stored content hashes. */
|
|
34
34
|
readonly list: () => Effect<O, readonly Vec[]>;
|
|
35
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Drains a `Cas<O>.read` chunk stream into a single `Vec`. Used by any caller
|
|
38
|
+
* that needs the whole blob at once (an MCP `content: true` fetch, an Evo
|
|
39
|
+
* revision decode): the chunk stream is concatenated and an error item is
|
|
40
|
+
* surfaced as the result. A single `Vec` cannot exceed `maxLength` bits;
|
|
41
|
+
* concatenating past it would overflow the runtime's `bigint` constraint, so
|
|
42
|
+
* that case is surfaced as an error item too, rather than crashing the
|
|
43
|
+
* process.
|
|
44
|
+
*/
|
|
45
|
+
export declare const collectRead: <O extends Operation>(stream: List<O, IoResult<Vec>>) => Effect<O, IoResult<Vec>>;
|
|
36
46
|
export type FileCas = Cas<FileCasOperation> & {
|
|
37
47
|
url: (v: Vec) => string;
|
|
38
48
|
};
|