elanous 0.2.42 → 0.2.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
- package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3507.97e1977bc4d5fb0a.js → 1406.a1dc2ab6f8449374.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{53c73f84.373b6160adfa89a4.js → 1970cf59.2d4d8ce5d6c81853.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9211-330b6736a63d4cb3.js → 2073-ba274e00e4f9efb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7411.9b4b8b747dc7b802.js → 2144.25b292396712196d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2312.0c8b61e22d3136d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6632.0eac1c554f8f2ef3.js → 2573.387a707f6f9d720c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1262.e804feb8fd1acb8c.js → 3072.01338851ca21a6f7.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{2456.b6de0e1c05f28843.js → 3095.dc44586a5f83b86d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3207.a756c95e9ec8c3c8.js → 3113.d7472bbc27d580c7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3557ac4a.c8931684475018ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8505.fd803c6c33b54cc3.js → 360.ae9f9f4c33c395e8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.js → 363bfab3.9623b9f89363541f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
- package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
- package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{8138.6c10b2a356d52fca.js → 4199.ce86b281fd0a60b7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2690.0521c738b7749931.js → 4445.7990c76b3751a918.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1945.7b54990d578c119b.js → 4894.fec2ca9e99caefa2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
- package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
- package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 5564.9e72532188f57586.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.js → 5628.6ddb2d5ffba4ff4c.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/{1319.b9b815ae0f181e06.js → 5730.43d7ccc09988e646.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.js → 5789.2da35c258292e1e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1487.2f67b79444062da6.js → 5930.8b4df3b46c32b05a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
- package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
- package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3347.f846266b5e5f3ede.js → 6540.c7bef57ad8f90a87.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.js → 6944.309f4e3ea54d1537.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4770.769c9cd9c7034eba.js → 7483.427a2fe2049e388d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{1147-5196d19c222051b3.js → 7502-be74718178e13e56.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
- package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
- package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
- package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +41 -0
- package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9656-374232558fd528d0.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5440-4236de26c5ea5856.js → 8967-7dfebf710c9dec9d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1063.2fb8a9dc55c731f2.js → 8986.8e2e4efbfa655c59.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4320.583cbab64db6be02.js → 923.2034d10ae91e9c20.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1574.878c18ecc97b1bd4.js → 943.39ae5e82f4f1893f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
- package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
- package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
- package/apps/pwa/out/_next/static/chunks/aa57532f.510551854ff239b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-0f291d3c8fd55a3a.js → page-9ee28f7df07428ea.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
- package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{e8543907.5b040a5f22a0b0e5.js → d96660fb.cbc21a2a88539dbb.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{50061469.0326382241ef3b2d.js → ea514caa.05a24f78d9dffe5f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/fb7d20d5-6892502b6ee39ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
- package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/external-commands.yaml +5 -3
- package/catalog/meta/catalogVersion.yaml +2 -1
- package/catalog/signing/catalog-signing-public.pem +3 -0
- package/graphs/intake/intake-daily.yaml +16 -0
- package/graphs/intake/news-sources.yaml +1 -0
- package/graphs/intake/recipes.yaml +7 -0
- package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
- package/graphs/profiles/local.yaml +5 -0
- package/graphs/profiles/pod.yaml +4 -0
- package/package.json +6 -2
- package/plugins/demo-absorption-briefing/plugin.json +18 -0
- package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
- package/plugins/demo-browser-hand/plugin.json +13 -0
- package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
- package/plugins/demo-linear-secretary/plugin.json +15 -0
- package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
- package/plugins/demo-plugin-wizard/plugin.json +11 -0
- package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
- package/plugins/demo-research/plugin.json +16 -0
- package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
- package/plugins/demo-video-briefing/plugin.json +15 -0
- package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
- package/scripts/build-signed-catalog.ts +48 -0
- package/scripts/ci-typecheck-main-delta.sh +88 -0
- package/scripts/codex-fallback-live-probe.ts +1 -1
- package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
- package/scripts/demo/demo1104-stage.config.ts +21 -0
- package/scripts/demo/demo1104-stage.ts +316 -0
- package/scripts/goal-method-audit.ts +17 -1
- package/scripts/graph-units/land-enqueue.ts +90 -0
- package/scripts/hooks/codex-notify.sh +32 -0
- package/scripts/install.sh +10 -38
- package/scripts/landing-heal/land-plan.ts +57 -0
- package/scripts/release-loop/auto-approve-node.ts +1 -1
- package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
- package/scripts/release-loop/gate-method.ts +139 -0
- package/scripts/release-loop/gate-node.ts +180 -20
- package/scripts/release-loop/gate-traffic-mode.ts +151 -3
- package/scripts/release-loop/node-verdict.ts +38 -25
- package/scripts/release-loop/preflight.ts +362 -8
- package/scripts/release-loop/unattended-release.ts +20 -9
- package/scripts/rhythm/daily.ts +36 -4
- package/scripts/rhythm/linear-progress-sync.ts +298 -0
- package/scripts/video-pipeline.ts +9 -1
- package/scripts/warm-pool-provider-config.ts +29 -6
- package/src/acp/agent-manager.ts +1 -0
- package/src/acp/codex-app-server-agent.ts +33 -0
- package/src/acp/codex-app-server-client.ts +153 -16
- package/src/acp/core-turn-bridge.ts +17 -12
- package/src/acp/event-router.ts +20 -1
- package/src/acp/server.ts +6 -0
- package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
- package/src/agent-mission/claude-headless.ts +4 -1
- package/src/agent-mission/codex-exec.ts +105 -0
- package/src/agent-mission/driver.ts +192 -11
- package/src/agent-mission/grok-auth-status.ts +47 -0
- package/src/agent-mission/hand-hooks.ts +101 -0
- package/src/agent-mission/mission-cli.ts +56 -21
- package/src/agent-mission/mission-hand-reply.ts +118 -0
- package/src/agent-mission/mission-line.ts +180 -0
- package/src/agent-mission/mission-out.ts +256 -18
- package/src/agent-mission/tool-install.ts +122 -11
- package/src/agents/general-purpose.md +1 -1
- package/src/auto-research/research-turn.ts +95 -10
- package/src/autopilot/pr-manager.ts +31 -3
- package/src/boot/daemon-tools/self-implement.ts +3 -1
- package/src/boot/daemon-tools/web-search.ts +1 -2
- package/src/briefing/brief-items.ts +55 -11
- package/src/cli/agent-cli.ts +2 -1
- package/src/cli/catalog-cli.ts +31 -0
- package/src/cli/connector-cli.ts +16 -0
- package/src/cli/doctor-fix.ts +2 -2
- package/src/cli/intake-source-cli.ts +44 -8
- package/src/cli/msg-cli.ts +32 -3
- package/src/cli/pr-cli.ts +21 -1
- package/src/cli/pr-land-heavy-remote.ts +44 -6
- package/src/cli/pr-land-overlap-evidence.ts +13 -1
- package/src/cli/pr-land-pod-shadow-job.ts +143 -5
- package/src/cli/pr-land-pod-shadow.ts +9 -2
- package/src/cli/release-checklist-read-cli.ts +44 -16
- package/src/cli/release-cli.ts +23 -3
- package/src/cli/research-cli.ts +9 -0
- package/src/cli/setup-cli.ts +166 -6
- package/src/cli/setup-keys.ts +187 -0
- package/src/cli/task-plugin-wizard-host.ts +114 -0
- package/src/cli/tasks-cli.ts +54 -9
- package/src/cli/tui-test-cli.ts +186 -0
- package/src/config.ts +4 -2
- package/src/connectors/linear-daily-progress.ts +228 -0
- package/src/connectors/linear-projector.ts +34 -12
- package/src/connectors/linear.ts +151 -7
- package/src/core-turn/deep-turn-bloom.ts +67 -0
- package/src/core-turn/research-policy.ts +37 -0
- package/src/core-turn/run-core-turn.ts +320 -30
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/chat/acp-chat.ts +10 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +103 -0
- package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
- package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
- package/src/dashboard/classic-sidetab-mission.ts +167 -5
- package/src/dashboard/index.ts +378 -13
- package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
- package/src/dashboard/mission-cli-consumer.ts +20 -8
- package/src/dashboard/plugin-wizard-runtime.ts +50 -0
- package/src/dashboard/plugin-wizard-tool.ts +55 -0
- package/src/dashboard/sidetab-runtime.ts +1 -1
- package/src/dashboard/terminal-popup-runtime.ts +6 -3
- package/src/decisions/linear-progress-summary.ts +78 -0
- package/src/decisions/linear-progress-sync.ts +152 -0
- package/src/domains/outbound-alert.ts +49 -11
- package/src/domains/telegram-kind-route.ts +16 -9
- package/src/graph-runner/arg-allowance.ts +13 -0
- package/src/graph-runner/graph-run-api.ts +3 -1
- package/src/graph-runner/runner.ts +85 -17
- package/src/graph-wizard/mission-compose.ts +407 -12
- package/src/harness/dispatch-backpressure.ts +54 -1
- package/src/harness/dispatch-shadow-compare.ts +74 -0
- package/src/harness/harness-cli-command.ts +11 -1
- package/src/harness/skill-exec.ts +21 -9
- package/src/harness/skill-select.ts +1 -1
- package/src/hooks/error-report-cloud.ts +101 -0
- package/src/hooks/receiver.ts +29 -2
- package/src/index.ts +127 -10
- package/src/intake-plane/actions.ts +354 -0
- package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
- package/src/intake-plane/intake-sources.ts +78 -8
- package/src/intake-plane/items.ts +14 -4
- package/src/intake-plane/linear-mission-sync.ts +80 -0
- package/src/intake-plane/linear-secretary-runtime.ts +178 -0
- package/src/intake-plane/linear-wish.ts +227 -1
- package/src/life/life-cli.ts +168 -0
- package/src/life/life-kinds.ts +160 -0
- package/src/live-supply/budget-consumer.ts +78 -0
- package/src/live-supply/read.ts +3 -0
- package/src/live-supply/snapshot.ts +45 -0
- package/src/llm/provider-credentials.ts +8 -2
- package/src/llm.ts +2 -1
- package/src/maturity/feature-maturity.ts +3 -3
- package/src/msg/msg-sse-server.ts +3 -3
- package/src/msg/msg-store.ts +177 -19
- package/src/native-tool-catalog.ts +36 -2
- package/src/nexus/api/http-server.ts +37 -1
- package/src/nexus/api/mcp-public-allowlist.ts +2 -0
- package/src/nexus/index.ts +7 -2
- package/src/nexus/outbound/format.ts +9 -0
- package/src/nexus/outbound/router.ts +98 -13
- package/src/nexus/setup-status.ts +9 -0
- package/src/nexus/state/state.ts +3 -0
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-owner-mirror.ts +44 -0
- package/src/oauth/codex.ts +17 -2
- package/src/oauth/fallback-chain.ts +47 -17
- package/src/onboarding/first-run-doctor.ts +8 -1
- package/src/onboarding/first-run.ts +85 -26
- package/src/onboarding/key-setup.ts +103 -0
- package/src/onboarding/menu-answer.ts +13 -0
- package/src/onboarding/secret-prompt.ts +37 -0
- package/src/plugins/install/plugin-install.ts +59 -0
- package/src/pr-tool/census.ts +130 -0
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/registry/catalog-server.ts +232 -0
- package/src/registry/loader.ts +45 -1
- package/src/registry/types.ts +1 -2
- package/src/research/axis-fanout.ts +43 -28
- package/src/self-dev/ask-launch-flow.ts +72 -1
- package/src/self-dev/dev-cli.ts +4 -1
- package/src/self-dev/dev-pipeline.ts +5 -0
- package/src/self-dev/draft-residue.ts +64 -5
- package/src/self-dev/graph-front-nodes.ts +2 -1
- package/src/self-dev/graph-journey-route.ts +76 -21
- package/src/self-dev/launch-preflight.ts +58 -0
- package/src/self-dev/orchestrate.ts +1 -1
- package/src/self-dev/shard-aggregate.ts +4 -0
- package/src/self-dev/shard-run.ts +36 -15
- package/src/self-implement/abandoned-classification.ts +12 -3
- package/src/self-implement/budget-gate.ts +7 -0
- package/src/self-implement/child-llm-preference.ts +10 -1
- package/src/self-implement/doctor-visit.ts +30 -8
- package/src/self-implement/elanous-tui-spawn.ts +3 -0
- package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
- package/src/self-implement/gate-artifacts.ts +2 -1
- package/src/self-implement/goal-author-cli.ts +4 -2
- package/src/self-implement/goal-author.ts +358 -4
- package/src/self-implement/graph-overlay-yaml.ts +30 -4
- package/src/self-implement/graph-overlay.ts +3 -1
- package/src/self-implement/graph-profile-yaml.ts +107 -0
- package/src/self-implement/graph-yaml.ts +26 -3
- package/src/self-implement/off-diff-evidence.ts +249 -5
- package/src/self-implement/orchestrator.ts +240 -15
- package/src/self-implement/run-chart.ts +6 -3
- package/src/self-implement/run-ledger.ts +51 -1
- package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
- package/src/self-implement/tdd-evidence-tags.ts +9 -0
- package/src/self-implement/train-gate-receipt.ts +166 -0
- package/src/self-implement/train-gate-remote.ts +62 -18
- package/src/session/chat.ts +4 -2
- package/src/session/session-fanout.ts +2 -0
- package/src/session/streaming/acp-stream-sink.ts +2 -1
- package/src/session/streaming/chunk-producer.ts +6 -0
- package/src/session/streaming/stream-compositor.ts +3 -2
- package/src/session-runtime/index.ts +37 -1
- package/src/session-runtime/retry-policy.ts +1 -1
- package/src/setup/llm-env-detect.ts +3 -0
- package/src/setup/service-key-catalog.ts +46 -0
- package/src/setup/service-keys.ts +241 -0
- package/src/sidetab-core/visible-agent-mission.ts +98 -22
- package/src/skills/tools/agent.ts +23 -4
- package/src/skills/tools/omni-search.ts +123 -25
- package/src/task-agent/parent-host.ts +10 -0
- package/src/task-agent/repair-outcomes.ts +65 -0
- package/src/task-agent/task-hand.ts +20 -7
- package/src/task-orchestrator/dispatcher.ts +14 -1
- package/src/task-orchestrator/linear-capture-events.ts +55 -0
- package/src/task-orchestrator/store.ts +16 -5
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +35 -9
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +172 -6
- package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
- package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
- package/src/task-orchestrator/types.ts +14 -0
- package/src/telegram.ts +14 -16
- package/src/terminal/coding-agent.ts +14 -5
- package/src/terminal/session-registry.ts +1 -1
- package/src/tool-hints/gate.ts +1 -0
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/browser-hand-runtime.ts +381 -0
- package/src/tool-runtime/browser-runtime.ts +2 -1
- package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
- package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
- package/src/tool-runtime/index.ts +6 -0
- package/src/tool-runtime/types.ts +3 -0
- package/src/tui/entry.ts +24 -1
- package/src/tui/sidetab/attach.ts +140 -11
- package/src/tui/sidetab/herdr-portal.ts +225 -0
- package/src/user-config.ts +34 -9
- package/src/user-intent/types.ts +4 -3
- package/src/ux-sim/browser-hand.ts +165 -0
- package/src/ux-sim/draft-inventory-builder.ts +198 -0
- package/src/ux-sim/fake-browser-page.ts +81 -0
- package/src/ux-sim/fake-linear-device.ts +31 -0
- package/src/ux-sim/graph-engine-sim.ts +47 -0
- package/src/ux-sim/linear-secretary.ts +216 -0
- package/src/ux-sim/mock-scenario-catalog.json +75 -23
- package/src/ux-sim/mock-scenario-catalog.ts +120 -2
- package/src/ux-sim/onboarding-first-run-device.ts +31 -21
- package/src/ux-sim/scenario.ts +70 -26
- package/src/ux-sim/service-key-setup.ts +50 -0
- package/src/ux-sim/term-slash-device.ts +74 -0
- package/src/ux-sim/turn-throw-sim.ts +31 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/exa.ts +77 -0
- package/src/web-search/index.ts +30 -9
- package/src/web-search/provider.ts +4 -1
- package/src/web-search/x-intent.ts +5 -0
- package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +0 -23
- package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
- package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
- package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
- package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +0 -287
- package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6377.bc7df239edbff244.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
- package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
- package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
- /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
|
@@ -52,6 +52,7 @@ export interface GateArtifactRun {
|
|
|
52
52
|
export interface GateArtifactShard {
|
|
53
53
|
shardId: string;
|
|
54
54
|
attempt: number;
|
|
55
|
+
elapsedMs?: number;
|
|
55
56
|
files: string[];
|
|
56
57
|
current: GateArtifactRun;
|
|
57
58
|
baseline: GateArtifactRun;
|
|
@@ -210,7 +211,7 @@ export function writeGateArtifacts(input: GateArtifactInput): { summaryPath: str
|
|
|
210
211
|
return run;
|
|
211
212
|
};
|
|
212
213
|
shardsDetail.push({
|
|
213
|
-
shardId: attempt.shardId, attempt: attempt.attempt, files, current: side('current'), baseline: side('baseline'),
|
|
214
|
+
shardId: attempt.shardId, attempt: attempt.attempt, ...(attempt.elapsedMs !== undefined ? { elapsedMs: attempt.elapsedMs } : {}), files, current: side('current'), baseline: side('baseline'),
|
|
214
215
|
...(input.sharded?.unmeasuredByShard?.[attempt.shardId] !== undefined
|
|
215
216
|
&& attempt === input.sharded.attempts.filter((item) => item.shardId === attempt.shardId).at(-1)
|
|
216
217
|
? { unmeasuredReason: input.sharded.unmeasuredByShard[attempt.shardId] } : {}),
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
type GoalAuthorDeps,
|
|
20
20
|
type GoalAuthorGradeSelection,
|
|
21
21
|
resolveGoalAuthorGrade,
|
|
22
|
+
resolveGoalAuthorReviewerPrecheckEnabled,
|
|
22
23
|
type GoalType,
|
|
23
24
|
type GoalFileLintFinding,
|
|
24
25
|
} from './goal-author.js';
|
|
@@ -292,9 +293,10 @@ export async function runGoalAuthorCli(
|
|
|
292
293
|
? { passed: false }
|
|
293
294
|
: { passed: true, titleChars: proseTitle.length });
|
|
294
295
|
const gradeDeps = authorGrade.grade === 'lite' || opts.authorGrade ? { authorGrade } : {};
|
|
296
|
+
const reviewerPrecheckDeps = { reviewerPrecheckEnabled: resolveGoalAuthorReviewerPrecheckEnabled() };
|
|
295
297
|
const authorDeps: Partial<GoalAuthorDeps> = parentGoalFile && parentQuestionId
|
|
296
|
-
? { parent: { goalFile: parentGoalFile, questionId: parentQuestionId }, parentDocument, clarificationAnswers, ...(decomposeSteps ? { decomposeSteps } : {}), ...gradeDeps, ...selfResolutionDeps, ...progressDeps, ...launchPreflightDeps, ...(opts.rootIntent !== undefined && { rootIntent: opts.rootIntent }), ...(goalType !== undefined && { goalType }), ...goalTitleDeps }
|
|
297
|
-
: { ...(clarificationAnswers && { clarificationAnswers }), ...(decomposeSteps ? { decomposeSteps } : {}), ...gradeDeps, ...selfResolutionDeps, ...progressDeps, ...launchPreflightDeps, ...(opts.rootIntent !== undefined && { rootIntent: opts.rootIntent }), ...(goalType !== undefined && { goalType }), ...goalTitleDeps };
|
|
298
|
+
? { parent: { goalFile: parentGoalFile, questionId: parentQuestionId }, parentDocument, clarificationAnswers, ...(decomposeSteps ? { decomposeSteps } : {}), ...gradeDeps, ...selfResolutionDeps, ...progressDeps, ...launchPreflightDeps, ...reviewerPrecheckDeps, ...(opts.rootIntent !== undefined && { rootIntent: opts.rootIntent }), ...(goalType !== undefined && { goalType }), ...goalTitleDeps }
|
|
299
|
+
: { ...(clarificationAnswers && { clarificationAnswers }), ...(decomposeSteps ? { decomposeSteps } : {}), ...gradeDeps, ...selfResolutionDeps, ...progressDeps, ...launchPreflightDeps, ...reviewerPrecheckDeps, ...(opts.rootIntent !== undefined && { rootIntent: opts.rootIntent }), ...(goalType !== undefined && { goalType }), ...goalTitleDeps };
|
|
298
300
|
const write = deps.write ?? writeAuthoredGoal;
|
|
299
301
|
const result = opts.groundingCwd === undefined
|
|
300
302
|
? await write(ask, opts.cwd, authorDeps, superseded ? { supersedes: superseded } : undefined)
|
|
@@ -10,6 +10,7 @@ import type { LLMUsage } from '../prompt-cache/types.js';
|
|
|
10
10
|
import { debug } from '../debug/log.js';
|
|
11
11
|
import { ensureDeviceFirstSteps, inspectDeviceFirstGoal } from './device-first.js';
|
|
12
12
|
import { COMPLETION_BOUNDARY_STEP_PREFIX, FOLDED_DEVICE_FIRST_ACTION_MARKER } from './goal-author-decompose.js';
|
|
13
|
+
import { loadMockScenarioCatalog, type MockScenarioDevice, type MockScenarioEntry } from '../ux-sim/mock-scenario-catalog.js';
|
|
13
14
|
|
|
14
15
|
function observeGoalAuthor(
|
|
15
16
|
category: 'goal-author' | 'goal-author.clarify',
|
|
@@ -20,6 +21,7 @@ function observeGoalAuthor(
|
|
|
20
21
|
debug.log(category === 'goal-author' ? 'harness.author' : 'harness.author.clarify', event, data);
|
|
21
22
|
}
|
|
22
23
|
import { getUserConfig } from '../user-config.js';
|
|
24
|
+
import { getProviderForConfig, streamLLM, type LLMMessage } from '../llm.js';
|
|
23
25
|
|
|
24
26
|
export type GoalAuthorGrade = 'full' | 'lite';
|
|
25
27
|
export type GoalAuthorGradeSource = 'flag' | 'env' | 'config' | 'default';
|
|
@@ -79,6 +81,10 @@ export interface GoalAuthorDeps {
|
|
|
79
81
|
ground: (ask: string, groundingDeps?: GoalAuthorGroundingDeps) => Promise<CodebaseGrounding>;
|
|
80
82
|
persistentGrounding?: GoalAuthorGroundingDeps;
|
|
81
83
|
authorGrade?: GoalAuthorGradeSelection;
|
|
84
|
+
/** Production Terra reviewer precheck; omitted is disabled unless the shared config switch is on. */
|
|
85
|
+
reviewerPrecheckEnabled?: boolean;
|
|
86
|
+
/** Optional seam for focused tests; production uses the pinned Terra medium reviewer. */
|
|
87
|
+
reviewerPrecheck?: (document: string, authorRunId: string) => Promise<GoalAuthorReviewerPrecheckResult>;
|
|
82
88
|
enhance: (ask: string, opts?: EnhanceOpts) => Promise<GoalEnhancement>;
|
|
83
89
|
/** Additive enhancer options supplied by the file-writing entrypoint. */
|
|
84
90
|
enhanceOpts?: EnhanceOpts;
|
|
@@ -137,6 +143,209 @@ export interface GoalAuthorDeps {
|
|
|
137
143
|
authoringLessons?: string;
|
|
138
144
|
}
|
|
139
145
|
|
|
146
|
+
export interface GoalAuthorReviewerPrecheckResult {
|
|
147
|
+
readonly suggestions: readonly string[];
|
|
148
|
+
readonly fixes: readonly string[];
|
|
149
|
+
/** Exact, replayable edits in fixes order; together they must explain the entire document diff. */
|
|
150
|
+
readonly fixEvidence?: readonly { readonly fix: string; readonly originalText: string; readonly revisedText: string }[];
|
|
151
|
+
readonly remainingNeedsHuman: readonly string[];
|
|
152
|
+
readonly revisedDocument: string;
|
|
153
|
+
readonly appliedFixes: readonly string[];
|
|
154
|
+
readonly unappliedItems: readonly string[];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL = 'gpt-6.1-terra';
|
|
158
|
+
|
|
159
|
+
export function parseGoalAuthorReviewerPrecheck(raw: string): GoalAuthorReviewerPrecheckResult {
|
|
160
|
+
const text = raw.trim().replace(/^```(?:json)?\s*/iu, '').replace(/\s*```$/u, '');
|
|
161
|
+
const value: unknown = JSON.parse(text);
|
|
162
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('reviewer response must be an object');
|
|
163
|
+
const record = value as Record<string, unknown>;
|
|
164
|
+
const readList = (key: string): string[] => {
|
|
165
|
+
const candidate = record[key];
|
|
166
|
+
if (!Array.isArray(candidate) || candidate.some((item) => typeof item !== 'string')) {
|
|
167
|
+
throw new Error(`reviewer response ${key} must be a string array`);
|
|
168
|
+
}
|
|
169
|
+
return candidate;
|
|
170
|
+
};
|
|
171
|
+
const revisedDocument = record.revisedDocument;
|
|
172
|
+
if (typeof revisedDocument !== 'string' || !revisedDocument.trim()) throw new Error('reviewer response revisedDocument must be non-empty text');
|
|
173
|
+
return {
|
|
174
|
+
suggestions: readList('suggestions'),
|
|
175
|
+
fixes: readList('fixes'),
|
|
176
|
+
...(record.fixEvidence === undefined ? {} : {
|
|
177
|
+
fixEvidence: (() => {
|
|
178
|
+
const candidate = record.fixEvidence;
|
|
179
|
+
if (!Array.isArray(candidate) || candidate.some((item) => !item || typeof item !== 'object'
|
|
180
|
+
|| typeof (item as Record<string, unknown>).fix !== 'string'
|
|
181
|
+
|| typeof (item as Record<string, unknown>).originalText !== 'string'
|
|
182
|
+
|| typeof (item as Record<string, unknown>).revisedText !== 'string')) {
|
|
183
|
+
throw new Error('reviewer response fixEvidence must be an array of { fix, originalText, revisedText }');
|
|
184
|
+
}
|
|
185
|
+
return candidate as { fix: string; originalText: string; revisedText: string }[];
|
|
186
|
+
})(),
|
|
187
|
+
}),
|
|
188
|
+
remainingNeedsHuman: readList('remainingNeedsHuman'),
|
|
189
|
+
revisedDocument,
|
|
190
|
+
appliedFixes: [],
|
|
191
|
+
unappliedItems: [],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function reviewerRevisionIsValid(original: string, revised: string): boolean {
|
|
196
|
+
if (!revised.trim() || verbatimOriginalAsk(revised) !== verbatimOriginalAsk(original)) return false;
|
|
197
|
+
if (parseGoalId(revised) !== parseGoalId(original)
|
|
198
|
+
|| parseRootIntent(revised) !== parseRootIntent(original)
|
|
199
|
+
|| parseGoalType(revised) !== parseGoalType(original)) return false;
|
|
200
|
+
if (JSON.stringify(canonicalBlocks(revised)) !== JSON.stringify(canonicalBlocks(original))) return false;
|
|
201
|
+
return !lintGoalFile(revised, 'reviewer-precheck').some((finding) => finding.level === 'ERROR');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function reviewerEditIsGrounded(original: string, edit: { fix: string; originalText: string; revisedText: string }): boolean {
|
|
205
|
+
if (!edit.originalText || edit.revisedText === edit.originalText || !edit.revisedText.startsWith(edit.originalText)) return false;
|
|
206
|
+
const acceptanceStart = original.indexOf('## ACCEPTANCE CRITERIA');
|
|
207
|
+
const evidenceStart = original.indexOf('## REQUIRED EVIDENCE');
|
|
208
|
+
const nextHeading = (start: number): number => {
|
|
209
|
+
const next = original.indexOf('\n## ', start + 1);
|
|
210
|
+
return next < 0 ? original.length : next;
|
|
211
|
+
};
|
|
212
|
+
const editStart = original.indexOf(edit.originalText);
|
|
213
|
+
if (editStart < 0 || original.indexOf(edit.originalText, editStart + edit.originalText.length) >= 0) return false;
|
|
214
|
+
const sectionTexts = [
|
|
215
|
+
acceptanceStart >= 0 ? original.slice(acceptanceStart + '## ACCEPTANCE CRITERIA'.length, nextHeading(acceptanceStart)) : '',
|
|
216
|
+
evidenceStart >= 0 ? original.slice(evidenceStart + '## REQUIRED EVIDENCE'.length, nextHeading(evidenceStart)) : '',
|
|
217
|
+
];
|
|
218
|
+
const isCompleteCriterion = sectionTexts.some((section) => section.split('\n').some((line) =>
|
|
219
|
+
/^\s*[-*]\s+\S/u.test(line) && line.trim() === edit.originalText.trim()));
|
|
220
|
+
if (!isCompleteCriterion) return false;
|
|
221
|
+
const appended = edit.revisedText.slice(edit.originalText.length);
|
|
222
|
+
if (!/^\r?\n[ \t]*[-*][ \t]+\S/u.test(appended)) return false;
|
|
223
|
+
const added = appended
|
|
224
|
+
.replace(/^\r?\n[ \t]*[-*][ \t]*/u, '')
|
|
225
|
+
.replace(/^\[[a-z-]+\][ \t]*/iu, '')
|
|
226
|
+
.trim();
|
|
227
|
+
if (edit.fix !== added) return false;
|
|
228
|
+
const ask = verbatimOriginalAsk(original);
|
|
229
|
+
if (!added || !ask) return false;
|
|
230
|
+
const sentences = ask
|
|
231
|
+
.split(/(?<=[.!?])(?:[ \t]+|$)|\r?\n/u)
|
|
232
|
+
.map((sentence) => sentence.trim())
|
|
233
|
+
.filter(Boolean);
|
|
234
|
+
return sentences.includes(added);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function resolveGoalAuthorReviewerPrecheckEnabled(config = getUserConfig()): boolean {
|
|
238
|
+
return config.tools.selfImplement.goalAuthorReviewerPrecheck === true;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export async function runGoalAuthorReviewerPrecheck(
|
|
242
|
+
document: string,
|
|
243
|
+
deps: { config?: ReturnType<typeof getUserConfig>; stream?: typeof streamLLM } = {},
|
|
244
|
+
): Promise<GoalAuthorReviewerPrecheckResult> {
|
|
245
|
+
const config = deps.config ?? getUserConfig();
|
|
246
|
+
const pinnedConfig = {
|
|
247
|
+
...config,
|
|
248
|
+
llm: { ...config.llm, provider: 'openai-codex' as const, model: GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL },
|
|
249
|
+
};
|
|
250
|
+
const provider = getProviderForConfig(pinnedConfig, GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL);
|
|
251
|
+
const prompt = [
|
|
252
|
+
'Review this completed goal document before it is written. Return only JSON with string-array fields suggestions, fixes, remainingNeedsHuman, a fixEvidence array of { fix, originalText, revisedText }, and a revisedDocument string.',
|
|
253
|
+
'Apply each necessary fix to revisedDocument exactly once while preserving the original ask, GoalId, RootIntent, GoalType, every existing criterion and scope boundary, and canonical section structure. Be strictly conservative: only append one complete sentence copied verbatim from the original ask to an existing acceptance-criteria or required-evidence line; never append a partial substring or clause, especially one inside a negation or condition, and do not delete or reword existing text, add new scope, or edit other sections. For every fixes item, include one fixEvidence object in the same order: fixes item and fix must both equal the exact complete sentence appended from the original ask; originalText and revisedText must be exact spans where revisedText starts with originalText and appends that sentence, and replaying every single replacement reproduces the complete revisedDocument with no other edits. If you cannot explain and ground every change this way, return no fixes and leave revisedDocument byte-for-byte unchanged. Keep optional suggestions separate; list unresolved decisions or evidence as remainingNeedsHuman.',
|
|
254
|
+
document,
|
|
255
|
+
].join('\n\n');
|
|
256
|
+
const messages: LLMMessage[] = [{ role: 'user', content: prompt }];
|
|
257
|
+
let actualProvider = provider.name;
|
|
258
|
+
let actualModel = GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL;
|
|
259
|
+
const raw = await (deps.stream ?? streamLLM)(messages, () => undefined, {
|
|
260
|
+
provider,
|
|
261
|
+
model: GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL,
|
|
262
|
+
reasoningEffort: 'medium',
|
|
263
|
+
maxTokens: 3000,
|
|
264
|
+
usageRole: 'review',
|
|
265
|
+
usagePhase: 'author-reviewer-precheck',
|
|
266
|
+
usageSite: 'author-reviewer-precheck',
|
|
267
|
+
onResolvedProvider: (resolvedProvider, resolvedModel) => { actualProvider = resolvedProvider; actualModel = resolvedModel; },
|
|
268
|
+
});
|
|
269
|
+
debug.log('author.reviewer-precheck', 'response', { provider: actualProvider, model: actualModel, responseChars: raw.length });
|
|
270
|
+
return parseGoalAuthorReviewerPrecheck(raw);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export async function executeGoalAuthorReviewerPrecheck(
|
|
274
|
+
enabled: boolean,
|
|
275
|
+
document: string,
|
|
276
|
+
authorRunId: string,
|
|
277
|
+
run: (document: string) => Promise<GoalAuthorReviewerPrecheckResult> = (value) => runGoalAuthorReviewerPrecheck(value),
|
|
278
|
+
observe: (event: string, data: Record<string, unknown>) => void = (event, data) => debug.log('author.reviewer-precheck', event, data),
|
|
279
|
+
): Promise<{ status: 'skipped' | 'completed' | 'rejected-soft' | 'failed-soft'; result?: GoalAuthorReviewerPrecheckResult }> {
|
|
280
|
+
if (!enabled) {
|
|
281
|
+
observe('precheck-skipped', { authorRunId, reason: 'disabled', providerCalls: 0 });
|
|
282
|
+
return { status: 'skipped' };
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const proposed = await run(document);
|
|
286
|
+
const evidence = proposed.fixEvidence ?? [];
|
|
287
|
+
let replayed = document;
|
|
288
|
+
let fixesSupported = proposed.fixes.length === 0
|
|
289
|
+
? proposed.revisedDocument === document && evidence.length === 0
|
|
290
|
+
: evidence.length === proposed.fixes.length;
|
|
291
|
+
if (fixesSupported) {
|
|
292
|
+
for (let index = 0; index < proposed.fixes.length; index += 1) {
|
|
293
|
+
const edit = evidence[index];
|
|
294
|
+
if (!edit || edit.fix !== proposed.fixes[index] || !reviewerEditIsGrounded(document, edit) || !replayed.includes(edit.originalText)) {
|
|
295
|
+
fixesSupported = false;
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
const at = replayed.indexOf(edit.originalText);
|
|
299
|
+
if (replayed.indexOf(edit.originalText, at + edit.originalText.length) !== -1) {
|
|
300
|
+
fixesSupported = false;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
replayed = replayed.slice(0, at) + edit.revisedText + replayed.slice(at + edit.originalText.length);
|
|
304
|
+
}
|
|
305
|
+
fixesSupported = fixesSupported && replayed === proposed.revisedDocument;
|
|
306
|
+
}
|
|
307
|
+
const valid = reviewerRevisionIsValid(document, proposed.revisedDocument)
|
|
308
|
+
&& fixesSupported
|
|
309
|
+
&& (proposed.fixes.length === 0 || proposed.revisedDocument !== document);
|
|
310
|
+
const result: GoalAuthorReviewerPrecheckResult = valid
|
|
311
|
+
? { ...proposed, appliedFixes: proposed.fixes, unappliedItems: [] }
|
|
312
|
+
: {
|
|
313
|
+
...proposed,
|
|
314
|
+
revisedDocument: document,
|
|
315
|
+
appliedFixes: [],
|
|
316
|
+
unappliedItems: proposed.fixes,
|
|
317
|
+
remainingNeedsHuman: [...new Set([...proposed.remainingNeedsHuman, ...proposed.fixes])],
|
|
318
|
+
};
|
|
319
|
+
const status = valid ? 'completed' : 'rejected-soft';
|
|
320
|
+
observe(valid ? 'completed' : 'revision-rejected', {
|
|
321
|
+
authorRunId,
|
|
322
|
+
provider: 'openai-codex',
|
|
323
|
+
model: GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL,
|
|
324
|
+
status,
|
|
325
|
+
proposedSuggestionCount: result.suggestions.length,
|
|
326
|
+
proposedFixCount: result.fixes.length,
|
|
327
|
+
appliedFixCount: result.appliedFixes.length,
|
|
328
|
+
appliedFixes: result.appliedFixes,
|
|
329
|
+
fixEvidence: result.fixEvidence ?? [],
|
|
330
|
+
correctedItems: result.appliedFixes.length,
|
|
331
|
+
unappliedItemCount: result.unappliedItems.length,
|
|
332
|
+
unappliedItems: result.unappliedItems,
|
|
333
|
+
remainingNeedsHuman: result.remainingNeedsHuman,
|
|
334
|
+
suggestionsResult: result.suggestions,
|
|
335
|
+
fixesResult: result.fixes,
|
|
336
|
+
remainingNeedsHumanResult: result.remainingNeedsHuman,
|
|
337
|
+
});
|
|
338
|
+
return { status, result };
|
|
339
|
+
} catch (error) {
|
|
340
|
+
observe('failed-soft', {
|
|
341
|
+
authorRunId,
|
|
342
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
343
|
+
correctedItems: 0,
|
|
344
|
+
});
|
|
345
|
+
return { status: 'failed-soft' };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
140
349
|
export type GoalAuthorGroundingPath = 'groundMissionInCodebase';
|
|
141
350
|
|
|
142
351
|
export interface GoalAuthorGroundingDeps {
|
|
@@ -663,9 +872,139 @@ export function inspectGoalDoneBoundary(document: string): { values: Partial<Rec
|
|
|
663
872
|
return { values, missing: GOAL_DONE_BOUNDARY_LABELS.filter((label) => !values[label]) };
|
|
664
873
|
}
|
|
665
874
|
|
|
666
|
-
|
|
875
|
+
function goalDoneTestPaths(targetPath: string): string[] {
|
|
876
|
+
if (/\.(?:test|spec)\.[cm]?[jt]sx?$/i.test(targetPath)) return [targetPath];
|
|
877
|
+
const source = /^(.*)\.([cm]?[jt]sx?)$/i.exec(targetPath);
|
|
878
|
+
if (!source) return [`${targetPath}.test.ts`, `${targetPath}.spec.ts`];
|
|
879
|
+
const extension = source[2]!.toLowerCase();
|
|
880
|
+
const siblingExtensions = extension === 'tsx' ? ['tsx', 'ts'] : extension === 'jsx' ? ['jsx', 'js'] : extension === 'ts' ? ['ts', 'tsx'] : extension === 'js' ? ['js', 'jsx'] : [extension];
|
|
881
|
+
return siblingExtensions.flatMap((testExtension) => [`${source[1]}.test.${testExtension}`, `${source[1]}.spec.${testExtension}`]);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
function bunTestEvidencePath(command: string | undefined): string | undefined {
|
|
885
|
+
if (command === undefined) return undefined;
|
|
886
|
+
return /^bun\s+test\s+(?:(?:--\s+)?)(\S+\.(?:test|spec)\.[cm]?[jt]sx?)(?:\s|$)/u.exec(unwrapGoalDoneValue(command))?.[1];
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
function goalPathTokens(paths: readonly string[]): Set<string> {
|
|
890
|
+
return new Set(paths.map((path) => path.split(/[\\/]/u).at(-1) ?? path)
|
|
891
|
+
.flatMap((path) => path.toLowerCase().split(/[._-]+/u))
|
|
892
|
+
.filter((token) => token.length > 2 && !['src', 'test', 'tests', 'spec', 'tsx', 'ts', 'jsx', 'js'].includes(token)));
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function goalPathStems(paths: readonly string[]): Set<string> {
|
|
896
|
+
return new Set(paths.map((path) => (path.split(/[\\/]/u).at(-1) ?? path).toLowerCase()
|
|
897
|
+
.replace(/\.(?:test|spec)\.[^.]+$/u, '')
|
|
898
|
+
.replace(/\.[^.]+$/u, '')));
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function matchingPathCount(paths: readonly string[], targetPaths: readonly string[]): number {
|
|
902
|
+
const targetStems = goalPathStems(targetPaths);
|
|
903
|
+
if ([...goalPathStems(paths)].some((stem) => targetStems.has(stem))) return 10;
|
|
904
|
+
const targetTokens = goalPathTokens(targetPaths);
|
|
905
|
+
return [...goalPathTokens(paths)].filter((token) => targetTokens.has(token)).length;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function behaviorTokens(value: string): Set<string> {
|
|
909
|
+
const stop = new Set(['the', 'and', 'with', 'from', 'this', 'that', 'when', 'then', 'into', 'only', 'are', 'is', 'for', 'bun', 'test', 'code', 'boundary', 'request', 'expected', 'target', 'file', '완료', '경계', '증거', '명령', '대상', '요청', '기대', '시험', '확인', '시나리오']);
|
|
910
|
+
return new Set((value.toLowerCase().match(/[\p{L}\p{N}]{2,}/gu) ?? []).filter((token) => !stop.has(token)));
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
function matchingScenarioBehaviorCount(scenario: MockScenarioEntry, ask: string): number {
|
|
914
|
+
const { values } = inspectGoalDoneBoundary(ask);
|
|
915
|
+
const requestedText = `${values['완료 경계 코드'] ?? ''} ${values['완료 경계 실물'] ?? ''}`;
|
|
916
|
+
const describedText = `${scenario.name} ${scenario.kind} ${scenario.trigger} ${scenario.observe.join(' ')} ${scenario.expected}`;
|
|
917
|
+
const requested = behaviorTokens(requestedText);
|
|
918
|
+
const described = behaviorTokens(describedText);
|
|
919
|
+
const polarity = (text: string, token: string): boolean => {
|
|
920
|
+
const words = text.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
921
|
+
return words.some((word, index) => word === token && words.slice(Math.max(0, index - 3), index).some((nearby) => /^(?:not|never|no|without|isn't|doesn't|않|못|아니)/u.test(nearby)));
|
|
922
|
+
};
|
|
923
|
+
const oppositePairs = [
|
|
924
|
+
['distinct', 'indistinguishable'], ['preserved', 'lost'], ['visible', 'hidden'], ['visible', 'invisible'],
|
|
925
|
+
['harvestable', 'unharvestable'], ['independent', 'dependent'], ['succeeds', 'fails'], ['accepted', 'rejected'],
|
|
926
|
+
];
|
|
927
|
+
const shared = [...described].filter((token) => requested.has(token));
|
|
928
|
+
if (shared.some((token) => polarity(requestedText, token) !== polarity(describedText, token))
|
|
929
|
+
|| oppositePairs.some(([left, right]) => (requested.has(left) && described.has(right)) || (requested.has(right) && described.has(left)))) return 0;
|
|
930
|
+
return shared.length;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
function nextGoalScenarioId(catalogIds: readonly string[], targets: readonly string[]): string {
|
|
934
|
+
const targetName = targets.map((path) => path.split(/[\\/]/u).at(-1) ?? '')
|
|
935
|
+
.map((name) => name.replace(/\.[^.]+$/u, '').replace(/\.(?:test|spec)$/u, ''))
|
|
936
|
+
.find(Boolean) ?? 'TARGET';
|
|
937
|
+
const slug = targetName.toUpperCase().replace(/[^A-Z0-9]+/gu, '-').replace(/^-|-$/gu, '').slice(0, 32) || 'TARGET';
|
|
938
|
+
const prefix = `MK-${slug}-TDD-EVIDENCE`;
|
|
939
|
+
const existing = new Set(catalogIds);
|
|
940
|
+
for (let sequence = 1; sequence <= 99; sequence++) {
|
|
941
|
+
const candidate = `${prefix}-${String(sequence).padStart(2, '0')}`;
|
|
942
|
+
if (!existing.has(candidate)) return candidate;
|
|
943
|
+
}
|
|
944
|
+
return `${prefix}-${Date.now().toString(36).toUpperCase()}`;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
function selectGoalMockStage(ask: string, targets: readonly string[]): { device: MockScenarioDevice; scenario?: MockScenarioEntry } | undefined {
|
|
948
|
+
const catalog = loadMockScenarioCatalog();
|
|
949
|
+
const device = catalog.devices
|
|
950
|
+
.map((candidate) => ({ candidate, score: matchingPathCount([...candidate.implementation, ...candidate.tests], targets) }))
|
|
951
|
+
.filter((entry) => entry.score >= 2)
|
|
952
|
+
.sort((left, right) => right.score - left.score)[0]?.candidate
|
|
953
|
+
?? (/(?:author|goal|mission|저작|골|미션)/iu.test(`${targets.join(' ')}\n${ask}`)
|
|
954
|
+
? catalog.devices.find((candidate) => candidate.id === 'product-devices')
|
|
955
|
+
: catalog.devices.find((candidate) => candidate.id === 'scenario-runner'));
|
|
956
|
+
if (!device) return undefined;
|
|
957
|
+
const scenario = catalog.scenarios
|
|
958
|
+
.filter((candidate) => candidate.device === device.id)
|
|
959
|
+
.map((candidate) => ({ candidate, pathScore: matchingPathCount([...candidate.implementation, ...candidate.tests], targets), behaviorScore: matchingScenarioBehaviorCount(candidate, ask) }))
|
|
960
|
+
.filter((entry) => entry.pathScore >= 2 && entry.behaviorScore >= 2)
|
|
961
|
+
.sort((left, right) => right.behaviorScore - left.behaviorScore || right.pathScore - left.pathScore)[0]?.candidate;
|
|
962
|
+
return { device, ...(scenario ? { scenario } : {}) };
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
export function explicitGoalDoneBoundaryLines(ask: string, repositoryRoot?: string): string[] {
|
|
667
966
|
const { values } = inspectGoalDoneBoundary(ask);
|
|
668
|
-
|
|
967
|
+
const explicitLines = GOAL_DONE_BOUNDARY_LABELS.flatMap((label) => values[label] ? [`- ${label}: ${values[label]}`] : []);
|
|
968
|
+
// Keep the exported extractor's original contract for callers that only ask
|
|
969
|
+
// for verbatim values. Goal authoring opts into catalog planning by supplying
|
|
970
|
+
// its repository root at the production call sites below.
|
|
971
|
+
if (repositoryRoot === undefined) return explicitLines;
|
|
972
|
+
const unquotedAsk = ask.replace(/```[\s\S]*?```/gu, '');
|
|
973
|
+
const targets = declaredTargetPaths(unquotedAsk);
|
|
974
|
+
const existingEvidence = values['완료 경계 증거 명령'];
|
|
975
|
+
const targetTestPaths = targets.flatMap(goalDoneTestPaths);
|
|
976
|
+
const existingBunTestPath = bunTestEvidencePath(existingEvidence);
|
|
977
|
+
const testPath = targetTestPaths.find((path) => existsSync(resolve(repositoryRoot, path)))
|
|
978
|
+
?? (existingBunTestPath && targetTestPaths.includes(existingBunTestPath) ? existingBunTestPath : undefined)
|
|
979
|
+
?? targetTestPaths[0]
|
|
980
|
+
?? existingBunTestPath;
|
|
981
|
+
const shouldReplaceEvidence = existingBunTestPath === undefined;
|
|
982
|
+
const plannedTestPath = !shouldReplaceEvidence && existingBunTestPath ? existingBunTestPath : testPath;
|
|
983
|
+
const evidenceCommand = shouldReplaceEvidence && testPath ? `bun test ${testPath}` : existingEvidence;
|
|
984
|
+
const needsNewTest = plannedTestPath !== undefined && !existsSync(resolve(repositoryRoot, plannedTestPath));
|
|
985
|
+
const mockStage = targets.length ? selectGoalMockStage(ask, targets) : undefined;
|
|
986
|
+
const lines = GOAL_DONE_BOUNDARY_LABELS.flatMap((label) => {
|
|
987
|
+
if (label === '완료 경계 증거 명령' && evidenceCommand !== undefined) return [`- ${label}: ${evidenceCommand}`];
|
|
988
|
+
return values[label] ? [`- ${label}: ${values[label]}`] : [];
|
|
989
|
+
});
|
|
990
|
+
if (needsNewTest && plannedTestPath) lines.push(`- 신설: ${plannedTestPath}`);
|
|
991
|
+
if (shouldReplaceEvidence && existingEvidence && /type-?check|tsc|typescript/iu.test(existingEvidence)) {
|
|
992
|
+
lines.push(`- 증거 보충: ${existingEvidence} (타입검사는 보조 검증)`);
|
|
993
|
+
}
|
|
994
|
+
if (mockStage) {
|
|
995
|
+
lines.push(`- 장치: ${mockStage.device.id} — ${mockStage.device.name} (카탈로그 경로 일치: ${[...mockStage.device.implementation, ...mockStage.device.tests].filter((path) => matchingPathCount([path], targets) > 0).join(' · ') || mockStage.device.target})`);
|
|
996
|
+
if (mockStage.scenario) {
|
|
997
|
+
lines.push(`- 시나리오: ${mockStage.scenario.id} — ${mockStage.scenario.name}`);
|
|
998
|
+
} else {
|
|
999
|
+
const id = nextGoalScenarioId(loadMockScenarioCatalog().scenarios.map((scenario) => scenario.id), targets);
|
|
1000
|
+
const requestedCode = values['완료 경계 코드'] ?? '요청 대상의 완료 경계';
|
|
1001
|
+
const requestedObservation = values['완료 경계 실물'] ?? '격리 시험에서 요청된 생산 동작과 결과를 관측한다';
|
|
1002
|
+
lines.push(`- 시나리오: 신설 초안 (MS-id 후보: ${id})`);
|
|
1003
|
+
lines.push(`- 시나리오 초안: 사건은 ${targets.join(' · ') || '요청 대상'}에 «${requestedCode}» 경계를 적용한 입력; 기대는 생산 경로에서 «${requestedObservation}»을 관측하고 bun test ${plannedTestPath ?? '<대상 시험 파일>'}로 GREEN을 확인하는 것이다. 자식은 기존 카탈로그 API·ScenarioV0 형식에 맞춰 요청 대상의 사건·기대를 구체화해 등록한다.`);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
if (plannedTestPath) lines.push(`- 검증 계획(TDD): 장치 ${mockStage?.device.id ?? '미선정'} · 시나리오 ${mockStage?.scenario?.id ?? '신설 초안'} · ${needsNewTest ? '신설 시험' : '기존 시험에 요청 동작 회귀 사례 추가'} ${plannedTestPath} · 피처 시험 bun test ${plannedTestPath}를 구현 전에 RED로 확인한다.`);
|
|
1007
|
+
return lines;
|
|
669
1008
|
}
|
|
670
1009
|
|
|
671
1010
|
/**
|
|
@@ -2535,6 +2874,8 @@ export interface AuthoredGoal {
|
|
|
2535
2874
|
authorRunId: string;
|
|
2536
2875
|
/** AUTHOR-TIMEBOX: present only when the `ground` phase was short-circuited for exceeding its budget. */
|
|
2537
2876
|
groundingTimebox?: GoalAuthorGroundingTimebox;
|
|
2877
|
+
/** Raw structured reviewer output is preserved for the caller and run observability. */
|
|
2878
|
+
reviewerPrecheck?: GoalAuthorReviewerPrecheckResult;
|
|
2538
2879
|
}
|
|
2539
2880
|
|
|
2540
2881
|
/** AUTHOR-TIMEBOX 산출 — 예산과 실제 경과. 둘 다 «잰 값»이고 지어낸 값이 아니다. */
|
|
@@ -6236,7 +6577,7 @@ async function authorGoalWithSupersededRootIntent(
|
|
|
6236
6577
|
'',
|
|
6237
6578
|
'## ACCEPTANCE CRITERIA',
|
|
6238
6579
|
...enhancement.checklist.map(requestedCriterionLine),
|
|
6239
|
-
...explicitGoalDoneBoundaryLines(ask),
|
|
6580
|
+
...explicitGoalDoneBoundaryLines(ask, deps.repositoryRoot ?? process.cwd()),
|
|
6240
6581
|
'',
|
|
6241
6582
|
'## REQUIRED EVIDENCE',
|
|
6242
6583
|
'- [requested] Verify the decision signal and the verbatim ask.',
|
|
@@ -6721,7 +7062,7 @@ async function authorGoalWithSupersededRootIntent(
|
|
|
6721
7062
|
: ['## STEPS', ...(resolvedSteps.length ? resolvedSteps.map((step) => `- ${step}`) : ['- No externally injected steps.']), '']),
|
|
6722
7063
|
'## ACCEPTANCE CRITERIA',
|
|
6723
7064
|
...acceptanceSection,
|
|
6724
|
-
...explicitGoalDoneBoundaryLines(ask),
|
|
7065
|
+
...explicitGoalDoneBoundaryLines(ask, deps.repositoryRoot ?? process.cwd()),
|
|
6725
7066
|
...preservationAmbiguityCriteria(ambiguities, clarificationAnswers),
|
|
6726
7067
|
...preservationAmbiguityNotice(ambiguities),
|
|
6727
7068
|
...preservationAmbiguityClarification(clarificationQuestions, clarificationResponses),
|
|
@@ -7067,6 +7408,19 @@ export async function writeAuthoredGoal(
|
|
|
7067
7408
|
...(supersededGoalId && { goalId: supersededGoalId }),
|
|
7068
7409
|
...(supersededRootIntent !== null && { supersessionRootIntent: supersededRootIntent }),
|
|
7069
7410
|
});
|
|
7411
|
+
const reviewerPrecheckEnabled = resolvedDeps.reviewerPrecheckEnabled ?? resolveGoalAuthorReviewerPrecheckEnabled();
|
|
7412
|
+
const precheck = await executeGoalAuthorReviewerPrecheck(
|
|
7413
|
+
reviewerPrecheckEnabled,
|
|
7414
|
+
authored.document,
|
|
7415
|
+
authored.authorRunId,
|
|
7416
|
+
(document) => (resolvedDeps.reviewerPrecheck
|
|
7417
|
+
? resolvedDeps.reviewerPrecheck(document, authored.authorRunId)
|
|
7418
|
+
: runGoalAuthorReviewerPrecheck(document)),
|
|
7419
|
+
);
|
|
7420
|
+
if (precheck.result) {
|
|
7421
|
+
authored.reviewerPrecheck = precheck.result;
|
|
7422
|
+
if (precheck.status === 'completed') authored.document = precheck.result.revisedDocument;
|
|
7423
|
+
}
|
|
7070
7424
|
const stampedAt = fileDeps.now?.() ?? new Date();
|
|
7071
7425
|
const identity = identityLines(ask, cwd, fileDeps.env ?? process.env, stampedAt);
|
|
7072
7426
|
if (identity.length) {
|
|
@@ -167,8 +167,10 @@ export function applyGraphOverlays(
|
|
|
167
167
|
rejections.push({ kind: 'unknown-target', overlayId: overlay.overlayId, target: overlay.target });
|
|
168
168
|
continue;
|
|
169
169
|
}
|
|
170
|
+
const beforeNodes = new Map(next.nodes.map((node) => [node.nodeId, node]));
|
|
170
171
|
const beforeVisits = new Map(next.nodes.map((node) => [node.nodeId, node.maxVisits]));
|
|
171
|
-
const beforeRoutes =
|
|
172
|
+
const beforeRoutes = graphRouteMap(next);
|
|
173
|
+
const beforeEdgeMap = edgeMapOf(next);
|
|
172
174
|
for (const op of overlay.patch) {
|
|
173
175
|
const resolved = resolvePointer(next, op.path);
|
|
174
176
|
if (!resolved) { rejections.push({ kind: 'bad-pointer', overlayId: overlay.overlayId, path: op.path }); continue; }
|
|
@@ -190,15 +192,27 @@ export function applyGraphOverlays(
|
|
|
190
192
|
if (op.op === 'remove') delete bag[key]; else bag[key] = op.value;
|
|
191
193
|
} else rejections.push({ kind: 'bad-pointer', overlayId: overlay.overlayId, path: op.path });
|
|
192
194
|
}
|
|
195
|
+
for (const node of next.nodes) {
|
|
196
|
+
if (beforeNodes.has(node.nodeId)) continue;
|
|
197
|
+
patches.push({ overlayId: overlay.overlayId, field: 'node-added', node: node.nodeId, kind: node.kind, maxVisits: node.maxVisits });
|
|
198
|
+
}
|
|
199
|
+
const afterRoutes = graphRouteMap(next);
|
|
200
|
+
for (const [key, route] of afterRoutes) {
|
|
201
|
+
const before = beforeRoutes.get(key);
|
|
202
|
+
if (before && before.to !== route.to) {
|
|
203
|
+
patches.push({ overlayId: overlay.overlayId, field: 'edge-rerouted', from: route.from, outcome: route.outcome, was: before.to, to: route.to });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
193
206
|
for (const node of next.nodes) {
|
|
194
207
|
const before = beforeVisits.get(node.nodeId);
|
|
195
208
|
if (before !== undefined && before !== node.maxVisits) {
|
|
196
209
|
patches.push({ overlayId: overlay.overlayId, field: 'maxVisits', node: node.nodeId, before, after: node.maxVisits });
|
|
197
210
|
}
|
|
198
211
|
}
|
|
199
|
-
const
|
|
200
|
-
for (const
|
|
201
|
-
const
|
|
212
|
+
const afterEdgeMap = edgeMapOf(next);
|
|
213
|
+
for (const node of Object.keys(beforeEdgeMap)) {
|
|
214
|
+
const before = beforeEdgeMap[node] ?? [];
|
|
215
|
+
const after = afterEdgeMap[node] ?? [];
|
|
202
216
|
if (before.length !== after.length || before.some((destination, index) => destination !== after[index])) {
|
|
203
217
|
patches.push({ overlayId: overlay.overlayId, field: 'routes', node, before, after });
|
|
204
218
|
}
|
|
@@ -246,6 +260,18 @@ export function applyGraphOverlays(
|
|
|
246
260
|
return { ok: true, template: next, overlayIds: applied, patches };
|
|
247
261
|
}
|
|
248
262
|
|
|
263
|
+
/** Keep outcome names while comparing route changes; the compiled edge map deliberately drops them. */
|
|
264
|
+
function graphRouteMap(template: GraphTemplateSpec): Map<string, { from: string; outcome: string; to: string }> {
|
|
265
|
+
const routes = new Map<string, { from: string; outcome: string; to: string }>();
|
|
266
|
+
for (const [index, edge] of template.edges.entries()) {
|
|
267
|
+
if (edge.to) routes.set(`${edge.from}\u0000direct\u0000${index}`, { from: edge.from, outcome: '', to: edge.to });
|
|
268
|
+
for (const [outcome, to] of Object.entries(edge.map ?? {})) {
|
|
269
|
+
routes.set(`${edge.from}\u0000${edge.on ?? 'outcome'}\u0000${outcome}`, { from: edge.from, outcome, to });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return routes;
|
|
273
|
+
}
|
|
274
|
+
|
|
249
275
|
export interface OverlayLoadResult {
|
|
250
276
|
readonly overlays: readonly GraphOverlaySpec[];
|
|
251
277
|
readonly errors: readonly GraphParseIssue[];
|
|
@@ -26,7 +26,9 @@ export type OverlayRejection =
|
|
|
26
26
|
|
|
27
27
|
export type OverlayPatch =
|
|
28
28
|
| { readonly overlayId: string; readonly field: 'maxVisits'; readonly node: string; readonly before: number; readonly after: number }
|
|
29
|
-
| { readonly overlayId: string; readonly field: 'routes'; readonly node: string; readonly before: readonly string[]; readonly after: readonly string[] }
|
|
29
|
+
| { readonly overlayId: string; readonly field: 'routes'; readonly node: string; readonly before: readonly string[]; readonly after: readonly string[] }
|
|
30
|
+
| { readonly overlayId: string; readonly field: 'node-added'; readonly node: string; readonly kind: string; readonly maxVisits: number }
|
|
31
|
+
| { readonly overlayId: string; readonly field: 'edge-rerouted'; readonly from: string; readonly outcome: string; readonly was: string; readonly to: string };
|
|
30
32
|
|
|
31
33
|
export type OverlayResult =
|
|
32
34
|
| { ok: true; template: GraphTemplate; patches: readonly OverlayPatch[] }
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
import { evaluateOverlayCondition, parseOverlayCondition } from './graph-overlay-condition.js';
|
|
6
|
+
import type { GraphParseIssue } from './graph-yaml.js';
|
|
7
|
+
|
|
8
|
+
/** L1 profile: a deterministic state bundle and references to already-declared overlays. */
|
|
9
|
+
export interface GraphProfileSpec {
|
|
10
|
+
readonly profileId: string;
|
|
11
|
+
readonly appliesWhen: string;
|
|
12
|
+
readonly state: Readonly<Record<string, string | number | boolean>>;
|
|
13
|
+
readonly overlays: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface GraphProfileParseResult {
|
|
17
|
+
readonly profile?: GraphProfileSpec;
|
|
18
|
+
readonly errors: readonly GraphParseIssue[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function parseGraphProfileYaml(source: string, label = '<inline>'): GraphProfileParseResult {
|
|
22
|
+
let raw: unknown;
|
|
23
|
+
try { raw = parseYaml(source); }
|
|
24
|
+
catch (error) {
|
|
25
|
+
return { errors: [{ path: label, message: `YAML 파싱 실패: ${error instanceof Error ? error.message : String(error)}` }] };
|
|
26
|
+
}
|
|
27
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
28
|
+
return { errors: [{ path: label, message: 'YAML 최상위가 맵이 아니다' }] };
|
|
29
|
+
const doc = raw as Record<string, unknown>;
|
|
30
|
+
const errors: GraphParseIssue[] = [];
|
|
31
|
+
const profileId = typeof doc.profile_id === 'string' && /^[a-z][a-z0-9-]*$/.test(doc.profile_id) ? doc.profile_id : undefined;
|
|
32
|
+
if (!profileId) errors.push({ path: `${label}/profile_id`, message: 'profile_id는 소문자·숫자·하이픈 식별자여야 한다' });
|
|
33
|
+
const appliesWhen = typeof doc.applies_when === 'string' ? doc.applies_when : undefined;
|
|
34
|
+
if (!appliesWhen || !parseOverlayCondition(appliesWhen).ok)
|
|
35
|
+
errors.push({ path: `${label}/applies_when`, message: 'applies_when은 오버레이 조건 한 개(key op literal)여야 한다' });
|
|
36
|
+
const stateRaw = doc.state;
|
|
37
|
+
const state: Record<string, string | number | boolean> = {};
|
|
38
|
+
if (!stateRaw || typeof stateRaw !== 'object' || Array.isArray(stateRaw)) {
|
|
39
|
+
errors.push({ path: `${label}/state`, message: 'state는 스칼라 값만 담는 맵이어야 한다' });
|
|
40
|
+
} else {
|
|
41
|
+
for (const [key, value] of Object.entries(stateRaw as Record<string, unknown>)) {
|
|
42
|
+
if (!/^[a-z_][a-z0-9_]*$/i.test(key) || !['string', 'number', 'boolean'].includes(typeof value)
|
|
43
|
+
|| (typeof value === 'number' && !Number.isFinite(value))) {
|
|
44
|
+
errors.push({ path: `${label}/state/${key}`, message: 'state 키와 값은 조건 파서가 다루는 키·문자열·유한수·불리언이어야 한다' });
|
|
45
|
+
} else state[key] = value as string | number | boolean;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const overlaysRaw = doc.overlays;
|
|
49
|
+
const overlays = Array.isArray(overlaysRaw) ? overlaysRaw.filter((value): value is string => typeof value === 'string') : undefined;
|
|
50
|
+
if (!Array.isArray(overlaysRaw) || !overlays || overlays.length !== overlaysRaw.length || new Set(overlays).size !== overlays.length)
|
|
51
|
+
errors.push({ path: `${label}/overlays`, message: 'overlays는 중복 없는 문자열 목록이어야 한다' });
|
|
52
|
+
if (errors.length > 0) return { errors };
|
|
53
|
+
return { profile: { profileId: profileId!, appliesWhen: appliesWhen!, state, overlays: overlays! }, errors };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface GraphProfileLoadResult {
|
|
57
|
+
readonly profiles: readonly GraphProfileSpec[];
|
|
58
|
+
readonly errors: readonly GraphParseIssue[];
|
|
59
|
+
readonly scannedFiles: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function loadGraphProfiles(dir: string): GraphProfileLoadResult {
|
|
63
|
+
let files: string[];
|
|
64
|
+
try { files = readdirSync(dir).filter((file) => file.endsWith('.yaml') || file.endsWith('.yml')).sort(); }
|
|
65
|
+
catch (error) { return { profiles: [], errors: [{ path: dir, message: `프로필 디렉토리를 못 읽었다: ${error instanceof Error ? error.message : String(error)}` }], scannedFiles: 0 }; }
|
|
66
|
+
const errors: GraphParseIssue[] = [];
|
|
67
|
+
const profiles: GraphProfileSpec[] = [];
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
try {
|
|
70
|
+
const parsed = parseGraphProfileYaml(readFileSync(join(dir, file), 'utf8'), file);
|
|
71
|
+
errors.push(...parsed.errors);
|
|
72
|
+
if (parsed.profile) profiles.push(parsed.profile);
|
|
73
|
+
} catch (error) { errors.push({ path: file, message: `읽기 실패: ${error instanceof Error ? error.message : String(error)}` }); }
|
|
74
|
+
}
|
|
75
|
+
const seen = new Set<string>();
|
|
76
|
+
for (const profile of profiles) {
|
|
77
|
+
if (seen.has(profile.profileId)) errors.push({ path: `${dir}/${profile.profileId}`, message: `profile_id '${profile.profileId}'가 중복이다` });
|
|
78
|
+
seen.add(profile.profileId);
|
|
79
|
+
}
|
|
80
|
+
return errors.length ? { profiles: [], errors, scannedFiles: files.length } : { profiles, errors, scannedFiles: files.length };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function defaultProfilesDir(): string {
|
|
84
|
+
return join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'graphs', 'profiles');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface GraphProfileSelection {
|
|
88
|
+
readonly applied: readonly GraphProfileSpec[];
|
|
89
|
+
readonly errors: readonly string[];
|
|
90
|
+
readonly state: Readonly<Record<string, unknown>>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Match all profiles deterministically; conflicting owned state rejects the whole profile set. */
|
|
94
|
+
export function selectGraphProfiles(
|
|
95
|
+
profiles: readonly GraphProfileSpec[],
|
|
96
|
+
state: Readonly<Record<string, unknown>>,
|
|
97
|
+
): GraphProfileSelection {
|
|
98
|
+
const applied = profiles.filter((profile) => evaluateOverlayCondition(profile.appliesWhen, state).kind === 'applies');
|
|
99
|
+
const owned = new Map<string, string | number | boolean>();
|
|
100
|
+
const errors: string[] = [];
|
|
101
|
+
for (const profile of applied) for (const [key, value] of Object.entries(profile.state)) {
|
|
102
|
+
if (owned.has(key) && owned.get(key) !== value) errors.push(`profile state conflict: ${key} (${String(owned.get(key))} vs ${String(value)})`);
|
|
103
|
+
else owned.set(key, value);
|
|
104
|
+
}
|
|
105
|
+
if (errors.length) return { applied: [], errors, state };
|
|
106
|
+
return { applied, errors, state: { ...state, ...Object.fromEntries(owned) } };
|
|
107
|
+
}
|