groove-dev 0.27.92 → 0.27.94
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/moe-training/package.json +2 -1
- package/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/api.js +17 -9
- package/node_modules/@groove-dev/daemon/src/process.js +2 -0
- package/node_modules/@groove-dev/gui/dist/assets/{codemirror-BBL3i_JW.js → codemirror-CFF1Lrnz.js} +10 -10
- package/{packages/gui/dist/assets/index-DWv32qyJ.js → node_modules/@groove-dev/gui/dist/assets/index-B3GUKInH.js} +1740 -1740
- package/{packages/gui/dist/assets/index-Bo6AeNmM.css → node_modules/@groove-dev/gui/dist/assets/index-C1k-GuDg.css} +1 -1
- package/node_modules/@groove-dev/gui/dist/index.html +3 -3
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +2 -0
- package/node_modules/@groove-dev/gui/src/components/editor/code-editor.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/stores/groove.js +23 -16
- package/node_modules/@groove-dev/gui/src/views/agents.jsx +44 -113
- package/node_modules/base64-js/LICENSE +21 -0
- package/node_modules/base64-js/README.md +34 -0
- package/node_modules/base64-js/base64js.min.js +1 -0
- package/node_modules/base64-js/index.d.ts +3 -0
- package/node_modules/base64-js/index.js +150 -0
- package/node_modules/base64-js/package.json +47 -0
- package/node_modules/better-sqlite3/LICENSE +21 -0
- package/node_modules/better-sqlite3/README.md +99 -0
- package/node_modules/better-sqlite3/binding.gyp +38 -0
- package/node_modules/better-sqlite3/deps/common.gypi +68 -0
- package/node_modules/better-sqlite3/deps/copy.js +31 -0
- package/node_modules/better-sqlite3/deps/defines.gypi +41 -0
- package/node_modules/better-sqlite3/deps/download.sh +122 -0
- package/node_modules/better-sqlite3/deps/patches/1208.patch +15 -0
- package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.c +268845 -0
- package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.h +14335 -0
- package/node_modules/better-sqlite3/deps/sqlite3/sqlite3ext.h +739 -0
- package/node_modules/better-sqlite3/deps/sqlite3.gyp +80 -0
- package/node_modules/better-sqlite3/deps/test_extension.c +21 -0
- package/node_modules/better-sqlite3/lib/database.js +90 -0
- package/node_modules/better-sqlite3/lib/index.js +3 -0
- package/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
- package/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
- package/node_modules/better-sqlite3/lib/methods/function.js +31 -0
- package/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
- package/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
- package/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
- package/node_modules/better-sqlite3/lib/methods/table.js +189 -0
- package/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
- package/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
- package/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
- package/node_modules/better-sqlite3/lib/util.js +12 -0
- package/node_modules/better-sqlite3/package.json +59 -0
- package/node_modules/better-sqlite3/src/addon.cpp +47 -0
- package/node_modules/better-sqlite3/src/better_sqlite3.cpp +74 -0
- package/node_modules/better-sqlite3/src/objects/backup.cpp +120 -0
- package/node_modules/better-sqlite3/src/objects/backup.hpp +36 -0
- package/node_modules/better-sqlite3/src/objects/database.cpp +417 -0
- package/node_modules/better-sqlite3/src/objects/database.hpp +103 -0
- package/node_modules/better-sqlite3/src/objects/statement-iterator.cpp +113 -0
- package/node_modules/better-sqlite3/src/objects/statement-iterator.hpp +50 -0
- package/node_modules/better-sqlite3/src/objects/statement.cpp +383 -0
- package/node_modules/better-sqlite3/src/objects/statement.hpp +58 -0
- package/node_modules/better-sqlite3/src/util/bind-map.cpp +73 -0
- package/node_modules/better-sqlite3/src/util/binder.cpp +193 -0
- package/node_modules/better-sqlite3/src/util/constants.cpp +172 -0
- package/node_modules/better-sqlite3/src/util/custom-aggregate.cpp +121 -0
- package/node_modules/better-sqlite3/src/util/custom-function.cpp +59 -0
- package/node_modules/better-sqlite3/src/util/custom-table.cpp +409 -0
- package/node_modules/better-sqlite3/src/util/data-converter.cpp +17 -0
- package/node_modules/better-sqlite3/src/util/data.cpp +194 -0
- package/node_modules/better-sqlite3/src/util/helpers.cpp +109 -0
- package/node_modules/better-sqlite3/src/util/macros.cpp +83 -0
- package/node_modules/better-sqlite3/src/util/query-macros.cpp +71 -0
- package/node_modules/better-sqlite3/src/util/row-builder.cpp +49 -0
- package/node_modules/bindings/LICENSE.md +22 -0
- package/node_modules/bindings/README.md +98 -0
- package/node_modules/bindings/bindings.js +221 -0
- package/node_modules/bindings/package.json +28 -0
- package/node_modules/bl/.travis.yml +17 -0
- package/node_modules/bl/BufferList.js +396 -0
- package/node_modules/bl/LICENSE.md +13 -0
- package/node_modules/bl/README.md +247 -0
- package/node_modules/bl/bl.js +84 -0
- package/node_modules/bl/package.json +37 -0
- package/node_modules/bl/test/convert.js +21 -0
- package/node_modules/bl/test/indexOf.js +492 -0
- package/node_modules/bl/test/isBufferList.js +32 -0
- package/node_modules/bl/test/test.js +869 -0
- package/node_modules/buffer/AUTHORS.md +70 -0
- package/node_modules/buffer/LICENSE +21 -0
- package/node_modules/buffer/README.md +410 -0
- package/node_modules/buffer/index.d.ts +186 -0
- package/node_modules/buffer/index.js +1817 -0
- package/node_modules/buffer/package.json +96 -0
- package/node_modules/decompress-response/index.d.ts +22 -0
- package/node_modules/decompress-response/index.js +58 -0
- package/node_modules/decompress-response/license +9 -0
- package/node_modules/decompress-response/node_modules/mimic-response/index.d.ts +17 -0
- package/node_modules/decompress-response/node_modules/mimic-response/index.js +77 -0
- package/node_modules/decompress-response/node_modules/mimic-response/license +9 -0
- package/node_modules/decompress-response/node_modules/mimic-response/package.json +42 -0
- package/node_modules/decompress-response/node_modules/mimic-response/readme.md +78 -0
- package/node_modules/decompress-response/package.json +56 -0
- package/node_modules/decompress-response/readme.md +48 -0
- package/node_modules/deep-extend/LICENSE +20 -0
- package/node_modules/deep-extend/README.md +91 -0
- package/node_modules/deep-extend/index.js +1 -0
- package/node_modules/deep-extend/lib/deep-extend.js +150 -0
- package/node_modules/deep-extend/package.json +62 -0
- package/node_modules/end-of-stream/LICENSE +21 -0
- package/node_modules/end-of-stream/README.md +54 -0
- package/node_modules/end-of-stream/index.js +96 -0
- package/node_modules/end-of-stream/package.json +37 -0
- package/node_modules/expand-template/.travis.yml +6 -0
- package/node_modules/expand-template/LICENSE +21 -0
- package/node_modules/expand-template/README.md +43 -0
- package/node_modules/expand-template/index.js +26 -0
- package/node_modules/expand-template/package.json +29 -0
- package/node_modules/expand-template/test.js +67 -0
- package/node_modules/file-uri-to-path/.npmignore +1 -0
- package/node_modules/file-uri-to-path/.travis.yml +30 -0
- package/node_modules/file-uri-to-path/History.md +21 -0
- package/node_modules/file-uri-to-path/LICENSE +20 -0
- package/node_modules/file-uri-to-path/README.md +74 -0
- package/node_modules/file-uri-to-path/index.d.ts +2 -0
- package/node_modules/file-uri-to-path/index.js +66 -0
- package/node_modules/file-uri-to-path/package.json +32 -0
- package/node_modules/file-uri-to-path/test/test.js +24 -0
- package/node_modules/file-uri-to-path/test/tests.json +13 -0
- package/node_modules/fs-constants/LICENSE +21 -0
- package/node_modules/fs-constants/README.md +26 -0
- package/node_modules/fs-constants/browser.js +1 -0
- package/node_modules/fs-constants/index.js +1 -0
- package/node_modules/fs-constants/package.json +19 -0
- package/node_modules/github-from-package/.travis.yml +4 -0
- package/node_modules/github-from-package/LICENSE +18 -0
- package/node_modules/github-from-package/example/package.json +8 -0
- package/node_modules/github-from-package/example/url.js +3 -0
- package/node_modules/github-from-package/index.js +17 -0
- package/node_modules/github-from-package/package.json +30 -0
- package/node_modules/github-from-package/readme.markdown +53 -0
- package/node_modules/github-from-package/test/a.json +8 -0
- package/node_modules/github-from-package/test/b.json +5 -0
- package/node_modules/github-from-package/test/c.json +5 -0
- package/node_modules/github-from-package/test/d.json +7 -0
- package/node_modules/github-from-package/test/e.json +5 -0
- package/node_modules/github-from-package/test/url.js +19 -0
- package/node_modules/ieee754/LICENSE +11 -0
- package/node_modules/ieee754/README.md +51 -0
- package/node_modules/ieee754/index.d.ts +10 -0
- package/node_modules/ieee754/index.js +85 -0
- package/node_modules/ieee754/package.json +52 -0
- package/node_modules/ini/LICENSE +15 -0
- package/node_modules/ini/README.md +102 -0
- package/node_modules/ini/ini.js +206 -0
- package/node_modules/ini/package.json +33 -0
- package/node_modules/minimist/.eslintrc +29 -0
- package/node_modules/minimist/.github/FUNDING.yml +12 -0
- package/node_modules/minimist/.nycrc +14 -0
- package/node_modules/minimist/CHANGELOG.md +298 -0
- package/node_modules/minimist/LICENSE +18 -0
- package/node_modules/minimist/README.md +121 -0
- package/node_modules/minimist/example/parse.js +4 -0
- package/node_modules/minimist/index.js +263 -0
- package/node_modules/minimist/package.json +75 -0
- package/node_modules/minimist/test/all_bool.js +34 -0
- package/node_modules/minimist/test/bool.js +177 -0
- package/node_modules/minimist/test/dash.js +43 -0
- package/node_modules/minimist/test/default_bool.js +37 -0
- package/node_modules/minimist/test/dotted.js +24 -0
- package/node_modules/minimist/test/kv_short.js +32 -0
- package/node_modules/minimist/test/long.js +33 -0
- package/node_modules/minimist/test/num.js +38 -0
- package/node_modules/minimist/test/parse.js +209 -0
- package/node_modules/minimist/test/parse_modified.js +11 -0
- package/node_modules/minimist/test/proto.js +64 -0
- package/node_modules/minimist/test/short.js +69 -0
- package/node_modules/minimist/test/stop_early.js +17 -0
- package/node_modules/minimist/test/unknown.js +104 -0
- package/node_modules/minimist/test/whitespace.js +10 -0
- package/node_modules/mkdirp-classic/LICENSE +21 -0
- package/node_modules/mkdirp-classic/README.md +18 -0
- package/node_modules/mkdirp-classic/index.js +98 -0
- package/node_modules/mkdirp-classic/package.json +18 -0
- package/node_modules/moe-training/DEPLOY_CENTRAL_COMMAND.md +413 -0
- package/node_modules/moe-training/client/consent.js +96 -0
- package/node_modules/moe-training/client/envelope-builder.js +56 -0
- package/node_modules/moe-training/client/index.js +10 -0
- package/node_modules/moe-training/client/parsers/claude-code.js +108 -0
- package/node_modules/moe-training/client/parsers/codex.js +80 -0
- package/node_modules/moe-training/client/parsers/gemini.js +80 -0
- package/node_modules/moe-training/client/parsers/grok.js +16 -0
- package/node_modules/moe-training/client/parsers/index.js +20 -0
- package/node_modules/moe-training/client/scrubber.js +128 -0
- package/node_modules/moe-training/client/session-attestation.js +115 -0
- package/node_modules/moe-training/client/step-classifier.js +68 -0
- package/node_modules/moe-training/client/trajectory-capture.js +307 -0
- package/node_modules/moe-training/client/transmission-queue.js +104 -0
- package/node_modules/moe-training/package.json +21 -0
- package/node_modules/moe-training/server/enrichment.js +24 -0
- package/node_modules/moe-training/server/index.js +119 -0
- package/node_modules/moe-training/server/ledger.js +110 -0
- package/node_modules/moe-training/server/routes/ingest.js +96 -0
- package/node_modules/moe-training/server/routes/sessions.js +43 -0
- package/node_modules/moe-training/server/routes/stats.js +31 -0
- package/node_modules/moe-training/server/scoring.js +63 -0
- package/node_modules/moe-training/server/session-registry.js +156 -0
- package/node_modules/moe-training/server/stats.js +129 -0
- package/node_modules/moe-training/server/stitcher.js +69 -0
- package/node_modules/moe-training/server/storage.js +147 -0
- package/node_modules/moe-training/server/verifier.js +102 -0
- package/node_modules/moe-training/shared/constants.js +30 -0
- package/node_modules/moe-training/shared/crypto.js +45 -0
- package/node_modules/moe-training/shared/envelope-schema.js +220 -0
- package/node_modules/moe-training/test/client/consent.test.js +121 -0
- package/node_modules/moe-training/test/client/envelope-builder.test.js +107 -0
- package/node_modules/moe-training/test/client/parsers/claude-code.test.js +119 -0
- package/node_modules/moe-training/test/client/parsers/codex.test.js +83 -0
- package/node_modules/moe-training/test/client/parsers/gemini.test.js +99 -0
- package/node_modules/moe-training/test/client/scrubber.test.js +143 -0
- package/node_modules/moe-training/test/client/session-attestation-security.test.js +95 -0
- package/node_modules/moe-training/test/client/step-classifier.test.js +135 -0
- package/node_modules/moe-training/test/client/transmission-queue.test.js +33 -0
- package/node_modules/moe-training/test/integration/handshake.test.js +260 -0
- package/node_modules/moe-training/test/server/ingest-security.test.js +166 -0
- package/node_modules/moe-training/test/server/ledger.test.js +131 -0
- package/node_modules/moe-training/test/server/scoring.test.js +242 -0
- package/node_modules/moe-training/test/server/session-registry.test.js +125 -0
- package/node_modules/moe-training/test/server/stitcher.test.js +157 -0
- package/node_modules/moe-training/test/server/verifier.test.js +232 -0
- package/node_modules/moe-training/test/shared/crypto.test.js +87 -0
- package/node_modules/moe-training/test/shared/envelope-schema.test.js +351 -0
- package/node_modules/napi-build-utils/.github/workflows/run-npm-tests.yml +31 -0
- package/node_modules/napi-build-utils/LICENSE +21 -0
- package/node_modules/napi-build-utils/README.md +52 -0
- package/node_modules/napi-build-utils/index.js +214 -0
- package/node_modules/napi-build-utils/index.md +0 -0
- package/node_modules/napi-build-utils/package.json +42 -0
- package/node_modules/prebuild-install/CHANGELOG.md +131 -0
- package/node_modules/prebuild-install/CONTRIBUTING.md +6 -0
- package/node_modules/prebuild-install/LICENSE +21 -0
- package/node_modules/prebuild-install/README.md +163 -0
- package/node_modules/prebuild-install/asset.js +44 -0
- package/node_modules/prebuild-install/bin.js +78 -0
- package/node_modules/prebuild-install/download.js +142 -0
- package/node_modules/prebuild-install/error.js +14 -0
- package/node_modules/prebuild-install/help.txt +16 -0
- package/node_modules/prebuild-install/index.js +1 -0
- package/node_modules/prebuild-install/log.js +33 -0
- package/node_modules/prebuild-install/node_modules/node-abi/LICENSE +21 -0
- package/node_modules/prebuild-install/node_modules/node-abi/README.md +54 -0
- package/node_modules/prebuild-install/node_modules/node-abi/abi_registry.json +439 -0
- package/node_modules/prebuild-install/node_modules/node-abi/index.js +179 -0
- package/node_modules/prebuild-install/node_modules/node-abi/package.json +45 -0
- package/node_modules/prebuild-install/node_modules/semver/LICENSE +15 -0
- package/node_modules/prebuild-install/node_modules/semver/README.md +665 -0
- package/node_modules/prebuild-install/node_modules/semver/bin/semver.js +191 -0
- package/node_modules/prebuild-install/node_modules/semver/classes/comparator.js +143 -0
- package/node_modules/prebuild-install/node_modules/semver/classes/index.js +7 -0
- package/node_modules/prebuild-install/node_modules/semver/classes/range.js +557 -0
- package/node_modules/prebuild-install/node_modules/semver/classes/semver.js +333 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/clean.js +8 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/cmp.js +54 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/coerce.js +62 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/compare-build.js +9 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/compare-loose.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/compare.js +7 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/diff.js +60 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/eq.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/gt.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/gte.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/inc.js +21 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/lt.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/lte.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/major.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/minor.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/neq.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/parse.js +18 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/patch.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/prerelease.js +8 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/rcompare.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/rsort.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/satisfies.js +12 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/sort.js +5 -0
- package/node_modules/prebuild-install/node_modules/semver/functions/valid.js +8 -0
- package/node_modules/prebuild-install/node_modules/semver/index.js +91 -0
- package/node_modules/prebuild-install/node_modules/semver/internal/constants.js +37 -0
- package/node_modules/prebuild-install/node_modules/semver/internal/debug.js +11 -0
- package/node_modules/prebuild-install/node_modules/semver/internal/identifiers.js +29 -0
- package/node_modules/prebuild-install/node_modules/semver/internal/lrucache.js +42 -0
- package/node_modules/prebuild-install/node_modules/semver/internal/parse-options.js +17 -0
- package/node_modules/prebuild-install/node_modules/semver/internal/re.js +223 -0
- package/node_modules/prebuild-install/node_modules/semver/package.json +78 -0
- package/node_modules/prebuild-install/node_modules/semver/preload.js +4 -0
- package/node_modules/prebuild-install/node_modules/semver/range.bnf +16 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/gtr.js +6 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/intersects.js +9 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/ltr.js +6 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/max-satisfying.js +27 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/min-satisfying.js +26 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/min-version.js +63 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/outside.js +82 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/simplify.js +49 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/subset.js +249 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/to-comparators.js +10 -0
- package/node_modules/prebuild-install/node_modules/semver/ranges/valid.js +13 -0
- package/node_modules/prebuild-install/package.json +67 -0
- package/node_modules/prebuild-install/proxy.js +35 -0
- package/node_modules/prebuild-install/rc.js +64 -0
- package/node_modules/prebuild-install/util.js +143 -0
- package/node_modules/pump/.github/FUNDING.yml +2 -0
- package/node_modules/pump/.travis.yml +5 -0
- package/node_modules/pump/LICENSE +21 -0
- package/node_modules/pump/README.md +74 -0
- package/node_modules/pump/SECURITY.md +5 -0
- package/node_modules/pump/empty.js +1 -0
- package/node_modules/pump/index.js +86 -0
- package/node_modules/pump/package.json +30 -0
- package/node_modules/pump/test-browser.js +66 -0
- package/node_modules/pump/test-node.js +53 -0
- package/node_modules/rc/LICENSE.APACHE2 +15 -0
- package/node_modules/rc/LICENSE.BSD +26 -0
- package/node_modules/rc/LICENSE.MIT +24 -0
- package/node_modules/rc/README.md +227 -0
- package/node_modules/rc/browser.js +7 -0
- package/node_modules/rc/cli.js +4 -0
- package/node_modules/rc/index.js +53 -0
- package/node_modules/rc/lib/utils.js +104 -0
- package/node_modules/rc/package.json +29 -0
- package/node_modules/rc/test/ini.js +16 -0
- package/node_modules/rc/test/nested-env-vars.js +50 -0
- package/node_modules/rc/test/test.js +59 -0
- package/node_modules/readable-stream/CONTRIBUTING.md +38 -0
- package/node_modules/readable-stream/GOVERNANCE.md +136 -0
- package/node_modules/readable-stream/LICENSE +47 -0
- package/node_modules/readable-stream/README.md +106 -0
- package/node_modules/readable-stream/errors-browser.js +127 -0
- package/node_modules/readable-stream/errors.js +116 -0
- package/node_modules/readable-stream/experimentalWarning.js +17 -0
- package/node_modules/readable-stream/lib/_stream_duplex.js +126 -0
- package/node_modules/readable-stream/lib/_stream_passthrough.js +37 -0
- package/node_modules/readable-stream/lib/_stream_readable.js +1027 -0
- package/node_modules/readable-stream/lib/_stream_transform.js +190 -0
- package/node_modules/readable-stream/lib/_stream_writable.js +641 -0
- package/node_modules/readable-stream/lib/internal/streams/async_iterator.js +180 -0
- package/node_modules/readable-stream/lib/internal/streams/buffer_list.js +183 -0
- package/node_modules/readable-stream/lib/internal/streams/destroy.js +96 -0
- package/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +86 -0
- package/node_modules/readable-stream/lib/internal/streams/from-browser.js +3 -0
- package/node_modules/readable-stream/lib/internal/streams/from.js +52 -0
- package/node_modules/readable-stream/lib/internal/streams/pipeline.js +86 -0
- package/node_modules/readable-stream/lib/internal/streams/state.js +22 -0
- package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
- package/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
- package/node_modules/readable-stream/package.json +68 -0
- package/node_modules/readable-stream/readable-browser.js +9 -0
- package/node_modules/readable-stream/readable.js +16 -0
- package/node_modules/simple-concat/.travis.yml +3 -0
- package/node_modules/simple-concat/LICENSE +20 -0
- package/node_modules/simple-concat/README.md +44 -0
- package/node_modules/simple-concat/index.js +15 -0
- package/node_modules/simple-concat/package.json +47 -0
- package/node_modules/simple-concat/test/basic.js +41 -0
- package/node_modules/simple-get/.github/dependabot.yml +15 -0
- package/node_modules/simple-get/.github/workflows/ci.yml +23 -0
- package/node_modules/simple-get/LICENSE +20 -0
- package/node_modules/simple-get/README.md +333 -0
- package/node_modules/simple-get/index.js +108 -0
- package/node_modules/simple-get/package.json +67 -0
- package/node_modules/string_decoder/LICENSE +48 -0
- package/node_modules/string_decoder/README.md +47 -0
- package/node_modules/string_decoder/lib/string_decoder.js +296 -0
- package/node_modules/string_decoder/package.json +34 -0
- package/node_modules/strip-json-comments/index.js +70 -0
- package/node_modules/strip-json-comments/license +21 -0
- package/node_modules/strip-json-comments/package.json +42 -0
- package/node_modules/strip-json-comments/readme.md +64 -0
- package/node_modules/tar-fs/.travis.yml +6 -0
- package/node_modules/tar-fs/LICENSE +21 -0
- package/node_modules/tar-fs/README.md +165 -0
- package/node_modules/tar-fs/index.js +363 -0
- package/node_modules/tar-fs/node_modules/chownr/LICENSE +15 -0
- package/node_modules/tar-fs/node_modules/chownr/README.md +3 -0
- package/node_modules/tar-fs/node_modules/chownr/chownr.js +167 -0
- package/node_modules/tar-fs/node_modules/chownr/package.json +29 -0
- package/node_modules/tar-fs/package.json +41 -0
- package/node_modules/tar-fs/test/fixtures/a/hello.txt +1 -0
- package/node_modules/tar-fs/test/fixtures/b/a/test.txt +1 -0
- package/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
- package/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
- package/node_modules/tar-fs/test/fixtures/e/file +0 -0
- package/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
- package/node_modules/tar-fs/test/index.js +346 -0
- package/node_modules/tar-stream/LICENSE +21 -0
- package/node_modules/tar-stream/README.md +168 -0
- package/node_modules/tar-stream/extract.js +257 -0
- package/node_modules/tar-stream/headers.js +295 -0
- package/node_modules/tar-stream/index.js +2 -0
- package/node_modules/tar-stream/pack.js +255 -0
- package/node_modules/tar-stream/package.json +58 -0
- package/node_modules/tar-stream/sandbox.js +11 -0
- package/node_modules/tunnel-agent/LICENSE +55 -0
- package/node_modules/tunnel-agent/README.md +4 -0
- package/node_modules/tunnel-agent/index.js +244 -0
- package/node_modules/tunnel-agent/package.json +22 -0
- package/node_modules/util-deprecate/History.md +16 -0
- package/node_modules/util-deprecate/LICENSE +24 -0
- package/node_modules/util-deprecate/README.md +53 -0
- package/node_modules/util-deprecate/browser.js +67 -0
- package/node_modules/util-deprecate/node.js +6 -0
- package/node_modules/util-deprecate/package.json +27 -0
- package/node_modules/uuid/CHANGELOG.md +274 -0
- package/node_modules/uuid/CONTRIBUTING.md +18 -0
- package/node_modules/uuid/LICENSE.md +9 -0
- package/node_modules/uuid/README.md +466 -0
- package/node_modules/uuid/dist/bin/uuid +2 -0
- package/node_modules/uuid/dist/commonjs-browser/index.js +79 -0
- package/node_modules/uuid/dist/commonjs-browser/md5.js +223 -0
- package/node_modules/uuid/dist/commonjs-browser/native.js +11 -0
- package/node_modules/uuid/dist/commonjs-browser/nil.js +8 -0
- package/node_modules/uuid/dist/commonjs-browser/parse.js +45 -0
- package/node_modules/uuid/dist/commonjs-browser/regex.js +8 -0
- package/node_modules/uuid/dist/commonjs-browser/rng.js +25 -0
- package/node_modules/uuid/dist/commonjs-browser/sha1.js +104 -0
- package/node_modules/uuid/dist/commonjs-browser/stringify.js +44 -0
- package/node_modules/uuid/dist/commonjs-browser/v1.js +107 -0
- package/node_modules/uuid/dist/commonjs-browser/v3.js +16 -0
- package/node_modules/uuid/dist/commonjs-browser/v35.js +80 -0
- package/node_modules/uuid/dist/commonjs-browser/v4.js +43 -0
- package/node_modules/uuid/dist/commonjs-browser/v5.js +16 -0
- package/node_modules/uuid/dist/commonjs-browser/validate.js +17 -0
- package/node_modules/uuid/dist/commonjs-browser/version.js +21 -0
- package/node_modules/uuid/dist/esm-browser/index.js +9 -0
- package/node_modules/uuid/dist/esm-browser/md5.js +215 -0
- package/node_modules/uuid/dist/esm-browser/native.js +4 -0
- package/node_modules/uuid/dist/esm-browser/nil.js +1 -0
- package/node_modules/uuid/dist/esm-browser/parse.js +35 -0
- package/node_modules/uuid/dist/esm-browser/regex.js +1 -0
- package/node_modules/uuid/dist/esm-browser/rng.js +18 -0
- package/node_modules/uuid/dist/esm-browser/sha1.js +96 -0
- package/node_modules/uuid/dist/esm-browser/stringify.js +33 -0
- package/node_modules/uuid/dist/esm-browser/v1.js +95 -0
- package/node_modules/uuid/dist/esm-browser/v3.js +4 -0
- package/node_modules/uuid/dist/esm-browser/v35.js +66 -0
- package/node_modules/uuid/dist/esm-browser/v4.js +29 -0
- package/node_modules/uuid/dist/esm-browser/v5.js +4 -0
- package/node_modules/uuid/dist/esm-browser/validate.js +7 -0
- package/node_modules/uuid/dist/esm-browser/version.js +11 -0
- package/node_modules/uuid/dist/esm-node/index.js +9 -0
- package/node_modules/uuid/dist/esm-node/md5.js +13 -0
- package/node_modules/uuid/dist/esm-node/native.js +4 -0
- package/node_modules/uuid/dist/esm-node/nil.js +1 -0
- package/node_modules/uuid/dist/esm-node/parse.js +35 -0
- package/node_modules/uuid/dist/esm-node/regex.js +1 -0
- package/node_modules/uuid/dist/esm-node/rng.js +12 -0
- package/node_modules/uuid/dist/esm-node/sha1.js +13 -0
- package/node_modules/uuid/dist/esm-node/stringify.js +33 -0
- package/node_modules/uuid/dist/esm-node/v1.js +95 -0
- package/node_modules/uuid/dist/esm-node/v3.js +4 -0
- package/node_modules/uuid/dist/esm-node/v35.js +66 -0
- package/node_modules/uuid/dist/esm-node/v4.js +29 -0
- package/node_modules/uuid/dist/esm-node/v5.js +4 -0
- package/node_modules/uuid/dist/esm-node/validate.js +7 -0
- package/node_modules/uuid/dist/esm-node/version.js +11 -0
- package/node_modules/uuid/dist/index.js +79 -0
- package/node_modules/uuid/dist/md5-browser.js +223 -0
- package/node_modules/uuid/dist/md5.js +23 -0
- package/node_modules/uuid/dist/native-browser.js +11 -0
- package/node_modules/uuid/dist/native.js +15 -0
- package/node_modules/uuid/dist/nil.js +8 -0
- package/node_modules/uuid/dist/parse.js +45 -0
- package/node_modules/uuid/dist/regex.js +8 -0
- package/node_modules/uuid/dist/rng-browser.js +25 -0
- package/node_modules/uuid/dist/rng.js +24 -0
- package/node_modules/uuid/dist/sha1-browser.js +104 -0
- package/node_modules/uuid/dist/sha1.js +23 -0
- package/node_modules/uuid/dist/stringify.js +44 -0
- package/node_modules/uuid/dist/uuid-bin.js +85 -0
- package/node_modules/uuid/dist/v1.js +107 -0
- package/node_modules/uuid/dist/v3.js +16 -0
- package/node_modules/uuid/dist/v35.js +80 -0
- package/node_modules/uuid/dist/v4.js +43 -0
- package/node_modules/uuid/dist/v5.js +16 -0
- package/node_modules/uuid/dist/validate.js +17 -0
- package/node_modules/uuid/dist/version.js +21 -0
- package/node_modules/uuid/package.json +135 -0
- package/node_modules/uuid/wrapper.mjs +10 -0
- package/package.json +5 -3
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/api.js +17 -9
- package/packages/daemon/src/process.js +2 -0
- package/packages/gui/dist/assets/{codemirror-BBL3i_JW.js → codemirror-CFF1Lrnz.js} +10 -10
- package/{node_modules/@groove-dev/gui/dist/assets/index-DWv32qyJ.js → packages/gui/dist/assets/index-B3GUKInH.js} +1740 -1740
- package/{node_modules/@groove-dev/gui/dist/assets/index-Bo6AeNmM.css → packages/gui/dist/assets/index-C1k-GuDg.css} +1 -1
- package/packages/gui/dist/index.html +3 -3
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/components/agents/agent-panel.jsx +2 -0
- package/packages/gui/src/components/editor/code-editor.jsx +3 -3
- package/packages/gui/src/stores/groove.js +23 -16
- package/packages/gui/src/views/agents.jsx +44 -113
- package/workspace.png +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { EnvelopeBuilder } from '../../client/envelope-builder.js';
|
|
6
|
+
import { CHUNK_SIZE } from '../../shared/constants.js';
|
|
7
|
+
|
|
8
|
+
const metadata = {
|
|
9
|
+
model_engine: 'claude-opus-4-6',
|
|
10
|
+
provider: 'claude-code',
|
|
11
|
+
agent_role: 'backend',
|
|
12
|
+
agent_id: 'backend-1',
|
|
13
|
+
task_complexity: 'medium',
|
|
14
|
+
team_size: 2,
|
|
15
|
+
session_quality: 80,
|
|
16
|
+
groove_version: '0.27.0',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
describe('EnvelopeBuilder', () => {
|
|
20
|
+
it('adding steps below CHUNK_SIZE returns null', () => {
|
|
21
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
22
|
+
for (let i = 0; i < CHUNK_SIZE - 1; i++) {
|
|
23
|
+
const result = builder.addStep({ step: i + 1, type: 'thought', timestamp: Date.now() / 1000 });
|
|
24
|
+
assert.equal(result, null);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('adding step that hits CHUNK_SIZE returns envelope', () => {
|
|
29
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
30
|
+
let envelope = null;
|
|
31
|
+
for (let i = 0; i < CHUNK_SIZE; i++) {
|
|
32
|
+
envelope = builder.addStep({ step: i + 1, type: 'thought', timestamp: Date.now() / 1000 });
|
|
33
|
+
}
|
|
34
|
+
assert.ok(envelope);
|
|
35
|
+
assert.equal(envelope.trajectory_log.length, CHUNK_SIZE);
|
|
36
|
+
assert.equal(envelope.session_id, 'sess_1');
|
|
37
|
+
assert.equal(envelope.contributor_id, 'user_1');
|
|
38
|
+
assert.ok(envelope.envelope_id.startsWith('env_'));
|
|
39
|
+
assert.equal(envelope.chunk_sequence, 0);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('flush returns remaining steps', () => {
|
|
43
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
44
|
+
builder.addStep({ step: 1, type: 'thought', timestamp: 123 });
|
|
45
|
+
builder.addStep({ step: 2, type: 'action', timestamp: 124 });
|
|
46
|
+
const envelope = builder.flush();
|
|
47
|
+
assert.ok(envelope);
|
|
48
|
+
assert.equal(envelope.trajectory_log.length, 2);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('flush returns null when buffer is empty', () => {
|
|
52
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
53
|
+
assert.equal(builder.flush(), null);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('SESSION_CLOSE includes outcome data', () => {
|
|
57
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
58
|
+
const outcome = {
|
|
59
|
+
status: 'SUCCESS',
|
|
60
|
+
user_interventions: 1,
|
|
61
|
+
total_steps: 50,
|
|
62
|
+
total_chunks: 1,
|
|
63
|
+
total_tokens: 5000,
|
|
64
|
+
duration_seconds: 120,
|
|
65
|
+
files_modified: 3,
|
|
66
|
+
errors_encountered: 1,
|
|
67
|
+
errors_recovered: 1,
|
|
68
|
+
coordination_events: 0,
|
|
69
|
+
};
|
|
70
|
+
const close = builder.buildSessionClose(outcome);
|
|
71
|
+
assert.ok(close.envelope_id.startsWith('env_'));
|
|
72
|
+
assert.equal(close.session_id, 'sess_1');
|
|
73
|
+
assert.equal(close.type, 'SESSION_CLOSE');
|
|
74
|
+
assert.deepEqual(close.outcome, outcome);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('truncates step content at 10000 characters', () => {
|
|
78
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
79
|
+
const longContent = 'x'.repeat(15_000);
|
|
80
|
+
builder.addStep({ step: 1, type: 'thought', timestamp: 123, content: longContent });
|
|
81
|
+
const envelope = builder.flush();
|
|
82
|
+
assert.equal(envelope.trajectory_log[0].content.length, 10_000);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('caps token_count at 100000', () => {
|
|
86
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
87
|
+
builder.addStep({ step: 1, type: 'thought', timestamp: 123, token_count: 999_999 });
|
|
88
|
+
const envelope = builder.flush();
|
|
89
|
+
assert.equal(envelope.trajectory_log[0].token_count, 100_000);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('chunk sequence increments correctly', () => {
|
|
93
|
+
const builder = new EnvelopeBuilder('sess_1', 'user_1', metadata);
|
|
94
|
+
let first = null;
|
|
95
|
+
let second = null;
|
|
96
|
+
|
|
97
|
+
for (let i = 0; i < CHUNK_SIZE; i++) {
|
|
98
|
+
first = builder.addStep({ step: i + 1, type: 'thought', timestamp: Date.now() / 1000 }) || first;
|
|
99
|
+
}
|
|
100
|
+
for (let i = 0; i < CHUNK_SIZE; i++) {
|
|
101
|
+
second = builder.addStep({ step: CHUNK_SIZE + i + 1, type: 'action', timestamp: Date.now() / 1000 }) || second;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
assert.equal(first.chunk_sequence, 0);
|
|
105
|
+
assert.equal(second.chunk_sequence, 1);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { ClaudeCodeParser } from '../../../client/parsers/claude-code.js';
|
|
6
|
+
|
|
7
|
+
describe('ClaudeCodeParser', () => {
|
|
8
|
+
it('parses assistant message as thought', () => {
|
|
9
|
+
const parser = new ClaudeCodeParser();
|
|
10
|
+
const event = {
|
|
11
|
+
type: 'assistant',
|
|
12
|
+
message: {
|
|
13
|
+
content: [{ type: 'text', text: 'I need to fix the bug' }],
|
|
14
|
+
usage: { input_tokens: 100, output_tokens: 50 },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const result = parser.parseEvent(event);
|
|
18
|
+
assert.equal(result.type, 'thought');
|
|
19
|
+
assert.equal(result.content, 'I need to fix the bug');
|
|
20
|
+
assert.equal(result.token_count, undefined);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('parses tool_use block as action', () => {
|
|
24
|
+
const parser = new ClaudeCodeParser();
|
|
25
|
+
const event = {
|
|
26
|
+
type: 'assistant',
|
|
27
|
+
message: {
|
|
28
|
+
content: [{ type: 'tool_use', id: 'tu_1', name: 'Read', input: { file_path: '/test.js' } }],
|
|
29
|
+
usage: { output_tokens: 10 },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const result = parser.parseEvent(event);
|
|
33
|
+
assert.equal(result.type, 'action');
|
|
34
|
+
assert.equal(result.tool, 'Read');
|
|
35
|
+
assert.deepEqual(result.arguments, { file_path: '/test.js' });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('parses tool_result as observation', () => {
|
|
39
|
+
const parser = new ClaudeCodeParser();
|
|
40
|
+
// First register a tool use
|
|
41
|
+
parser.parseEvent({
|
|
42
|
+
type: 'assistant',
|
|
43
|
+
message: {
|
|
44
|
+
content: [{ type: 'tool_use', id: 'tu_2', name: 'Read', input: {} }],
|
|
45
|
+
usage: {},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
// Then parse result
|
|
49
|
+
const event = {
|
|
50
|
+
type: 'assistant',
|
|
51
|
+
message: {
|
|
52
|
+
content: [{ type: 'tool_result', tool_use_id: 'tu_2', content: 'file contents here', is_error: false }],
|
|
53
|
+
usage: {},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
const result = parser.parseEvent(event);
|
|
57
|
+
assert.equal(result.type, 'observation');
|
|
58
|
+
assert.equal(result.content, 'file contents here');
|
|
59
|
+
assert.equal(result.is_error, false);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('parses error tool_result as error', () => {
|
|
63
|
+
const parser = new ClaudeCodeParser();
|
|
64
|
+
const event = {
|
|
65
|
+
type: 'assistant',
|
|
66
|
+
message: {
|
|
67
|
+
content: [{ type: 'tool_result', tool_use_id: 'tu_3', content: 'Permission denied', is_error: true }],
|
|
68
|
+
usage: {},
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const result = parser.parseEvent(event);
|
|
72
|
+
assert.equal(result.type, 'error');
|
|
73
|
+
assert.equal(result.is_error, true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('parses result event as resolution', () => {
|
|
77
|
+
const parser = new ClaudeCodeParser();
|
|
78
|
+
const event = { type: 'result', result: 'Task completed successfully', total_tokens_used: 500 };
|
|
79
|
+
const result = parser.parseEvent(event);
|
|
80
|
+
assert.equal(result.type, 'resolution');
|
|
81
|
+
assert.equal(result.content, 'Task completed successfully');
|
|
82
|
+
assert.equal(result.token_count, undefined);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('extracts tokens from assistant event', () => {
|
|
86
|
+
const parser = new ClaudeCodeParser();
|
|
87
|
+
const event = {
|
|
88
|
+
type: 'assistant',
|
|
89
|
+
message: {
|
|
90
|
+
usage: {
|
|
91
|
+
input_tokens: 100,
|
|
92
|
+
output_tokens: 50,
|
|
93
|
+
cache_read_input_tokens: 30,
|
|
94
|
+
cache_creation_input_tokens: 10,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
const tokens = parser.extractTokens(event);
|
|
99
|
+
assert.deepEqual(tokens, { input: 100, output: 50, cacheRead: 30, cacheCreation: 10 });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('extracts session id', () => {
|
|
103
|
+
const parser = new ClaudeCodeParser();
|
|
104
|
+
assert.equal(parser.extractSessionId({ session_id: 'sess-abc' }), 'sess-abc');
|
|
105
|
+
assert.equal(parser.extractSessionId({}), null);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('extracts model from assistant event', () => {
|
|
109
|
+
const parser = new ClaudeCodeParser();
|
|
110
|
+
assert.equal(parser.extractModel({ type: 'assistant', message: { model: 'claude-opus-4-6' } }), 'claude-opus-4-6');
|
|
111
|
+
assert.equal(parser.extractModel({ type: 'result' }), null);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('returns null for unknown event types', () => {
|
|
115
|
+
const parser = new ClaudeCodeParser();
|
|
116
|
+
assert.equal(parser.parseEvent({ type: 'system' }), null);
|
|
117
|
+
assert.equal(parser.parseEvent(null), null);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { CodexParser } from '../../../client/parsers/codex.js';
|
|
6
|
+
|
|
7
|
+
describe('CodexParser', () => {
|
|
8
|
+
it('parses item.started agent_message as thought', () => {
|
|
9
|
+
const parser = new CodexParser();
|
|
10
|
+
const result = parser.parseEvent({
|
|
11
|
+
type: 'item.started',
|
|
12
|
+
item: { type: 'agent_message', text: 'Let me analyze this' },
|
|
13
|
+
});
|
|
14
|
+
assert.equal(result.type, 'thought');
|
|
15
|
+
assert.equal(result.content, 'Let me analyze this');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('parses item.started command_execution as action', () => {
|
|
19
|
+
const parser = new CodexParser();
|
|
20
|
+
const result = parser.parseEvent({
|
|
21
|
+
type: 'item.started',
|
|
22
|
+
item: { type: 'command_execution', command: 'ls -la' },
|
|
23
|
+
});
|
|
24
|
+
assert.equal(result.type, 'action');
|
|
25
|
+
assert.equal(result.tool, 'command_execution');
|
|
26
|
+
assert.deepEqual(result.arguments, { command: 'ls -la' });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('parses item.started file_edit as action', () => {
|
|
30
|
+
const parser = new CodexParser();
|
|
31
|
+
const result = parser.parseEvent({
|
|
32
|
+
type: 'item.started',
|
|
33
|
+
item: { type: 'file_edit', path: '/src/app.js' },
|
|
34
|
+
});
|
|
35
|
+
assert.equal(result.type, 'action');
|
|
36
|
+
assert.equal(result.tool, 'file_edit');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('parses item.completed command_execution as observation', () => {
|
|
40
|
+
const parser = new CodexParser();
|
|
41
|
+
const result = parser.parseEvent({
|
|
42
|
+
type: 'item.completed',
|
|
43
|
+
item: { type: 'command_execution', aggregated_output: 'file1\nfile2', exit_code: 0 },
|
|
44
|
+
});
|
|
45
|
+
assert.equal(result.type, 'observation');
|
|
46
|
+
assert.equal(result.content, 'file1\nfile2');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('parses item.completed with error exit code as error', () => {
|
|
50
|
+
const parser = new CodexParser();
|
|
51
|
+
const result = parser.parseEvent({
|
|
52
|
+
type: 'item.completed',
|
|
53
|
+
item: { type: 'command_execution', aggregated_output: 'ENOENT', exit_code: 1 },
|
|
54
|
+
});
|
|
55
|
+
assert.equal(result.type, 'error');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('parses turn.completed as resolution', () => {
|
|
59
|
+
const parser = new CodexParser();
|
|
60
|
+
const result = parser.parseEvent({ type: 'turn.completed' });
|
|
61
|
+
assert.equal(result.type, 'resolution');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('extracts tokens from usage', () => {
|
|
65
|
+
const parser = new CodexParser();
|
|
66
|
+
const tokens = parser.extractTokens({
|
|
67
|
+
type: 'item.completed',
|
|
68
|
+
usage: { input_tokens: 200, output_tokens: 100 },
|
|
69
|
+
});
|
|
70
|
+
assert.deepEqual(tokens, { input: 200, output: 100, cacheRead: 0, cacheCreation: 0 });
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('extracts session id from thread.started', () => {
|
|
74
|
+
const parser = new CodexParser();
|
|
75
|
+
assert.equal(parser.extractSessionId({ type: 'thread.started', thread_id: 'th_123' }), 'th_123');
|
|
76
|
+
assert.equal(parser.extractSessionId({ type: 'item.started' }), null);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('returns null for unknown event types', () => {
|
|
80
|
+
const parser = new CodexParser();
|
|
81
|
+
assert.equal(parser.parseEvent({ type: 'unknown.event' }), null);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { GeminiParser } from '../../../client/parsers/gemini.js';
|
|
6
|
+
|
|
7
|
+
describe('GeminiParser', () => {
|
|
8
|
+
it('parses thought content type as thought', () => {
|
|
9
|
+
const parser = new GeminiParser();
|
|
10
|
+
const result = parser.parseEvent({
|
|
11
|
+
type: 'message',
|
|
12
|
+
role: 'model',
|
|
13
|
+
content: [{ type: 'thought', thought: 'I should check the imports' }],
|
|
14
|
+
});
|
|
15
|
+
assert.equal(result.type, 'thought');
|
|
16
|
+
assert.equal(result.content, 'I should check the imports');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('parses model text message as thought', () => {
|
|
20
|
+
const parser = new GeminiParser();
|
|
21
|
+
const result = parser.parseEvent({
|
|
22
|
+
type: 'message',
|
|
23
|
+
role: 'model',
|
|
24
|
+
content: [{ text: 'Let me look at that file' }],
|
|
25
|
+
});
|
|
26
|
+
assert.equal(result.type, 'thought');
|
|
27
|
+
assert.equal(result.content, 'Let me look at that file');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('skips user messages', () => {
|
|
31
|
+
const parser = new GeminiParser();
|
|
32
|
+
const result = parser.parseEvent({
|
|
33
|
+
type: 'message',
|
|
34
|
+
role: 'user',
|
|
35
|
+
content: [{ text: 'fix the bug' }],
|
|
36
|
+
});
|
|
37
|
+
assert.equal(result, null);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('parses tool_request as action', () => {
|
|
41
|
+
const parser = new GeminiParser();
|
|
42
|
+
const result = parser.parseEvent({
|
|
43
|
+
type: 'tool_request',
|
|
44
|
+
name: 'Grep',
|
|
45
|
+
args: { pattern: 'TODO' },
|
|
46
|
+
});
|
|
47
|
+
assert.equal(result.type, 'action');
|
|
48
|
+
assert.equal(result.tool, 'Grep');
|
|
49
|
+
assert.deepEqual(result.arguments, { pattern: 'TODO' });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('parses tool_response as observation', () => {
|
|
53
|
+
const parser = new GeminiParser();
|
|
54
|
+
const result = parser.parseEvent({
|
|
55
|
+
type: 'tool_response',
|
|
56
|
+
content: 'Found 3 matches',
|
|
57
|
+
});
|
|
58
|
+
assert.equal(result.type, 'observation');
|
|
59
|
+
assert.equal(result.content, 'Found 3 matches');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('parses error event', () => {
|
|
63
|
+
const parser = new GeminiParser();
|
|
64
|
+
const result = parser.parseEvent({
|
|
65
|
+
type: 'error',
|
|
66
|
+
message: 'Rate limit exceeded',
|
|
67
|
+
});
|
|
68
|
+
assert.equal(result.type, 'error');
|
|
69
|
+
assert.equal(result.content, 'Rate limit exceeded');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('parses agent_end as resolution', () => {
|
|
73
|
+
const parser = new GeminiParser();
|
|
74
|
+
const result = parser.parseEvent({ type: 'agent_end' });
|
|
75
|
+
assert.equal(result.type, 'resolution');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('extracts tokens from usage event', () => {
|
|
79
|
+
const parser = new GeminiParser();
|
|
80
|
+
const tokens = parser.extractTokens({
|
|
81
|
+
type: 'usage',
|
|
82
|
+
inputTokens: 300,
|
|
83
|
+
outputTokens: 150,
|
|
84
|
+
cachedTokens: 50,
|
|
85
|
+
});
|
|
86
|
+
assert.deepEqual(tokens, { input: 300, output: 150, cacheRead: 50, cacheCreation: 0 });
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('returns null for non-usage token extraction', () => {
|
|
90
|
+
const parser = new GeminiParser();
|
|
91
|
+
assert.equal(parser.extractTokens({ type: 'message' }), null);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('extracts session id from agent_start', () => {
|
|
95
|
+
const parser = new GeminiParser();
|
|
96
|
+
assert.equal(parser.extractSessionId({ type: 'agent_start', streamId: 'stream-456' }), 'stream-456');
|
|
97
|
+
assert.equal(parser.extractSessionId({ type: 'message' }), null);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { PIIScrubber } from '../../client/scrubber.js';
|
|
6
|
+
|
|
7
|
+
const scrubber = new PIIScrubber();
|
|
8
|
+
|
|
9
|
+
describe('PIIScrubber', () => {
|
|
10
|
+
it('scrubs PEM private keys', () => {
|
|
11
|
+
const input = '-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIB...\n-----END RSA PRIVATE KEY-----';
|
|
12
|
+
assert.equal(scrubber.scrub(input), '[PRIVATE_KEY]');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('scrubs AWS access keys', () => {
|
|
16
|
+
const input = 'key is AKIAIOSFODNN7EXAMPLE here';
|
|
17
|
+
assert.equal(scrubber.scrub(input), 'key is [AWS_KEY] here');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('scrubs Bearer tokens', () => {
|
|
21
|
+
const input = 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
|
|
22
|
+
assert.equal(scrubber.scrub(input), 'Authorization: [API_KEY]');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('scrubs sk_/pk_ prefixed keys', () => {
|
|
26
|
+
const input = 'apikey: sk_test_51HQdMnAbcDefGhIjKlMn';
|
|
27
|
+
assert.equal(scrubber.scrub(input), 'apikey: [API_KEY]');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('scrubs valid credit cards with Luhn check', () => {
|
|
31
|
+
const input = 'card: 4111 1111 1111 1111';
|
|
32
|
+
assert.equal(scrubber.scrub(input), 'card: [CREDIT_CARD]');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('does not scrub random 16-digit numbers failing Luhn', () => {
|
|
36
|
+
const input = 'number: 1234 5678 9012 3456';
|
|
37
|
+
assert.equal(scrubber.scrub(input), 'number: 1234 5678 9012 3456');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('scrubs SSNs', () => {
|
|
41
|
+
const input = 'ssn: 123-45-6789';
|
|
42
|
+
assert.equal(scrubber.scrub(input), 'ssn: [SSN]');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('scrubs email addresses', () => {
|
|
46
|
+
const input = 'contact user@example.com for info';
|
|
47
|
+
assert.equal(scrubber.scrub(input), 'contact [EMAIL] for info');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('scrubs IPv6 addresses', () => {
|
|
51
|
+
const input = 'server at 2001:0db8:85a3:0000:0000:8a2e:0370:7334';
|
|
52
|
+
assert.equal(scrubber.scrub(input), 'server at [IP]');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('scrubs IPv4 addresses', () => {
|
|
56
|
+
const input = 'connect to 192.168.1.100';
|
|
57
|
+
assert.equal(scrubber.scrub(input), 'connect to [IP]');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('scrubs phone numbers', () => {
|
|
61
|
+
const input = 'call (555) 123-4567';
|
|
62
|
+
assert.equal(scrubber.scrub(input), 'call [PHONE]');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('scrubs URLs with token/key/secret params', () => {
|
|
66
|
+
const input = 'visit https://api.example.com/data?token=abc123&other=val';
|
|
67
|
+
assert.equal(scrubber.scrub(input), 'visit [REDACTED_URL]&other=val');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('scrubs long hex strings (40+ chars)', () => {
|
|
71
|
+
const hex = 'a'.repeat(40);
|
|
72
|
+
const input = `hash: ${hex}`;
|
|
73
|
+
assert.equal(scrubber.scrub(input), 'hash: [API_KEY]');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('scrubs home directory paths preserving relative path', () => {
|
|
77
|
+
const input = 'file at /Users/john/Documents/secret.txt';
|
|
78
|
+
assert.equal(scrubber.scrub(input), 'file at ~/Documents/secret.txt');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('scrubs URL-encoded emails', () => {
|
|
82
|
+
const input = 'param=ryan%40motovizion.com&next=home';
|
|
83
|
+
assert.equal(scrubber.scrub(input), 'param=[EMAIL]&next=home');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('scrubs international phone numbers', () => {
|
|
87
|
+
const input = 'call +44 20 7946 0958 for help';
|
|
88
|
+
assert.equal(scrubber.scrub(input), 'call [PHONE] for help');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('scrubs JWT tokens without Bearer prefix', () => {
|
|
92
|
+
const input = 'token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
|
|
93
|
+
const result = scrubber.scrub(input);
|
|
94
|
+
assert.ok(result.includes('[API_KEY]'));
|
|
95
|
+
assert.ok(!result.includes('eyJhbGciOi'));
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('scrubs file paths preserving relative path', () => {
|
|
99
|
+
const input = 'reading /home/alice/project/secret.key now';
|
|
100
|
+
const result = scrubber.scrub(input);
|
|
101
|
+
assert.equal(result, 'reading ~/project/secret.key now');
|
|
102
|
+
assert.ok(!result.includes('/home/alice'));
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('scrubs base64 encoded secrets', () => {
|
|
106
|
+
const b64 = 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODk=';
|
|
107
|
+
const input = `secret: ${b64} done`;
|
|
108
|
+
const result = scrubber.scrub(input);
|
|
109
|
+
assert.ok(result.includes('[API_KEY]'));
|
|
110
|
+
assert.ok(!result.includes(b64));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('passes through non-PII content unchanged', () => {
|
|
114
|
+
const input = 'This is a normal sentence about coding in JavaScript.';
|
|
115
|
+
assert.equal(scrubber.scrub(input), input);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('handles null/undefined input gracefully', () => {
|
|
119
|
+
assert.equal(scrubber.scrub(null), null);
|
|
120
|
+
assert.equal(scrubber.scrub(undefined), undefined);
|
|
121
|
+
assert.equal(scrubber.scrub(''), '');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('scrubs Windows home paths preserving relative path', () => {
|
|
125
|
+
const input = 'file at C:\\Users\\bob\\Desktop\\project\\app.js';
|
|
126
|
+
assert.equal(scrubber.scrub(input), 'file at ~\\Desktop\\project\\app.js');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('scrubs home path with no trailing path', () => {
|
|
130
|
+
const input = 'cd /Users/john';
|
|
131
|
+
assert.equal(scrubber.scrub(input), 'cd ~');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('patterns do not interfere with each other', () => {
|
|
135
|
+
const input = 'user@example.com called 555-123-4567 from 192.168.1.1';
|
|
136
|
+
const result = scrubber.scrub(input);
|
|
137
|
+
assert.ok(result.includes('[EMAIL]'));
|
|
138
|
+
assert.ok(result.includes('[PHONE]'));
|
|
139
|
+
assert.ok(result.includes('[IP]'));
|
|
140
|
+
assert.ok(!result.includes('user@example.com'));
|
|
141
|
+
assert.ok(!result.includes('192.168.1.1'));
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
|
|
3
|
+
import { describe, it, beforeEach } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { SessionAttestation } from '../../client/session-attestation.js';
|
|
6
|
+
import { verifyEnvelope } from '../../shared/crypto.js';
|
|
7
|
+
|
|
8
|
+
describe('SessionAttestation security', () => {
|
|
9
|
+
let attestation;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
attestation = new SessionAttestation('http://localhost:9999');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('HMAC signs entire envelope — tampering metadata after signing fails verification', async () => {
|
|
16
|
+
const sessionId = 'sess_test_1';
|
|
17
|
+
await attestation.openSession(sessionId, {
|
|
18
|
+
provider: 'claude-code',
|
|
19
|
+
model_engine: 'claude-opus-4-6',
|
|
20
|
+
groove_version: '0.27.0',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const session = attestation._sessions.get(sessionId);
|
|
24
|
+
if (session.offline) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const envelope = {
|
|
29
|
+
envelope_id: 'env_test',
|
|
30
|
+
session_id: sessionId,
|
|
31
|
+
chunk_sequence: 0,
|
|
32
|
+
contributor_id: 'user_1',
|
|
33
|
+
attestation: { session_hmac: '', sequence: 0, app_version_hash: '' },
|
|
34
|
+
metadata: { agent_role: 'backend', agent_id: 'backend-1', provider: 'claude-code' },
|
|
35
|
+
trajectory_log: [{ step: 1, type: 'thought', timestamp: 123 }],
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const signed = attestation.signEnvelope(sessionId, envelope);
|
|
39
|
+
const hmac = signed.attestation.session_hmac;
|
|
40
|
+
const seq = signed.attestation.sequence - 1;
|
|
41
|
+
|
|
42
|
+
const forVerify = { ...signed };
|
|
43
|
+
delete forVerify.attestation;
|
|
44
|
+
const valid = verifyEnvelope(session.sharedSecret, JSON.stringify(forVerify), seq, hmac);
|
|
45
|
+
assert.equal(valid, true, 'HMAC should verify against the full envelope minus attestation');
|
|
46
|
+
|
|
47
|
+
forVerify.metadata.agent_role = 'hacked';
|
|
48
|
+
const invalid = verifyEnvelope(session.sharedSecret, JSON.stringify(forVerify), seq, hmac);
|
|
49
|
+
assert.equal(invalid, false, 'Tampered metadata should fail HMAC verification');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('offline mode uses OFFLINE marker not empty string', async () => {
|
|
53
|
+
const sessionId = 'sess_offline';
|
|
54
|
+
attestation._sessions.set(sessionId, {
|
|
55
|
+
keypair: null,
|
|
56
|
+
sharedSecret: null,
|
|
57
|
+
sequence: 0,
|
|
58
|
+
appVersionHash: 'test',
|
|
59
|
+
offline: true,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const envelope = {
|
|
63
|
+
envelope_id: 'env_off',
|
|
64
|
+
session_id: sessionId,
|
|
65
|
+
attestation: { session_hmac: '', sequence: 0, app_version_hash: '' },
|
|
66
|
+
metadata: {},
|
|
67
|
+
trajectory_log: [],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const signed = attestation.signEnvelope(sessionId, envelope);
|
|
71
|
+
assert.equal(signed.attestation.session_hmac, 'OFFLINE');
|
|
72
|
+
assert.notEqual(signed.attestation.session_hmac, '');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('machine fingerprint includes hostname and core count', async () => {
|
|
76
|
+
const os = await import('node:os');
|
|
77
|
+
const fp = SessionAttestation.getMachineFingerprint();
|
|
78
|
+
assert.equal(typeof fp, 'string');
|
|
79
|
+
assert.equal(fp.length, 64);
|
|
80
|
+
|
|
81
|
+
const signals = [
|
|
82
|
+
os.platform(),
|
|
83
|
+
os.arch(),
|
|
84
|
+
os.cpus()[0]?.model || '',
|
|
85
|
+
String(os.totalmem()),
|
|
86
|
+
os.hostname(),
|
|
87
|
+
String(os.cpus().length),
|
|
88
|
+
os.release(),
|
|
89
|
+
os.endianness(),
|
|
90
|
+
];
|
|
91
|
+
const { createHash } = await import('node:crypto');
|
|
92
|
+
const expected = createHash('sha256').update(signals.join('|')).digest('hex');
|
|
93
|
+
assert.equal(fp, expected);
|
|
94
|
+
});
|
|
95
|
+
});
|