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
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { DEMO1104_STAGE_CONFIG, type DemoActId, type DemoLaneId } from './demo1104-stage.config.js';
|
|
2
|
+
import { createDemoStageConsole, type StageSnapshot } from './demo1104-stage.js';
|
|
3
|
+
import { appendFileSync, chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
|
+
import { handleGraphRunRoute, type GraphRunView } from '../../src/graph-runner/graph-run-api.js';
|
|
7
|
+
import { runGraph, type GraphRunOptions } from '../../src/graph-runner/runner.js';
|
|
8
|
+
import { appendTopicBriefingTelegramDryRun, deliverTopicBriefingWithReceipts } from '../../src/intake-plane/actions.js';
|
|
9
|
+
import type { BriefItem } from '../../src/briefing/brief-items.js';
|
|
10
|
+
import { spawnCodingAgent } from '../../src/terminal/coding-agent.js';
|
|
11
|
+
import type { TerminalSession, TerminalSessionRegistry } from '../../src/terminal/session-registry.js';
|
|
12
|
+
|
|
13
|
+
export const DEMO1104_SURFACES = [
|
|
14
|
+
{ id: 'claude-code-tui', lane: 'maker', title: 'Claude Code TUI' },
|
|
15
|
+
{ id: 'codex-tui', lane: 'maker', title: 'Codex TUI' },
|
|
16
|
+
{ id: 'web-run-graph', lane: 'secretary', title: '웹 실행 그래프' },
|
|
17
|
+
{ id: 'telegram', lane: 'secretary', title: 'Telegram (dry-run)' },
|
|
18
|
+
] as const;
|
|
19
|
+
|
|
20
|
+
export type DemoSurfaceId = typeof DEMO1104_SURFACES[number]['id'];
|
|
21
|
+
export type DemoSurfaceAdapter = {
|
|
22
|
+
start(signal: AbortSignal): Promise<void>;
|
|
23
|
+
runAct(act: typeof DEMO1104_STAGE_CONFIG.acts[number], signal: AbortSignal): Promise<void>;
|
|
24
|
+
showVideo(videoId: string, act: typeof DEMO1104_STAGE_CONFIG.acts[number], signal: AbortSignal): Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type DemoVideoTransition = { videoId: string; source: string; actId: typeof DEMO1104_STAGE_CONFIG.acts[number]['id']; title: string };
|
|
28
|
+
|
|
29
|
+
function videoTransition(videoId: string, act: typeof DEMO1104_STAGE_CONFIG.acts[number], sources: Readonly<Record<string, string>>): DemoVideoTransition {
|
|
30
|
+
const source = sources[videoId]?.trim();
|
|
31
|
+
if (!source) throw new Error(`highlight video source is missing: ${videoId}`);
|
|
32
|
+
return { videoId, source, actId: act.id, title: act.title };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function writeTelegramVideoDryRun(file: string, linearIssueId: string, transition: DemoVideoTransition): void {
|
|
36
|
+
appendFileSync(file, `${JSON.stringify({ recordedAt: new Date().toISOString(), linearIssueId, kind: 'video', ...transition })}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
37
|
+
chmodSync(file, 0o600);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type DemoTerminalTabAdapters = Pick<Record<DemoSurfaceId, DemoSurfaceAdapter>, 'claude-code-tui' | 'codex-tui'>;
|
|
41
|
+
|
|
42
|
+
/** Uses the existing dashboard session registry and spawnCodingAgent → TerminalSessionRegistry.spawn path. */
|
|
43
|
+
export function createDemo1104TuiTabAdapters(options: {
|
|
44
|
+
registry: TerminalSessionRegistry;
|
|
45
|
+
cwd: string;
|
|
46
|
+
termSize: () => { cols: number; rows: number };
|
|
47
|
+
runMission: (session: TerminalSession, act: typeof DEMO1104_STAGE_CONFIG.acts[number], signal: AbortSignal) => Promise<void>;
|
|
48
|
+
showVideo: (session: TerminalSession, transition: DemoVideoTransition, signal: AbortSignal) => Promise<void> | void;
|
|
49
|
+
videoSources: Readonly<Record<string, string>>;
|
|
50
|
+
spawnAgent?: typeof spawnCodingAgent;
|
|
51
|
+
}): DemoTerminalTabAdapters {
|
|
52
|
+
const sessions = new Map<'claude-code-tui' | 'codex-tui', TerminalSession>();
|
|
53
|
+
const create = (id: 'claude-code-tui' | 'codex-tui', brand: 'claude-code' | 'codex'): DemoSurfaceAdapter => ({
|
|
54
|
+
async start(signal) {
|
|
55
|
+
if (signal.aborted) throw new Error(`${id} startup cancelled`);
|
|
56
|
+
const size = options.termSize();
|
|
57
|
+
const session = (options.spawnAgent ?? spawnCodingAgent)(
|
|
58
|
+
{ brand, cwd: options.cwd, title: `11-04 demo · ${brand}` },
|
|
59
|
+
{ registry: options.registry, termCols: size.cols, termRows: size.rows },
|
|
60
|
+
);
|
|
61
|
+
sessions.set(id, session);
|
|
62
|
+
},
|
|
63
|
+
async runAct(act, signal) {
|
|
64
|
+
if (act.id !== 'act-2' && act.id !== 'act-5') return;
|
|
65
|
+
const session = sessions.get(id);
|
|
66
|
+
if (!session) throw new Error(`${id} session was not started`);
|
|
67
|
+
if (signal.aborted) throw new Error(`${id} mission cancelled`);
|
|
68
|
+
await options.runMission(session, act, signal);
|
|
69
|
+
if (signal.aborted) throw new Error(`${id} mission cancelled`);
|
|
70
|
+
},
|
|
71
|
+
async showVideo(videoId, act, signal) {
|
|
72
|
+
const session = sessions.get(id);
|
|
73
|
+
if (!session) throw new Error(`${id} session was not started`);
|
|
74
|
+
if (signal.aborted) throw new Error(`${id} video transition cancelled`);
|
|
75
|
+
await options.showVideo(session, videoTransition(videoId, act, options.videoSources), signal);
|
|
76
|
+
if (signal.aborted) throw new Error(`${id} video transition cancelled`);
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
'claude-code-tui': create('claude-code-tui', 'claude-code'),
|
|
81
|
+
'codex-tui': create('codex-tui', 'codex'),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Run the same graph API the web editor calls and publish its live run view to a screen renderer. */
|
|
86
|
+
export function createDemoRunGraphSurfaceAdapter(options: {
|
|
87
|
+
graphId: string;
|
|
88
|
+
graphYaml: string;
|
|
89
|
+
videoSources: Readonly<Record<string, string>>;
|
|
90
|
+
onView: (view: GraphRunView, act: typeof DEMO1104_STAGE_CONFIG.acts[number], signal: AbortSignal) => void;
|
|
91
|
+
onVideo: (transition: DemoVideoTransition, signal: AbortSignal) => Promise<void> | void;
|
|
92
|
+
recipesFile?: string;
|
|
93
|
+
}): DemoSurfaceAdapter & { close(): void } {
|
|
94
|
+
const root = mkdtempSync(join(tmpdir(), 'demo1104-run-graph-'));
|
|
95
|
+
const mineDir = join(root, 'mine');
|
|
96
|
+
mkdirSync(mineDir, { recursive: true });
|
|
97
|
+
const graphId = options.graphId;
|
|
98
|
+
const graphFile = join(mineDir, `${graphId}.yaml`);
|
|
99
|
+
writeFileSync(graphFile, options.graphYaml);
|
|
100
|
+
let executionSettled: Promise<void> | undefined;
|
|
101
|
+
const deps = {
|
|
102
|
+
root, mineDir, recipesFile: options.recipesFile ?? resolve(import.meta.dir, '../../graphs/demo/editor-recipes.yaml'),
|
|
103
|
+
run(path: string, runOptions?: GraphRunOptions) {
|
|
104
|
+
const execution = runGraph(path, runOptions);
|
|
105
|
+
executionSettled = execution.then(() => {}, () => {});
|
|
106
|
+
return execution;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
const abortCheck = (signal: AbortSignal) => { if (signal.aborted) throw new Error('graph screen run aborted'); };
|
|
110
|
+
const awaitExecutionCleanup = async () => {
|
|
111
|
+
if (!executionSettled) throw new Error('graph run completion handle is missing');
|
|
112
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
113
|
+
try {
|
|
114
|
+
const settled = await Promise.race([
|
|
115
|
+
executionSettled.then(() => true),
|
|
116
|
+
new Promise<false>(resolve => { timeout = setTimeout(() => resolve(false), DEMO1104_STAGE_CONFIG.failoverDeadlineMs); }),
|
|
117
|
+
]);
|
|
118
|
+
if (!settled) throw new Error(`graph runner cleanup exceeded ${DEMO1104_STAGE_CONFIG.failoverDeadlineMs}ms`);
|
|
119
|
+
} finally { if (timeout) clearTimeout(timeout); }
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
async start(signal) { abortCheck(signal); },
|
|
123
|
+
async runAct(act, signal) {
|
|
124
|
+
abortCheck(signal);
|
|
125
|
+
try {
|
|
126
|
+
const started = handleGraphRunRoute('POST', `/v1/graphs/${graphId}/run`, { ...deps, signal });
|
|
127
|
+
if (!started || started.status !== 202) throw new Error(`run-graph start failed: ${started?.status ?? 'no route'}`);
|
|
128
|
+
const { runId } = await started.json() as { runId: string };
|
|
129
|
+
if (!executionSettled) throw new Error('run-graph route did not start a tracked execution');
|
|
130
|
+
for (let attempt = 0; attempt < 200; attempt += 1) {
|
|
131
|
+
abortCheck(signal);
|
|
132
|
+
const response = handleGraphRunRoute('GET', `/v1/graphs/${graphId}/runs/${runId}`, deps);
|
|
133
|
+
if (!response?.ok) throw new Error(`run-graph view failed: ${response?.status ?? 'no route'}`);
|
|
134
|
+
const view = await response.json() as GraphRunView;
|
|
135
|
+
abortCheck(signal);
|
|
136
|
+
options.onView(view, act, signal);
|
|
137
|
+
abortCheck(signal);
|
|
138
|
+
if (view.status === 'done') { await awaitExecutionCleanup(); return; }
|
|
139
|
+
if (view.status === 'failed' || view.status === 'budget-exceeded') {
|
|
140
|
+
await awaitExecutionCleanup();
|
|
141
|
+
throw new Error(`run-graph ${view.status}: ${view.error ?? runId}`);
|
|
142
|
+
}
|
|
143
|
+
await Bun.sleep(25);
|
|
144
|
+
}
|
|
145
|
+
throw new Error('run-graph screen did not settle within 5 seconds');
|
|
146
|
+
} finally {
|
|
147
|
+
if (signal.aborted && executionSettled) await awaitExecutionCleanup();
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
async showVideo(videoId, act, signal) {
|
|
151
|
+
abortCheck(signal);
|
|
152
|
+
await options.onVideo(videoTransition(videoId, act, options.videoSources), signal);
|
|
153
|
+
abortCheck(signal);
|
|
154
|
+
},
|
|
155
|
+
close() { rmSync(root, { recursive: true, force: true }); },
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Exercise the production delivery/receipt path with its landed Telegram file recorder; never sends externally. */
|
|
160
|
+
export function createDemoTelegramDryRunAdapter(options: {
|
|
161
|
+
stateDir?: string;
|
|
162
|
+
file: string;
|
|
163
|
+
linearIssueId: string;
|
|
164
|
+
videoSources: Readonly<Record<string, string>>;
|
|
165
|
+
appendDryRun?: typeof appendTopicBriefingTelegramDryRun;
|
|
166
|
+
}): DemoSurfaceAdapter & { close(): void } {
|
|
167
|
+
const ownsStateDir = options.stateDir === undefined;
|
|
168
|
+
const stateDir = options.stateDir ?? mkdtempSync(join(tmpdir(), 'demo1104-telegram-'));
|
|
169
|
+
const appendDryRun = options.appendDryRun ?? appendTopicBriefingTelegramDryRun;
|
|
170
|
+
mkdirSync(dirname(options.file), { recursive: true });
|
|
171
|
+
const brief = (act: typeof DEMO1104_STAGE_CONFIG.acts[number]): BriefItem => ({
|
|
172
|
+
id: DEMO1104_STAGE_CONFIG.acts.findIndex(row => row.id === act.id) + 1,
|
|
173
|
+
text: `11-04 데모 · ${act.title}`, domain: '운영', priority: 'P1', deadline: null,
|
|
174
|
+
evidence: `https://example.invalid/demo/${act.id}`, source: 'demo1104', linearIssueId: options.linearIssueId,
|
|
175
|
+
created_at: new Date(0).toISOString(), sent_at: null,
|
|
176
|
+
});
|
|
177
|
+
return {
|
|
178
|
+
async start() {},
|
|
179
|
+
async runAct(act, signal) {
|
|
180
|
+
const assertActive = () => { if (signal.aborted) throw new Error('Telegram dry-run superseded'); };
|
|
181
|
+
const item = brief(act);
|
|
182
|
+
const defaults: Parameters<typeof deliverTopicBriefingWithReceipts>[2] = {
|
|
183
|
+
sendIssueCard: async ({ text }) => { assertActive(); appendDryRun(options.file, { linearIssueId: options.linearIssueId, text, kind: 'issue' }); },
|
|
184
|
+
commentIssue: async () => { assertActive(); },
|
|
185
|
+
issueIsDone: async () => { assertActive(); return false; },
|
|
186
|
+
isDecisionImpacting: async () => { assertActive(); return false; },
|
|
187
|
+
reopenIssue: async () => { assertActive(); },
|
|
188
|
+
sendMemoUpdateCard: async ({ text }) => { assertActive(); appendDryRun(options.file, { linearIssueId: options.linearIssueId, text, kind: 'memo' }); },
|
|
189
|
+
};
|
|
190
|
+
const guarded: typeof defaults = {
|
|
191
|
+
async sendIssueCard(input) { assertActive(); await defaults.sendIssueCard(input); assertActive(); },
|
|
192
|
+
async commentIssue(id, text) { assertActive(); await defaults.commentIssue(id, text); assertActive(); },
|
|
193
|
+
async issueIsDone(id) { assertActive(); const done = await defaults.issueIsDone(id); assertActive(); return done; },
|
|
194
|
+
async isDecisionImpacting(items) { assertActive(); const impact = await defaults.isDecisionImpacting(items); assertActive(); return impact; },
|
|
195
|
+
async reopenIssue(id) { assertActive(); await defaults.reopenIssue(id); assertActive(); },
|
|
196
|
+
async sendMemoUpdateCard(input) { assertActive(); await defaults.sendMemoUpdateCard(input); assertActive(); },
|
|
197
|
+
};
|
|
198
|
+
await deliverTopicBriefingWithReceipts({ linearIssueId: options.linearIssueId, issueLabel: '11-04 데모', summary: item.text, items: [item] }, stateDir, guarded, 'telegram-dry-run');
|
|
199
|
+
},
|
|
200
|
+
async showVideo(videoId, act, signal) {
|
|
201
|
+
if (signal.aborted) throw new Error('Telegram video transition superseded');
|
|
202
|
+
writeTelegramVideoDryRun(options.file, options.linearIssueId, videoTransition(videoId, act, options.videoSources));
|
|
203
|
+
if (signal.aborted) throw new Error('Telegram video transition superseded');
|
|
204
|
+
},
|
|
205
|
+
close() { if (ownsStateDir) rmSync(stateDir, { recursive: true, force: true }); },
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export type DemoParallelSnapshot = StageSnapshot & {
|
|
210
|
+
surfaces: Array<{ id: DemoSurfaceId; lane: DemoLaneId; title: string; status: 'pending' | 'starting' | 'ready' | 'failed'; error: string | null }>;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
async function runSurfaces(operations: Array<(signal: AbortSignal) => Promise<void>>, parentSignal: AbortSignal): Promise<void> {
|
|
214
|
+
const controller = new AbortController();
|
|
215
|
+
let interrupt!: () => void;
|
|
216
|
+
const interrupted = new Promise<{ kind: 'interrupted' }>(resolve => { interrupt = () => resolve({ kind: 'interrupted' }); });
|
|
217
|
+
const abortChildren = () => { controller.abort(); interrupt(); };
|
|
218
|
+
if (parentSignal.aborted) controller.abort();
|
|
219
|
+
else parentSignal.addEventListener('abort', abortChildren, { once: true });
|
|
220
|
+
let firstFailure: unknown;
|
|
221
|
+
let fail!: (error: unknown) => void;
|
|
222
|
+
const failed = new Promise<{ kind: 'failed'; error: unknown }>(resolve => { fail = error => resolve({ kind: 'failed', error }); });
|
|
223
|
+
const pending = operations.map(operation => Promise.resolve().then(() => {
|
|
224
|
+
if (controller.signal.aborted) throw new Error('demo surface action cancelled');
|
|
225
|
+
return operation(controller.signal);
|
|
226
|
+
}).catch(error => {
|
|
227
|
+
if (firstFailure === undefined) {
|
|
228
|
+
firstFailure = error;
|
|
229
|
+
controller.abort();
|
|
230
|
+
fail(error);
|
|
231
|
+
}
|
|
232
|
+
throw error;
|
|
233
|
+
}));
|
|
234
|
+
const settled = Promise.allSettled(pending);
|
|
235
|
+
try {
|
|
236
|
+
const first = await Promise.race([
|
|
237
|
+
settled.then(results => ({ kind: 'settled' as const, results })),
|
|
238
|
+
failed,
|
|
239
|
+
interrupted,
|
|
240
|
+
]);
|
|
241
|
+
if (first.kind === 'settled') {
|
|
242
|
+
const failure = first.results.find((result): result is PromiseRejectedResult => result.status === 'rejected');
|
|
243
|
+
if (failure) throw failure.reason;
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
// Let abort-aware adapters clean up briefly; a wedged host callback cannot hold failover.
|
|
247
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
248
|
+
try {
|
|
249
|
+
const clean = await Promise.race([
|
|
250
|
+
settled.then(() => true),
|
|
251
|
+
new Promise<false>(resolve => { timeout = setTimeout(() => resolve(false), Math.min(250, DEMO1104_STAGE_CONFIG.failoverDeadlineMs)); }),
|
|
252
|
+
]);
|
|
253
|
+
if (!clean) throw new Error(`demo surface cleanup exceeded ${Math.min(250, DEMO1104_STAGE_CONFIG.failoverDeadlineMs)}ms`);
|
|
254
|
+
} finally { if (timeout) clearTimeout(timeout); }
|
|
255
|
+
if (first.kind === 'failed') throw first.error;
|
|
256
|
+
if (firstFailure !== undefined) throw firstFailure;
|
|
257
|
+
throw new Error('demo surface action cancelled');
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
parentSignal.removeEventListener('abort', abortChildren);
|
|
261
|
+
controller.abort();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** Connects the existing five-second failover controller to all four real demo surfaces.
|
|
266
|
+
* Launches stay adapter-owned: the CLI/session manager supplies TUI tabs, the PWA run-graph
|
|
267
|
+
* client supplies the web surface, and the Telegram adapter must use file-only dry-run output. */
|
|
268
|
+
export function createDemo1104ParallelScenes(adapters: Record<DemoSurfaceId, DemoSurfaceAdapter>) {
|
|
269
|
+
const surfaceState = new Map<DemoSurfaceId, DemoParallelSnapshot['surfaces'][number]>(
|
|
270
|
+
DEMO1104_SURFACES.map(surface => [surface.id, { ...surface, status: 'pending' as const, error: null }] as const),
|
|
271
|
+
);
|
|
272
|
+
const controller = createDemoStageConsole({
|
|
273
|
+
adapters: {
|
|
274
|
+
async startLane(lane) {
|
|
275
|
+
const surfaces = DEMO1104_SURFACES.filter(surface => surface.lane === lane.id);
|
|
276
|
+
await Promise.all(surfaces.map(async surface => {
|
|
277
|
+
const state = surfaceState.get(surface.id)!;
|
|
278
|
+
state.status = 'starting';
|
|
279
|
+
try {
|
|
280
|
+
await adapters[surface.id].start(new AbortController().signal);
|
|
281
|
+
state.status = 'ready';
|
|
282
|
+
} catch (error) {
|
|
283
|
+
state.status = 'failed';
|
|
284
|
+
state.error = error instanceof Error ? error.message : String(error);
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
}));
|
|
288
|
+
},
|
|
289
|
+
async runAct(act, signal) { await runSurfaces(DEMO1104_SURFACES.map(surface => childSignal => adapters[surface.id].runAct(act, childSignal)), signal); },
|
|
290
|
+
async showVideo(videoId, act, signal) { await runSurfaces(DEMO1104_SURFACES.map(surface => childSignal => adapters[surface.id].showVideo(videoId, act, childSignal)), signal); },
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
return {
|
|
294
|
+
start: () => controller.start(),
|
|
295
|
+
runActNow: (id: DemoActId) => controller.runActNow(id),
|
|
296
|
+
switchToVideo: (id: DemoActId) => controller.switchToVideo(id),
|
|
297
|
+
snapshot(): DemoParallelSnapshot {
|
|
298
|
+
return { ...controller.snapshot(), surfaces: DEMO1104_SURFACES.map(surface => ({ ...surfaceState.get(surface.id)! })) };
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Script timing and pre-recorded failover map for the 11-04 demo. */
|
|
2
|
+
export const DEMO1104_STAGE_CONFIG = {
|
|
3
|
+
failoverDeadlineMs: 5_000,
|
|
4
|
+
acts: [
|
|
5
|
+
{ id: 'prologue', title: '프롤로그', targetStartSec: 0, targetEndSec: 40, highlightVideoId: null },
|
|
6
|
+
{ id: 'act-1', title: '아침 브리핑', targetStartSec: 40, targetEndSec: 90, highlightVideoId: 'V1' },
|
|
7
|
+
{ id: 'act-2', title: '깊이 파기', targetStartSec: 90, targetEndSec: 210, highlightVideoId: 'V2' },
|
|
8
|
+
{ id: 'act-3', title: '맡기기', targetStartSec: 210, targetEndSec: 240, highlightVideoId: 'V3' },
|
|
9
|
+
{ id: 'act-4', title: '끝까지 처리', targetStartSec: 240, targetEndSec: 420, highlightVideoId: 'V4' },
|
|
10
|
+
{ id: 'act-5', title: '스스로 만든다', targetStartSec: 420, targetEndSec: 510, highlightVideoId: 'V5' },
|
|
11
|
+
{ id: 'act-6', title: '이어진다', targetStartSec: 510, targetEndSec: 570, highlightVideoId: 'V6' },
|
|
12
|
+
{ id: 'epilogue', title: '에필로그', targetStartSec: 570, targetEndSec: 600, highlightVideoId: null },
|
|
13
|
+
],
|
|
14
|
+
lanes: [
|
|
15
|
+
{ id: 'secretary', title: '업무 비서', startsAtAct: 'prologue' },
|
|
16
|
+
{ id: 'maker', title: '만드는 엘라누스', startsAtAct: 'prologue' },
|
|
17
|
+
],
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
export type DemoActId = typeof DEMO1104_STAGE_CONFIG.acts[number]['id'];
|
|
21
|
+
export type DemoLaneId = typeof DEMO1104_STAGE_CONFIG.lanes[number]['id'];
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { DEMO1104_STAGE_CONFIG, type DemoActId, type DemoLaneId } from './demo1104-stage.config.js';
|
|
2
|
+
|
|
3
|
+
type Act = typeof DEMO1104_STAGE_CONFIG.acts[number];
|
|
4
|
+
type Lane = typeof DEMO1104_STAGE_CONFIG.lanes[number];
|
|
5
|
+
type ActStatus = 'pending' | 'running' | 'live' | 'failed' | 'video';
|
|
6
|
+
type TimerHandle = ReturnType<typeof setTimeout>;
|
|
7
|
+
type TimerScheduler = {
|
|
8
|
+
setTimeout(callback: () => void, delayMs: number): TimerHandle;
|
|
9
|
+
clearTimeout(handle: TimerHandle): void;
|
|
10
|
+
};
|
|
11
|
+
type LaneStatus = 'pending' | 'running' | 'started' | 'failed';
|
|
12
|
+
type VideoTrigger = 'failure' | 'deadline' | 'manual';
|
|
13
|
+
type VideoTransition = { actId: DemoActId; videoId: string; trigger: VideoTrigger; failedAt: number; requestedAt: number; completedAt: number | null; latencyMs: number | null; status: 'shown' | 'failed' | 'superseded'; error: string | null };
|
|
14
|
+
|
|
15
|
+
export type StageAdapters = {
|
|
16
|
+
startLane(lane: Lane): Promise<void>;
|
|
17
|
+
runAct(act: Act, signal: AbortSignal): Promise<void>;
|
|
18
|
+
showVideo(videoId: string, act: Act, signal: AbortSignal): Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type StageSnapshot = {
|
|
22
|
+
startedAt: number | null;
|
|
23
|
+
elapsedMs: number;
|
|
24
|
+
lanes: Array<{ id: DemoLaneId; title: string; startsAtAct: DemoActId; status: LaneStatus; startedAt: number | null }>;
|
|
25
|
+
acts: Array<{ id: DemoActId; title: string; targetStartSec: number; targetEndSec: number; videoId: string | null; status: ActStatus }>;
|
|
26
|
+
transitions: VideoTransition[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function createDemoStageConsole(options: {
|
|
30
|
+
adapters: StageAdapters;
|
|
31
|
+
now?: () => number;
|
|
32
|
+
timers?: TimerScheduler;
|
|
33
|
+
}): {
|
|
34
|
+
start(): Promise<void>;
|
|
35
|
+
runActNow(id: DemoActId): Promise<void>;
|
|
36
|
+
switchToVideo(id: DemoActId): Promise<void>;
|
|
37
|
+
snapshot(): StageSnapshot;
|
|
38
|
+
} {
|
|
39
|
+
const now = options.now ?? Date.now;
|
|
40
|
+
const timers: TimerScheduler = options.timers ?? {
|
|
41
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs) as TimerHandle,
|
|
42
|
+
clearTimeout: handle => clearTimeout(handle),
|
|
43
|
+
};
|
|
44
|
+
const startedAt = { value: null as number | null };
|
|
45
|
+
const laneStarts = new Map<DemoLaneId, number>();
|
|
46
|
+
const laneStatuses = new Map<DemoLaneId, LaneStatus>(
|
|
47
|
+
DEMO1104_STAGE_CONFIG.lanes.map(lane => [lane.id, 'pending']),
|
|
48
|
+
);
|
|
49
|
+
const actStatuses = new Map<DemoActId, ActStatus>(DEMO1104_STAGE_CONFIG.acts.map(act => [act.id, 'pending']));
|
|
50
|
+
const actGenerations = new Map<DemoActId, number>();
|
|
51
|
+
const actControllers = new Map<DemoActId, { generation: number; controller: AbortController }>();
|
|
52
|
+
const videoControllers = new Map<DemoActId, { generation: number; controller: AbortController }>();
|
|
53
|
+
const transitions: VideoTransition[] = [];
|
|
54
|
+
const abortActWork = (id: DemoActId): void => {
|
|
55
|
+
actControllers.get(id)?.controller.abort();
|
|
56
|
+
videoControllers.get(id)?.controller.abort();
|
|
57
|
+
};
|
|
58
|
+
const nextActGeneration = (id: DemoActId): number => {
|
|
59
|
+
abortActWork(id);
|
|
60
|
+
const next = (actGenerations.get(id) ?? 0) + 1;
|
|
61
|
+
actGenerations.set(id, next);
|
|
62
|
+
return next;
|
|
63
|
+
};
|
|
64
|
+
const isCurrentActGeneration = (id: DemoActId, generation: number): boolean => actGenerations.get(id) === generation;
|
|
65
|
+
|
|
66
|
+
const actFor = (id: DemoActId): Act => {
|
|
67
|
+
const act = DEMO1104_STAGE_CONFIG.acts.find(candidate => candidate.id === id);
|
|
68
|
+
if (!act) throw new Error(`Unknown demo act: ${id}`);
|
|
69
|
+
return act;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const switchToVideo = async (id: DemoActId, failedAt: number, trigger: VideoTrigger, generation: number): Promise<void> => {
|
|
73
|
+
const act = actFor(id);
|
|
74
|
+
if (!act.highlightVideoId) throw new Error(`${id} has no configured highlight video`);
|
|
75
|
+
if (!isCurrentActGeneration(id, generation)) return;
|
|
76
|
+
const requestedAt = now();
|
|
77
|
+
const transition: VideoTransition = { actId: id, videoId: act.highlightVideoId, trigger, failedAt, requestedAt, completedAt: null, latencyMs: null, status: 'failed', error: null };
|
|
78
|
+
transitions.push(transition);
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
videoControllers.set(id, { generation, controller });
|
|
81
|
+
const remainingMs = DEMO1104_STAGE_CONFIG.failoverDeadlineMs - (requestedAt - failedAt);
|
|
82
|
+
if (remainingMs <= 0) {
|
|
83
|
+
transition.error = `video display exceeded ${DEMO1104_STAGE_CONFIG.failoverDeadlineMs}ms`;
|
|
84
|
+
if (isCurrentActGeneration(id, generation)) actStatuses.set(id, 'failed');
|
|
85
|
+
controller.abort();
|
|
86
|
+
videoControllers.delete(id);
|
|
87
|
+
throw new Error(`${id} video transition failed: ${transition.error}`);
|
|
88
|
+
}
|
|
89
|
+
let timeout: TimerHandle | undefined;
|
|
90
|
+
let timedOut = false;
|
|
91
|
+
let removeAbortListener = () => {};
|
|
92
|
+
const aborted = new Promise<never>((_resolve, reject) => {
|
|
93
|
+
const onAbort = () => reject(new Error('video transition superseded'));
|
|
94
|
+
if (controller.signal.aborted) onAbort();
|
|
95
|
+
else {
|
|
96
|
+
controller.signal.addEventListener('abort', onAbort, { once: true });
|
|
97
|
+
removeAbortListener = () => controller.signal.removeEventListener('abort', onAbort);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
const deadline = new Promise<never>((_resolve, reject) => {
|
|
101
|
+
timeout = timers.setTimeout(() => {
|
|
102
|
+
timedOut = true;
|
|
103
|
+
reject(new Error(`video display exceeded ${DEMO1104_STAGE_CONFIG.failoverDeadlineMs}ms`));
|
|
104
|
+
}, remainingMs);
|
|
105
|
+
});
|
|
106
|
+
const display = Promise.resolve()
|
|
107
|
+
.then(() => options.adapters.showVideo(act.highlightVideoId!, act, controller.signal))
|
|
108
|
+
.then(() => {
|
|
109
|
+
transition.completedAt = now();
|
|
110
|
+
transition.latencyMs = transition.completedAt - failedAt;
|
|
111
|
+
});
|
|
112
|
+
try {
|
|
113
|
+
await Promise.race([display, deadline, aborted]);
|
|
114
|
+
if (transition.latencyMs! > DEMO1104_STAGE_CONFIG.failoverDeadlineMs) {
|
|
115
|
+
timedOut = true;
|
|
116
|
+
throw new Error(`video display exceeded ${DEMO1104_STAGE_CONFIG.failoverDeadlineMs}ms`);
|
|
117
|
+
}
|
|
118
|
+
if (!isCurrentActGeneration(id, generation)) {
|
|
119
|
+
transition.status = 'superseded';
|
|
120
|
+
transition.error = 'video transition superseded';
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
transition.status = 'shown';
|
|
124
|
+
actStatuses.set(id, 'video');
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (!isCurrentActGeneration(id, generation)) {
|
|
127
|
+
transition.status = 'superseded';
|
|
128
|
+
transition.error = 'video transition superseded';
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
transition.error = timedOut ? `video display exceeded ${DEMO1104_STAGE_CONFIG.failoverDeadlineMs}ms` : error instanceof Error ? error.message : String(error);
|
|
132
|
+
if (isCurrentActGeneration(id, generation)) actStatuses.set(id, 'failed');
|
|
133
|
+
controller.abort();
|
|
134
|
+
throw new Error(`${id} video transition failed: ${transition.error}`);
|
|
135
|
+
} finally {
|
|
136
|
+
removeAbortListener();
|
|
137
|
+
if (timeout) timers.clearTimeout(timeout);
|
|
138
|
+
if (videoControllers.get(id)?.generation === generation) videoControllers.delete(id);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
async start() {
|
|
144
|
+
if (startedAt.value !== null) throw new Error('Demo stage already started');
|
|
145
|
+
startedAt.value = now();
|
|
146
|
+
// Invoke both lanes before awaiting either one so the two story lines start together.
|
|
147
|
+
const launches = DEMO1104_STAGE_CONFIG.lanes.map(lane => {
|
|
148
|
+
laneStatuses.set(lane.id, 'running');
|
|
149
|
+
const laneStartedAt = now();
|
|
150
|
+
laneStarts.set(lane.id, laneStartedAt);
|
|
151
|
+
return options.adapters.startLane(lane).then(
|
|
152
|
+
() => { laneStatuses.set(lane.id, 'started'); },
|
|
153
|
+
error => { laneStatuses.set(lane.id, 'failed'); throw error; },
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
await Promise.all(launches);
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
async runActNow(id) {
|
|
160
|
+
if (startedAt.value === null) throw new Error('Start the demo stage before running an act');
|
|
161
|
+
const act = actFor(id);
|
|
162
|
+
const generation = nextActGeneration(id);
|
|
163
|
+
const controller = new AbortController();
|
|
164
|
+
actControllers.set(id, { generation, controller });
|
|
165
|
+
actStatuses.set(id, 'running');
|
|
166
|
+
let timeout: TimerHandle | undefined;
|
|
167
|
+
let failedAt: number | undefined;
|
|
168
|
+
let trigger: VideoTrigger = 'failure';
|
|
169
|
+
let removeAbortListener = () => {};
|
|
170
|
+
const timeoutMs = DEMO1104_STAGE_CONFIG.failoverDeadlineMs;
|
|
171
|
+
const aborted = new Promise<never>((_resolve, reject) => {
|
|
172
|
+
const onAbort = () => reject(new Error('act execution superseded'));
|
|
173
|
+
if (controller.signal.aborted) onAbort();
|
|
174
|
+
else {
|
|
175
|
+
controller.signal.addEventListener('abort', onAbort, { once: true });
|
|
176
|
+
removeAbortListener = () => controller.signal.removeEventListener('abort', onAbort);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const deadline = new Promise<never>((_resolve, reject) => {
|
|
180
|
+
timeout = timers.setTimeout(() => {
|
|
181
|
+
failedAt = now();
|
|
182
|
+
trigger = 'deadline';
|
|
183
|
+
reject(new Error(`Act exceeded ${timeoutMs}ms`));
|
|
184
|
+
}, timeoutMs);
|
|
185
|
+
});
|
|
186
|
+
try {
|
|
187
|
+
await Promise.race([options.adapters.runAct(act, controller.signal), deadline, aborted]);
|
|
188
|
+
if (!isCurrentActGeneration(id, generation)) return;
|
|
189
|
+
actStatuses.set(id, 'live');
|
|
190
|
+
} catch {
|
|
191
|
+
if (!isCurrentActGeneration(id, generation)) return;
|
|
192
|
+
failedAt ??= now();
|
|
193
|
+
actStatuses.set(id, 'failed');
|
|
194
|
+
if (!act.highlightVideoId) throw new Error(`${id} failed and has no configured highlight video`);
|
|
195
|
+
controller.abort();
|
|
196
|
+
if (actControllers.get(id)?.generation === generation) actControllers.delete(id);
|
|
197
|
+
await switchToVideo(id, failedAt, trigger, generation);
|
|
198
|
+
} finally {
|
|
199
|
+
removeAbortListener();
|
|
200
|
+
if (timeout) timers.clearTimeout(timeout);
|
|
201
|
+
if (actControllers.get(id)?.generation === generation) actControllers.delete(id);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
switchToVideo(id) {
|
|
206
|
+
if (startedAt.value === null) throw new Error('Start the demo stage before switching to video');
|
|
207
|
+
if (!actFor(id).highlightVideoId) throw new Error(`${id} has no configured highlight video`);
|
|
208
|
+
const generation = nextActGeneration(id);
|
|
209
|
+
return switchToVideo(id, now(), 'manual', generation);
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
snapshot() {
|
|
213
|
+
const current = now();
|
|
214
|
+
return {
|
|
215
|
+
startedAt: startedAt.value,
|
|
216
|
+
elapsedMs: startedAt.value === null ? 0 : Math.max(0, current - startedAt.value),
|
|
217
|
+
lanes: DEMO1104_STAGE_CONFIG.lanes.map(lane => ({
|
|
218
|
+
id: lane.id,
|
|
219
|
+
title: lane.title,
|
|
220
|
+
startsAtAct: lane.startsAtAct,
|
|
221
|
+
status: laneStatuses.get(lane.id) ?? 'pending',
|
|
222
|
+
startedAt: laneStarts.get(lane.id) ?? null,
|
|
223
|
+
})),
|
|
224
|
+
acts: DEMO1104_STAGE_CONFIG.acts.map(act => ({
|
|
225
|
+
id: act.id,
|
|
226
|
+
title: act.title,
|
|
227
|
+
targetStartSec: act.targetStartSec,
|
|
228
|
+
targetEndSec: act.targetEndSec,
|
|
229
|
+
videoId: act.highlightVideoId,
|
|
230
|
+
status: actStatuses.get(act.id) ?? 'pending',
|
|
231
|
+
})),
|
|
232
|
+
transitions: transitions.map(transition => ({ ...transition })),
|
|
233
|
+
};
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
type CliOptions = { mock: boolean; help?: boolean; runAct?: DemoActId; failAct?: DemoActId; hangAct?: DemoActId; switchToVideo?: DemoActId };
|
|
239
|
+
|
|
240
|
+
const HELP = 'Usage: bun scripts/demo/demo1104-stage.ts --mock [--run-act <act> [--fail-act <act>|--hang-act <act>]] [--switch-to-video <act>]';
|
|
241
|
+
|
|
242
|
+
export function parseStageArgs(argv: string[]): CliOptions {
|
|
243
|
+
if (argv.includes('--help')) return { mock: false, help: true };
|
|
244
|
+
let mock = false;
|
|
245
|
+
let runAct: DemoActId | undefined;
|
|
246
|
+
let failAct: DemoActId | undefined;
|
|
247
|
+
let hangAct: DemoActId | undefined;
|
|
248
|
+
let switchToVideo: DemoActId | undefined;
|
|
249
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
250
|
+
const arg = argv[index];
|
|
251
|
+
if (arg === '--mock') { mock = true; continue; }
|
|
252
|
+
if (arg === '--run-act' || arg === '--fail-act' || arg === '--hang-act' || arg === '--switch-to-video') {
|
|
253
|
+
const value = argv[++index];
|
|
254
|
+
if (!value) throw new Error(`${arg} needs an act id`);
|
|
255
|
+
const act = DEMO1104_STAGE_CONFIG.acts.find(candidate => candidate.id === value);
|
|
256
|
+
if (!act) throw new Error(`Unknown act id: ${value}`);
|
|
257
|
+
if (arg !== '--run-act' && !act.highlightVideoId) throw new Error(`${value} has no configured highlight video`);
|
|
258
|
+
if (arg === '--run-act') runAct = act.id;
|
|
259
|
+
else if (arg === '--fail-act') failAct = act.id;
|
|
260
|
+
else if (arg === '--hang-act') hangAct = act.id;
|
|
261
|
+
else switchToVideo = act.id;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
265
|
+
}
|
|
266
|
+
if (!mock) throw new Error('This first-stage console is mock-only; pass --mock');
|
|
267
|
+
if (failAct && failAct !== runAct) throw new Error('--fail-act must match --run-act');
|
|
268
|
+
if (hangAct && hangAct !== runAct) throw new Error('--hang-act must match --run-act');
|
|
269
|
+
if (hangAct && failAct) throw new Error('--hang-act cannot be combined with --fail-act');
|
|
270
|
+
if (switchToVideo && (runAct || failAct)) throw new Error('--switch-to-video cannot be combined with act execution');
|
|
271
|
+
if (switchToVideo && hangAct) throw new Error('--switch-to-video cannot be combined with --hang-act');
|
|
272
|
+
return { mock, ...(runAct ? { runAct } : {}), ...(failAct ? { failAct } : {}), ...(hangAct ? { hangAct } : {}), ...(switchToVideo ? { switchToVideo } : {}) };
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export async function runMockStage(args: CliOptions, stageOptions: { now?: () => number; timers?: TimerScheduler } = {}): Promise<StageSnapshot> {
|
|
276
|
+
const adapters: StageAdapters = {
|
|
277
|
+
async startLane(lane) { console.log(`시작: ${lane.title}`); },
|
|
278
|
+
async runAct(act) {
|
|
279
|
+
console.log(`지금 실행: ${act.title}`);
|
|
280
|
+
if (args.failAct === act.id) throw new Error('mock failure injected');
|
|
281
|
+
if (args.hangAct === act.id) return new Promise<void>(() => {});
|
|
282
|
+
},
|
|
283
|
+
async showVideo(videoId, act) { console.log(`영상 전환: ${act.title} → ${videoId}`); },
|
|
284
|
+
};
|
|
285
|
+
const stage = createDemoStageConsole({ adapters, ...stageOptions });
|
|
286
|
+
await stage.start();
|
|
287
|
+
if (args.runAct) {
|
|
288
|
+
await stage.runActNow(args.runAct);
|
|
289
|
+
const transition = stage.snapshot().transitions.at(-1);
|
|
290
|
+
if (transition?.status === 'shown') {
|
|
291
|
+
const cause = transition.trigger === 'deadline' ? '정체' : transition.trigger === 'failure' ? '실패' : '수동';
|
|
292
|
+
console.log(`씬 ${cause} · 영상 전환 완료: ${transition.actId} → ${transition.videoId} · ${transition.latencyMs}ms`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (args.switchToVideo) {
|
|
296
|
+
await stage.switchToVideo(args.switchToVideo);
|
|
297
|
+
const transition = stage.snapshot().transitions.at(-1);
|
|
298
|
+
if (transition?.status === 'shown') console.log(`수동 영상 전환 완료: ${transition.actId} → ${transition.videoId} · ${transition.latencyMs}ms`);
|
|
299
|
+
}
|
|
300
|
+
return stage.snapshot();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (import.meta.main) {
|
|
304
|
+
try {
|
|
305
|
+
const args = parseStageArgs(process.argv.slice(2));
|
|
306
|
+
if (args.help) {
|
|
307
|
+
console.log(HELP);
|
|
308
|
+
process.exit(0);
|
|
309
|
+
}
|
|
310
|
+
const snapshot = await runMockStage(args);
|
|
311
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
314
|
+
process.exitCode = 2;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
@@ -107,6 +107,22 @@ export function collectSlotLoads(lines: readonly string[]): readonly SlotLoad[]
|
|
|
107
107
|
return out;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
/** §6 머리말이 선언한 「사람 몫」 — 매뉴얼이 canonical 이므로 «수»를 이 파일에 박지 않는다.
|
|
111
|
+
* 🩸 계기(2026-10-31): `«여섯»` 이 여기 박혀 있었고 매뉴얼 §6 이 `«둘»` 로 바뀐 뒤에도 그 수를 계속 찍었다. */
|
|
112
|
+
const HUMAN_SLOT_DECLARATION = /사람\s*(?:몫|칸)\s*«([^»]+)»/u;
|
|
113
|
+
|
|
114
|
+
export function declaredHumanSlots(lines: readonly string[]): string | null {
|
|
115
|
+
const start = lines.findIndex(l => /^##\s*6\./u.test(l));
|
|
116
|
+
if (start < 0) return null;
|
|
117
|
+
const rel = lines.slice(start + 1).findIndex(l => /^##\s/u.test(l));
|
|
118
|
+
const end = rel < 0 ? lines.length : start + 1 + rel;
|
|
119
|
+
for (const line of lines.slice(start, end)) {
|
|
120
|
+
const match = HUMAN_SLOT_DECLARATION.exec(line);
|
|
121
|
+
if (match) return match[1]!;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
110
126
|
export interface NarrativeCount { readonly name: string; readonly lines: number }
|
|
111
127
|
|
|
112
128
|
/** 머리말이 「여기 없다」고 선언한 것들이 실제로 몇 줄인가. */
|
|
@@ -135,7 +151,7 @@ function report(path = MANUAL): number {
|
|
|
135
151
|
console.log('');
|
|
136
152
|
const slots = collectSlotLoads(lines);
|
|
137
153
|
const mapped = new Set(slots.flatMap(s => s.clauses));
|
|
138
|
-
console.log(`축② 사람 칸 — §6 선언
|
|
154
|
+
console.log(`축② 사람 칸 — §6 선언 «${declaredHumanSlots(lines) ?? '없음'}» ↔ 조항 ${clauses.length} · 칸에 «걸린» 조항 ${mapped.size}`);
|
|
139
155
|
for (const { slot, clauses: c } of slots) {
|
|
140
156
|
console.log(` ${slot.padEnd(3)} ${String(c.length).padStart(2)}개 ${c.join(' ')}`);
|
|
141
157
|
}
|