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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Coding-agent terminal preset.
|
|
2
2
|
//
|
|
3
3
|
// Thin wrapper over TerminalSessionRegistry that knows how to spawn
|
|
4
|
-
// a "live agent host" session (claude-code / codex) with:
|
|
4
|
+
// a "live agent host" session (claude-code / codex / grok) with:
|
|
5
5
|
//
|
|
6
6
|
// • ELANOUS_SESSION_ID env so the child can self-identify in any
|
|
7
7
|
// scripts/hooks it runs
|
|
@@ -22,6 +22,8 @@ import type { ChromeControlResult } from '../ui/modal-adapter.js';
|
|
|
22
22
|
export interface SpawnCodingAgentOpts {
|
|
23
23
|
brand: CodingAgentBrand;
|
|
24
24
|
cwd: string;
|
|
25
|
+
/** Optional stable UUID used to bind scoped mission-line authority to this PTY. */
|
|
26
|
+
id?: string;
|
|
25
27
|
/** Extra CLI args to pass through after the binary name. */
|
|
26
28
|
extraArgs?: string[];
|
|
27
29
|
/** Override title. Defaults to `<brand> [<basename(cwd)>]`. */
|
|
@@ -74,8 +76,9 @@ export function spawnCodingAgent(
|
|
|
74
76
|
|
|
75
77
|
const cwdName = basenameSafe(opts.cwd);
|
|
76
78
|
const title = opts.title ?? `${opts.brand} [${cwdName}]`;
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
+
const extraArgs = opts.extraArgs ?? (opts.brand === 'grok' ? ['--always-approve'] : undefined);
|
|
80
|
+
const rawCommand = extraArgs && extraArgs.length > 0
|
|
81
|
+
? `${binary} ${extraArgs.join(' ')}`
|
|
79
82
|
: binary;
|
|
80
83
|
// Only `claude` reads the macOS keychain — codex does not. Gate
|
|
81
84
|
// the SSH unlock preamble on brand to avoid spawning a `sh -c`
|
|
@@ -92,8 +95,12 @@ export function spawnCodingAgent(
|
|
|
92
95
|
// SSH keychain wrap and any other path-relative lookup. The
|
|
93
96
|
// captured env mirrors what a fresh Terminal.app login would see
|
|
94
97
|
// (see shell-env-bootstrap.ts), so it's the right baseline.
|
|
98
|
+
const callerEnv = { ...(opts.env ?? {}) };
|
|
99
|
+
const grokAuthEnvKeys = ['XAI_API_KEY', 'GROK_API_KEY', 'GROK_CODE_XAI_API_KEY'] as const;
|
|
100
|
+
if (opts.brand === 'grok') for (const key of grokAuthEnvKeys) delete callerEnv[key];
|
|
95
101
|
const env: Record<string, string> = buildPtyEnv({
|
|
96
|
-
...
|
|
102
|
+
...callerEnv,
|
|
103
|
+
...(opts.brand === 'grok' ? { GROK_DISABLE_API_KEY_AUTH: '1' } : {}),
|
|
97
104
|
ELANOUS_AGENT_BRAND: opts.brand,
|
|
98
105
|
// Session id is filled in below once we know it.
|
|
99
106
|
TERM: 'xterm-ghostty',
|
|
@@ -104,10 +111,11 @@ export function spawnCodingAgent(
|
|
|
104
111
|
COLORTERM: 'truecolor',
|
|
105
112
|
CLICOLOR: '1',
|
|
106
113
|
CLICOLOR_FORCE: '1',
|
|
107
|
-
});
|
|
114
|
+
}, process.env, { unset: opts.brand === 'grok' ? grokAuthEnvKeys : [] });
|
|
108
115
|
|
|
109
116
|
const session = deps.registry.spawn(
|
|
110
117
|
{
|
|
118
|
+
id: opts.id,
|
|
111
119
|
title,
|
|
112
120
|
cwd: opts.cwd,
|
|
113
121
|
command,
|
|
@@ -138,6 +146,7 @@ function binaryForBrand(brand: CodingAgentBrand): string {
|
|
|
138
146
|
case 'claude-code': return 'claude';
|
|
139
147
|
case 'codex': return 'codex';
|
|
140
148
|
case 'gemini': return 'gemini';
|
|
149
|
+
case 'grok': return 'grok';
|
|
141
150
|
}
|
|
142
151
|
}
|
|
143
152
|
|
|
@@ -33,7 +33,7 @@ import { defaultControlSignalBus, type ControlSignalBus } from '../input/control
|
|
|
33
33
|
|
|
34
34
|
export type SessionState = 'foreground' | 'background' | 'exited';
|
|
35
35
|
export type SessionKind = 'shell' | 'coding-agent';
|
|
36
|
-
export type CodingAgentBrand = 'claude-code' | 'codex' | 'gemini';
|
|
36
|
+
export type CodingAgentBrand = 'claude-code' | 'codex' | 'gemini' | 'grok';
|
|
37
37
|
|
|
38
38
|
export interface TerminalSession {
|
|
39
39
|
readonly id: string;
|
package/src/tool-hints/gate.ts
CHANGED
|
@@ -144,6 +144,7 @@ export function evaluateGate(
|
|
|
144
144
|
if (signals.intentResearch) {
|
|
145
145
|
bumpIfEnabled(enabled, boost, 'web_search', 2);
|
|
146
146
|
bumpIfEnabled(enabled, boost, 'omni_search', 2);
|
|
147
|
+
bumpIfEnabled(enabled, boost, 'web_fetch', 2);
|
|
147
148
|
}
|
|
148
149
|
if (signals.intentDiagram) {
|
|
149
150
|
bumpIfEnabled(enabled, boost, 'mermaid_render', 2);
|
|
@@ -15,6 +15,7 @@ export const agentRuntime: ToolRuntime<Record<string, unknown>, AgentToolResult>
|
|
|
15
15
|
hostTools: ctx.agentHostTools,
|
|
16
16
|
dispatchTool: ctx.agentDispatchTool,
|
|
17
17
|
buildChildToolCatalog: ctx.buildChildToolCatalog,
|
|
18
|
+
inheritGeneralPurposeToolCatalog: ctx.inheritGeneralPurposeToolCatalog,
|
|
18
19
|
signal: ctx.signal,
|
|
19
20
|
});
|
|
20
21
|
},
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { awaitGlobalPersonaLoad, getGlobalPersonaRegistry } from '../persona/global-registry.js';
|
|
4
|
+
import { getSecretAsync } from '../nexus/config/secrets/index.js';
|
|
5
|
+
import { commentLinearIssue, createLinearAttachment, uploadLinearFile } from '../connectors/linear.js';
|
|
6
|
+
import { performBrowserAction, type BrowserActionDeps } from '../harness/browser-act.js';
|
|
7
|
+
import { decideActionBoundary } from '../harness/browser-act-boundary.js';
|
|
8
|
+
import { BROWSER_ACT_CATEGORY, BROWSER_ACT_EVENT } from '../harness/browser-act-step.js';
|
|
9
|
+
import type { BrowserActionResult } from '../harness/browser-act.js';
|
|
10
|
+
import { createCdpClientFromEndpoint } from '../browser-cdp/client.js';
|
|
11
|
+
import { orchestrationId } from '../grounding/ref-index.js';
|
|
12
|
+
import { debug } from '../debug/log.js';
|
|
13
|
+
import { requestConfirmation } from '../hitl/confirm.js';
|
|
14
|
+
import type { ToolRuntime, ToolRuntimeContext } from './types.js';
|
|
15
|
+
import { coordinateBrowserRoundtrip } from '../agent-mission/browser-roundtrip-coordinator.js';
|
|
16
|
+
import { appendRunLedgerEntry } from '../self-implement/run-ledger.js';
|
|
17
|
+
|
|
18
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
19
|
+
const SELECTION_COMMENT = '이것도 반영';
|
|
20
|
+
const PAYWALL_PATTERN = /(paywall|subscribe\s?to\s?continue|subscription\srequired|유료\s?구독)/i;
|
|
21
|
+
const LOGIN_PATTERN = /(login\srequired|please\s+log\s?in|sign\s?in\s+to\s+continue|authentication\srequired|로그인\s*(이|가)?\s*필요|로그인\s*후\s*계속)/i;
|
|
22
|
+
const ASIDE_HAND_NODE_BRANCH = 'ASIDE-HAND-NODE·BROWSER-ROUNDTRIP-ASIDE' as const;
|
|
23
|
+
const PAGE_INSPECT_TIMEOUT_MS = 3_000;
|
|
24
|
+
|
|
25
|
+
export interface BrowserHandArgs {
|
|
26
|
+
url: string;
|
|
27
|
+
target: string;
|
|
28
|
+
armed: boolean;
|
|
29
|
+
linearSubtaskId: string;
|
|
30
|
+
persona?: string;
|
|
31
|
+
alternateUrl?: string;
|
|
32
|
+
includeThisToo?: boolean;
|
|
33
|
+
selection?: { text?: string; tab?: string };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface BrowserHandRepairNode extends Record<string, unknown> {
|
|
37
|
+
branch: typeof ASIDE_HAND_NODE_BRANCH;
|
|
38
|
+
orchestrationId: string;
|
|
39
|
+
blockedOn: string;
|
|
40
|
+
detourUrl: string;
|
|
41
|
+
outcome: 'detoured' | 'detour-failed';
|
|
42
|
+
graphEvent: {
|
|
43
|
+
seq: number;
|
|
44
|
+
ts: string;
|
|
45
|
+
type: 'node-added';
|
|
46
|
+
node: string;
|
|
47
|
+
kind: 'hand';
|
|
48
|
+
decider: 'browser-hand';
|
|
49
|
+
reason: string;
|
|
50
|
+
who: 'Elanous';
|
|
51
|
+
what: string;
|
|
52
|
+
missionId: string;
|
|
53
|
+
runId?: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface BrowserHandResult extends Record<string, unknown> {
|
|
58
|
+
ok: boolean;
|
|
59
|
+
output: string;
|
|
60
|
+
captureUrl?: string;
|
|
61
|
+
attachmentId?: string;
|
|
62
|
+
selectionReflected?: boolean;
|
|
63
|
+
blocked?: boolean;
|
|
64
|
+
detoured?: boolean;
|
|
65
|
+
repairNode?: BrowserHandRepairNode;
|
|
66
|
+
reason?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface BrowserHandDeps {
|
|
70
|
+
browserAct?: (request: Parameters<typeof performBrowserAction>[0], deps?: BrowserActionDeps) => Promise<BrowserActionResult>;
|
|
71
|
+
browserActDeps?: BrowserActionDeps;
|
|
72
|
+
readCapture?: (path: string) => Promise<Buffer>;
|
|
73
|
+
getApiKey?: (name: string) => Promise<string | undefined>;
|
|
74
|
+
upload?: typeof uploadLinearFile;
|
|
75
|
+
attach?: typeof createLinearAttachment;
|
|
76
|
+
reflectSelection?: (input: { issueId: string; body: string }) => Promise<boolean>;
|
|
77
|
+
resolvePersona?: (id: string) => Promise<NonNullable<Parameters<typeof performBrowserAction>[0]['persona']> | undefined>;
|
|
78
|
+
/** Read-only inspection seam. A missing/unavailable observation is unknown, not unblocked. */
|
|
79
|
+
readPageText?: (url: string, port: number) => Promise<string | undefined>;
|
|
80
|
+
confirmHuman?: (input: { url: string; target: string }, ctx?: ToolRuntimeContext) => Promise<boolean>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function readPageTextWithCdp(url: string, port: number): Promise<string | undefined> {
|
|
84
|
+
let client: Awaited<ReturnType<typeof createCdpClientFromEndpoint>> | undefined;
|
|
85
|
+
try {
|
|
86
|
+
client = await createCdpClientFromEndpoint(port, { attachTimeoutMs: PAGE_INSPECT_TIMEOUT_MS, timeoutMs: PAGE_INSPECT_TIMEOUT_MS });
|
|
87
|
+
const page = await client.evaluate('({ href: location.href, text: document.body?.innerText ?? "" })');
|
|
88
|
+
if (!page || typeof page !== 'object' || !('href' in page) || !('text' in page)) return undefined;
|
|
89
|
+
const inspected = page as { href?: unknown; text?: unknown };
|
|
90
|
+
if (typeof inspected.href !== 'string' || typeof inspected.text !== 'string') return undefined;
|
|
91
|
+
const observedUrl = new URL(inspected.href);
|
|
92
|
+
const requestedUrl = new URL(url);
|
|
93
|
+
if (observedUrl.origin !== requestedUrl.origin || observedUrl.pathname !== requestedUrl.pathname || observedUrl.search !== requestedUrl.search) return undefined;
|
|
94
|
+
return inspected.text.slice(0, 20_000);
|
|
95
|
+
} catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
} finally {
|
|
98
|
+
try { await client?.close(); } catch { /* attached browser remains user-owned */ }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function blockedKind(value: string | undefined): 'login' | 'paywall' | undefined {
|
|
103
|
+
if (!value) return undefined;
|
|
104
|
+
if (PAYWALL_PATTERN.test(value)) return 'paywall';
|
|
105
|
+
return LOGIN_PATTERN.test(value) ? 'login' : undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function failureBlockKind(action: BrowserActionResult): 'login' | 'paywall' | undefined {
|
|
109
|
+
return action.ok ? undefined : blockedKind(action.error);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function recordRepairNode(node: BrowserHandRepairNode, deps: BrowserHandDeps): void {
|
|
113
|
+
try { debug.log('agent-mission', 'browser-repair-node', node); } catch { /* observability is fail-soft */ }
|
|
114
|
+
try { deps.browserActDeps?.observe?.('repair-node', node); } catch { /* observers must not alter the browser result */ }
|
|
115
|
+
const graphEvent = node.graphEvent;
|
|
116
|
+
if (!graphEvent.runId) return;
|
|
117
|
+
try {
|
|
118
|
+
// The external browser result and its one-retry repair decision become a real
|
|
119
|
+
// sequenced node-added row on the active research run, not just a debug event.
|
|
120
|
+
appendRunLedgerEntry({
|
|
121
|
+
timestamp: graphEvent.ts,
|
|
122
|
+
runId: graphEvent.runId,
|
|
123
|
+
event: graphEvent.type,
|
|
124
|
+
data: {
|
|
125
|
+
node: graphEvent.node,
|
|
126
|
+
kind: graphEvent.kind,
|
|
127
|
+
decider: graphEvent.decider,
|
|
128
|
+
reason: graphEvent.reason,
|
|
129
|
+
who: graphEvent.who,
|
|
130
|
+
what: graphEvent.what,
|
|
131
|
+
missionId: graphEvent.missionId,
|
|
132
|
+
orchestrationId: node.orchestrationId,
|
|
133
|
+
outcome: node.outcome,
|
|
134
|
+
blockedOn: node.blockedOn,
|
|
135
|
+
detourUrl: node.detourUrl,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
debug.log('agent-mission', 'browser-repair-node-ledger-recorded', {
|
|
139
|
+
runId: graphEvent.runId, node: graphEvent.node, orchestrationId: node.orchestrationId,
|
|
140
|
+
});
|
|
141
|
+
} catch (error) {
|
|
142
|
+
try { debug.log('agent-mission', 'browser-repair-node-ledger-failed', {
|
|
143
|
+
runId: graphEvent.runId, node: graphEvent.node,
|
|
144
|
+
error: error instanceof Error ? error.message : String(error),
|
|
145
|
+
}, { level: 'warn' }); } catch { /* graph evidence must remain fail-soft */ }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function createRepairNode(input: {
|
|
150
|
+
block: 'login' | 'paywall';
|
|
151
|
+
sourceUrl: string;
|
|
152
|
+
detourUrl: string;
|
|
153
|
+
outcome: 'detoured' | 'detour-failed';
|
|
154
|
+
issueId: string;
|
|
155
|
+
deps: BrowserHandDeps;
|
|
156
|
+
}): BrowserHandRepairNode {
|
|
157
|
+
const runId = input.deps.browserActDeps?.getRunId?.() ?? undefined;
|
|
158
|
+
const orchestration = orchestrationId('aside-hand-node', runId ?? input.issueId);
|
|
159
|
+
const ts = new Date().toISOString();
|
|
160
|
+
const graphEvent = {
|
|
161
|
+
seq: 1 as const,
|
|
162
|
+
ts,
|
|
163
|
+
type: 'node-added' as const,
|
|
164
|
+
node: `browser-repair-${orchestration}`,
|
|
165
|
+
kind: 'hand' as const,
|
|
166
|
+
decider: 'browser-hand' as const,
|
|
167
|
+
reason: `${input.block} blocked source; one alternate source checked`,
|
|
168
|
+
who: 'Elanous' as const,
|
|
169
|
+
what: input.outcome === 'detoured' ? `Continue browser work from ${input.detourUrl}` : 'Stop after blocked browser source',
|
|
170
|
+
missionId: input.issueId,
|
|
171
|
+
...(runId ? { runId } : {}),
|
|
172
|
+
};
|
|
173
|
+
return {
|
|
174
|
+
branch: ASIDE_HAND_NODE_BRANCH,
|
|
175
|
+
orchestrationId: orchestration,
|
|
176
|
+
blockedOn: `${input.block}:${input.sourceUrl}`,
|
|
177
|
+
detourUrl: input.detourUrl,
|
|
178
|
+
outcome: input.outcome,
|
|
179
|
+
graphEvent,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function reflectSelectionWithLinearIssueTool(input: { issueId: string; body: string }, deps: BrowserHandDeps): Promise<boolean> {
|
|
184
|
+
const apiKey = await (deps.getApiKey ?? getSecretAsync)('connector.linear.apiKey');
|
|
185
|
+
if (!apiKey?.trim()) return false;
|
|
186
|
+
await commentLinearIssue({ apiKey, issueId: input.issueId, body: input.body });
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function loadPersona(id: string) {
|
|
191
|
+
await awaitGlobalPersonaLoad();
|
|
192
|
+
return getGlobalPersonaRegistry().get(id);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Attached-CDP browser action stays behind harness browser-act's armed, host and reversibility checks. */
|
|
196
|
+
export async function dispatchBrowserHand(args: BrowserHandArgs, _ctx?: ToolRuntimeContext, deps: BrowserHandDeps = {}): Promise<BrowserHandResult> {
|
|
197
|
+
const url = args.url.trim();
|
|
198
|
+
const target = args.target.trim();
|
|
199
|
+
const issueId = args.linearSubtaskId.trim();
|
|
200
|
+
if (!args.armed) return { ok: false, reason: 'unarmed', output: '브라우저 조작은 사람의 명시적 armed 승인 뒤에만 실행합니다.' };
|
|
201
|
+
if (!url || !target || !UUID.test(issueId)) return { ok: false, reason: 'invalid-input', output: 'URL, CSS 대상, Linear 서브태스크 UUID가 필요합니다.' };
|
|
202
|
+
let parsed: URL;
|
|
203
|
+
try { parsed = new URL(url); } catch { return { ok: false, reason: 'invalid-url', output: '절대 URL이 필요합니다.' }; }
|
|
204
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return { ok: false, reason: 'invalid-url', output: 'http(s) URL만 허용합니다.' };
|
|
205
|
+
let humanApproved = false;
|
|
206
|
+
try {
|
|
207
|
+
if (deps.confirmHuman) humanApproved = await deps.confirmHuman({ url, target }, _ctx);
|
|
208
|
+
else humanApproved = (await requestConfirmation({
|
|
209
|
+
prompt: `Browser hand action on ${url}`,
|
|
210
|
+
detail: `Target: ${target}\nExplicit human approval is required before navigation or click.`,
|
|
211
|
+
...(_ctx?.confirmChannels ? { channels: _ctx.confirmChannels } : {}),
|
|
212
|
+
onTimeout: () => false,
|
|
213
|
+
})).answer === true;
|
|
214
|
+
} catch { /* approval failure is denial */ }
|
|
215
|
+
if (!humanApproved) return { ok: false, reason: 'human-approval-required', output: '사람의 확인 승인을 받지 못해 브라우저를 조작하지 않았습니다.' };
|
|
216
|
+
|
|
217
|
+
if (!args.persona?.trim()) return { ok: false, reason: 'persona-required', output: '허용 호스트가 선언된 브라우저 페르소나가 필요합니다.' };
|
|
218
|
+
const persona = await (deps.resolvePersona ?? loadPersona)(args.persona);
|
|
219
|
+
if (!persona) return { ok: false, reason: 'persona-not-found', output: '브라우저 페르소나를 찾지 못했습니다.' };
|
|
220
|
+
if (!persona.actionHosts?.some(host => host.trim())) {
|
|
221
|
+
return { ok: false, reason: 'host-boundary-undeclared', output: '브라우저 페르소나에 허용 호스트가 선언되지 않아 이동을 시작하지 않았습니다.' };
|
|
222
|
+
}
|
|
223
|
+
const entryBoundary = decideActionBoundary({ hosts: persona.actionHosts, url, href: null });
|
|
224
|
+
if (!entryBoundary.allowed) return { ok: false, reason: 'host-boundary-blocked', output: `허용 호스트 경계가 시작 URL을 차단했습니다: ${entryBoundary.detail}` };
|
|
225
|
+
const pagePort = persona.browserPort ?? 9222;
|
|
226
|
+
const inspect = deps.readPageText ?? readPageTextWithCdp;
|
|
227
|
+
let actionUrl = url;
|
|
228
|
+
let blocked = false;
|
|
229
|
+
let detoured = false;
|
|
230
|
+
let repairNode: BrowserHandRepairNode | undefined;
|
|
231
|
+
let sourceText: string | undefined;
|
|
232
|
+
let capturedPath: string | undefined;
|
|
233
|
+
const runBrowserAction = async (actionUrl: string) => {
|
|
234
|
+
const observe = (event: string, data: Record<string, unknown>) => {
|
|
235
|
+
if (event === BROWSER_ACT_EVENT) {
|
|
236
|
+
const attachmentRef = data.attachmentRef;
|
|
237
|
+
if (typeof attachmentRef === 'string' && attachmentRef.trim()) capturedPath = attachmentRef;
|
|
238
|
+
}
|
|
239
|
+
(deps.browserActDeps?.observe ?? ((name, value) => debug.log(BROWSER_ACT_CATEGORY, name, value)))(event, data);
|
|
240
|
+
};
|
|
241
|
+
return (deps.browserAct ?? performBrowserAction)({
|
|
242
|
+
url: actionUrl, target, armed: true, entryPoint: 'tool-runtime/browser-hand', ...(persona ? { persona } : {}),
|
|
243
|
+
}, { ...deps.browserActDeps, observe, reversibilityPolicy: 'navigation-only' });
|
|
244
|
+
};
|
|
245
|
+
try { sourceText = await inspect(url, pagePort); } catch { /* unavailable observation stays unknown */ }
|
|
246
|
+
let block = blockedKind(sourceText);
|
|
247
|
+
if (block) {
|
|
248
|
+
blocked = true;
|
|
249
|
+
const alternate = args.alternateUrl?.trim() ?? '';
|
|
250
|
+
let alternateAllowed = false;
|
|
251
|
+
let alternateParsed: URL | undefined;
|
|
252
|
+
try { alternateParsed = new URL(alternate); } catch { /* no valid fallback */ }
|
|
253
|
+
if (alternateParsed && ['http:', 'https:'].includes(alternateParsed.protocol)) {
|
|
254
|
+
const boundary = decideActionBoundary({ hosts: persona.actionHosts, url: alternate, href: null });
|
|
255
|
+
alternateAllowed = boundary.allowed;
|
|
256
|
+
}
|
|
257
|
+
let alternateText: string | undefined;
|
|
258
|
+
if (alternateAllowed) {
|
|
259
|
+
try { alternateText = await inspect(alternate, pagePort); } catch { /* unknown is allowed only after the source was verified blocked */ }
|
|
260
|
+
}
|
|
261
|
+
if (alternateAllowed && !blockedKind(alternateText)) {
|
|
262
|
+
actionUrl = alternate;
|
|
263
|
+
detoured = true;
|
|
264
|
+
}
|
|
265
|
+
if (!detoured) {
|
|
266
|
+
repairNode = createRepairNode({ block, sourceUrl: url, detourUrl: '', outcome: 'detour-failed', issueId, deps });
|
|
267
|
+
recordRepairNode(repairNode, deps);
|
|
268
|
+
return { ok: false, blocked, detoured, repairNode, reason: 'blocked-source-no-safe-alternate', output: '로그인·페이월이 관측됐지만 허용된 대체 출처를 확인하지 못해 브라우저 조작을 멈췄습니다.' };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let action = await runBrowserAction(actionUrl);
|
|
273
|
+
if (!action.ok && !blocked) {
|
|
274
|
+
block = failureBlockKind(action);
|
|
275
|
+
const alternate = args.alternateUrl?.trim() ?? '';
|
|
276
|
+
let alternateParsed: URL | undefined;
|
|
277
|
+
try { alternateParsed = new URL(alternate); } catch { /* no valid fallback */ }
|
|
278
|
+
let alternateText: string | undefined;
|
|
279
|
+
if (block && alternateParsed && ['http:', 'https:'].includes(alternateParsed.protocol)
|
|
280
|
+
&& decideActionBoundary({ hosts: persona.actionHosts, url: alternate, href: null }).allowed) {
|
|
281
|
+
try { alternateText = await inspect(alternate, pagePort); } catch { /* unknown is allowed after an explicit login/paywall error */ }
|
|
282
|
+
}
|
|
283
|
+
if (block && alternateParsed && ['http:', 'https:'].includes(alternateParsed.protocol)
|
|
284
|
+
&& decideActionBoundary({ hosts: persona.actionHosts, url: alternate, href: null }).allowed
|
|
285
|
+
&& !blockedKind(alternateText)) {
|
|
286
|
+
blocked = true;
|
|
287
|
+
actionUrl = alternate;
|
|
288
|
+
action = await runBrowserAction(actionUrl);
|
|
289
|
+
detoured = true;
|
|
290
|
+
} else if (block) {
|
|
291
|
+
blocked = true;
|
|
292
|
+
}
|
|
293
|
+
if (block) {
|
|
294
|
+
repairNode = createRepairNode({ block, sourceUrl: url, detourUrl: detoured ? alternate : '', outcome: detoured && action.ok ? 'detoured' : 'detour-failed', issueId, deps });
|
|
295
|
+
recordRepairNode(repairNode, deps);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (block && !repairNode) {
|
|
299
|
+
repairNode = createRepairNode({ block, sourceUrl: url, detourUrl: detoured ? actionUrl : '', outcome: detoured && action.ok ? 'detoured' : 'detour-failed', issueId, deps });
|
|
300
|
+
recordRepairNode(repairNode, deps);
|
|
301
|
+
}
|
|
302
|
+
if (!action.ok) return { ok: false, blocked, detoured, ...(repairNode ? { repairNode } : {}), reason: action.reason, output: `브라우저 작업이 안전 경계에서 중단되었습니다: ${action.reason}` };
|
|
303
|
+
|
|
304
|
+
let captureUrl: string | undefined;
|
|
305
|
+
let attachmentId: string | undefined;
|
|
306
|
+
const observedPath = (action.observed as unknown as { attachmentRef?: unknown } | undefined)?.attachmentRef;
|
|
307
|
+
const capturePath = capturedPath ?? (typeof observedPath === 'string' ? observedPath : undefined);
|
|
308
|
+
if (!capturePath || action.observed?.captureOutcome !== 'ok') {
|
|
309
|
+
return { ok: false, reason: 'capture-missing', output: '브라우저 동작은 끝났지만 캡처 증거가 없어 Linear 첨부 완료로 처리하지 않았습니다.' };
|
|
310
|
+
}
|
|
311
|
+
const apiKey = await (deps.getApiKey ?? getSecretAsync)('connector.linear.apiKey');
|
|
312
|
+
if (!apiKey?.trim()) return { ok: false, reason: 'linear-key-missing', output: '캡처는 생성했지만 Linear 키가 없어 서브태스크 첨부를 보류했습니다.' };
|
|
313
|
+
const bytes = await (deps.readCapture ?? (async path => readFile(path)))(capturePath);
|
|
314
|
+
captureUrl = await (deps.upload ?? uploadLinearFile)({ apiKey, filename: basename(capturePath), contentType: 'image/png', body: bytes });
|
|
315
|
+
attachmentId = await (deps.attach ?? createLinearAttachment)({ apiKey, issueId, title: '브라우저 캡처', url: captureUrl });
|
|
316
|
+
|
|
317
|
+
let selectionReflected = false;
|
|
318
|
+
if (args.includeThisToo === true) {
|
|
319
|
+
const text = args.selection?.text?.trim().slice(0, 3000) ?? '';
|
|
320
|
+
const tab = args.selection?.tab?.trim().slice(0, 500) ?? '';
|
|
321
|
+
if (!text && !tab) return { ok: false, reason: 'empty-selection', ...(captureUrl ? { captureUrl } : {}), ...(attachmentId ? { attachmentId } : {}), output: '선택 문장 또는 탭 정보가 없어 Linear 반영을 건너뛰었습니다.' };
|
|
322
|
+
try {
|
|
323
|
+
selectionReflected = deps.reflectSelection
|
|
324
|
+
? await deps.reflectSelection({
|
|
325
|
+
issueId, body: `${SELECTION_COMMENT}: ${[tab, text].filter(Boolean).join(' — ')}`,
|
|
326
|
+
})
|
|
327
|
+
: await reflectSelectionWithLinearIssueTool({
|
|
328
|
+
issueId, body: `${SELECTION_COMMENT}: ${[tab, text].filter(Boolean).join(' — ')}`,
|
|
329
|
+
}, deps);
|
|
330
|
+
} catch {
|
|
331
|
+
return { ok: false, reason: 'linear-reflection-failed', ...(captureUrl ? { captureUrl } : {}), ...(attachmentId ? { attachmentId } : {}), output: '캡처는 첨부했지만 Linear 선택 반영에 실패했습니다.' };
|
|
332
|
+
}
|
|
333
|
+
if (!selectionReflected) return { ok: false, reason: 'linear-reflection-failed', ...(captureUrl ? { captureUrl } : {}), ...(attachmentId ? { attachmentId } : {}), output: '캡처는 첨부했지만 Linear 서브태스크 선택 반영이 실패했습니다.' };
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
ok: true,
|
|
338
|
+
...(captureUrl ? { captureUrl } : {}),
|
|
339
|
+
...(attachmentId ? { attachmentId } : {}),
|
|
340
|
+
...(args.includeThisToo === true ? { selectionReflected } : {}),
|
|
341
|
+
blocked,
|
|
342
|
+
detoured,
|
|
343
|
+
...(repairNode ? { repairNode } : {}),
|
|
344
|
+
output: `브라우저 캡처를 Linear 서브태스크에 첨부했습니다${selectionReflected ? ' · 선택을 “이것도 반영”으로 기록했습니다' : ''}.`,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export const browserHandRuntime: ToolRuntime<BrowserHandArgs, BrowserHandResult> = {
|
|
349
|
+
id: 'browser_hand',
|
|
350
|
+
spec: {
|
|
351
|
+
name: 'BrowserHand',
|
|
352
|
+
description: '사람이 armed 승인한 브라우저 요소 하나를 기존 harness browser-act 안전 경로로 조작·캡처하고, 캡처와 명시적 “이것도 반영” 선택을 지정한 Linear 서브태스크에 기록합니다. 로그인·페이월이면 허용된 대체 출처로 한 번 우회하고 기존 그래프 갈래에 수리 노드를 기록합니다. 메일 발송은 없습니다.',
|
|
353
|
+
parameters: {
|
|
354
|
+
type: 'object',
|
|
355
|
+
properties: {
|
|
356
|
+
url: { type: 'string' }, target: { type: 'string', description: 'CSS selector of the element to click.' },
|
|
357
|
+
armed: { type: 'boolean', description: 'Must be true only after explicit human approval.' },
|
|
358
|
+
linearSubtaskId: { type: 'string', description: 'Linear issue UUID of the active subtask.' },
|
|
359
|
+
alternateUrl: { type: 'string', description: '로그인·페이월 시 1회만 이동할 대체 출처. persona actionHosts에 포함되어야 합니다.' },
|
|
360
|
+
persona: { type: 'string', description: '허용 호스트가 선언된 브라우저 페르소나 ID.' }, includeThisToo: { type: 'boolean' },
|
|
361
|
+
selection: { type: 'object', properties: { text: { type: 'string' }, tab: { type: 'string' } }, additionalProperties: false },
|
|
362
|
+
},
|
|
363
|
+
required: ['url', 'target', 'armed', 'linearSubtaskId', 'persona'], additionalProperties: false,
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
async run(args, ctx) {
|
|
367
|
+
const { result } = await coordinateBrowserRoundtrip({
|
|
368
|
+
url: args.url,
|
|
369
|
+
target: args.target,
|
|
370
|
+
armed: args.armed,
|
|
371
|
+
...(args.persona ? { persona: args.persona } : {}),
|
|
372
|
+
...(args.alternateUrl ? { alternateUrl: args.alternateUrl } : {}),
|
|
373
|
+
humanSelection: {
|
|
374
|
+
linearSubtaskId: args.linearSubtaskId,
|
|
375
|
+
...(args.selection ? { selection: args.selection } : {}),
|
|
376
|
+
},
|
|
377
|
+
...(args.includeThisToo === undefined ? {} : { includeThisToo: args.includeThisToo }),
|
|
378
|
+
}, {}, dispatchBrowserHand, ctx);
|
|
379
|
+
return result;
|
|
380
|
+
},
|
|
381
|
+
};
|
|
@@ -34,6 +34,7 @@ import { decideTypeAction } from '../harness/browser-act-type.js';
|
|
|
34
34
|
import { requestConfirmation } from '../hitl/confirm.js';
|
|
35
35
|
import type { TypeTarget } from '../harness/bot-type-request.js';
|
|
36
36
|
import type { ToolRuntime, ToolRuntimeContext } from './types.js';
|
|
37
|
+
import { browserHandRuntime } from './browser-hand-runtime.js';
|
|
37
38
|
|
|
38
39
|
// ─── Dependency injection ───────────────────────────────────────
|
|
39
40
|
|
|
@@ -496,4 +497,4 @@ export const browserReadRuntime: ToolRuntime<BrowserReadArgs, BrowserReadResult>
|
|
|
496
497
|
|
|
497
498
|
// ─── Barrel ─────────────────────────────────────────────────────
|
|
498
499
|
|
|
499
|
-
export const ALL_BROWSER_RUNTIMES = [browserNavigateRuntime, browserReadRuntime];
|
|
500
|
+
export const ALL_BROWSER_RUNTIMES = [browserNavigateRuntime, browserReadRuntime, browserHandRuntime];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { debug } from '../debug/log.js';
|
|
2
|
+
import { commentLinearIssue, createLinearTeamIssue, moveLinearIssueToStateType } from '../connectors/linear.js';
|
|
3
|
+
import { getSecretAsync } from '../nexus/config/secrets/index.js';
|
|
4
|
+
import type { LLMToolSpec } from '../llm.js';
|
|
5
|
+
import type { ToolRuntime, ToolRuntimeContext } from './types.js';
|
|
6
|
+
|
|
7
|
+
export type ElanousLinearIssueArgs =
|
|
8
|
+
| { action: 'create'; teamKey: string; title: string; description?: string }
|
|
9
|
+
| { action: 'comment'; issueId: string; body: string }
|
|
10
|
+
| { action: 'complete'; issueId: string };
|
|
11
|
+
export interface ElanousLinearIssueResult extends Record<string, unknown> { ok: boolean; output: string }
|
|
12
|
+
|
|
13
|
+
type Deps = {
|
|
14
|
+
getApiKey?: (id: string) => Promise<string | undefined>;
|
|
15
|
+
create?: typeof createLinearTeamIssue;
|
|
16
|
+
comment?: typeof commentLinearIssue;
|
|
17
|
+
complete?: typeof moveLinearIssueToStateType;
|
|
18
|
+
fetch?: typeof fetch;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function createElanousLinearIssueRuntime(deps: Deps = {}): ToolRuntime<ElanousLinearIssueArgs, ElanousLinearIssueResult> {
|
|
22
|
+
return {
|
|
23
|
+
id: 'elanous_linear_issue',
|
|
24
|
+
surfaces: ['tui', 'mcp'],
|
|
25
|
+
spec: {
|
|
26
|
+
name: 'elanous_linear_issue',
|
|
27
|
+
description: 'Perform one explicitly requested Linear issue action: create directly in a team without a project, add a comment, or mark an issue complete. Requires connector.linear.apiKey. Never use for an action the user did not request.',
|
|
28
|
+
parameters: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
action: { type: 'string', enum: ['create', 'comment', 'complete'] },
|
|
32
|
+
teamKey: { type: 'string', description: 'Required only for create; Linear team key, such as DEMO.' },
|
|
33
|
+
title: { type: 'string', description: 'Required only for create.' },
|
|
34
|
+
description: { type: 'string', description: 'Optional create description.' },
|
|
35
|
+
issueId: { type: 'string', description: 'Required for comment and complete.' },
|
|
36
|
+
body: { type: 'string', description: 'Required only for comment.' },
|
|
37
|
+
},
|
|
38
|
+
required: ['action'],
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
},
|
|
41
|
+
} satisfies LLMToolSpec,
|
|
42
|
+
async run(args: ElanousLinearIssueArgs, _ctx: ToolRuntimeContext): Promise<ElanousLinearIssueResult> {
|
|
43
|
+
const apiKey = await (deps.getApiKey ?? getSecretAsync)('connector.linear.apiKey');
|
|
44
|
+
if (!apiKey?.trim()) return { ok: false, output: 'Linear API key is missing; run elanous connector linear set-key' };
|
|
45
|
+
const fetch = deps.fetch ?? globalThis.fetch;
|
|
46
|
+
try {
|
|
47
|
+
if (args?.action === 'create') {
|
|
48
|
+
const teamKey = typeof args.teamKey === 'string' ? args.teamKey.trim() : '';
|
|
49
|
+
const title = typeof args.title === 'string' ? args.title.trim() : '';
|
|
50
|
+
if (!teamKey || !title) return { ok: false, output: 'Linear issue 생성에는 teamKey와 title이 필요합니다.' };
|
|
51
|
+
const issueId = await (deps.create ?? createLinearTeamIssue)({ apiKey, teamKey, title,
|
|
52
|
+
...(typeof args.description === 'string' ? { description: args.description } : {}), fetch });
|
|
53
|
+
return { ok: true, output: `Linear 이슈를 생성했습니다: ${issueId}`, issueId };
|
|
54
|
+
}
|
|
55
|
+
const issueId = typeof args?.issueId === 'string' ? args.issueId.trim() : '';
|
|
56
|
+
if (!issueId) return { ok: false, output: 'Linear issueId가 필요합니다.' };
|
|
57
|
+
if (args.action === 'comment') {
|
|
58
|
+
const body = typeof args.body === 'string' ? args.body.trim() : '';
|
|
59
|
+
if (!body) return { ok: false, output: 'Linear 댓글 내용이 필요합니다.' };
|
|
60
|
+
await (deps.comment ?? commentLinearIssue)({ apiKey, issueId, body, fetch });
|
|
61
|
+
return { ok: true, output: `Linear 이슈에 댓글을 추가했습니다: ${issueId}`, issueId };
|
|
62
|
+
}
|
|
63
|
+
if (args.action === 'complete') {
|
|
64
|
+
await (deps.complete ?? moveLinearIssueToStateType)({ apiKey, issueId, type: 'completed', fetch });
|
|
65
|
+
return { ok: true, output: `Linear 이슈를 완료 상태로 바꿨습니다: ${issueId}`, issueId };
|
|
66
|
+
}
|
|
67
|
+
return { ok: false, output: '지원하지 않는 Linear 작업입니다.' };
|
|
68
|
+
} catch {
|
|
69
|
+
debug.log('tool.linear-issue', 'failed', { action: args?.action ?? 'unknown' });
|
|
70
|
+
return { ok: false, output: 'Linear 작업에 실패했습니다. 팀 키, 이슈 ID, 권한을 확인해 주세요.' };
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const elanousLinearIssueRuntime = createElanousLinearIssueRuntime();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { debug } from '../debug/log.js';
|
|
2
|
+
import type { LLMToolSpec } from '../llm.js';
|
|
3
|
+
import type { ToolRuntime, ToolRuntimeContext } from './types.js';
|
|
4
|
+
|
|
5
|
+
export interface ElanousLinearSecretaryArgs { request: string }
|
|
6
|
+
export interface ElanousLinearSecretaryResult extends Record<string, unknown> { ok: boolean; output: string }
|
|
7
|
+
|
|
8
|
+
type Runner = (request: string) => Promise<{ replyCard: string; parentIssueId: string; childIssueIds: string[] }>;
|
|
9
|
+
const productionRunner: Runner = async request =>
|
|
10
|
+
(await import('../intake-plane/linear-secretary-runtime.js')).runLinearSecretaryRequest(request);
|
|
11
|
+
let runner = productionRunner;
|
|
12
|
+
|
|
13
|
+
export function setElanousLinearSecretaryRunnerForTest(next?: Runner): () => void {
|
|
14
|
+
if (runner !== productionRunner) throw new Error('Linear secretary runner already replaced');
|
|
15
|
+
runner = next ?? productionRunner;
|
|
16
|
+
const installed = runner;
|
|
17
|
+
return () => { if (runner === installed) runner = productionRunner; };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const elanousLinearSecretaryRuntime: ToolRuntime<ElanousLinearSecretaryArgs, ElanousLinearSecretaryResult> = {
|
|
21
|
+
id: 'elanous_linear_secretary',
|
|
22
|
+
surfaces: ['tui', 'mcp'],
|
|
23
|
+
spec: {
|
|
24
|
+
name: 'elanous_linear_secretary',
|
|
25
|
+
description: 'Ground a request in repository evidence and create a Linear parent issue with 3–5 assigned subtasks. Requires an explicit due date and verified evidence. Use configured project by default; team-only creation requires `projectless=true` and exactly one explicit `teamKey=<KEY>` token in the request.',
|
|
26
|
+
parameters: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: { request: { type: 'string', minLength: 1, description: 'The user request. Include an explicit YYYY-MM-DD due date.' } },
|
|
29
|
+
required: ['request'],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
},
|
|
32
|
+
} satisfies LLMToolSpec,
|
|
33
|
+
async run(args: ElanousLinearSecretaryArgs, _ctx: ToolRuntimeContext): Promise<ElanousLinearSecretaryResult> {
|
|
34
|
+
const request = typeof args?.request === 'string' ? args.request.trim() : '';
|
|
35
|
+
if (!request) return { ok: false, output: 'Linear 비서 요청 내용이 필요합니다.' };
|
|
36
|
+
try {
|
|
37
|
+
const result = await runner(request);
|
|
38
|
+
debug.log('tool.linear-secretary', 'created', { childCount: result.childIssueIds.length });
|
|
39
|
+
return { ok: true, output: result.replyCard, parentIssueId: result.parentIssueId, childIssueIds: result.childIssueIds };
|
|
40
|
+
} catch (error) {
|
|
41
|
+
// The existing secretary validates key, project, evidence and dates before creating issues.
|
|
42
|
+
const message = error instanceof Error ? error.message : 'Linear 비서 실행 실패';
|
|
43
|
+
// Error.name is caller-controlled and may itself contain connector secrets.
|
|
44
|
+
debug.log('tool.linear-secretary', 'failed', { errorType: error instanceof Error ? 'Error' : 'unknown' });
|
|
45
|
+
const safeMessage = [
|
|
46
|
+
'Linear API key is missing; run elanous connector linear set-key',
|
|
47
|
+
'Linear COO 프로젝트 설정이 없어 이슈 등록을 보류했습니다. 프로젝트를 지정해 주세요.',
|
|
48
|
+
'projectless=true requires an explicit teamKey=<KEY>',
|
|
49
|
+
'저장소 근거 검색 총 시간 제한(20초)을 초과했습니다.',
|
|
50
|
+
'저장소 근거 검색 도구를 실행하지 못해 근거 확인을 완료하지 못했습니다.',
|
|
51
|
+
'저장소·문서·기억에서 확인된 근거가 없어 등록을 보류했습니다.',
|
|
52
|
+
'요청에 마감일이 없어 등록을 보류했습니다. 요청에 YYYY-MM-DD 날짜를 넣어 주세요.',
|
|
53
|
+
].find(known => message.includes(known));
|
|
54
|
+
return { ok: false, output: safeMessage ?? 'Linear 비서 작업을 진행하지 못했습니다. 키·프로젝트·요청 내용을 확인해 주세요.' };
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|