diff --git a/.gitnexus/lbug b/.gitnexus/lbug index 40e91616..0629677a 100644 Binary files a/.gitnexus/lbug and b/.gitnexus/lbug differ diff --git a/.gitnexus/meta.json b/.gitnexus/meta.json index e68f9865..e4a9d335 100644 --- a/.gitnexus/meta.json +++ b/.gitnexus/meta.json @@ -1,13 +1,13 @@ { - "repoPath": "/Users/a86198/Desktop/Wiki/AI/3-Application/FrontAgent-app", - "lastCommit": "487f612790679bd467d0987667bb9ee697658222", - "indexedAt": "2026-06-12T05:13:12.706Z", - "remoteUrl": "https://github.com/FrontAgent/FrontAgent", + "repoPath": "/Users/a86198/Desktop/FrontAgent", + "lastCommit": "51fd4bbaf69ea926cd670f6708dbbbc6b5b52327", + "indexedAt": "2026-07-12T08:26:27.526Z", + "remoteUrl": "https://github.com/ceilf6/FrontAgent", "stats": { - "files": 473, - "nodes": 5084, - "edges": 12429, - "communities": 377, + "files": 566, + "nodes": 5716, + "edges": 13719, + "communities": 469, "processes": 300, "embeddings": 0 }, @@ -32,13 +32,15 @@ "turbo.json": "0b46c401b4149e562e9408c92f023f0c75c1427af4ceff629e9b215c9d4e3d5a", "tsconfig.json": "6c2753eea1c2f2be8d7fa1f4702cc4ccc279bbc314440c2dd38f708208ef9b01", "pnpm-workspace.yaml": "37c662a036df6d96bccc32a64ba6535de9f6c87e3057f69d32caa5f25d306a91", - "package.json": "4baec0d5c09c701b6b6b82a1a47e342888900fa246e56c50bfd531ce8981aee3", + "package.json": "464af1784c1a5566f2e4158fd0f267f4089eaa1de6cbb3a9ec0393c82163632a", "build.mjs": "d0a0528a37280d0f969e03452e92b59f877cbdb9825b570568c5e4d415c0f57b", "biome.json": "8c12a7577f38f158aac3b53136b63e20f85a0ad4690a7c38a9ba8c123bf37de9", - "README.md": "52a3a7cf58aed71415516c354d597964ee5b238ab488d2995eadc5442eb68b64", + "README.md": "eead4fb3635bb87bb01eea3b10c24f4a60af479c7e209329de56a75177fdf775", "CLAUDE.md": "03ba21d21c48a8226d5d3660b69ca02f5d788b4ff9162c28d0388380dec0d8ad", "AGENTS.md": "03ba21d21c48a8226d5d3660b69ca02f5d788b4ff9162c28d0388380dec0d8ad", "scripts/sync-vscode-version.mjs": "fb86db0dcbf95a72963748dcb09e2b36aeda5a698c62668a8b96e9ce1c55c3a3", + "benchmarks/frontagent-flow-benchmark.mjs": "916f10ec40ff6445a83862e534147609cc801d3b6d4222301d9cc0487df4f730", + "benchmarks/frontagent-agent-flow-benchmark.mjs": "81874bfa525b61c2fd3476630bff42238c666ca138d697fce840d400ba8887b2", "docs/极其规范的审计型.md": "80185dda160d2c081e3c33112d9b9a5c1949337388871b951993951ae8aaf412", "docs/workflow.md": "3a55a54fb8dc432402d920c7eeddfc3cfd0b720f733a3fb3a7ceb8670d4cd780", "docs/oss-harness-engineering-workflow.md": "a31368c6faf91f657e15bb280e2f44e97e45510697ca5b903b4cb1b1175e5159", @@ -50,14 +52,12 @@ "docs/design.md": "90e5ed4f77914d01b65a05b2bf3fda6c191725b35a931142d69813c0cf643b3d", "docs/architecture.md": "965fd96466620145251ee668495e4c9b150b6584faea2ff077e59520c52a5b45", "docs/TWO_STAGE_ARCHITECTURE.md": "b3c364f1e9f7bc403c54ecc1dd4575d3cfb4349fa68d750bf61cda220c8495e5", - "docs/README-CN.md": "1d4314f6b32c5221d22ff309d10c64369f7c7684a6b09bab63573ccc45ca589b", + "docs/README-CN.md": "f691a15ad2fcf91f231d0cbaf4ee023944711ca7559e97e3bb2d1e41b4e61bfa", "docs/QUICKSTART.md": "c2ecca75ef0968084fa2c54cb2b92e12dc90147233837c074c0c06f5fa13b381", "docs/FrontAgent-Skill-Structure-Proposal-CN.md": "1be549d2ec996f095a1cb0cda346dcb3a7b3aac8b9db1415918bba9b84d766d0", "docs/FrontAgent-Skill-Patterns-Analysis-CN.md": "ccc8267d64a1b2e04ee60e9a368a53c23624938db04cd811ad824a50f94779ba", "docs/FrontAgent-Introduction.md": "40eb84caa868d334463c5e32e831b502457f4aefc810376803a7e41bd8d4a49b", "docs/CHANGELOG-CN.md": "916f6d591bf787c93e5ba448233905a68d9c545eb70fc1d082f644beb7643392", - "benchmarks/frontagent-flow-benchmark.mjs": "916f10ec40ff6445a83862e534147609cc801d3b6d4222301d9cc0487df4f730", - "benchmarks/frontagent-agent-flow-benchmark.mjs": "81874bfa525b61c2fd3476630bff42238c666ca138d697fce840d400ba8887b2", "skills/skill-lifecycle/SKILL.md": "9cd76f1fa8230f7b99b65f76e8d8373b18b3201dc1077489362aa6d18ac37957", "skills/skill-lifecycle/ADAPTATION.md": "d11e68afa39643bc872a22c6c18d46c55d9715acf5be94446762ae821be1fd6b", "skills/requirement-interviewer/SKILL.md": "424a38059feedc835057babefe074a93ae0df5ffe1d42fa2ba9772f25b29ba5c", @@ -67,13 +67,23 @@ "scripts/workflows/install-hooks.mjs": "0aba80b136682117476fbf9a3e454cdd56af6de541fa70be0138dd438320c8ff", "scripts/workflows/contract-rules.mjs": "4c094cd0eb820d23b7ffc07503566d0957d3caf02c98f86399e48499b8bb813a", "scripts/workflows/contract-check.mjs": "590d05b63a6817223e1428596d543ea6df89464076a118c4c1578e21ec1101d4", - "scripts/tests/workflow-rules.test.mjs": "e83514d42c202ad9711c767cafaf944c96f47f4a263e9f60f0806d85ff4398a4", + "scripts/tests/workflow-rules.test.mjs": "630784a69cdae2cc837a8165b7c89932e676e53703fa6633442dbe4e47e219c9", + "models/frontagent-planner/train_mlx.py": "b9fe515dadde8449b711b561fb0ac5c32bec6762829128f83af7878a5341f217", + "models/frontagent-planner/train.py": "31dd7aac03cddc0347d9ed9b696fda8c5e459da8b4d8f5777f6642269dbf5812", + "models/frontagent-planner/publish.py": "9f430e5a2ae1db40b9130340f0fc881fe85b9f038c38e1e1a8c428d3e03327cf", + "models/frontagent-planner/plan.md": "e4daff3197bf0f63f396d616dab3166db55a5ab0c2d16b70387be4fbadce0945", + "models/frontagent-planner/eval.py": "faebd2f049efa3f4f49756747dfd7a11b183637b6152f6d52064b5208d5012e6", + "models/frontagent-planner/colab_train.ipynb": "a59956575aa9d1b84939fcf09024269451811109472be31968aa153b87be51ac", + "models/frontagent-planner/README.md": "7742f3c6b6b556ba69095f128b2ef27e5ef959aae8a095ccb6fbe4aa9402cb06", "packages/shared/tsconfig.json": "e4ed044d99005d1d36c726849468ff721d4fd6ed12967cc420470a4d9f690004", "packages/shared/package.json": "c769ce47b0d355923ef1ec07102efbac795d0cd818918f3234f9826bc239b505", "packages/sdd/tsconfig.json": "e4ed044d99005d1d36c726849468ff721d4fd6ed12967cc420470a4d9f690004", "packages/sdd/package.json": "16a5bead536e2eec66cffc18ada2fc8cee9e55f1eb4bfef5194dabde637e77b5", "packages/runtime-node/tsconfig.json": "069c50abf7c771629212bdd8057211886843d3d0c95beb5bad0c061990e9634b", - "packages/runtime-node/package.json": "e17e892b8b6e0c20e7d752f5184b870817274bbbfbc47bcf6122dc0d1ec29ce0", + "packages/runtime-node/package.json": "85c580bb6d7fac07e0e5d6d29a9926fa9fecfd9d09ae6edba8274a3471c96663", + "packages/mcp-web-fetch/vitest.config.ts": "cf0b3263b2ded3747c8cd6139fb005c1ec49fc894f3f983c4e2e4dd5e004e660", + "packages/mcp-web-fetch/tsconfig.json": "8cec1d1a079b2b5c4f113fa566fb30800a65a530b920f0375f076a9dd1565402", + "packages/mcp-web-fetch/package.json": "a3a15aa9c4849689e5417753e53beb10c1cad00f6d708b77b7738623a9aa82f0", "packages/mcp-web/tsconfig.json": "5a925cf30a676237351af85a2da9e65440839ade260be6d7a1945843af1fef63", "packages/mcp-web/package.json": "dc0ab5559a649c895d062bcf681eadf066b5db0108c6b156b5034a216db80c62", "packages/mcp-shell/tsconfig.json": "658b1f1615d30e66c1cb846e0dc7b6975b162d534ee0597e70ceb165dfff17a9", @@ -84,18 +94,19 @@ "packages/mcp-filesense/tsconfig.json": "8cec1d1a079b2b5c4f113fa566fb30800a65a530b920f0375f076a9dd1565402", "packages/mcp-filesense/package.json": "7f8ee91b670b5efd8da6a2ae6086292f1a072eaded9fa444b71b7b9e55ad532a", "packages/mcp-file/tsconfig.json": "658b1f1615d30e66c1cb846e0dc7b6975b162d534ee0597e70ceb165dfff17a9", - "packages/mcp-file/package.json": "81c0388a6786f74e4f1e215b6dc30f3f4f567c01ebaf3580817ad3ecc7442304", + "packages/mcp-file/package.json": "b02da70d84a45be3145b1c720a23f6dbdcbfa7203b02f6636c728350136665d7", "packages/hallucination-guard/tsconfig.json": "e4ed044d99005d1d36c726849468ff721d4fd6ed12967cc420470a4d9f690004", "packages/hallucination-guard/package.json": "1a4f3a9597a8e28b5128a9a9fa27ac076d4537bf1b1ff3012e7e2f81c0e051f1", "packages/core/tsconfig.json": "658b1f1615d30e66c1cb846e0dc7b6975b162d534ee0597e70ceb165dfff17a9", - "packages/core/package.json": "def3a5d9305c6049ae5658b471fa03672e8f7332bc12929d864e148bbab1c504", - "models/frontagent-planner/train_mlx.py": "b9fe515dadde8449b711b561fb0ac5c32bec6762829128f83af7878a5341f217", - "models/frontagent-planner/train.py": "31dd7aac03cddc0347d9ed9b696fda8c5e459da8b4d8f5777f6642269dbf5812", - "models/frontagent-planner/publish.py": "9f430e5a2ae1db40b9130340f0fc881fe85b9f038c38e1e1a8c428d3e03327cf", - "models/frontagent-planner/plan.md": "e4daff3197bf0f63f396d616dab3166db55a5ab0c2d16b70387be4fbadce0945", - "models/frontagent-planner/eval.py": "faebd2f049efa3f4f49756747dfd7a11b183637b6152f6d52064b5208d5012e6", - "models/frontagent-planner/colab_train.ipynb": "a59956575aa9d1b84939fcf09024269451811109472be31968aa153b87be51ac", - "models/frontagent-planner/README.md": "7742f3c6b6b556ba69095f128b2ef27e5ef959aae8a095ccb6fbe4aa9402cb06", + "packages/core/package.json": "fd42f86bb485c2a8b201237f2c8eb26edb67cbee8d769dd6de6b4982431ca86d", + "benchmarks/results/full.jsonl": "5f559a51159f5e06406c3320c6e90699012f212e5dd75bf8ef467dd5e169565c", + "benchmarks/results/ablation.jsonl": "c1d650a79f0241d8d01b99b538f3bdfa254e5c95518f45624ba9ac88a1accd84", + "benchmarks/results/2026-07-12-sdd-ablation.md": "140b5a71e8adc25ea55fcdac97df945c34e7dce64ef1dca832ebd82dd7a50ad1", + "benchmarks/eval/tasks.json": "debb0756e46464a343004c8e462931b7e21c6184dfd42261253660bf7ccb7b58", + "benchmarks/eval/run-eval.mjs": "f5e1ba3fe2dc62ad82a32b57e2f522bf2a3b8f66289f8dc9b053fbbfac715354", + "benchmarks/eval/report.mjs": "f86887d8d3e593bdaef69320732e232b878642c92809de79585453ea4fa6cdc8", + "benchmarks/eval/claude-cli-backend.mjs": "d5ddc7e37a5588ad19e07094818851221596c58099ed725f3d8a9ce0668da9a7", + "benchmarks/eval/checks.mjs": "b91a6b91072a6de582fb7f9a53ee16ca5ec46f903647eb08778d5f9f17378484", "docs/releases/v2.1.1.md": "d5655a64fe45287c5c7d53a12d938cbef6d7f4a421717afe7208e51c9c90969b", "docs/releases/v2.1.0.md": "0ee3a55c007dc6f0013d51f5f5ebe055131ab66c904c48a33e04ad43d1b2a674", "docs/releases/v1.0.1.md": "9fe4ecd85ac40e5eabcb1ad85d80d0f29206f902eba5fffd32c835d31f2b69dd", @@ -104,6 +115,13 @@ "apps/vscode/package.json": "a3f4cb18ccfa3c2c616cb388b90169aca55a49ea20a07665285ac12c954c671b", "apps/vscode/build.mjs": "b5ec637148141150dce57c3873b93c81dcbebcfba4492dca79b9b1f130198285", "apps/vscode/README.md": "0f23c00c7fe764be2a634cb65919311bfb1c7d8eec0174afc61e6aa708942376", + "apps/desktop/vite.config.ts": "e00df58cc72667d847b73a65502addc92188692789d0cd9ca0c2d2ea21b83b2e", + "apps/desktop/tsconfig.json": "c7c055335c3bc71b0ab8b792b210a4773b07b7672d50be0338c3639d1b78ebc6", + "apps/desktop/package.json": "5350eb7ad979b9abfd061442f150f10199b4b33569eb03d6872b30680e134648", + "apps/desktop/index.html": "ba8721f782879628852bde1c757346af81fe7b875ef612b1b12517dda1d499ba", + "apps/desktop/electron.build.mjs": "fcbc16da735fd10599b891aecd4c4d74b803532c61e06509f2dc39d312cdc1b0", + "apps/desktop/electron-builder.yml": "26dccd84550211248330a932c37ae43ae08f2c429cc4346ecb97f5b361c9549a", + "apps/desktop/README.md": "14e8a75a695c049763a7a351a0e4a21d8f069f44fd798d361767737da588bc98", "apps/cli/tsconfig.json": "0953a70e0a34454b7b2fb91379ec781fee970b356df4fcf10c46c283ae12df44", "apps/cli/package.json": "580bd1869f4ef8ee395777abb42e5f74f2904a5d371ed9bde9d61655c823d976", "skills/skill-lifecycle/references/workflow.md": "9bbfb6603ebdb9e8a0ee07df56d2d3ec98145533b40736faa97419694224c414", @@ -113,15 +131,29 @@ "skills/requirement-interviewer/references/gating-rules.md": "9cd78087187e516b332356e8efe57e57f5a6fd83dafe826aec07712f53e80ae9", "skills/requirement-interviewer/references/answer-completeness.md": "dc9bdae3e5b2152d812a33e5afa32c3ec8f4eaef00438b7149d93c9470defe8a", "skills/requirement-interviewer/agents/openai.yaml": "e2c34847985eca7237dfb05c775b838057847dfd82f24eae4292ddd62794fbd1", + "skills/frontend-reviewer/agents/openai.yaml": "7d5402e7b2bb02f6516d6cb6b6716873ac4531bd89253b419158af1dfe5c0a9c", "skills/frontend-reviewer/references/severity-rubric.md": "ba20153f6c37c0c78934247a9f78a27f2ee93ef24afe458462a63a732666c737", "skills/frontend-reviewer/references/review-checklist.md": "07336b379eba82caf3ccbc87e0f6902a0fe056c806e0c64c052824a82603fcbe", "skills/frontend-reviewer/references/frontend-quality-rules.md": "c847613b52fa1ad897fef2fcae3b7839a6b61c590f4d476d332afabecad4bebc", - "skills/frontend-reviewer/agents/openai.yaml": "7d5402e7b2bb02f6516d6cb6b6716873ac4531bd89253b419158af1dfe5c0a9c", "skills/frontend-design/references/integration-guardrails.md": "220fe5770347cef846d35161f8984c121d6954ab62649413c8694e763cca120a", "skills/frontend-design/references/design-direction.md": "317cea721742b1047dbc994c0fe2407aef3ac3dcf5671d8afae345cf0c26057f", "skills/frontend-design/references/delivery-checks.md": "6b2e604844693e5ae47a53c529bc7b3e9193a347985ec8148cfd99314ae8a9c8", "skills/frontend-design/references/aesthetics-guidelines.md": "4d9adf4fc0d2f0ed8fc56a3d42647040b691233008a9ef99269ddb2ee61cbb34", "skills/frontend-design/agents/openai.yaml": "00e5faccdd684676a87b3da9ad8e17760f43c929d66c097fcdfe18d6668fbe53", + "models/frontagent-planner/test/05-10.py": "7641412379b14a6118fa9692d85ef0d01818d6fc31beb5ca77d0744d73e8047a", + "models/frontagent-planner/prompts/schema.json": "4d2734ebc225963ff770dc1cd8e255bbb94c2c340e539a5d33aba03c64486689", + "models/frontagent-planner/prompts/planner-prompt.md": "2059bc8238f85ca74c2af0ed305fd0289f59b1ce0a69cfebbc4278043d4204ca", + "models/frontagent-planner/prompts/error-recovery-prompt.md": "a7d547bb87277a0aa4af404960449eb4888d7d22b57ff7b597b0f527cbbfac98", + "models/frontagent-planner/hf-release-14b/adapter_config.json": "538e2560e452ecfddb184b51c03e6a9745cd79a10ab210c4233070d6962232cb", + "models/frontagent-planner/hf-release-14b/README.md": "34effd563d8f79ad356883e877c779b25d665e9c0da7d2544c6746388eb5d178", + "models/frontagent-planner/hf-release-14b/EVAL_RESULTS.md": "9795f9df99cb5aa51a2bcb1d3174078cecdc661093660190ccf5ff4d95bd7b13", + "models/frontagent-planner/hf-release/tokenizer_config.json": "f38df2b424046acfd6bca1a712900bffa2a8a5e1690d10b1566da92eb2dc0bc3", + "models/frontagent-planner/hf-release/chat_template.jinja": "3e3e4ccd01b95ae100e861475e34dd42d044d15858f876bb73fe2934fe1603db", + "models/frontagent-planner/hf-release/adapter_config.json": "52098a437e9746f43e18e54a7aaa610e3f5953640937fc9d9abffd9fb46fca4b", + "models/frontagent-planner/hf-release/README.md": "5d23189b40ee100941e0ab2adf37fc81effe8a73ebf18d7d3bf4d91cdfabc941", + "models/frontagent-planner/hf-release/EVAL_RESULTS.md": "e05d09d123972ef6da8aa96e6af2ed39f8aa79ef7c27c792e5c6931d58c7d957", + "models/frontagent-planner/data/generate_data.py": "e38c6d8b8081200dc93e3ca1efdb728cbd872c25aef1efbadc82b587f46a25dc", + "models/frontagent-planner/data/eval_v2.json": "d1a0d6d1ce8dfea26e3fca620fe784fa4948916804c74f5dde5c70e738e373ae", "packages/shared/src/utils.ts": "f0b6d5a6a8a05199e2918f450f088978eb8e5d8146230f3da6c1a8de5e4ec8c8", "packages/shared/src/utils.test.ts": "d021afcc5e0fb52ada2e65889cb29473818562dc40417f4e22fb2a9e92fb474a", "packages/shared/src/logger.ts": "dd6dcdace53ab520ff36622a9d380f5ad4eec3146e5dd9f7306e72cd99b52ed3", @@ -141,17 +173,31 @@ "packages/runtime-node/src/sdd.ts": "3ca889e898be3892b8378964fb89f1dbe3c115e59b82779e832279516eb61519", "packages/runtime-node/src/sampling-llm.ts": "6f944584929891a01ad35b496b355af12beb8426ca3bf59fa57310003901550e", "packages/runtime-node/src/sampling-llm.test.ts": "e7f2e157d27c86a538e2742f8a719b9e1c7bddcda3fdc010323497fc64cc41fd", - "packages/runtime-node/src/run.ts": "3d2804e374e4a72537d2242df8104ad052f18e2af13aefe487f5cc631293a3bc", + "packages/runtime-node/src/run.ts": "0ab32d15971fbe57bfc7762238d997c5bffa60cc4b8ff3b9249f6f3cc12a3df2", + "packages/runtime-node/src/run.test.ts": "1b991e2476bde4a084f1aab388182cc2f3889f6e3fc92d2a71fac8fde6b38610", "packages/runtime-node/src/run-logger.ts": "988a2193777b1196f3b10e05fa33ef729fea03efa210e322ce4b21dca237631e", "packages/runtime-node/src/run-logger.test.ts": "6507657dccf2d543934bbc8870922dc1c12795b83ede436a15cd16f9f4016280", "packages/runtime-node/src/mcp-server.ts": "4b8b09687546df2689f31c75d1d4a46507ad7dce85d9baab340bc1e6f1c7a720", "packages/runtime-node/src/mcp-server.test.ts": "a893b49b3d12d1171936b6dc16b09ac33163d9e5321f3cd801c90c45f0e52e41", - "packages/runtime-node/src/mcp-clients.ts": "9089cb23d21ebda6c1b8e3cb306cba096f3f67a9a0a968fdb30e13437e80fc79", + "packages/runtime-node/src/mcp-clients.ts": "e632c290522e3f3635ea9b35cca3f6071992404cd41624401d015d8ffa7ba686", + "packages/runtime-node/src/mcp-clients.test.ts": "63527526b41b2f49dd45014e0cacc71dc85109b586936cc8c651b0a53ac0029f", "packages/runtime-node/src/index.ts": "5c183ab246921ee2c3b3253135fdcbca31f57d110d2688c313e1af5bda3e80d8", "packages/runtime-node/src/hooks.ts": "81fb19f6dfe4c698fc8c0e4982ad1e1aeb77695ce4264ebbd67be32e2f7d7032", - "packages/runtime-node/src/hooks.test.ts": "11209a5e48af2ce7c948d7b28f195822bf80946ee17e3689ce05c8e521b06642", + "packages/runtime-node/src/hooks.test.ts": "1d2b374b5e432a0924b91ac5a7db5b6dfc48a7161efaa0e1bf95b103d1bdfe9a", "packages/runtime-node/src/config.ts": "da46e647792e1b8cbc02dacd5f190aee2175ad28a5cef51ec8e60e1de96502df", "packages/runtime-node/src/config.test.ts": "47f290bba87c19b5b4cac3428e69391d607121d882f8f40c43b67e187bbaf467", + "packages/mcp-web-fetch/src/url-safety.ts": "ba11ec3ded9a8286be47bb375ff41817354c8c0c398aa60b3825696c743500a8", + "packages/mcp-web-fetch/src/url-safety.test.ts": "774c63fcd5b82545499d12f1dccb92c134b77965d26e526cd9edf78e41d1ee75", + "packages/mcp-web-fetch/src/types.ts": "2592bcf6f201c910296e6b7d85e07d0a7b5d7242ffb0963d6af48fdfa6fdb193", + "packages/mcp-web-fetch/src/tools.ts": "53c64a38b793048b66e1ba6776a3a8e09d99c4687f57c114063554a467985985", + "packages/mcp-web-fetch/src/tools.security.test.ts": "06bda79cb7c6a2f0f065fabf26a8f097d9459ddcac804532bbf5f2f1939b1b0b", + "packages/mcp-web-fetch/src/limits.test.ts": "5d2a2d317f05124f2cd1e76f59c97d0575015760699ba47d1808615fc67657a7", + "packages/mcp-web-fetch/src/index.ts": "bb89e653a22cf4f6778f28674ca664c2fb17e31fbee830e236d37eb56435a293", + "packages/mcp-web-fetch/src/html-to-text.ts": "9ae4c23754c29b68fac312f859edefd7a5ee7cbcf3a274a746d2798004434672", + "packages/mcp-web-fetch/src/html-to-text.test.ts": "537ced004700d5c860c69c939f6524ab6c39976bbd444bfc9e3807e258f3c504", + "packages/mcp-web-fetch/src/engine.ts": "6c7687faf56ad410a9334b52f4848ee841e46d08bf4f15ad1db75c979f242dcc", + "packages/mcp-web-fetch/src/engine.test.ts": "7e88181d2af4b7776002e560bca787dbdf30ea6525ff62a750222ab56893be90", + "packages/mcp-web-fetch/src/engine.lookup.test.ts": "3bf01dbbed0a9e242befa6b34bcd8250115bb31674ff6f0d74969502680d0cdc", "packages/mcp-web/src/url-safety.ts": "e2c0e96b2ce1ba756fc758c464587c99946c5762b47b638fbc97540ea72e2c3a", "packages/mcp-web/src/url-safety.test.ts": "c336e3e5404451277e90c79f24c4af228046259c5bb04eb3fb00418de2d9f3fd", "packages/mcp-web/src/server.ts": "72572ce5c3d25cb77d4051709c3aa6a376e70e4b9a257adab7511fd677d38f9d", @@ -193,9 +239,9 @@ "packages/core/src/workflow-integration.ts": "66b8ee8f5e580ddf3a27d8a8a748ae0f223233f4d632497e1b567a791be14574", "packages/core/src/types.ts": "b65ac88501152fdf1a56db5dc40400f46bb4c6d7c7fc06babc9ca6ad2cdb14c4", "packages/core/src/security.ts": "6fe1a0a064aaeb8141482a374170c1b7e9f158389cb25c80653442b8846fd546", - "packages/core/src/security.test.ts": "59281e8ede199f098fb9912deebd8c4516be51ebc212c429cca43bc0b39b756d", - "packages/core/src/planner.ts": "ebfa94c4253e12e32dff800dfcb447018c35c8cb0e8b6584418173c3c8ca5f50", - "packages/core/src/planner.test.ts": "4337c21dce5dfcb18346b25c58efff929edb2b4b95a1502b246ae39c5ee77796", + "packages/core/src/security.test.ts": "9f68c4b5c51bbdbc578febfc71211ad8ddc76ea8b222deb9b21da971384398a9", + "packages/core/src/planner.ts": "54918438dc7f08663a4de935194e157c13cc3882c2d8d9dcf208b72e34cc4f05", + "packages/core/src/planner.test.ts": "437d480e41ce6ff3606d1fc1d00194e0110b9c0418fa0fda6134361d594b167c", "packages/core/src/planner-phase-helpers.ts": "9cf7dcaf4faa6c2a6ef3351ce4ff24eb8f84a5d056ba80c1526355cb50eb3a39", "packages/core/src/planner-phase-helpers.test.ts": "62d59ffdff4f01e8bfd1ba20e8660223bf9c37d98f924bc2a21252b205c42cb6", "packages/core/src/llm.ts": "a65bcc07b3ee168db391929352cffd719384d7e080713ff1e153cce4896f889d", @@ -206,20 +252,12 @@ "packages/core/src/context-filesense.test.ts": "185e08bc36963359fd7d2e2457da5059d47f5094a4713add2af2f3e0b6e17ef1", "packages/core/src/a2a.ts": "80764ec469da695ea3025bf4b1e265abb60ba5d592734f96af7e0e8009557a0d", "packages/core/src/a2a.test.ts": "e64d44430cd2a80f3a7fd3d5850da6cd06dfab439dfab8897717aafa8c4fe29c", - "models/frontagent-planner/test/05-10.py": "7641412379b14a6118fa9692d85ef0d01818d6fc31beb5ca77d0744d73e8047a", - "models/frontagent-planner/prompts/schema.json": "4d2734ebc225963ff770dc1cd8e255bbb94c2c340e539a5d33aba03c64486689", - "models/frontagent-planner/prompts/planner-prompt.md": "2059bc8238f85ca74c2af0ed305fd0289f59b1ce0a69cfebbc4278043d4204ca", - "models/frontagent-planner/prompts/error-recovery-prompt.md": "a7d547bb87277a0aa4af404960449eb4888d7d22b57ff7b597b0f527cbbfac98", - "models/frontagent-planner/hf-release-14b/adapter_config.json": "538e2560e452ecfddb184b51c03e6a9745cd79a10ab210c4233070d6962232cb", - "models/frontagent-planner/hf-release-14b/README.md": "34effd563d8f79ad356883e877c779b25d665e9c0da7d2544c6746388eb5d178", - "models/frontagent-planner/hf-release-14b/EVAL_RESULTS.md": "9795f9df99cb5aa51a2bcb1d3174078cecdc661093660190ccf5ff4d95bd7b13", - "models/frontagent-planner/hf-release/tokenizer_config.json": "f38df2b424046acfd6bca1a712900bffa2a8a5e1690d10b1566da92eb2dc0bc3", - "models/frontagent-planner/hf-release/chat_template.jinja": "3e3e4ccd01b95ae100e861475e34dd42d044d15858f876bb73fe2934fe1603db", - "models/frontagent-planner/hf-release/adapter_config.json": "52098a437e9746f43e18e54a7aaa610e3f5953640937fc9d9abffd9fb46fca4b", - "models/frontagent-planner/hf-release/README.md": "5d23189b40ee100941e0ab2adf37fc81effe8a73ebf18d7d3bf4d91cdfabc941", - "models/frontagent-planner/hf-release/EVAL_RESULTS.md": "e05d09d123972ef6da8aa96e6af2ed39f8aa79ef7c27c792e5c6931d58c7d957", - "models/frontagent-planner/data/generate_data.py": "e38c6d8b8081200dc93e3ca1efdb728cbd872c25aef1efbadc82b587f46a25dc", - "models/frontagent-planner/data/eval_v2.json": "d1a0d6d1ce8dfea26e3fca620fe784fa4948916804c74f5dde5c70e738e373ae", + "benchmarks/eval/out-smoke/full.jsonl": "e9aecc6ebf189bbe5c5f327a47ff2c86bf15f377f3e18dd695cc76799d45657d", + "benchmarks/eval/out-smoke/ablation.jsonl": "82b56ee1138667369da1cac5b4c8e9c3d482902f56c54cdaff07bee7150bb72e", + "benchmarks/eval/fixture/tsconfig.json": "3f8e83433971f199d6ec3f029db97b4d832ff483f11a223131aee0ed12e3b241", + "benchmarks/eval/fixture/sdd.yaml": "e7e31eae2b88b87eead36b7230463e18baaf0e45185feb756ce21cece0e71372", + "benchmarks/eval/fixture/package.json": "e89af11d460bde5fc240e65426495785d39ad6a2bae8ca02d3d90cf6875483cc", + "benchmarks/eval/fixture/README.md": "51d92a0a381d6fa2e981a24f0442ce08dbf59f2f09b88b2d8dc6a8802491bf09", "docs/superpowers/specs/2026-06-11-gitguardian-ci-design.md": "292229a60ccb6c15c00bd1ecb0f2f052e3df7ef308ba4c717623b55cfd016c72", "docs/superpowers/specs/2026-06-05-frontagent-oss-harness-design.md": "f0948f03e6d21128229df42d46be1008454ff0df3ee2cb7f5f551f18306a6161", "docs/superpowers/specs/2026-05-20-frontagent-repo-guard-design.md": "924705c8c507e21079d63e838942706fc43e7a191ae7680ce7d943b73239805b", @@ -285,13 +323,13 @@ "apps/cli/src/run-logger.ts": "439d3f0d7db3cb5aa7259e3c3754dbc8a676995b252b524d9639a358728284c3", "apps/cli/src/run-logger.test.ts": "98cf812a1251be78f384ccff62709b1a99997c8c9b40fb6879ce46a0b2d5b7f3", "apps/cli/src/mcp-client.ts": "c4b41745c77d7806850e21ab385e0339a305796bcfcf550de1ae983b4f7e3e13", - "apps/cli/src/index.ts": "360e75a14c42fecb1c22df1e04be40847d4b689f0d95f2a20fc5ddb01c5b3315", + "apps/cli/src/index.ts": "3f07f97bf0f7c27e129e2c28cc3b41245ed3625bfea746cbc94f8958f1cc89a9", "apps/cli/src/index.test.ts": "ef81661c2e89dc3586afcc4788d2d2191bd2053aeee39d1209b45851d1cfbe8b", "apps/cli/src/bootstrap.ts": "30faec23379af02d64337f24cc743b62f2b720eaf6b0b8b1ba7c3ae2fabfdc8e", "apps/cli/src/bootstrap.test.ts": "0257c4822f3ebd3aa29914f302438158ad5f5d14d072a1ba85f510b047a76d8d", "skills/frontend-design/assets/templates/visual-brief.md": "2e7e116227d0489e5cb886cc8e1f0d5e303bd35166d6e4a3f598cbfef795e897", "packages/shared/src/types/validation.ts": "d80143b224dbc1dd26186c523ee8d64788df88629c23546a79e6afa5b83a9e76", - "packages/shared/src/types/task.ts": "3935a80cb3ddf91259b9d4218e76c29a6df15bfe7bc052c7503ef622eb06c36f", + "packages/shared/src/types/task.ts": "182a6f407db6f72b31b48f67ed9ad0713ccb4844c313a8c0ee681749385270c6", "packages/shared/src/types/sdd.ts": "51fa604aec9961284ffa198dabc82d21b34211c8ddcf57c0bcf25c8c7cdf6691", "packages/shared/src/types/page.ts": "53562720a980625a8743b06c87ecbf9ee0dfd36cd0780305972accbc46e459aa", "packages/shared/src/types/mcp.ts": "4d5f536029543329cb1d131442b1c38e0897f4b5aaa7ce3f0ee733979fe7742d", @@ -341,8 +379,8 @@ "packages/mcp-memory/src/rag/index.ts": "8140815159eaec7792ffea54261acacee07c3bb5c28247c7421282e2be986a2d", "packages/mcp-memory/src/rag/embedding.ts": "9d34925a6e1cea0d14d98a4c5b72db4c94b36541b537680002780dff2c306865", "packages/mcp-memory/src/rag/config.ts": "42df1919561d9a1eb792cc25a8c2d87c920fa16683fe62fa326dfa8f4431f587", - "packages/mcp-memory/src/rag/chunking.ts": "98aafd8bc85c2b55c3c7345ddc67eaf550298a559c3ebc1097690819181cd155", - "packages/mcp-memory/src/rag/chunking.test.ts": "14e18f45e14ab275ac360bf3d2857679c8c455d2ee18b4d163df98c71a147cdb", + "packages/mcp-memory/src/rag/chunking.ts": "cd542c66be4abfe8b41dfcca9c36b178990c6e3b3e8e46806e9877cef7b90236", + "packages/mcp-memory/src/rag/chunking.test.ts": "8faa0aaa3c56f68d21a1403c63ce10eaaf62a769f42b32034ef4c951ef166546", "packages/mcp-memory/src/rag/bm25.ts": "d62cc31c992b648e4edeacdacc26fca248b629d5bdd8639f2c001e256e819f8d", "packages/mcp-memory/src/rag/bm25.test.ts": "04cfe2532ba68fb3edfc55bc74c627a7c9d11402f8414490c983152718260a80", "packages/mcp-file/src/tools/search-code.ts": "03bd8a4feb391ed2b70de513d07ef0f6d9105d3ff6ac9bc9dd75d971cb660283", @@ -352,6 +390,7 @@ "packages/mcp-file/src/tools/list-directory.ts": "d66b7c71b16758797f04785a870fa83b78c98f6dcb529d10448cf48fb3e9e8a9", "packages/mcp-file/src/tools/list-directory.test.ts": "3b9b13a03dd09b54c806e3b23376425c593b4d1acd0d36e7e4083b58bb8206f6", "packages/mcp-file/src/tools/get-ast.ts": "6d71c80ca67f9e7d4acec9d24b5583f439a93168e50f3e2942bed31410c32ab9", + "packages/mcp-file/src/tools/get-ast.test.ts": "60780528c3ad2d441d7e926a7599ef6ba618108f2ec5dbee4d83dc3d5b9c7df9", "packages/mcp-file/src/tools/create-file.ts": "65106c198b77ed1d0188eed4972d612ce92c9527892d41c8265226e18236448d", "packages/mcp-file/src/tools/apply-patch.ts": "a3f36f90a9795ff2d98b3d365dc58909e50bf89681fd63372b67e85d7839571a", "packages/mcp-file/src/tools/apply-patch.test.ts": "a69b407be8406ef7104a6408a9f468bf9cdeb52f002c281bc4cee4e0b70b0edf", @@ -370,15 +409,13 @@ "packages/core/src/sub-agents/index.ts": "5e418464ce940767df6d6532e156595d23b879d7357f23b3e204253e68b362e2", "packages/core/src/sub-agents/code-quality-subagent.ts": "1c224562414843daf0569781ac30904b5617a7e478549d24c4717b76c04792da", "packages/core/src/sub-agents/code-quality-subagent-worker.ts": "e9bb56c7dddc6801434ec07b9cab73c1db469fa9f85f9e8df8cd7e54c9ee2b97", - "packages/core/src/sub-agents/code-quality-prompt.ts": "5f10b7b48d51839bea1783edb6da08171270b35717e35aebe87aa916c154cb70", - "packages/core/src/sub-agents/code-quality-prompt.test.ts": "07123ac26bc72a0ddd944851e8673a65ad962db377b7debdc18b2d1227d5d9e7", + "packages/core/src/sub-agents/code-quality-prompt.ts": "c9f2319f9339b31ae7412ece235533227c66285028c99dac9a01a370b9d7a657", + "packages/core/src/sub-agents/code-quality-prompt.test.ts": "6d6e787aa91e742dff455f18f914d9167488bc283c6c868e01724fa2d39cb9f7", "packages/core/src/skills/types.ts": "8531586e4271c389ff519757c31be29c666801948036eaeb637f247c6b3b06df", "packages/core/src/skills/planner-skills.ts": "4baa53855f73554639eed73bdc4bc2d8e84fe517f6b6c72d8b50b1d19e419160", "packages/core/src/skills/index.ts": "e9ec8b593e7239d3c9a5918302c983dac20ed4f967a62c0f8d3edd1d99de6536", - "packages/core/src/skills/executor-skills.ts": "06d7096eae0e07f85c08724314b0af2e1d7e0b84df06ad8cf1af66b521a93bf0", - "packages/core/src/skill-content/types.ts": "4f04bc41f0b2138f761ee0e12d951e6194eaa98a35d4295b1283a287ec03df05", - "packages/core/src/skill-content/resolver.ts": "43352803efb6de138a7cd2ffb5f6e50d3adc7edb0d4536ac2ea977fa7388214b", - "packages/core/src/skill-content/loader.ts": "4d9af6e5427ee4e46e8356f8ada39a3ba53eedf162e365dfee49683d85e7ebc5", + "packages/core/src/skills/executor-skills.ts": "c397ebc881185c77e1867a06d04b922f29e16e2d2c9e3dd60f3d50ed948226ea", + "packages/core/src/skills/executor-skills.test.ts": "ac70181ff4a47922a6b508c1611f4040d0146fdea7b3d08babdb6101ab52506b", "packages/core/src/skill-lab/utils.ts": "b1492635e04603cc0890888dcb6bf084d9a840d3e217218b040739e1c8fc9f54", "packages/core/src/skill-lab/utils.test.ts": "07eeee6577a820b666219f6e23566abf6f837d203793463a526af786676756a9", "packages/core/src/skill-lab/types.ts": "7148f36c4610fb2da8f4247ab236884082d66599b410fd3315c959ac7cafe96d", @@ -391,6 +428,9 @@ "packages/core/src/skill-lab/improve.ts": "29ea61dadbbb0652a5d72ff6cf41c383450d256636ae853431f591271b8fa702", "packages/core/src/skill-lab/benchmark.ts": "8c6f45755bc2b96808be370e1cafd6b979602cbe7bd92af18fb653b19424a2c8", "packages/core/src/skill-lab/behavior-benchmark.ts": "35f10cfdd6d08801129ddd389763faf182d0e1508a9149ef6ac2b5bdc9ea3fb7", + "packages/core/src/skill-content/types.ts": "4f04bc41f0b2138f761ee0e12d951e6194eaa98a35d4295b1283a287ec03df05", + "packages/core/src/skill-content/resolver.ts": "43352803efb6de138a7cd2ffb5f6e50d3adc7edb0d4536ac2ea977fa7388214b", + "packages/core/src/skill-content/loader.ts": "4d9af6e5427ee4e46e8356f8ada39a3ba53eedf162e365dfee49683d85e7ebc5", "packages/core/src/memory/types.ts": "97fb8897e147fdc1ba7084153a8b2e1fdc737e83882105ae36b54ddc81745344", "packages/core/src/memory/store.ts": "40d1b0697b92211954baeb96b577e42665180ff50ad8f2052b67bb5a06ee529c", "packages/core/src/memory/store.test.ts": "1731709002ca2e3edc219ae994b175591f4bdaf8590026834d5473e981606675", @@ -400,20 +440,35 @@ "packages/core/src/memory/open-memory-gateway.ts": "fd818b67d607bf97d083d7e509378ac2fff9ff714b983a4eebaadb0fc35aefaf", "packages/core/src/memory/open-memory-gateway.test.ts": "8dc2624b47aca5b3b649fa96bb0aaf7ebad872eefbd695c3c24020d1f3830931", "packages/core/src/memory/index.ts": "f3a37d193cfffe4bff863972ea4a488f3300abf06f56516fd669a1ace4dbf1b6", - "packages/core/src/llm/schemas.ts": "5495272d665299e00a17c61b275e0fdd0527ac7afdf53588101825de832e5584", - "packages/core/src/llm/prompts.ts": "97d9522bf05e592d934f9df118d8d2e64c6348b1f595256b751cf9992fc15702", - "packages/core/src/llm/plan-generation.ts": "a49bab4c9a2c39d91cb25069c5d1e94b37cabcbec853ed500cde8d3ef8cb4635", - "packages/core/src/llm/plan-generation.test.ts": "15c8cc571b8f9fae37f39855852d88270822b11682709f34401519698e2d579a", + "packages/core/src/llm/schemas.ts": "4d98d139412e68c740fd969fb0f9827a91da57030eb926bf2d3f9472030833a3", + "packages/core/src/llm/prompts.ts": "e68f9b311d7fe94d725fe715d7685f3116271b1798e02831a0e6f56a16aa0bc7", + "packages/core/src/llm/plan-generation.ts": "4429730839dd7bc66b645387473ab28ecc5b00f0dafea184c12c7a89af0ca643", + "packages/core/src/llm/plan-generation.test.ts": "defae704ddee029a79cee91dc9b2f3b1fb3e7768c268df64b298e100cdb2800a", "packages/core/src/llm/object-repair.ts": "ac93064b3e4157f9246160a6ef39d719a0464921567b33f3ee653f360950870e", "packages/core/src/llm/object-repair.test.ts": "ee9a9669f3d350eb42c54076899f0f55fac70c734d6ea23524e560e7cd07093f", - "packages/core/src/llm/llm-service.ts": "9d1b78d14d2c9c8101ab0bc3f5666e45f95ba812daf3718376ae36c8108a60e5", - "packages/core/src/llm/llm-service.test.ts": "d1f4f25dfb18197c4b4d16cc01b05c98f16f4777e1dfd0f575a540122d977b36", + "packages/core/src/llm/llm-service.ts": "1065b3ddcdfaa299650425795f339aa129fa49699fea452769eb7e03d3a97d95", + "packages/core/src/llm/llm-service.test.ts": "e78c99cdcb52a3c8844e879d7dcf04006e2d95987ecd1f1cc8f716329b63d266", "packages/core/src/llm/index.ts": "9099ae980c974075574497195af7ee167da67c002f061599570077407a421c71", "packages/core/src/llm/factory.ts": "84439c057c0027efbfa9d4873c855c51845f7dae985cac685a122c016b8c0ca5", - "packages/core/src/llm/code-generation.ts": "cf55a99d48918070120c9be9ccb09e69c95b089087088c864575c5de857f223a", - "packages/core/src/llm/code-generation.test.ts": "15f23109fa11c93030db8a4c08f78481e2158e6263d59bb6e45e4868b4c5f495", + "packages/core/src/llm/code-generation.ts": "f44594e983718ff05630c3d2108b39aa869165430a8339a21ae79ec67ab5f98b", + "packages/core/src/llm/code-generation.test.ts": "bc12ed05116eded21359e5c0af698a3eba5cc74b788ec8567d530a7d77737359", "packages/core/src/filesense/trigger-policy.ts": "becfb5ac97f431b88236597d096f0e8d64a72befcd22e82c0b3305dc9ce1f4fa", "packages/core/src/filesense/trigger-policy.test.ts": "0d0098cb511c6d6f574833fd3c9ea0b2b62252fe5fdfe0fa5367c6fa522fed89", + "packages/core/src/context/project-instructions.ts": "5b4f2e64d6965ff972bbb76038db0f353f12bde872e677fbc1b2d6dd3617bc94", + "packages/core/src/context/project-instructions.test.ts": "380f404c8824d9e92af06dc7808e702a59678d835c6885f7566633395fe764b5", + "packages/core/src/context/module-dependency-graph.ts": "8cae095707cef46249cb5141f2e570420cabfd23b0efc7742896c626097809d5", + "packages/core/src/context/module-dependency-graph.test.ts": "3b86ca71329444b84f6bb1940f128a462a69f2b99591923fd76de6a390f5bbbc", + "packages/core/src/context/index.ts": "3f2545c79b7c63f75bf5461810c1f43c32cf6766ca29a57f626ab6087cdccd0a", + "packages/core/src/context/helpers.ts": "a6463181a4cdc8d9ea7e2145b36ac7d5a6124e7be8d6318a1a2b021f523b1be2", + "packages/core/src/context/helpers.test.ts": "ca2cae1f6d3addc97bd1f9920e106256e6af390e22b4c7eeaa3d694cc44df669", + "packages/core/src/context/filesystem-facts-update.ts": "4439f47b4854083e151f993df53cb969f26fd6fcdb27c4fa26ba805f9108f97a", + "packages/core/src/context/facts-merge-helpers.ts": "c300c9368dbdb9561ea005f0d3d78e65f0d0b4759c8633cd9a25c3013a5b18c7", + "packages/core/src/context/fact-serializer.ts": "25e3773276512aa52be43092f6339e5600f71406bd221972764ddc1242f2595f", + "packages/core/src/context/fact-serializer.test.ts": "72c82961e7c6c5ad07ab8e952e179fa8df4a97ce5fd27bdc63e82cd6a58dee44", + "packages/core/src/context/context-manager.ts": "f5ba69b1d1ec7d04968d326bd38e463076cec05065f17a9fb499e549830004e5", + "packages/core/src/context/context-manager.test.ts": "7620dba14a25845b8f2883581d4a2a03a3fa2b3bd8b2afa24fe611fcf65c4025", + "packages/core/src/context/budget.ts": "0530402b7bfa3a2da5601f5b15a923278f8acdc2e9334814616ba1c5d335dcaa", + "packages/core/src/context/budget.test.ts": "d7f11aab8fc4859a61d1d0c88ae5839ebc4eb1060901d6c8f4719ee031eb5b78", "packages/core/src/executor/types.ts": "1b5d42eb6abe73c13fc317c98fc95e0bc6b199c0ee3b660a54abc6cee910d987", "packages/core/src/executor/trace.ts": "294032d09c18a549db371474cfe6387c369d6ca4f5493d0c2b79339c5b5d87f4", "packages/core/src/executor/trace.test.ts": "cd9340cef2ed972be6bc64de3979b25053352ac37f47176c09bcf44427a086fc", @@ -431,24 +486,10 @@ "packages/core/src/executor/index.ts": "ae4ff32e0e696a01a6f66f2bc963d45d08ced83361be39e32f58018ec6ed38e8", "packages/core/src/executor/executor.ts": "002d61ca4b93f5e42c7fba9b526444e8f142e58361c3fa970b910fc75417540c", "packages/core/src/executor/executor.test.ts": "ec0c491de48ce27a138289ac6ac05b5b0429b017b0f4c5a9947329d1ff957edd", - "packages/core/src/context/project-instructions.ts": "5b4f2e64d6965ff972bbb76038db0f353f12bde872e677fbc1b2d6dd3617bc94", - "packages/core/src/context/project-instructions.test.ts": "380f404c8824d9e92af06dc7808e702a59678d835c6885f7566633395fe764b5", - "packages/core/src/context/module-dependency-graph.ts": "8cae095707cef46249cb5141f2e570420cabfd23b0efc7742896c626097809d5", - "packages/core/src/context/module-dependency-graph.test.ts": "3b86ca71329444b84f6bb1940f128a462a69f2b99591923fd76de6a390f5bbbc", - "packages/core/src/context/index.ts": "3f2545c79b7c63f75bf5461810c1f43c32cf6766ca29a57f626ab6087cdccd0a", - "packages/core/src/context/helpers.ts": "a6463181a4cdc8d9ea7e2145b36ac7d5a6124e7be8d6318a1a2b021f523b1be2", - "packages/core/src/context/helpers.test.ts": "ca2cae1f6d3addc97bd1f9920e106256e6af390e22b4c7eeaa3d694cc44df669", - "packages/core/src/context/filesystem-facts-update.ts": "4439f47b4854083e151f993df53cb969f26fd6fcdb27c4fa26ba805f9108f97a", - "packages/core/src/context/facts-merge-helpers.ts": "c300c9368dbdb9561ea005f0d3d78e65f0d0b4759c8633cd9a25c3013a5b18c7", - "packages/core/src/context/fact-serializer.ts": "25e3773276512aa52be43092f6339e5600f71406bd221972764ddc1242f2595f", - "packages/core/src/context/fact-serializer.test.ts": "72c82961e7c6c5ad07ab8e952e179fa8df4a97ce5fd27bdc63e82cd6a58dee44", - "packages/core/src/context/context-manager.ts": "f5ba69b1d1ec7d04968d326bd38e463076cec05065f17a9fb499e549830004e5", - "packages/core/src/context/context-manager.test.ts": "7620dba14a25845b8f2883581d4a2a03a3fa2b3bd8b2afa24fe611fcf65c4025", - "packages/core/src/context/budget.ts": "0530402b7bfa3a2da5601f5b15a923278f8acdc2e9334814616ba1c5d335dcaa", - "packages/core/src/context/budget.test.ts": "d7f11aab8fc4859a61d1d0c88ae5839ebc4eb1060901d6c8f4719ee031eb5b78", "packages/core/src/agent/task-execution-setup.ts": "f46a6d58bb9b11931bb5ef78f96e63e87309d03f116487fd5247e58f7b54019b", "packages/core/src/agent/task-execution-setup.test.ts": "ef7d803ae494446c6099fff6628c9f15d5604fd9ad9237a50b40da0e692c67e0", - "packages/core/src/agent/step-callbacks.ts": "c74dcaba76e1bc189c485d27fc91801f1fe3f431c9c7eb9b4fab367d1cae9179", + "packages/core/src/agent/step-callbacks.ts": "39638ccf6570507a05ce8ca52cd00dbe1ca9be09849c237abdb0873fad226d66", + "packages/core/src/agent/step-callbacks.test.ts": "b9d1b47675161b5f7b26495bf78b72b077ef949fb30c3a76887b1923cdd18c42", "packages/core/src/agent/rag-retrieval.ts": "f19c654d82704d7ed61a32fc2cd11689e4561d4a0187f2c2a51b3505983bffb2", "packages/core/src/agent/project-prescan-preparation.ts": "424f383a917da902ec2bd4e0b561b3961aa639706453aa54b993f76e121a9ea1", "packages/core/src/agent/project-prescan-preparation.test.ts": "459a030f607d1bc5584754d49f4f63451037b7f9e7e4877b346cad160c3e5976", @@ -467,10 +508,35 @@ "packages/core/src/agent/context-gathering.ts": "dce973327ffb3611cc1365ca28466b38555201ac9b709ee484de7ff4f99a5f05", "packages/core/src/agent/context-gathering.test.ts": "0e91333250b59e6561eb36b14162aa67a7e566ce8fee4332e9895f127f88a42a", "packages/core/src/agent/answer-generation.ts": "0f727f88ff5914ae26e3b9c22750ece0929fa5312ead958bc3e648d1b7e39644", - "packages/core/src/agent/agent.ts": "1c8a391df82010660ed372a4d653a39f45c1d04697670ea0acba8c544165132a", - "packages/core/src/agent/agent.test.ts": "0c3545da0c7fc0b010c4b4b14965cd78e267410bd314bb224dd3c91e8e13621b", + "packages/core/src/agent/agent.ts": "d5f3271fe4de4ed9ebd15e42a3791afdd02573a8cf8dfc607428794192357c00", + "packages/core/src/agent/agent.test.ts": "1416f694bfa99a597a8d8c3bf7cfd56de56324c1d31a5e5abff5eb1bebe592b8", + "benchmarks/eval/fixture/src/App.tsx": "d4bea307ccedeffc80ade36baadf8792f6d14b0bf13f38ae695904f613fd514c", "apps/vscode/src/test/vscode-stub.ts": "a43f4fb5b3333b3007229013f6ec8374bac986e1ae2f816aa2da1a3e3aef99d8", "apps/vscode/src/test/view-provider.test.ts": "a1af5b19cd0f666f80f64be75e83ac6fd627c679b3b7b8e39d8c2b030f8aa71b", + "apps/desktop/src/state/executionReducer.ts": "24e0090887dfb26272e02106313dc8cf613da2ad54a2a4f83d8e8b5b3feeff69", + "apps/desktop/src/state/executionReducer.test.ts": "1c607c6d61ea69e7b338b2b08f7faf9051f639387513b456cd704dfca0f8635b", + "apps/desktop/src/preload/preload.ts": "77fe49259e6d0fb8dc9611f7878f23aa18c9e5a61fa05f030c257159dc826cc9", + "apps/desktop/src/preload/install.ts": "670af61d45e8e54f46714a3849ed7bc35899b75b26fb3e83859ca05cf93ab7da", + "apps/desktop/src/preload/install.test.ts": "d57018724377b811884103c49253c90c8d924ded0249a88922ba10100de00ec8", + "apps/desktop/src/preload/bridge.ts": "f053b465d5eef0061722d511711d994e2cfc9af2177a5330a4ff8df11d1c4c02", + "apps/desktop/src/preload/bridge.test.ts": "a86dedfe04c2ed8efd3eb155bf256297ecfd71530d87ce5f19babc1f847c787e", + "apps/desktop/src/renderer/theme.css": "4631f5dc6626b375b7b51ca041d76e8bf9ca165a4f6e42a20ab7294d8ceb76c0", + "apps/desktop/src/renderer/selectBridge.ts": "752400cae9611427c8120a41a3d598e452b163706ec942280c0a789b1de2ae41", + "apps/desktop/src/renderer/selectBridge.test.ts": "3e73690337d931bddfad0686fec03f6935018fa76bdcd10127efec1a0cd171d1", + "apps/desktop/src/renderer/main.tsx": "15a0329e72706d02354b9b08d57619de4e3724cb62a54cb7c571dd3e93ff6628", + "apps/desktop/src/renderer/App.tsx": "5f512dcb824fd6ad180da74807d2b8eccc3b070e9a324f47942663bac64c8e60", + "apps/desktop/src/main/smokeProbe.ts": "945f855472ddb0121a4cdbff9888fa5815d2091e54c289de4d7bd597f0483479", + "apps/desktop/src/main/smokeProbe.test.ts": "bdb9c6cdca1f00d325c74aadf83e84f70789cdb8f5ffd744aaa9a7d3e5c549c2", + "apps/desktop/src/main/settingsStore.ts": "b0c0400e205222a142076d206c6582d7ffbd16b96b4045041dd4c44aa61d5fcd", + "apps/desktop/src/main/settingsStore.test.ts": "0e61fc7f66c4b1e9002a26302494db466092bcb3a9fcd6335e473cf98c8a1236", + "apps/desktop/src/main/runtimeIO.ts": "8c1a8c8c5bc8b0236c87cde79766ac1d2bfd47a077f777e375a50a3efe2a5b49", + "apps/desktop/src/main/runtimeIO.test.ts": "c53f766a7646ab4ede0571487ad8bcd06d08ef5ca3d7c5fe1182dd094ba5571c", + "apps/desktop/src/main/runtimeBridge.ts": "b52a42503fb3a5ceee263ee89d90e640f7bb543eb8706e58a477c1bbe4d69200", + "apps/desktop/src/main/runtimeBridge.test.ts": "a689ce8a9dbbc341544a54c2e6f474e4cd7439a94449e1e4d79d1090f240d4e8", + "apps/desktop/src/main/main.ts": "50b848626f309780190506453a0c322a09245b1f2b7fea5a6caf822e3053489a", + "apps/desktop/src/main/ipcHandlers.ts": "1f2cac26e38c2e8084c5de85b36a40218ac7d8c5bb0a8cb680e96b7a1a1f0bdb", + "apps/desktop/src/main/ipcHandlers.test.ts": "a12fcc84c307e2609a6e7716481af99e4bc850c3ce509271424a034d65fb50bb", + "apps/desktop/src/ipc/contract.ts": "069f94e8ab1782ca933a9572315e8d517e4c9f1806ca0f017626ccaadb54e332", "apps/cli/src/ui/store.ts": "4f8221870061f581d25c52e15827e6cc0fb0960d64ed5c54df375a8ba57f2a0e", "apps/cli/src/ui/store.test.ts": "93c4a61c0637806f86d9fddad9adc3d18693521948ff4b580b8b9d2bc28cd20e", "apps/cli/src/ui/index.ts": "ca9e3a5b4986b07685586dad2df1fd12904d91a813b9e7c483421b6b55d11269", @@ -478,7 +544,7 @@ "apps/cli/src/ui/bridge.ts": "00d529d4bc2637f7e3708c8f61dd798c241bedd90c185a7766d4afccf8cddfe3", "apps/cli/src/commands/validate.ts": "73f3c9e931c17ecee63487b486866b8531d43a699ee83b93fdbc049ce8aeea5f", "apps/cli/src/commands/skill.ts": "de5f58e9e06d0eca43e4cdb52b3ed245290ac7c0400802abde1b63682eeb2c6c", - "apps/cli/src/commands/run.tsx": "781c9e3a3f012990041a1a6849f601b8565a25e46cb66947f96caaff2ed883f0", + "apps/cli/src/commands/run.tsx": "bb314afbdcf00cfba16c016fe0931417274c0b54b840865ca3f8198d15f75c9b", "apps/cli/src/commands/rag.ts": "bd0f6994a36ce02ebf8b2ddaa3bfd192c202d10cc1cca43f68098a6562d51ca0", "apps/cli/src/commands/prompt.ts": "41c570dbe98042bfca9c90b9f0f183063c28e341c24064e24150306429abaeeb", "apps/cli/src/commands/init.ts": "b30d6db0091ba7cf488fca3750de86a72f80d194c1b00506c0165d52930a1aef", @@ -494,6 +560,33 @@ "packages/sdd/src/workflow/checklist/validator.test.ts": "ac4662439c3c332a85b7d671ea696a43ebc230965548a08a9c82c2f79d6e6162", "packages/sdd/src/workflow/checklist/types.ts": "82d2ae676e3d25d590ead701601188b9833d0a0773e720ebea653e915a16604a", "packages/sdd/src/workflow/checklist/built-in.ts": "061ddaeec91bd19470f81e27def1ad1745e462d76e87f7dabe575a8b36513919", + "benchmarks/eval/fixture/src/hooks/useToggle.ts": "043d5853e956288120d906d43eaaf5703ecc6a98e6ede114d849247f13161487", + "benchmarks/eval/fixture/src/utils/truncate.ts": "6e1da7866b40ab5e3876bd0f91f91c51a6d872191c2cd5a9be83a713b74b0b92", + "benchmarks/eval/fixture/src/utils/truncate.test.ts": "efa0cacfdb81f0aa87ca538fdb9e783121bf51d6cac7b776db4cfb08443cd20e", + "benchmarks/eval/fixture/src/utils/pluralize.ts": "b8cce9384c7ed887bf45c66d59e595255a97e91197a3c4990dd1f270a2f7cd01", + "benchmarks/eval/fixture/src/utils/pluralize.test.ts": "42b84d9235d1c6128e47362e731c64062b4bac62ed2dba4cef770f08011b2a14", + "benchmarks/eval/fixture/src/utils/parseQuery.ts": "4d518009a3d0056c435a05381df563be4839358ccee9a597bb2330d8f8608648", + "benchmarks/eval/fixture/src/utils/parseQuery.test.ts": "18ac549e3be40be9ef55ffe6468b8db6d7524c28caa2fd1afc516f4190ea01a3", + "benchmarks/eval/fixture/src/utils/formatDate.ts": "f19a2beb1ea3db2f252496e1e4d3d77ff88bbaa75e4aabd0cbdde9d7e2518f78", + "benchmarks/eval/fixture/src/utils/formatDate.test.ts": "db7f07391c5b26b002fb69639b210ed6e46301601b1eb580e2c15d283637e4a5", + "benchmarks/eval/fixture/src/utils/clamp.ts": "d2d94d7531e2947bc6d0df52c4d8803384b79a1c6c36fc03e3cafaa679830a5a", + "benchmarks/eval/fixture/src/utils/clamp.test.ts": "c2a287cc86ac5c5154e040f5e19b54c0c4b7b93eebb887dd885307979a021576", + "benchmarks/eval/fixture/src/components/TodoList.tsx": "2088ca87d00e73b3b6ae9a61e1877c11673d31f92a20f3e6744eb75511326c4b", + "benchmarks/eval/fixture/src/components/Button.tsx": "c1ca7aebd1bd65be6ef3c52f791a386a957a3fdc840e4471fd161b05410d0d3d", + "apps/desktop/src/renderer/mock/mockBridge.ts": "487f0ba9eeda19322e0c0456d1d4597be523b0011258c2140e518d424c074082", + "apps/desktop/src/renderer/mock/mockBridge.test.ts": "401c06a4fb2b193b75aaab8130d45493fe44566fa021ea88c7972c2e2b531ba3", + "apps/desktop/src/renderer/store/useSettings.ts": "909dc8c915cf3df75c1cce9a47ef79398ab4afc01830b283cbd90cfcb4702a03", + "apps/desktop/src/renderer/store/useConsoleState.ts": "d8c87166fa0b6e63ddeff64df53bc4d7d8601b4bc868de76292fe0b8ec9e2ac9", + "apps/desktop/src/renderer/store/settingsController.ts": "052704df2acfb595921a6be18d8d0285a86ab808324cf1421e15ddd69c218e0d", + "apps/desktop/src/renderer/store/settingsController.test.ts": "6702d4b5b7f9c4454f808843a7ec4c5a4d21e8b757b4446796c6ab19f7f0e320", + "apps/desktop/src/renderer/store/consoleStore.ts": "486d10d56bbfa00c5592f536ea7c57f8a200678cbda8dd9bd8ca1a6309005875", + "apps/desktop/src/renderer/store/consoleStore.test.ts": "0d62b476bf0ff38e82911d7bfe1348829f79ec9e184e0990510f5a2fa706a394", + "apps/desktop/src/renderer/components/TaskComposer.tsx": "6909be319466a05a519569bab3b38cfda62598a10a5a8efb321f903f043cce15", + "apps/desktop/src/renderer/components/StatusPill.tsx": "687d4a4ff3492d1b4487fcc067d7e99b312a7acbc1dc3cdb5ac1e51d4e0c0ef6", + "apps/desktop/src/renderer/components/SettingsPanel.tsx": "9a0403419286990b7de1bbc35ef25fd4ce6c37c8e9a9f6f1446c77a02810b46a", + "apps/desktop/src/renderer/components/ExecutionTimeline.tsx": "329f4d3296dc0c55d9c974c77a9563e0d3e2a52c5a8ba49410d5b44caed734f9", + "apps/desktop/src/renderer/components/EventStream.tsx": "fa1785033082f6b8eec68d7ea87daae6601b71ff83b513c16b6c755f49591e65", + "apps/desktop/src/renderer/components/ApprovalDrawer.tsx": "9b8c05dc6cd0f8be9f5ef27bd40760044fa2229184a1700861ddf95de48a1154", "apps/cli/src/ui/components/StreamView.tsx": "ee731bd505d280503553f96af3edb05a7333df0f521a54a7cc13614080983c59", "apps/cli/src/ui/components/ResultSummary.tsx": "865fdca08c4102c19c805e58c3e0a872642f3d43d0709101023cf857d99f420d", "apps/cli/src/ui/components/RagInfo.tsx": "068d4c6b396e50770c9b947edb53b3d8e89c15b3b8329ace8a4cc8daf04b1783", diff --git a/README.md b/README.md index faa6c2a6..ce5992c5 100644 --- a/README.md +++ b/README.md @@ -1297,6 +1297,19 @@ pnpm clean - [RedBox](https://github.com/Jamailar/RedBox) - Local AI creation workspace for Xiaohongshu creators. - [1flowbase](https://github.com/taichuy/1flowbase) - Virtual model gateway for publishing multi-model workflows as OpenAI/Claude-compatible endpoints, with trace, token, latency, and cost visibility. +## Ablation Benchmark (reproducible) + +A frozen 30-task benchmark measures whether SDD constraints and the hallucination guard actually improve first-pass success. It runs on an isolated fixture project with machine-checkable acceptance (`tsc --noEmit`, `vitest`, file assertions), two arms, and resume-on-interrupt. + +```bash +pnpm build +node benchmarks/eval/run-eval.mjs --arm full --tasks all # SDD on +node benchmarks/eval/run-eval.mjs --arm ablation --tasks all # SDD off +node benchmarks/eval/report.mjs benchmarks/eval/out +``` + +Latest results: [`benchmarks/results/`](benchmarks/results/). **The current findings are negative and actionable**: SDD showed no measurable effect on first-pass rate, and the hallucination guard recorded zero interceptions while syntactically invalid files still landed on disk. Three root causes are documented in the report and tracked as issues. + ## Contributing Welcome to contribute! Submit issues, bugs, or suggestions: diff --git a/benchmarks/eval/checks.mjs b/benchmarks/eval/checks.mjs new file mode 100644 index 00000000..bddb823d --- /dev/null +++ b/benchmarks/eval/checks.mjs @@ -0,0 +1,40 @@ +import { existsSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { spawnSync } from 'node:child_process'; + +/** 逐条执行任务 checks;返回 [{kind, ok, detail}],全 ok 即任务 pass */ +export function runChecks(checks, { workspace, resultText }) { + return checks.map((check) => { + try { + switch (check.kind) { + case 'file_exists': { + const ok = existsSync(join(workspace, check.path)); + return { kind: check.kind, ok, detail: check.path }; + } + case 'file_contains': { + const p = join(workspace, check.path); + if (!existsSync(p)) return { kind: check.kind, ok: false, detail: `missing ${check.path}` }; + const ok = new RegExp(check.pattern).test(readFileSync(p, 'utf8')); + return { kind: check.kind, ok, detail: check.pattern }; + } + case 'result_contains': { + const ok = new RegExp(check.pattern, 'i').test(resultText ?? ''); + return { kind: check.kind, ok, detail: check.pattern }; + } + case 'typecheck': { + const r = spawnSync('npx', ['tsc', '--noEmit'], { cwd: workspace, timeout: 120000 }); + return { kind: check.kind, ok: r.status === 0, detail: r.status === 0 ? '' : String(r.stdout).slice(0, 300) }; + } + case 'cmd': { + const [bin, ...rest] = check.argv; + const r = spawnSync(bin, rest, { cwd: workspace, timeout: 180000 }); + return { kind: check.kind, ok: r.status === 0, detail: check.argv.join(' ') }; + } + default: + return { kind: check.kind, ok: false, detail: 'unknown check kind' }; + } + } catch (error) { + return { kind: check.kind, ok: false, detail: String(error).slice(0, 200) }; + } + }); +} diff --git a/benchmarks/eval/claude-cli-backend.mjs b/benchmarks/eval/claude-cli-backend.mjs new file mode 100644 index 00000000..8636dcf9 --- /dev/null +++ b/benchmarks/eval/claude-cli-backend.mjs @@ -0,0 +1,126 @@ +import { spawn } from 'node:child_process'; +import { mkdirSync } from 'node:fs'; + +// 空目录作为 CLI 工作目录:阻断 Claude Code 对宿主仓库 CLAUDE.md/项目上下文的注入 +const CLI_CWD = '/tmp/frontagent-eval/claude-cli-cwd'; +mkdirSync(CLI_CWD, { recursive: true }); + +const MODEL = process.env.EVAL_MODEL ?? 'claude-haiku-4-5'; +const CALL_TIMEOUT_MS = Number(process.env.EVAL_LLM_TIMEOUT_MS ?? 180000); + +const tally = { calls: 0, failures: 0, inputTokens: 0, outputTokens: 0 }; +export function getUsageTally() { + return { ...tally }; +} + +function recordFailure(error) { + tally.failures += 1; + console.error(`[claude-cli-backend] call failed (#${tally.failures}): ${String(error?.message ?? error).slice(0, 200)}`); +} + +function renderPrompt(messages, system) { + const parts = []; + if (system) parts.push(`[System]\n${system}`); + for (const m of messages ?? []) { + parts.push(`[${m.role}]\n${typeof m.content === 'string' ? m.content : JSON.stringify(m.content)}`); + } + return parts.join('\n\n'); +} + +function callClaude(prompt) { + return new Promise((resolvePromise, reject) => { + // 纯文本生成后端:禁用全部工具,否则「列目录」类 prompt 会诱发 tool_use + // 并在 --max-turns 1 下报 error_max_turns + const args = [ + '-p', + '--model', + MODEL, + '--output-format', + 'json', + '--max-turns', + '1', + '--disallowedTools', + '*', + '--system-prompt', + '你是一次性文本生成后端:只依据提示词中给出的信息直接作答,没有任何工具可用,不要尝试读取文件或执行命令。', + ]; + const child = spawn('claude', args, { stdio: ['pipe', 'pipe', 'pipe'], cwd: CLI_CWD }); + let stdout = ''; + let stderr = ''; + const timer = setTimeout(() => { + child.kill('SIGKILL'); + const err = new Error('claude CLI timeout'); + recordFailure(err); + reject(err); + }, CALL_TIMEOUT_MS); + child.stdout.on('data', (d) => { + stdout += d; + }); + child.stderr.on('data', (d) => { + stderr += d; + }); + child.on('error', (e) => { + clearTimeout(timer); + recordFailure(e); + reject(e); + }); + child.on('close', (code) => { + clearTimeout(timer); + if (code !== 0) { + const err = new Error( + `claude exit ${code}: stderr=${stderr.slice(0, 300)} stdoutHead=${stdout.slice(0, 200)} promptChars=${prompt.length}`, + ); + recordFailure(err); + return reject(err); + } + try { + const parsed = JSON.parse(stdout); + tally.calls += 1; + tally.inputTokens += parsed.usage?.input_tokens ?? 0; + tally.outputTokens += parsed.usage?.output_tokens ?? 0; + if (parsed.is_error) { + const err = new Error(`claude error result: ${String(parsed.result).slice(0, 300)}`); + recordFailure(err); + return reject(err); + } + resolvePromise(String(parsed.result ?? '')); + } catch (e) { + const err = new Error(`bad CLI JSON: ${String(e)}; head=${stdout.slice(0, 200)}`); + recordFailure(err); + reject(err); + } + }); + child.stdin.end(prompt); + }); +} + +function extractJson(text) { + const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/); + const body = fenced ? fenced[1] : text; + const start = body.indexOf('{'); + const end = body.lastIndexOf('}'); + if (start === -1 || end <= start) throw new Error('no JSON object in output'); + return body.slice(start, end + 1); +} + +export function createClaudeCliBackend() { + return { + name: `claude-cli:${MODEL}`, + async generateText({ messages, system }) { + return callClaude(renderPrompt(messages, system)); + }, + async generateObject({ messages, system, schema, maxRetries = 2 }) { + let lastError = ''; + for (let attempt = 0; attempt <= maxRetries; attempt += 1) { + const suffix = `\n\n只输出一个 JSON 对象:不要 markdown 代码围栏、不要解释文字。${lastError ? `上次输出未通过 schema 校验(${lastError}),请修正。` : ''}`; + const text = await callClaude(renderPrompt(messages, system) + suffix); + try { + return schema.parse(JSON.parse(extractJson(text))); + } catch (error) { + lastError = String(error).slice(0, 400); + } + } + throw new Error(`generateObject retries exhausted: ${lastError}`); + }, + }; +} diff --git a/benchmarks/eval/fixture/.gitignore b/benchmarks/eval/fixture/.gitignore new file mode 100644 index 00000000..c2658d7d --- /dev/null +++ b/benchmarks/eval/fixture/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/benchmarks/eval/fixture/README.md b/benchmarks/eval/fixture/README.md new file mode 100644 index 00000000..b80fccc9 --- /dev/null +++ b/benchmarks/eval/fixture/README.md @@ -0,0 +1,10 @@ +# Eval Fixture + +架构消融评测的冻结夹具:一个最小 React + TypeScript 工程。 + +- `src/components/` —— UI 组件(PascalCase 命名导出) +- `src/hooks/` —— 自定义 hooks(`use*` 前缀) +- `src/utils/` —— 纯函数工具与对应测试 +- `npm run typecheck` / `npm run test` 为验收门禁 + +组件与函数的具体接口以源码为准,本 README 不重复文档。 diff --git a/benchmarks/eval/fixture/package.json b/benchmarks/eval/fixture/package.json new file mode 100644 index 00000000..ebde8ad1 --- /dev/null +++ b/benchmarks/eval/fixture/package.json @@ -0,0 +1,13 @@ +{ + "name": "eval-fixture", + "private": true, + "type": "module", + "scripts": { "typecheck": "tsc --noEmit", "test": "vitest run" }, + "devDependencies": { + "@types/react": "^18.3.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", + "typescript": "^5.6.0", + "vitest": "^2.0.0" + } +} diff --git a/benchmarks/eval/fixture/pnpm-lock.yaml b/benchmarks/eval/fixture/pnpm-lock.yaml new file mode 100644 index 00000000..d756818b --- /dev/null +++ b/benchmarks/eval/fixture/pnpm-lock.yaml @@ -0,0 +1,950 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/react': + specifier: ^18.3.0 + version: 18.3.31 + react: + specifier: ^18.3.0 + version: 18.3.1 + react-dom: + specifier: ^18.3.0 + version: 18.3.1(react@18.3.1) + typescript: + specifier: ^5.6.0 + version: 5.9.3 + vitest: + specifier: ^2.0.0 + version: 2.1.9 + +packages: + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@rollup/rollup-android-arm-eabi@4.62.2': + resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.62.2': + resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.62.2': + resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.62.2': + resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.62.2': + resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.62.2': + resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.62.2': + resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.62.2': + resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.62.2': + resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.62.2': + resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.62.2': + resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.62.2': + resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.62.2': + resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.62.2': + resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.62.2': + resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.62.2': + resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.62.2': + resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.62.2': + resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.62.2': + resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.62.2': + resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.62.2': + resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==} + cpu: [x64] + os: [win32] + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react@18.3.31': + resolution: {integrity: sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==} + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.15: + resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + postcss@8.5.16: + resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} + engines: {node: ^10 || ^12 || >=14} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + rollup@4.62.2: + resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + +snapshots: + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@rollup/rollup-android-arm-eabi@4.62.2': + optional: true + + '@rollup/rollup-android-arm64@4.62.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.62.2': + optional: true + + '@rollup/rollup-darwin-x64@4.62.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.62.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.62.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.62.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.62.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.62.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.62.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.62.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.62.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.62.2': + optional: true + + '@types/estree@1.0.9': {} + + '@types/prop-types@15.7.15': {} + + '@types/react@18.3.31': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(vite@5.4.21)': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21 + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.21 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + + assertion-error@2.0.1: {} + + cac@6.7.14: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + check-error@2.1.3: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + es-module-lexer@1.7.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + expect-type@1.4.0: {} + + fsevents@2.3.3: + optional: true + + js-tokens@4.0.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.2.1: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + ms@2.1.3: {} + + nanoid@3.3.15: {} + + pathe@1.1.2: {} + + pathval@2.0.1: {} + + picocolors@1.1.1: {} + + postcss@8.5.16: + dependencies: + nanoid: 3.3.15 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + rollup@4.62.2: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.62.2 + '@rollup/rollup-android-arm64': 4.62.2 + '@rollup/rollup-darwin-arm64': 4.62.2 + '@rollup/rollup-darwin-x64': 4.62.2 + '@rollup/rollup-freebsd-arm64': 4.62.2 + '@rollup/rollup-freebsd-x64': 4.62.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.2 + '@rollup/rollup-linux-arm-musleabihf': 4.62.2 + '@rollup/rollup-linux-arm64-gnu': 4.62.2 + '@rollup/rollup-linux-arm64-musl': 4.62.2 + '@rollup/rollup-linux-loong64-gnu': 4.62.2 + '@rollup/rollup-linux-loong64-musl': 4.62.2 + '@rollup/rollup-linux-ppc64-gnu': 4.62.2 + '@rollup/rollup-linux-ppc64-musl': 4.62.2 + '@rollup/rollup-linux-riscv64-gnu': 4.62.2 + '@rollup/rollup-linux-riscv64-musl': 4.62.2 + '@rollup/rollup-linux-s390x-gnu': 4.62.2 + '@rollup/rollup-linux-x64-gnu': 4.62.2 + '@rollup/rollup-linux-x64-musl': 4.62.2 + '@rollup/rollup-openbsd-x64': 4.62.2 + '@rollup/rollup-openharmony-arm64': 4.62.2 + '@rollup/rollup-win32-arm64-msvc': 4.62.2 + '@rollup/rollup-win32-ia32-msvc': 4.62.2 + '@rollup/rollup-win32-x64-gnu': 4.62.2 + '@rollup/rollup-win32-x64-msvc': 4.62.2 + fsevents: 2.3.3 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinypool@1.1.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + typescript@5.9.3: {} + + vite-node@2.1.9: + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.21 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.21: + dependencies: + esbuild: 0.21.5 + postcss: 8.5.16 + rollup: 4.62.2 + optionalDependencies: + fsevents: 2.3.3 + + vitest@2.1.9: + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.21) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.4.0 + magic-string: 0.30.21 + pathe: 1.1.2 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 1.2.0 + vite: 5.4.21 + vite-node: 2.1.9 + why-is-node-running: 2.3.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 diff --git a/benchmarks/eval/fixture/sdd.yaml b/benchmarks/eval/fixture/sdd.yaml new file mode 100644 index 00000000..9e8f5b44 --- /dev/null +++ b/benchmarks/eval/fixture/sdd.yaml @@ -0,0 +1,65 @@ +# FrontAgent SDD 配置文件(评测夹具冻结版) +# 规格驱动开发 - Agent 行为约束 + +version: "1.0" + +project: + name: "eval-fixture" + type: "react-spa" + description: "架构消融评测的冻结夹具工程" + +# 技术栈约束 +tech_stack: + framework: "react" + version: "^18.0.0" + language: "typescript" + styling: "css" + state_management: "none" + forbidden_packages: + - "jquery" + - "moment" + +# 目录结构约束 +directory_structure: + src/components: + pattern: "PascalCase" + max_lines: 300 + src/hooks: + pattern: "use*.ts" + src/utils: + pattern: "camelCase" + must_be_pure: true + +# 模块边界约束 +module_boundaries: + - from: "src/components/*" + can_import: + - "src/hooks/*" + - "src/utils/*" + cannot_import: + - "src/api/*" + +# 命名规范 +naming_conventions: + components: "PascalCase" + hooks: "camelCase with 'use' prefix" + utils: "camelCase" + constants: "SCREAMING_SNAKE_CASE" + +# 代码质量约束 +code_quality: + max_function_lines: 50 + max_file_lines: 300 + max_parameters: 4 + forbidden_patterns: + - "any" + - "// @ts-ignore" + - "console.log" + +# 修改安全边界 +modification_rules: + protected_files: + - "package.json" + - "tsconfig.json" + protected_directories: + - "node_modules" diff --git a/benchmarks/eval/fixture/src/App.tsx b/benchmarks/eval/fixture/src/App.tsx new file mode 100644 index 00000000..955fb8ad --- /dev/null +++ b/benchmarks/eval/fixture/src/App.tsx @@ -0,0 +1,12 @@ +import { Button } from "./components/Button"; +import { TodoList } from "./components/TodoList"; + +export default function App() { + return ( +
+

Eval Fixture

+
+ ); +} diff --git a/benchmarks/eval/fixture/src/components/Button.tsx b/benchmarks/eval/fixture/src/components/Button.tsx new file mode 100644 index 00000000..ccfd627e --- /dev/null +++ b/benchmarks/eval/fixture/src/components/Button.tsx @@ -0,0 +1,12 @@ +interface ButtonProps { + label: string; + onClick: () => void; +} + +export function Button({ label, onClick }: ButtonProps) { + return ( + + ); +} diff --git a/benchmarks/eval/fixture/src/components/TodoList.tsx b/benchmarks/eval/fixture/src/components/TodoList.tsx new file mode 100644 index 00000000..413bffbf --- /dev/null +++ b/benchmarks/eval/fixture/src/components/TodoList.tsx @@ -0,0 +1,13 @@ +interface TodoListProps { + items: string[]; +} + +export function TodoList({ items }: TodoListProps) { + return ( + + ); +} diff --git a/benchmarks/eval/fixture/src/hooks/useToggle.ts b/benchmarks/eval/fixture/src/hooks/useToggle.ts new file mode 100644 index 00000000..69996e59 --- /dev/null +++ b/benchmarks/eval/fixture/src/hooks/useToggle.ts @@ -0,0 +1,7 @@ +import { useState } from "react"; + +export function useToggle(initial = false): [boolean, () => void] { + const [on, setOn] = useState(initial); + const toggle = () => setOn((v) => !v); + return [on, toggle]; +} diff --git a/benchmarks/eval/fixture/src/utils/clamp.test.ts b/benchmarks/eval/fixture/src/utils/clamp.test.ts new file mode 100644 index 00000000..6de3d222 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/clamp.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from "vitest"; +import { clamp } from "./clamp"; + +describe("clamp", () => { + it("小于下界取下界", () => { + expect(clamp(-1, 0, 10)).toBe(0); + }); + it("大于上界取上界", () => { + expect(clamp(11, 0, 10)).toBe(10); + }); + it("区间内原样返回", () => { + expect(clamp(5, 0, 10)).toBe(5); + }); +}); diff --git a/benchmarks/eval/fixture/src/utils/clamp.ts b/benchmarks/eval/fixture/src/utils/clamp.ts new file mode 100644 index 00000000..2e041e39 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/clamp.ts @@ -0,0 +1,5 @@ +export function clamp(value: number, min: number, max: number): number { + if (value < min) return min; + if (value > max) return min; + return value; +} diff --git a/benchmarks/eval/fixture/src/utils/formatDate.test.ts b/benchmarks/eval/fixture/src/utils/formatDate.test.ts new file mode 100644 index 00000000..d75a99cd --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/formatDate.test.ts @@ -0,0 +1,8 @@ +import { describe, expect, it } from "vitest"; +import { formatDate } from "./formatDate"; + +describe("formatDate", () => { + it("格式化为 YYYY-MM-DD", () => { + expect(formatDate(new Date(2026, 6, 11))).toBe("2026-07-11"); + }); +}); diff --git a/benchmarks/eval/fixture/src/utils/formatDate.ts b/benchmarks/eval/fixture/src/utils/formatDate.ts new file mode 100644 index 00000000..0c5aeae1 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/formatDate.ts @@ -0,0 +1,6 @@ +export function formatDate(d: Date): string { + const y = d.getFullYear(); + const m = String(d.getMonth()).padStart(2, "0"); + const day = String(d.getDate()).padStart(2, "0"); + return `${y}-${m}-${day}`; +} diff --git a/benchmarks/eval/fixture/src/utils/parseQuery.test.ts b/benchmarks/eval/fixture/src/utils/parseQuery.test.ts new file mode 100644 index 00000000..20327945 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/parseQuery.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from "vitest"; +import { parseQuery } from "./parseQuery"; + +describe("parseQuery", () => { + it("解析问号前缀查询串", () => { + expect(parseQuery("?a=1&b=2")).toEqual({ a: "1", b: "2" }); + }); + it("URL 编码的值要解码", () => { + expect(parseQuery("q=hello%20world")).toEqual({ q: "hello world" }); + }); + it("空串返回空对象", () => { + expect(parseQuery("")).toEqual({}); + }); +}); diff --git a/benchmarks/eval/fixture/src/utils/parseQuery.ts b/benchmarks/eval/fixture/src/utils/parseQuery.ts new file mode 100644 index 00000000..56c25ef1 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/parseQuery.ts @@ -0,0 +1,10 @@ +export function parseQuery(query: string): Record { + const result: Record = {}; + const trimmed = query.startsWith("?") ? query.slice(1) : query; + if (!trimmed) return result; + for (const pair of trimmed.split("&")) { + const [key, value] = pair.split("="); + if (key) result[key] = value ?? ""; + } + return result; +} diff --git a/benchmarks/eval/fixture/src/utils/pluralize.test.ts b/benchmarks/eval/fixture/src/utils/pluralize.test.ts new file mode 100644 index 00000000..3615c7d6 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/pluralize.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from "vitest"; +import { pluralize } from "./pluralize"; + +describe("pluralize", () => { + it("单数不加 s", () => { + expect(pluralize("item", 1)).toBe("1 item"); + }); + it("复数加 s", () => { + expect(pluralize("item", 2)).toBe("2 items"); + }); +}); diff --git a/benchmarks/eval/fixture/src/utils/pluralize.ts b/benchmarks/eval/fixture/src/utils/pluralize.ts new file mode 100644 index 00000000..9a508037 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/pluralize.ts @@ -0,0 +1,3 @@ +export function pluralize(word: string, count: number): string { + return `${count} ${word}s`; +} diff --git a/benchmarks/eval/fixture/src/utils/truncate.test.ts b/benchmarks/eval/fixture/src/utils/truncate.test.ts new file mode 100644 index 00000000..d7899466 --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/truncate.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from "vitest"; +import { truncate } from "./truncate"; + +describe("truncate", () => { + it("不超长原样返回", () => { + expect(truncate("abc", 5)).toBe("abc"); + }); + it("超长截到 maxLength 并加省略号", () => { + expect(truncate("abcdefg", 3)).toBe("abc…"); + }); +}); diff --git a/benchmarks/eval/fixture/src/utils/truncate.ts b/benchmarks/eval/fixture/src/utils/truncate.ts new file mode 100644 index 00000000..fd40a93c --- /dev/null +++ b/benchmarks/eval/fixture/src/utils/truncate.ts @@ -0,0 +1,4 @@ +export function truncate(text: string, maxLength: number): string { + if (text.length <= maxLength) return text; + return `${text.slice(0, maxLength + 1)}…`; +} diff --git a/benchmarks/eval/fixture/tsconfig.json b/benchmarks/eval/fixture/tsconfig.json new file mode 100644 index 00000000..9714625a --- /dev/null +++ b/benchmarks/eval/fixture/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "noEmit": true + }, + "include": ["src"] +} diff --git a/benchmarks/eval/out-smoke/ablation.jsonl b/benchmarks/eval/out-smoke/ablation.jsonl new file mode 100644 index 00000000..d1f42090 --- /dev/null +++ b/benchmarks/eval/out-smoke/ablation.jsonl @@ -0,0 +1,5 @@ +{"taskId":"query-button-props","category":"query","arm":"ablation","pass":false,"agentSuccess":true,"validationCount":1,"runError":null,"checks":[{"kind":"result_contains","ok":false,"detail":"label"},{"kind":"result_contains","ok":true,"detail":"onClick"}],"events":{"task_started":1,"status_update":15,"security_decision":4,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":150729,"llmCalls":1,"llmFailures":0,"inputTokens":10,"outputTokens":952} +{"taskId":"create-usedebounce","category":"create","arm":"ablation","pass":false,"agentSuccess":false,"validationCount":3,"runError":null,"checks":[{"kind":"file_exists","ok":false,"detail":"src/hooks/useDebounce.ts"},{"kind":"file_contains","ok":false,"detail":"missing src/hooks/useDebounce.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":5,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":2,"phase_completed":2,"step_failed":1,"task_completed":1},"elapsedMs":465285,"llmCalls":12,"llmFailures":1,"inputTokens":120,"outputTokens":29639} +{"taskId":"create-checkbox","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"validationCount":3,"runError":null,"checks":[{"kind":"file_exists","ok":true,"detail":"src/components/Checkbox.tsx"},{"kind":"file_contains","ok":true,"detail":"onChange"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":7,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":323016,"llmCalls":7,"llmFailures":0,"inputTokens":70,"outputTokens":18788} +{"taskId":"bugfix-formatdate","category":"bugfix","arm":"ablation","pass":true,"agentSuccess":true,"validationCount":2,"runError":null,"checks":[{"kind":"cmd","ok":true,"detail":"npx vitest run src/utils/formatDate.test.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":8,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":253827,"llmCalls":7,"llmFailures":0,"inputTokens":70,"outputTokens":11270} +{"taskId":"refactor-todolist-empty","category":"refactor","arm":"ablation","pass":false,"agentSuccess":true,"validationCount":2,"runError":null,"checks":[{"kind":"file_contains","ok":false,"detail":"暂无待办"},{"kind":"typecheck","ok":false,"detail":"src/components/TodoList.tsx(1,1): error TS1434: Unexpected keyword or identifier.\nsrc/components/TodoList.tsx(1,16): error TS1005: ';' expected.\nsrc/components/TodoList.tsx(1,31): error TS1127: Invalid character.\nsrc/components/TodoList.tsx(1,42): error TS1127: Invalid character.\nsrc/components/Todo"}],"events":{"task_started":1,"status_update":21,"security_decision":8,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":322254,"llmCalls":7,"llmFailures":0,"inputTokens":70,"outputTokens":16738} diff --git a/benchmarks/eval/out-smoke/full.jsonl b/benchmarks/eval/out-smoke/full.jsonl new file mode 100644 index 00000000..a79e2c65 --- /dev/null +++ b/benchmarks/eval/out-smoke/full.jsonl @@ -0,0 +1,5 @@ +{"taskId":"query-button-props","category":"query","arm":"full","pass":false,"agentSuccess":true,"validationCount":1,"runError":null,"checks":[{"kind":"result_contains","ok":false,"detail":"label"},{"kind":"result_contains","ok":false,"detail":"onClick"}],"events":{"task_started":1,"status_update":15,"security_decision":4,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":140240,"llmCalls":1,"llmFailures":0,"inputTokens":10,"outputTokens":577} +{"taskId":"create-usedebounce","category":"create","arm":"full","pass":false,"agentSuccess":false,"validationCount":3,"runError":null,"checks":[{"kind":"file_exists","ok":false,"detail":"src/hooks/useDebounce.ts"},{"kind":"file_contains","ok":false,"detail":"missing src/hooks/useDebounce.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":5,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":2,"phase_completed":2,"step_failed":1,"task_completed":1},"elapsedMs":393303,"llmCalls":9,"llmFailures":1,"inputTokens":90,"outputTokens":23821} +{"taskId":"create-checkbox","category":"create","arm":"full","pass":false,"agentSuccess":false,"validationCount":3,"runError":null,"checks":[{"kind":"file_exists","ok":false,"detail":"src/components/Checkbox.tsx"},{"kind":"file_contains","ok":false,"detail":"missing src/components/Checkbox.tsx"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":5,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":2,"phase_completed":2,"step_failed":1,"task_completed":1},"elapsedMs":478316,"llmCalls":12,"llmFailures":1,"inputTokens":120,"outputTokens":33917} +{"taskId":"bugfix-formatdate","category":"bugfix","arm":"full","pass":true,"agentSuccess":true,"validationCount":2,"runError":null,"checks":[{"kind":"cmd","ok":true,"detail":"npx vitest run src/utils/formatDate.test.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":8,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":256759,"llmCalls":7,"llmFailures":0,"inputTokens":70,"outputTokens":10789} +{"taskId":"refactor-todolist-empty","category":"refactor","arm":"full","pass":false,"agentSuccess":true,"validationCount":2,"runError":null,"checks":[{"kind":"file_contains","ok":false,"detail":"暂无待办"},{"kind":"typecheck","ok":false,"detail":"src/components/TodoList.tsx(1,13): error TS1127: Invalid character.\nsrc/components/TodoList.tsx(1,14): error TS1434: Unexpected keyword or identifier.\nsrc/components/TodoList.tsx(1,57): error TS1127: Invalid character.\nsrc/components/TodoList.tsx(1,69): error TS1127: Invalid character.\nsrc/component"}],"events":{"task_started":1,"status_update":21,"security_decision":8,"rag_retrieved":1,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":275785,"llmCalls":7,"llmFailures":0,"inputTokens":70,"outputTokens":13672} diff --git a/benchmarks/eval/out/ablation.jsonl b/benchmarks/eval/out/ablation.jsonl new file mode 100644 index 00000000..b69addb7 --- /dev/null +++ b/benchmarks/eval/out/ablation.jsonl @@ -0,0 +1,27 @@ +{"taskId":"query-button-props","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# Button 组件 Props 说明\n\n根据当前工作区文件 `src/components/Button.tsx`,Button 组件接受以下 props:\n\n| Prop | 类型 | 用途 |\n|------|------|------|\n| **label** | `string` | 按钮显示的文本内容 |\n| **onClick** | `() => void` | 按钮点击时的回调","checks":[{"kind":"result_contains","ok":true,"detail":"label"},{"kind":"result_contains","ok":true,"detail":"onClick"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":7483,"llmCalls":1,"llmFailures":0,"inputTokens":991,"outputTokens":440} +{"taskId":"query-structure","category":"query","arm":"ablation","pass":false,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"我无法直接列出 src 下的目录结构及其职责。\n\n**原因是**:提供的证据中没有包含关于 src 目录结构的信息。既没有知识库条目描述项目结构,也没有当前工作区文件的内容。\n\n**建议**:\n- 如果你需要我分析项目结构,需要先提供 src 目录的实际内容或文件清单\n- 或者提供项目的架构文档、README 等说明性文件作为参考\n\n我是 FrontAgent,具备分析和解释前端项目结构的能力,一","checks":[{"kind":"result_contains","ok":false,"detail":"components"},{"kind":"result_contains","ok":false,"detail":"hooks"},{"kind":"result_contains","ok":false,"detail":"utils"}],"events":{"task_started":1,"status_update":16,"security_decision":4,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":2,"step_completed":2,"phase_completed":2,"filesense_navigated":1,"task_completed":1},"elapsedMs":7870,"llmCalls":1,"llmFailures":0,"inputTokens":907,"outputTokens":506} +{"taskId":"query-todolist-render","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"## 答案\n\nTodoList 组件使用 **`.map()` 遍历列表项数组**,并将每个项渲染为 `
  • ` 元素;**列表项的 key 使用的是 `item` 本身(字符串值)**。\n\n## 说明\n\n根据当前工作区文件 `src/components/TodoList.tsx` 的实现:\n\n```tsx\n{items.map((item) => (\n
  • {it","checks":[{"kind":"result_contains","ok":true,"detail":"key"},{"kind":"result_contains","ok":true,"detail":"item"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":8904,"llmCalls":1,"llmFailures":0,"inputTokens":1005,"outputTokens":625} +{"taskId":"query-usetoggle-behavior","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# useToggle Hook 返回值和状态切换说明\n\n## 返回值\n\n根据当前工作区文件 `src/hooks/useToggle.ts`,**useToggle 返回一个元组 `[boolean, () => void]`**:\n\n1. **第一项**:当前的布尔状态值(on/off)\n2. **第二项**:触发切换的函数\n\n```typescript\n[on, toggle]\n```\n\n#","checks":[{"kind":"result_contains","ok":true,"detail":"toggle"},{"kind":"result_contains","ok":true,"detail":"useState"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":8740,"llmCalls":1,"llmFailures":0,"inputTokens":994,"outputTokens":629} +{"taskId":"query-app-components","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# 回答\n\n根据当前工作区文件 `src/App.tsx`,**App 组件直接使用了 2 个子组件**:\n\n1. **Button** —— 来自 `./components/Button`,在 JSX 中调用时传入了 `label` 和 `onClick` 属性\n2. **TodoList** —— 来自 `./components/TodoList`,在 JSX 中调用时传入了 `items","checks":[{"kind":"result_contains","ok":true,"detail":"Button"},{"kind":"result_contains","ok":true,"detail":"TodoList"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":8061,"llmCalls":1,"llmFailures":0,"inputTokens":1009,"outputTokens":493} +{"taskId":"query-formatdate-io","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# 答案\n\n根据当前工作区文件 `src/utils/formatDate.ts` 的定义:\n\n**输入类型**:`Date` 对象\n\n**输出类型和格式**:`string` 类型,格式为 `YYYY-MM-DD`(例如 `2026-07-12`)\n\n## 原理说明\n\n该函数接收一个 JavaScript 的 `Date` 对象,通过以下步骤生成格式化字符串:\n- 提取年份(`getFullYe","checks":[{"kind":"result_contains","ok":true,"detail":"Date"},{"kind":"result_contains","ok":true,"detail":"string|字符串"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":9440,"llmCalls":1,"llmFailures":0,"inputTokens":1004,"outputTokens":681} +{"taskId":"query-tsconfig-strict","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# 答案\n\n**strict 已开启**。\n\n根据当前工作区文件 `tsconfig.json`,该项目开启了以下编译选项:\n\n| 选项 | 值 |\n|------|------|\n| `target` | ES2022 |\n| `module` | ESNext |\n| `moduleResolution` | bundler |\n| `jsx` | react-jsx |\n| **`stric","checks":[{"kind":"result_contains","ok":true,"detail":"strict"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":8116,"llmCalls":1,"llmFailures":0,"inputTokens":1013,"outputTokens":519} +{"taskId":"query-clamp-purpose","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# clamp 函数说明\n\n**结论:** `clamp` 函数用于将一个数值限制在指定的最小值和最大值范围内。\n\n## 三个参数含义\n\n根据当前工作区文件 `src/utils/clamp.ts` 的实现:\n\n| 参数 | 类型 | 含义 |\n|------|------|------|\n| `value` | number | 要被限制的原始值 |\n| `min` | number | 允许的","checks":[{"kind":"result_contains","ok":true,"detail":"min"},{"kind":"result_contains","ok":true,"detail":"max"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":10896,"llmCalls":1,"llmFailures":0,"inputTokens":975,"outputTokens":791} +{"taskId":"query-test-files","category":"query","arm":"ablation","pass":false,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"我无法直接回答这个问题。\n\n**原因**:当前的可用证据中,除了我的智能体身份定义外,**没有提供任何关于项目测试文件的知识库条目或当前工作区文件信息**。\n\n要回答\"项目里有哪些测试文件?分别测试什么?\"这样的问题,我需要:\n- 当前工作区的实际文件访问权限(特别是 `test/`、`__tests__/`、`.spec.js` 等测试文件)\n- 或相关的项目文档/知识库条目\n\n**建议**:\n","checks":[{"kind":"result_contains","ok":false,"detail":"formatDate"},{"kind":"result_contains","ok":false,"detail":"clamp"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":9798,"llmCalls":1,"llmFailures":0,"inputTokens":904,"outputTokens":588} +{"taskId":"query-button-export","category":"query","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"## 结论\n\n- **Button 组件**是**命名导出**\n- **App 组件**是**默认导出**\n\n## 证据\n\n来自当前工作区文件:\n\n1. **Button.tsx** 使用 `export function Button`:\n ```typescript\n export function Button({ label, onClick }: ButtonProps) { .","checks":[{"kind":"result_contains","ok":true,"detail":"命名|named"},{"kind":"result_contains","ok":true,"detail":"默认|default"}],"events":{"task_started":1,"status_update":15,"security_decision":4,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":8161,"llmCalls":1,"llmFailures":0,"inputTokens":1089,"outputTokens":504} +{"taskId":"create-usedebounce","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/hooks/useDebounce.ts 是否已存在\n✅ 创建文件 src/hooks/useDebounce.ts","checks":[{"kind":"file_exists","ok":true,"detail":"src/hooks/useDebounce.ts"},{"kind":"file_contains","ok":true,"detail":"export function useDebounce"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":322182,"llmCalls":9,"llmFailures":0,"inputTokens":18548,"outputTokens":37610} +{"taskId":"create-card","category":"create","arm":"ablation","pass":false,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/components/Card.tsx 是否已存在\n✅ 创建文件 src/components/Card.tsx","checks":[{"kind":"file_exists","ok":true,"detail":"src/components/Card.tsx"},{"kind":"file_contains","ok":false,"detail":"export function Card"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":374622,"llmCalls":9,"llmFailures":0,"inputTokens":18285,"outputTokens":40257} +{"taskId":"create-capitalize","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/utils/capitalize.ts 是否已存在\n✅ 创建文件 src/utils/capitalize.ts","checks":[{"kind":"file_exists","ok":true,"detail":"src/utils/capitalize.ts"},{"kind":"file_contains","ok":true,"detail":"export function capitalize"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":313715,"llmCalls":8,"llmFailures":0,"inputTokens":15648,"outputTokens":33029} +{"taskId":"create-uselocalstorage","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/hooks/useLocalStorage.ts 是否已存在\n✅ 创建文件 src/hooks/useLocalStorage.ts","checks":[{"kind":"file_exists","ok":true,"detail":"src/hooks/useLocalStorage.ts"},{"kind":"file_contains","ok":true,"detail":"export function useLocalStorage"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":349031,"llmCalls":9,"llmFailures":0,"inputTokens":18493,"outputTokens":37339} +{"taskId":"create-badge","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/components/Badge.tsx 是否已存在\n✅ 创建文件 src/components/Badge.tsx","checks":[{"kind":"file_exists","ok":true,"detail":"src/components/Badge.tsx"},{"kind":"file_contains","ok":true,"detail":"variant"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":301683,"llmCalls":4,"llmFailures":2,"inputTokens":7855,"outputTokens":14848} +{"taskId":"create-formatcurrency","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/utils/formatCurrency.ts 是否已存在\n✅ 创建文件 src/utils/formatCurrency.ts","checks":[{"kind":"file_exists","ok":true,"detail":"src/utils/formatCurrency.ts"},{"kind":"file_contains","ok":true,"detail":"export function formatCurrency"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":435109,"llmCalls":9,"llmFailures":0,"inputTokens":18113,"outputTokens":48064} +{"taskId":"create-spinner","category":"create","arm":"ablation","pass":false,"agentSuccess":false,"agentError":"Syntax errors found in src/components/Spinner.tsx","validationCount":3,"runError":null,"resultHead":"","checks":[{"kind":"file_exists","ok":true,"detail":"src/components/Spinner.tsx"},{"kind":"file_contains","ok":false,"detail":"export function Spinner"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":5,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":2,"phase_completed":2,"step_failed":1,"task_completed":1},"elapsedMs":630159,"llmCalls":12,"llmFailures":0,"inputTokens":23991,"outputTokens":61670} +{"taskId":"create-useinterval","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/hooks/useInterval.ts 是否已存在\n✅ 创建文件 src/hooks/useInterval.ts","checks":[{"kind":"file_exists","ok":true,"detail":"src/hooks/useInterval.ts"},{"kind":"file_contains","ok":true,"detail":"useEffect"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":457924,"llmCalls":9,"llmFailures":0,"inputTokens":18206,"outputTokens":40463} +{"taskId":"create-slugify","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/utils/slugify.ts 是否已存在\n✅ 创建文件 src/utils/slugify.ts","checks":[{"kind":"file_exists","ok":true,"detail":"src/utils/slugify.ts"},{"kind":"file_contains","ok":true,"detail":"export function slugify"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":314668,"llmCalls":8,"llmFailures":0,"inputTokens":15472,"outputTokens":30378} +{"taskId":"create-checkbox","category":"create","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":3,"runError":null,"resultHead":"执行完成 (3/3 步骤成功)\n\n✅ 按需构建目录导航上下文:create task benefits from nearby placement conventions\n✅ 检查目标路径 src/components/Checkbox.tsx 是否已存在\n✅ 创建文件 src/components/Checkbox.tsx","checks":[{"kind":"file_exists","ok":true,"detail":"src/components/Checkbox.tsx"},{"kind":"file_contains","ok":true,"detail":"onChange"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":20,"security_decision":6,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":3,"filesense_navigated":1,"step_completed":3,"phase_completed":2,"task_completed":1},"elapsedMs":391073,"llmCalls":10,"llmFailures":0,"inputTokens":21029,"outputTokens":42355} +{"taskId":"bugfix-formatdate","category":"bugfix","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"执行完成 (2/2 步骤成功)\n\n✅ 分析文件结构 src/utils/formatDate.ts\n✅ 修改文件 src/utils/formatDate.ts","checks":[{"kind":"cmd","ok":true,"detail":"npx vitest run src/utils/formatDate.test.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":7,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":298582,"llmCalls":8,"llmFailures":0,"inputTokens":14576,"outputTokens":28712} +{"taskId":"bugfix-clamp","category":"bugfix","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"执行完成 (2/2 步骤成功)\n\n✅ 分析文件结构 src/utils/clamp.ts\n✅ 修改文件 src/utils/clamp.ts","checks":[{"kind":"cmd","ok":true,"detail":"npx vitest run src/utils/clamp.test.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":7,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":331327,"llmCalls":9,"llmFailures":0,"inputTokens":16884,"outputTokens":32491} +{"taskId":"bugfix-pluralize","category":"bugfix","arm":"ablation","pass":false,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"执行完成 (2/2 步骤成功)\n\n✅ 分析文件结构 src/utils/pluralize.ts\n✅ 修改文件 src/utils/pluralize.ts","checks":[{"kind":"cmd","ok":false,"detail":"npx vitest run src/utils/pluralize.test.ts"},{"kind":"typecheck","ok":false,"detail":"src/utils/pluralize.ts(1,13): error TS1127: Invalid character.\nsrc/utils/pluralize.ts(3,1): error TS1434: Unexpected keyword or identifier.\nsrc/utils/pluralize.ts(3,11): error TS1005: ';' expected.\nsrc/utils/pluralize.ts(3,44): error TS1127: Invalid character.\nsrc/utils/pluralize.ts(3,59): error TS1"}],"events":{"task_started":1,"status_update":21,"security_decision":7,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":298556,"llmCalls":9,"llmFailures":0,"inputTokens":16921,"outputTokens":28980} +{"taskId":"bugfix-truncate","category":"bugfix","arm":"ablation","pass":false,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"执行完成 (2/2 步骤成功)\n\n✅ 分析文件结构 src/utils/truncate.ts\n✅ 修改文件 src/utils/truncate.ts","checks":[{"kind":"cmd","ok":false,"detail":"npx vitest run src/utils/truncate.test.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":7,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":338711,"llmCalls":9,"llmFailures":0,"inputTokens":16723,"outputTokens":28584} +{"taskId":"bugfix-parsequery","category":"bugfix","arm":"ablation","pass":true,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"执行完成 (2/2 步骤成功)\n\n✅ 分析文件结构 src/utils/parseQuery.ts\n✅ 修改文件 src/utils/parseQuery.ts","checks":[{"kind":"cmd","ok":true,"detail":"npx vitest run src/utils/parseQuery.test.ts"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":21,"security_decision":7,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":394377,"llmCalls":8,"llmFailures":0,"inputTokens":14583,"outputTokens":40862} +{"taskId":"refactor-todolist-empty","category":"refactor","arm":"ablation","pass":false,"agentSuccess":false,"agentError":"claude CLI timeout","validationCount":2,"runError":null,"resultHead":"","checks":[{"kind":"file_contains","ok":false,"detail":"暂无待办"},{"kind":"typecheck","ok":true,"detail":""}],"events":{"task_started":1,"status_update":22,"security_decision":5,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":1,"step_failed":1,"phase_completed":1,"task_completed":1},"elapsedMs":919701,"llmCalls":9,"llmFailures":3,"inputTokens":16383,"outputTokens":28668} +{"taskId":"refactor-button-disabled","category":"refactor","arm":"ablation","pass":false,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"执行完成 (2/2 步骤成功)\n\n✅ 分析文件结构 src/components/Button.tsx\n✅ 修改文件 src/components/Button.tsx","checks":[{"kind":"file_contains","ok":true,"detail":"disabled"},{"kind":"typecheck","ok":false,"detail":"src/components/Button.tsx(1,3): error TS1127: Invalid character.\nsrc/components/Button.tsx(1,29): error TS1127: Invalid character.\nsrc/components/Button.tsx(1,30): error TS1127: Invalid character.\nsrc/components/Button.tsx(1,43): error TS1443: Module declaration names may only use ' or \" quoted stri"}],"events":{"task_started":1,"status_update":21,"security_decision":7,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":2,"step_completed":2,"phase_completed":1,"task_completed":1},"elapsedMs":376167,"llmCalls":4,"llmFailures":3,"inputTokens":7293,"outputTokens":7589} diff --git a/benchmarks/eval/out/full.jsonl b/benchmarks/eval/out/full.jsonl new file mode 100644 index 00000000..f1d25621 --- /dev/null +++ b/benchmarks/eval/out/full.jsonl @@ -0,0 +1,27 @@ +{"taskId":"query-button-props","category":"query","arm":"full","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# Button 组件 Props 说明\n\n根据当前工作区文件 `src/components/Button.tsx` 的定义,Button 组件接受以下 props:\n\n| Prop | 类型 | 用途 |\n|------|------|------|\n| **label** | `string` | 按钮显示的文本标签 |\n| **onClick** | `() => void` | 点击按钮","checks":[{"kind":"result_contains","ok":true,"detail":"label"},{"kind":"result_contains","ok":true,"detail":"onClick"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":24151,"llmCalls":1,"llmFailures":0,"inputTokens":991,"outputTokens":550} +{"taskId":"query-structure","category":"query","arm":"full","pass":false,"agentSuccess":true,"agentError":null,"validationCount":2,"runError":null,"resultHead":"我无法列出 src 目录的结构。\n\n**原因:** 提供的证据中不包含当前工作区的任何文件内容。我没有看到关于 src 目录的本地文件信息,也没有相关的知识库条目。\n\n**我需要:**\n1. 访问当前工作区的文件系统(查看 src 目录的实际结构)\n2. 或者你直接提供 src 目录的结构信息\n\n如果你希望我分析和说明 src 目录各子目录的职责,请:\n- 让我读取当前工作区中 src 目录下的文","checks":[{"kind":"result_contains","ok":false,"detail":"components"},{"kind":"result_contains","ok":false,"detail":"hooks"},{"kind":"result_contains","ok":false,"detail":"utils"}],"events":{"task_started":1,"status_update":16,"security_decision":4,"planning_started":1,"planning_completed":1,"phase_started":2,"step_started":2,"step_completed":2,"phase_completed":2,"filesense_navigated":1,"task_completed":1},"elapsedMs":10077,"llmCalls":1,"llmFailures":0,"inputTokens":907,"outputTokens":567} +{"taskId":"query-todolist-render","category":"query","arm":"full","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"## 答案\n\n根据当前工作区文件 `src/components/TodoList.tsx` 的代码:\n\n**渲染方式:** TodoList 组件使用 `.map()` 方法遍历 `items` 数组,将每个 item 渲染为一个 `
  • ` 元素。\n\n**Key 值:** 列表项的 `key` 使用的是 **item 本身**(即字符串值),具体代码为:\n```tsx\nitems.map((","checks":[{"kind":"result_contains","ok":true,"detail":"key"},{"kind":"result_contains","ok":true,"detail":"item"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":9793,"llmCalls":1,"llmFailures":0,"inputTokens":1005,"outputTokens":605} +{"taskId":"query-usetoggle-behavior","category":"query","arm":"full","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# useToggle hook 返回和状态切换说明\n\n## 返回值\n根据当前工作区文件 `src/hooks/useToggle.ts`,**useToggle 返回一个二元组 `[boolean, () => void]`**:\n- **第一个元素**:当前的布尔状态值(初始值由参数决定,默认 `false`)\n- **第二个元素**:一个无参函数,调用它可以切换状态\n\n## 内部状态切换原理","checks":[{"kind":"result_contains","ok":true,"detail":"toggle"},{"kind":"result_contains","ok":true,"detail":"useState"}],"events":{"task_started":1,"status_update":15,"security_decision":3,"planning_started":1,"planning_completed":1,"phase_started":1,"step_started":1,"step_completed":1,"phase_completed":1,"task_completed":1},"elapsedMs":7652,"llmCalls":1,"llmFailures":0,"inputTokens":994,"outputTokens":608} +{"taskId":"query-app-components","category":"query","arm":"full","pass":true,"agentSuccess":true,"agentError":null,"validationCount":1,"runError":null,"resultHead":"# 回答\n\nApp 组件直接使用了 **2 个子组件**:\n\n1. **Button** - 来自 `./components/Button`\n2. **TodoList** - 来自 `./components/TodoList`\n\n---\n\n## 依据\n\n根据当前工作区文件 `src/App.tsx`,App 组件在其 JSX 中直接实例化了这两个组件:\n- `