elanous 0.2.22 → 0.2.23
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/NOTICE +7 -0
- package/README.md +32 -22
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
- package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
- package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
- 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 +24 -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 +24 -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/models/anthropic/claude-haiku-5-5.yaml +32 -0
- package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
- package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
- package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
- package/catalog/models/openai/gpt-6-astra.yaml +6 -0
- package/catalog/models/openai/gpt-6-luna.yaml +6 -0
- package/catalog/models/openai/gpt-6-sol.yaml +6 -0
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +1 -1
- package/graphs/release/release-loop.yaml +6 -2
- package/graphs/release-rehearsal/recipes.yaml +12 -0
- package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
- package/package.json +4 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +10 -1
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +73 -7
- package/scripts/release-loop/gate-wall.ts +208 -0
- package/scripts/release-loop/known-issues-node.ts +53 -8
- package/scripts/release-loop/publish-at.ts +14 -0
- package/scripts/release-loop/publish-node.ts +17 -2
- package/scripts/release-loop/resume-release.ts +34 -4
- package/scripts/release-loop/resume.ts +53 -0
- package/scripts/release-loop/shard-plan.ts +3 -11
- package/scripts/release-loop/tui-node-checks.ts +22 -0
- package/scripts/release-loop/unattended-release.ts +8 -1
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +8 -4
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +10 -0
- package/src/agent/tool-profile.ts +28 -2
- package/src/agent-mission/acp-judge.ts +8 -2
- package/src/agent-mission/capabilities-cli.ts +16 -1
- package/src/agent-mission/driver.ts +1 -1
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/review-loop.ts +33 -5
- package/src/agent-substrate/acp-reviewer.ts +17 -8
- package/src/agent-substrate/pr-reviewer.ts +164 -28
- package/src/agent-substrate/review-intent.ts +6 -4
- package/src/agent-substrate/self-review-cli.ts +111 -16
- package/src/agent-substrate/shard-boundary-intent.ts +92 -26
- package/src/ask-user-question/pending-questions.ts +8 -2
- package/src/autopilot/build/llm-conflict-merge.ts +216 -12
- package/src/autopilot/codebase-grounding.ts +44 -0
- package/src/autopilot/llm-control-brain.ts +13 -1
- package/src/autopilot/mission-codebase-gate.ts +8 -77
- package/src/autopilot/pr-manager.ts +12 -3
- package/src/boot/acp-server.ts +4 -7
- package/src/boot/acp-socket-path.ts +7 -0
- package/src/briefing/brief-items.ts +21 -13
- package/src/chat/index.ts +12 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/brief-cli.ts +27 -21
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/log-event-names.ts +3 -0
- package/src/cli/logs-cli.ts +1 -0
- package/src/cli/mcp-login.ts +111 -37
- package/src/cli/plugin-cli.ts +21 -1
- package/src/cli/pod-cli.ts +26 -0
- package/src/cli/pr-cli.ts +30 -2
- package/src/cli/pr-land-overlap-evidence.ts +131 -0
- package/src/cli/release-cli.ts +53 -11
- package/src/cli/self-update.ts +173 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +133 -27
- package/src/context-bus/context-first.ts +51 -2
- package/src/context-bus/context-now-surfaces.ts +13 -2
- package/src/context-bus/long-term-memory.ts +3 -1
- package/src/context-bus/nightly-condense.ts +3 -2
- package/src/core-turn/run-goal-loop.ts +86 -2
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +27 -5
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
- package/src/dashboard/stale-install-check.ts +13 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +159 -0
- package/src/debug/log.ts +52 -17
- package/src/display/coordinator.ts +25 -2
- package/src/domains/coo-admin-tool.ts +27 -0
- package/src/domains/cron-match.ts +1 -0
- package/src/domains/outbound-alert.ts +17 -6
- package/src/domains/release-tool.ts +119 -10
- package/src/domains/schedule-registry.ts +10 -7
- package/src/domains/schedule-runner.ts +1 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/elanous-daemon.ts +3 -3
- package/src/execution-loop/launch-gate.ts +1 -1
- package/src/expression/i18n/messages.en.ts +5 -0
- package/src/expression/i18n/messages.ja.ts +5 -0
- package/src/expression/i18n/messages.ko.ts +5 -0
- package/src/expression/i18n/messages.zh.ts +5 -0
- package/src/expression/i18n/types.ts +8 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/graph-runner/runner.ts +54 -5
- package/src/harness/dispatch-backpressure.ts +259 -0
- package/src/harness/harness-cli-command.ts +107 -28
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-substrate-default.ts +72 -1
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +114 -18
- package/src/index.ts +163 -64
- package/src/intake-plane/collect-github.ts +19 -1
- package/src/intake-plane/digest.ts +45 -20
- package/src/intake-plane/lens.ts +36 -8
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +41 -0
- package/src/knowledge/kgs/pack.ts +5 -2
- package/src/knowledge/kgs/sqlite-store.ts +15 -0
- package/src/knowledge/tools/knowledge-query.ts +20 -2
- package/src/knowledge/write.ts +234 -2
- package/src/llm/bedrock-provider.ts +175 -0
- package/src/llm/bedrock.ts +345 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm.ts +306 -35
- package/src/loops/budget.ts +150 -0
- package/src/loops/orchestrator/seat-share.ts +6 -49
- package/src/loops/orchestrator/traffic.ts +5 -81
- package/src/market/signed-index.ts +42 -0
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +48 -4
- package/src/models/prompts.ts +22 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +204 -15
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/consult-requests.ts +7 -10
- package/src/nexus/api/discord-trigger-bot.ts +6 -3
- package/src/nexus/api/error-reports.ts +30 -8
- package/src/nexus/api/http-server.ts +8 -0
- package/src/nexus/api/loop-resources.ts +42 -0
- package/src/nexus/api/outbound-report.ts +8 -3
- package/src/nexus/api/telegram-trigger-bot.ts +6 -3
- package/src/nexus/index.ts +10 -0
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/oauth/codex-account-rotation.ts +16 -18
- package/src/oauth/codex-account-store.ts +134 -5
- package/src/oauth/fallback-chain.ts +28 -6
- package/src/onboarding.ts +2 -1
- package/src/plugins/adapters/claude-package.ts +4 -12
- package/src/plugins/core/capability-policy.ts +141 -0
- package/src/plugins/core/host.ts +21 -8
- package/src/plugins/core/manifest.ts +19 -2
- package/src/plugins/core/trust-store.ts +15 -0
- package/src/plugins/core/types.ts +12 -0
- package/src/plugins/install/market-fetch.ts +68 -16
- package/src/plugins/install/plugin-install.ts +187 -16
- package/src/plugins/maker/plugin-maker.ts +25 -20
- package/src/plugins/maker/wizard-generate.ts +16 -2
- package/src/policy/llm-policy.ts +14 -1
- package/src/process/pid-liveness.ts +1 -1
- package/src/prompt-cache/openai.ts +10 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-enhance/enhance.ts +46 -5
- package/src/prompt-library/family-prompt-coverage.ts +1 -0
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
- package/src/registry/loader.ts +6 -1
- package/src/release-loop/checklist.ts +24 -9
- package/src/release-loop/feature-store.ts +3 -0
- package/src/release-loop/gate-shards.ts +48 -4
- package/src/release-loop/landed-to-green.ts +81 -0
- package/src/release-loop/light-rc.ts +11 -1
- package/src/release-loop/merged-pr-checklist.ts +10 -0
- package/src/release-loop/placement.ts +91 -22
- package/src/release-loop/rehearsal.ts +317 -0
- package/src/release-loop/release-schedule.ts +13 -1
- package/src/release-loop/rubric-types.ts +1 -0
- package/src/release-loop/rubric.ts +2 -2
- package/src/retro/daily.ts +23 -9
- package/src/seat-loop/seat-loop.ts +34 -1
- package/src/seat-loop/traffic-signal.ts +44 -0
- package/src/self-dev/ask-launch-flow.ts +2 -2
- package/src/self-dev/dev-cli.ts +67 -3
- package/src/self-dev/dev-pipeline.ts +4 -6
- package/src/self-dev/draft-residue.ts +463 -0
- package/src/self-dev/draft-sweep.ts +151 -10
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/launch-preflight-text.ts +549 -0
- package/src/self-dev/launch-preflight.ts +10 -545
- package/src/self-dev/orchestrate-cli.ts +57 -2
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +8 -135
- package/src/self-dev/review-provider-fallback.ts +115 -19
- package/src/self-dev/run-store.ts +1 -3
- package/src/self-dev/run-supervisor.ts +3 -22
- package/src/self-dev/run-types.ts +178 -0
- package/src/self-dev/shard-aggregate.ts +61 -13
- package/src/self-dev/shard-plan.ts +5 -1
- package/src/self-dev/shard-run.ts +23 -5
- package/src/self-dev/supervisor-verdict-edges.ts +2 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/gate-baseline-reap.ts +157 -0
- package/src/self-implement/gate-baseline.ts +78 -16
- package/src/self-implement/gate-cli.ts +12 -2
- package/src/self-implement/gate-remote.ts +17 -6
- package/src/self-implement/goal-author.ts +24 -4
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +4 -0
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/host-regate.ts +120 -29
- package/src/self-implement/l8-merge-queue.ts +67 -5
- package/src/self-implement/merge-train.ts +131 -0
- package/src/self-implement/off-diff-evidence.ts +9 -0
- package/src/self-implement/orchestrator.ts +133 -16
- package/src/self-implement/review-finding-recurrence.ts +28 -0
- package/src/self-implement/rework-policy.ts +2 -1
- package/src/self-implement/round-summary-card.ts +63 -0
- package/src/self-implement/run-ledger.ts +4 -3
- package/src/self-implement/run-step-projection.ts +147 -0
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/seams.ts +36 -3
- package/src/self-implement/self-implement-cli.ts +3 -1
- package/src/self-implement/train-gate-remote.ts +158 -0
- package/src/session-runtime/index.ts +10 -1
- package/src/session-runtime/retry-api.ts +11 -1
- package/src/skills/gift-install.ts +119 -0
- package/src/skills/runner.ts +59 -2
- package/src/skills/skill-feedback.ts +31 -1
- package/src/skills/skill-tier.ts +1 -0
- package/src/smart-wizard/capability-index.ts +231 -0
- package/src/smart-wizard/rung.ts +74 -0
- package/src/steward/launch.ts +20 -9
- package/src/steward/triage.ts +4 -2
- package/src/storage/file-lock.ts +8 -1
- package/src/task-agent/actions.ts +4 -0
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/judge.ts +4 -3
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +133 -0
- package/src/task-agent/live-moves.ts +106 -19
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +297 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/shadow.ts +103 -7
- package/src/task-agent/task-hand.ts +136 -11
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
- package/src/telegram-service.ts +5 -1
- package/src/telegram.ts +17 -4
- package/src/time/format.ts +13 -4
- package/src/tool-runtime/goal-author-runtime.ts +1 -0
- package/src/tool-runtime/self-cognition-catalog.ts +23 -0
- package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
- package/src/user-config.ts +132 -24
- package/src/ux-sim/slash-menu-frames.ts +168 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-terminal/preview-tap-registry.ts +5 -2
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
- package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
- package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
- package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
- package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
- /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
|
@@ -9,7 +9,8 @@ import { intakeOutboxDir, kstDay } from './route.js';
|
|
|
9
9
|
|
|
10
10
|
export type DigestLensVerdict = '대체 후보' | '보강' | '경쟁 대조';
|
|
11
11
|
export interface DigestEntry { id: string; sources: string[]; url?: string; note?: string; noteName?: string; oneLiner?: string; axis: string; impact?: { verdict: DigestLensVerdict; why: string; target: string } }
|
|
12
|
-
export interface
|
|
12
|
+
export interface DigestLedgerEntry { id: string; title: string; url: string; verdict: DigestLensVerdict | '참고' | '판정 대기' }
|
|
13
|
+
export interface IntakeDigest { day: string; seat?: string; absorbed: DigestEntry[]; goals: { fact: string; url?: string }[]; news?: { title: string; url: string; summary: string[]; implication: string[] }[]; xTrends?: DigestLedgerEntry[]; githubNew?: DigestLedgerEntry[]; shadowSuggestions?: { fact: string; url?: string; verdict: string }[]; review?: { fact: string; note?: string }[]; grounding: number; release: number; manual: number; savedSilence?: { days: number; lastNewAt: string } }
|
|
13
14
|
|
|
14
15
|
const AXIS_LABEL: Record<string, string> = {
|
|
15
16
|
video_automation: '영상 자동화', agent_basics: '에이전트 기본', agent_applied: '에이전트 응용', unrelated: '그 밖',
|
|
@@ -69,29 +70,31 @@ export function buildIntakeDigest(root: string, day: string, readFile: (p: strin
|
|
|
69
70
|
const briefedEarlier = new Set(selectedSeat
|
|
70
71
|
? readJsonl(seatBriefFile(root, selectedSeat)).filter((r) => typeof r.id === 'string' && r.day !== day).map((r) => r.id as string)
|
|
71
72
|
: []);
|
|
72
|
-
const
|
|
73
|
+
const ledgerItems = [...loadIntakeLedger(root).items.values()];
|
|
74
|
+
const items = ledgerItems
|
|
73
75
|
.filter((i) => (selectedSeat === undefined || (i.seat === selectedSeat && !briefedEarlier.has(i.id)))
|
|
74
76
|
&& (selectedSeat ? i.status !== 'discarded' : (i.status === 'absorbed' || i.status === 'routed') && i.outputs.some((o) => o.kind === 'note'))
|
|
75
77
|
&& kstDay(i.lastSeenAt) === day);
|
|
76
78
|
const out = intakeOutboxDir(root);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
79
|
+
const allLensRows = readJsonl(join(out, 'lens', `${day}.jsonl`));
|
|
80
|
+
const ledgerDecisions = new Map<string, { verdict: Exclude<DigestLedgerEntry['verdict'], '판정 대기'>; why: string; target: string }>();
|
|
81
|
+
// The first valid lens row owns an ID's verdict for both absorbed notes and same-day ledger sections.
|
|
82
|
+
for (const row of allLensRows) {
|
|
83
|
+
if (typeof row.id !== 'string' || ledgerDecisions.has(row.id)) continue;
|
|
84
|
+
const verdict = row.lensVerdict;
|
|
85
|
+
if (verdict !== '대체 후보' && verdict !== '보강' && verdict !== '경쟁 대조' && verdict !== '참고') continue;
|
|
86
|
+
const why = typeof row.why === 'string' ? row.why.trim() : '';
|
|
87
|
+
const target = typeof row.target === 'string' ? row.target.trim() : '';
|
|
88
|
+
// A check's fact/current or repo path is evidence, not a lens judgement or a reason for us.
|
|
89
|
+
if (!why || !target || pathOnly(why)) continue;
|
|
90
|
+
ledgerDecisions.set(row.id, { verdict, why, target });
|
|
90
91
|
}
|
|
91
92
|
const absorbed = items.map((i: IntakeItem): DigestEntry => {
|
|
92
93
|
const note = [...i.outputs].reverse().find((o) => o.kind === 'note')?.ref;
|
|
93
94
|
const md = note ? readFile(note) : undefined;
|
|
94
|
-
const
|
|
95
|
+
const decision = ledgerDecisions.get(i.id);
|
|
96
|
+
const impact = decision && decision.verdict !== '참고'
|
|
97
|
+
? { verdict: decision.verdict, why: decision.why, target: decision.target } : undefined;
|
|
95
98
|
return {
|
|
96
99
|
id: i.id, sources: i.sources, ...(i.url ? { url: i.url } : {}),
|
|
97
100
|
...(note ? { note, noteName: basename(note, '.md') } : {}),
|
|
@@ -101,11 +104,19 @@ export function buildIntakeDigest(root: string, day: string, readFile: (p: strin
|
|
|
101
104
|
};
|
|
102
105
|
});
|
|
103
106
|
const goals = selectedSeat ? [] : readJsonl(join(out, 'goals', `${day}.jsonl`)).map((g) => ({ fact: String(g.fact ?? ''), ...(g.url ? { url: String(g.url) } : {}) }));
|
|
104
|
-
const lensRows = selectedSeat ? [] :
|
|
107
|
+
const lensRows = selectedSeat ? [] : allLensRows;
|
|
105
108
|
const news = lensRows.flatMap((row) =>
|
|
106
109
|
typeof row.title === 'string' && typeof row.url === 'string' && Array.isArray(row.summary) && Array.isArray(row.implication)
|
|
107
110
|
? [{ title: row.title, url: row.url, summary: row.summary.filter((s): s is string => typeof s === 'string'), implication: row.implication.filter((s): s is string => typeof s === 'string') }]
|
|
108
111
|
: []);
|
|
112
|
+
const ledgerEntry = (item: IntakeItem): DigestLedgerEntry => ({
|
|
113
|
+
id: item.id, title: item.title?.trim() || item.url!, url: item.url!,
|
|
114
|
+
verdict: ledgerDecisions.get(item.id)?.verdict ?? '판정 대기',
|
|
115
|
+
});
|
|
116
|
+
const sameDayLedger = selectedSeat ? [] : ledgerItems
|
|
117
|
+
.filter((item) => item.status !== 'discarded' && item.url && kstDay(item.lastSeenAt) === day);
|
|
118
|
+
const xTrends = sameDayLedger.filter((item) => item.sources.includes('x')).map(ledgerEntry);
|
|
119
|
+
const githubNew = sameDayLedger.filter((item) => item.sources.includes('github')).map(ledgerEntry);
|
|
109
120
|
const shadowSuggestions = lensRows.flatMap((row) =>
|
|
110
121
|
Array.isArray(row.suggestions) ? row.suggestions.flatMap((raw: unknown) => {
|
|
111
122
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return [];
|
|
@@ -118,7 +129,7 @@ export function buildIntakeDigest(root: string, day: string, readFile: (p: strin
|
|
|
118
129
|
const lastNewAt = selectedSeat ? undefined : readSavedCursorAt(root);
|
|
119
130
|
const silentMs = lastNewAt ? now.getTime() - Date.parse(lastNewAt) : NaN;
|
|
120
131
|
return {
|
|
121
|
-
day, ...(selectedSeat ? { seat: selectedSeat } : {}), absorbed, goals, ...(news.length ? { news } : {}), ...(shadowSuggestions.length ? { shadowSuggestions } : {}), review, grounding,
|
|
132
|
+
day, ...(selectedSeat ? { seat: selectedSeat } : {}), absorbed, goals, ...(news.length ? { news } : {}), ...(xTrends.length ? { xTrends } : {}), ...(githubNew.length ? { githubNew } : {}), ...(shadowSuggestions.length ? { shadowSuggestions } : {}), review, grounding,
|
|
122
133
|
release: selectedSeat ? 0 : readJsonl(join(out, 'release', `${day}.jsonl`)).length,
|
|
123
134
|
manual: selectedSeat ? 0 : readJsonl(join(out, 'manual', `${day}.jsonl`)).length,
|
|
124
135
|
...(!selectedSeat && lastNewAt && silentMs > SAVED_SILENCE_MS ? { savedSilence: { days: Math.floor(silentMs / 86_400_000), lastNewAt } } : {}),
|
|
@@ -142,8 +153,10 @@ function digestReferenceLine(entries: DigestEntry[]): string {
|
|
|
142
153
|
export function renderDigestMarkdown(d: IntakeDigest): string {
|
|
143
154
|
const L: string[] = [`## 📰 오늘의 흡수 요약 (${d.absorbed.length})`, ''];
|
|
144
155
|
if (d.savedSilence) L.push(`> ⚠️ 텔레그램 «저장된 메시지»에서 새 글을 ${d.savedSilence.days}일째 못 받았다(마지막 새 글 수집 ${kstDay(d.savedSilence.lastNewAt)}) — 저장했는데 안 들어왔다면 저장한 곳(본인 «저장된 메시지»인지)을 확인한다.`, '');
|
|
145
|
-
if (!d.absorbed.length
|
|
146
|
-
|
|
156
|
+
if (!d.absorbed.length && !d.news?.length && !d.xTrends?.length && !d.githubNew?.length) {
|
|
157
|
+
L.push('오늘 흡수한 것이 없다.', '');
|
|
158
|
+
return L.join('\n');
|
|
159
|
+
}
|
|
147
160
|
const byAxis = new Map<string, DigestEntry[]>();
|
|
148
161
|
for (const e of d.absorbed) (byAxis.get(e.axis) ?? byAxis.set(e.axis, []).get(e.axis)!).push(e);
|
|
149
162
|
for (const [axis, rows] of byAxis) {
|
|
@@ -160,6 +173,12 @@ export function renderDigestMarkdown(d: IntakeDigest): string {
|
|
|
160
173
|
}
|
|
161
174
|
L.push('');
|
|
162
175
|
}
|
|
176
|
+
for (const [heading, entries] of [['X 트렌드', d.xTrends], ['GitHub 신규', d.githubNew]] as const) {
|
|
177
|
+
if (!entries?.length) continue;
|
|
178
|
+
L.push(`### ${heading} (${entries.length})`, '');
|
|
179
|
+
for (const entry of entries) L.push(`- [${entry.title}](${entry.url}) — ${entry.verdict}`);
|
|
180
|
+
L.push('');
|
|
181
|
+
}
|
|
163
182
|
if (d.goals.length) {
|
|
164
183
|
L.push(`### 🔴 엘라누스에 없는 것 — 골 후보 (${d.goals.length})`, '');
|
|
165
184
|
for (const g of d.goals.slice(0, 10)) L.push(`- ${g.fact}${g.url ? ` · [원본](${g.url})` : ''}`);
|
|
@@ -189,6 +208,12 @@ export function renderDigestTelegram(d: IntakeDigest, _opts: { vaultRoot?: strin
|
|
|
189
208
|
L.push(article.url);
|
|
190
209
|
}
|
|
191
210
|
if (d.shadowSuggestions?.length) L.push(`뉴스 칸 제안 ${d.shadowSuggestions.length}건 (그림자·판 미등록): ${d.shadowSuggestions.slice(0, 3).map((s) => `[${s.verdict}] ${s.fact}${s.url ? ` ${s.url}` : ''}`).join(' · ')}`);
|
|
211
|
+
for (const [heading, entries] of [['X 트렌드', d.xTrends], ['GitHub 신규', d.githubNew]] as const) {
|
|
212
|
+
if (!entries?.length) continue;
|
|
213
|
+
L.push('', `${heading} (${entries.length})`);
|
|
214
|
+
for (const entry of entries.slice(0, 5)) L.push(`- [${entry.verdict}] ${entry.title} — ${entry.url}`);
|
|
215
|
+
if (entries.length > 5) L.push(`외 ${entries.length - 5}건 · 원장 \`elanous intake items\``);
|
|
216
|
+
}
|
|
192
217
|
// At most three items are shown, each as its own S·C·A·note block so context and source stay paired.
|
|
193
218
|
// S must be the note's own summary: items without one still count as touching but are not shown (ACP must-fix).
|
|
194
219
|
const shownItems = touching.filter((e) => e.oneLiner?.trim()).slice(0, 3);
|
package/src/intake-plane/lens.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// 흡수 렌즈 — outbox
|
|
2
|
-
// 원 갈래(goals·manual·review·release)
|
|
1
|
+
// 흡수 렌즈 — E1 outbox 와 같은 날 공개 GitHub·X 원장 항목을 판정해 outbox/lens/<day>.jsonl 에만 남긴다.
|
|
2
|
+
// 원 갈래(goals·manual·review·release)와 원장은 읽기만 한다. LLM 은 judge 한 번(id 당).
|
|
3
3
|
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { debug } from '../debug/log.js';
|
|
6
6
|
import { judge } from '../llm/judge-layer.js';
|
|
7
|
-
import {
|
|
7
|
+
import { loadIntakeLedger } from './items.js';
|
|
8
|
+
import { intakeOutboxDir, kstDay } from './route.js';
|
|
8
9
|
|
|
9
10
|
export const LENS_VERDICTS = ['대체 후보', '보강', '경쟁 대조', '참고'] as const;
|
|
10
11
|
export type LensVerdict = (typeof LENS_VERDICTS)[number];
|
|
@@ -98,6 +99,26 @@ function groupOutbox(root: string, day: string): GroupedItem[] {
|
|
|
98
99
|
return order.map((id) => groups.get(id)!);
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
function ledgerLensItems(root: string, day: string, existing: ReadonlySet<string>): GroupedItem[] {
|
|
103
|
+
const items: GroupedItem[] = [];
|
|
104
|
+
const seen = new Set(existing);
|
|
105
|
+
const ledger = [...loadIntakeLedger(root).items.values()];
|
|
106
|
+
for (const source of ['github', 'x'] as const) {
|
|
107
|
+
for (const item of ledger) {
|
|
108
|
+
if (!item.id || seen.has(item.id) || item.status === 'discarded' || item.privacy !== 'public'
|
|
109
|
+
|| !item.url || kstDay(item.lastSeenAt) !== day || !item.sources?.includes(source)) continue;
|
|
110
|
+
const title = item.title?.trim();
|
|
111
|
+
const text = item.text?.trim();
|
|
112
|
+
const facts = [title, text].filter((value): value is string => Boolean(value)).slice(0, LENS_FACT_CAP)
|
|
113
|
+
.map((fact) => ({ fact, current: '' }));
|
|
114
|
+
if (!facts.length) continue;
|
|
115
|
+
seen.add(item.id);
|
|
116
|
+
items.push({ id: item.id, facts, url: item.url });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return items;
|
|
120
|
+
}
|
|
121
|
+
|
|
101
122
|
function judgedIds(file: string): Set<string> {
|
|
102
123
|
return new Set(readJsonl(file).flatMap((row) => typeof row.id === 'string' && row.id ? [row.id] : []));
|
|
103
124
|
}
|
|
@@ -130,7 +151,7 @@ async function defaultJudge(item: GroupedItem): Promise<unknown> {
|
|
|
130
151
|
return decision.value;
|
|
131
152
|
}
|
|
132
153
|
|
|
133
|
-
/** 그날 outbox
|
|
154
|
+
/** 그날 E1 outbox 뒤에 공개 GitHub·X 원장을 붙여 아직 없는 판정만 남긴다. 원천 파일은 쓰지 않는다. */
|
|
134
155
|
export async function annotateIntakeLens(
|
|
135
156
|
root: string,
|
|
136
157
|
day: string,
|
|
@@ -142,13 +163,20 @@ export async function annotateIntakeLens(
|
|
|
142
163
|
log('skipped-test', {});
|
|
143
164
|
return empty;
|
|
144
165
|
}
|
|
145
|
-
const
|
|
166
|
+
const outbox = groupOutbox(root, day);
|
|
167
|
+
const ledger = ledgerLensItems(root, day, new Set(outbox.map((item) => item.id)));
|
|
168
|
+
const items = [...outbox, ...ledger];
|
|
146
169
|
const file = join(intakeOutboxDir(root), 'lens', `${day}.jsonl`);
|
|
147
170
|
const done = judgedIds(file);
|
|
148
171
|
const pending = items.filter((item) => !done.has(item.id));
|
|
149
|
-
const
|
|
150
|
-
const
|
|
151
|
-
|
|
172
|
+
const remaining = Math.max(0, LENS_DAILY_CAP - done.size);
|
|
173
|
+
const capped = pending.length > remaining;
|
|
174
|
+
const batch = pending.slice(0, remaining);
|
|
175
|
+
if (capped) {
|
|
176
|
+
const skippedIds = pending.slice(remaining).map((item) => item.id);
|
|
177
|
+
log('capped', { day, total: pending.length, judged: batch.length, skippedIds,
|
|
178
|
+
...(skippedIds.length ? { marker: `외 ${skippedIds.length}건 · 원장 \`elanous intake items\`` } : {}) });
|
|
179
|
+
}
|
|
152
180
|
const judgeOne = deps.judge ?? ((input: LensJudgeInput) => defaultJudge(input));
|
|
153
181
|
const now = deps.now ?? (() => new Date().toISOString());
|
|
154
182
|
let judged = 0;
|
|
@@ -35,6 +35,12 @@ const MODEL_ALIASES: Readonly<Record<string, string>> = {
|
|
|
35
35
|
'opus-5': 'claude-opus-5',
|
|
36
36
|
'opus-4-8': 'claude-opus-4-8',
|
|
37
37
|
'opus-4-7': 'claude-opus-4-7', // 하위호환
|
|
38
|
+
// ⭐ 2026-10-10 (MK) — 5.5 세대는 판을 붙여서만 부른다(맨몸 `sonnet`·`haiku` 는 옮기지 않았다 — 별개 결정).
|
|
39
|
+
// 공식 API id 는 하이픈(`claude-sonnet-5-5`)인데 OpenRouter·사람은 점(`claude-sonnet-5.5`)으로 쓴다 — 둘 다 받는다.
|
|
40
|
+
'sonnet-5-5': 'claude-sonnet-5-5',
|
|
41
|
+
'haiku-5-5': 'claude-haiku-5-5',
|
|
42
|
+
'claude-sonnet-5.5': 'claude-sonnet-5-5',
|
|
43
|
+
'claude-haiku-5.5': 'claude-haiku-5-5',
|
|
38
44
|
// Google Gemini family
|
|
39
45
|
'flash': 'gemini-3.8-flash', // ⭐ 2026-09-25 최신 flash(models.list 실측)
|
|
40
46
|
'flash-3-7': 'gemini-3.7-flash',
|
|
@@ -794,6 +794,47 @@ export const BUILTIN_CATALOG: ModelCatalog = {
|
|
|
794
794
|
mlxRepo: 'lmstudio-community/NVIDIA-Nemotron-3-Nano-30B-A3B-MLX-8bit',
|
|
795
795
|
notes: 'NVIDIA Open Model License · 30B/3B MoE · 1M ctx · text+vision+audio+video · Q4 ~28GB / MLX-8bit ~36GB · M5 Max OK',
|
|
796
796
|
},
|
|
797
|
+
// ⭐ 2026-10-10 (MK · MODEL-ROUTING-MATRIX) — `--child-llm-model` 이 이 둘을 «알 수 없음»으로 거부했다
|
|
798
|
+
// (UX 17:36 실측 · 해석은 이 표 ⊕ src/anthropic/models.ts 만 본다). 값은 Anthropic 공식 1차
|
|
799
|
+
// (platform.claude.com/내부 문서 `overview` · 2026-10-10T08:38Z 직접 확인)
|
|
800
|
+
// ⊕ OpenRouter /api/v1/models 실측(05:10Z) 이 같다. 별칭(`sonnet`·`haiku`)은 옮기지 않는다 — 별개 결정.
|
|
801
|
+
// ⛔ 표의 «맨 끝»에 둔 것은 의도다 — `recommendModel` 은 같은 가격이면 표 순서로 고른다(안정 정렬).
|
|
802
|
+
// haiku-5-5($0.10/$0.50)는 gpt-6-luna 와 값이 같아, 앞에 두면 'cheap' 추천이 조용히 haiku 로 바뀐다
|
|
803
|
+
// (게다가 haiku 는 >100k 프롬프트가 5배라 이 칸 하나로는 싸다고 말할 수 없다). 추천 변경은 별개 결정.
|
|
804
|
+
{
|
|
805
|
+
// 📏 공식: Released 2026-09-28 · 1M ctx · 출력 128K · $2/$10 · 캐시 읽기 $0.10(입력의 5%) · Adaptive · 기본 effort high.
|
|
806
|
+
id: 'claude-sonnet-5-5',
|
|
807
|
+
provider: 'anthropic',
|
|
808
|
+
family: 'claude',
|
|
809
|
+
contextWindow: 1_000_000,
|
|
810
|
+
inputPerMtok: 2,
|
|
811
|
+
outputPerMtok: 10,
|
|
812
|
+
local: false,
|
|
813
|
+
tags: ['reasoning', 'coding', 'balanced', 'long-context'],
|
|
814
|
+
bestFor: ['daily-coding', 'multi-turn-chat', 'summarization'],
|
|
815
|
+
envKey: 'ANTHROPIC_API_KEY',
|
|
816
|
+
reservedOutputTokens: 8_000,
|
|
817
|
+
reasoningEffortCeiling: 'high', // adaptive thinking (공식 «Adaptive»)
|
|
818
|
+
releasedAt: '2026-09-28',
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
// 📏 공식: Released 2026-10-07 · 1M ctx · 출력 128K · Adaptive · 기본 effort medium.
|
|
822
|
+
// ⚠️ 가격이 프롬프트 길이 구간으로 갈린다 — ≤100k 토큰 $0.10/$0.50 · >100k $0.50/$2.50(요청 전체).
|
|
823
|
+
// 칸이 하나라 «≤100k» 를 싣는다.
|
|
824
|
+
id: 'claude-haiku-5-5',
|
|
825
|
+
provider: 'anthropic',
|
|
826
|
+
family: 'claude',
|
|
827
|
+
contextWindow: 1_000_000,
|
|
828
|
+
inputPerMtok: 0.1,
|
|
829
|
+
outputPerMtok: 0.5,
|
|
830
|
+
local: false,
|
|
831
|
+
tags: ['classification', 'summarization', 'cheap', 'fast', 'long-context'],
|
|
832
|
+
bestFor: ['classification', 'routing', 'bulk-summarization', 'subagent-tasks'],
|
|
833
|
+
envKey: 'ANTHROPIC_API_KEY',
|
|
834
|
+
reservedOutputTokens: 8_000,
|
|
835
|
+
reasoningEffortCeiling: 'high', // 공식: adaptive thinking ⊕ effort 파라미터 지원(haiku-4-5 의 'low' 와 다르다)
|
|
836
|
+
releasedAt: '2026-10-07',
|
|
837
|
+
},
|
|
797
838
|
],
|
|
798
839
|
};
|
|
799
840
|
|
|
@@ -50,14 +50,17 @@ export interface PackId {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const SLUG_RE = /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/;
|
|
53
|
-
const VERSION_RE =
|
|
53
|
+
const VERSION_RE = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[a-z0-9-]+(?:\.[a-z0-9-]+)*)?$/;
|
|
54
54
|
|
|
55
55
|
export function isPackSlug(v: unknown): v is string {
|
|
56
56
|
return typeof v === 'string' && SLUG_RE.test(v);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export function isPackVersion(v: unknown): v is string {
|
|
60
|
-
|
|
60
|
+
if (typeof v !== 'string' || !VERSION_RE.test(v)) return false;
|
|
61
|
+
const separator = v.indexOf('-');
|
|
62
|
+
const prerelease = separator < 0 ? undefined : v.slice(separator + 1);
|
|
63
|
+
return prerelease === undefined || prerelease.split('.').every(id => !/^\d+$/.test(id) || id === '0' || !id.startsWith('0'));
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
export function packIdString(id: PackId): string {
|
|
@@ -209,6 +209,21 @@ export class KgsSqliteStore {
|
|
|
209
209
|
);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/** Remove only the selected version; standalone pack cards live inside its payload. */
|
|
213
|
+
deletePack(slug: string, version: string): boolean {
|
|
214
|
+
return this.db.run('DELETE FROM kgs_pack WHERE slug = ? AND version = ?', [slug, version]).changes > 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Switch versions as one SQLite transaction so failed upgrades retain the old index. */
|
|
218
|
+
replacePack(previous: { slug: string; version: string }, next: Pack): void {
|
|
219
|
+
this.db.transaction(() => {
|
|
220
|
+
if (!this.readPack(previous.slug, previous.version)) throw new Error('pack not installed');
|
|
221
|
+
if (this.readPack(next.metadata.id.slug, next.metadata.id.version)) throw new Error('pack version already installed');
|
|
222
|
+
this.writePack(next);
|
|
223
|
+
if (!this.deletePack(previous.slug, previous.version)) throw new Error('pack not removed');
|
|
224
|
+
})();
|
|
225
|
+
}
|
|
226
|
+
|
|
212
227
|
readPack(slug: string, version: string): Pack | null {
|
|
213
228
|
const row = this.db
|
|
214
229
|
.query(`SELECT payload FROM kgs_pack WHERE slug = ? AND version = ?`)
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import type { LLMToolSpec } from '../../llm.js';
|
|
4
4
|
import { discoverObsidianVault, type ObsidianVault } from '../../auto-research/obsidian-bridge.js';
|
|
5
|
-
import { knowledgeQuery } from '../query.js';
|
|
5
|
+
import { knowledgeQuery, queryInstalledPack } from '../query.js';
|
|
6
6
|
import type { KnowledgeQueryInput, KnowledgeQueryResult } from '../types.js';
|
|
7
7
|
|
|
8
8
|
export interface KnowledgeQueryToolInput {
|
|
9
|
+
pack_id?: string;
|
|
10
|
+
question?: string;
|
|
9
11
|
tags?: string[];
|
|
10
12
|
fulltext?: string;
|
|
11
13
|
kind?: 'all' | 'rca' | 'a3' | 'incident' | 'wiki' | 'repomap' | 'note';
|
|
@@ -16,6 +18,8 @@ export interface KnowledgeQueryToolInput {
|
|
|
16
18
|
|
|
17
19
|
export interface KnowledgeQueryToolResult {
|
|
18
20
|
output: string;
|
|
21
|
+
/** Cited cards when pack_id is supplied; absent on the existing vault query path. */
|
|
22
|
+
pack_hits?: ReturnType<typeof queryInstalledPack>;
|
|
19
23
|
results: KnowledgeQueryResult['results'];
|
|
20
24
|
total: number;
|
|
21
25
|
truncated: boolean;
|
|
@@ -24,12 +28,24 @@ export interface KnowledgeQueryToolResult {
|
|
|
24
28
|
|
|
25
29
|
export interface KnowledgeQueryDispatchOpts {
|
|
26
30
|
vault?: ObsidianVault;
|
|
31
|
+
searchPack?: typeof queryInstalledPack;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
export async function dispatchKnowledgeQuery(
|
|
30
35
|
input: KnowledgeQueryToolInput,
|
|
31
36
|
opts: KnowledgeQueryDispatchOpts = {},
|
|
32
37
|
): Promise<KnowledgeQueryToolResult> {
|
|
38
|
+
if (input.pack_id !== undefined) {
|
|
39
|
+
try {
|
|
40
|
+
if (!input.question?.trim()) throw new Error('question required for pack search');
|
|
41
|
+
const hits = (opts.searchPack ?? queryInstalledPack)(input.pack_id, input.question);
|
|
42
|
+
return { output: hits.map(hit => `[${hit.ref}] ${hit.title}: ${hit.body}`).join('\n') || 'No matching installed pack cards.',
|
|
43
|
+
pack_hits: hits, results: [], total: hits.length, truncated: false };
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return { output: `KnowledgeQuery failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
46
|
+
pack_hits: [], results: [], total: 0, truncated: false };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
33
49
|
const vault = opts.vault ?? discoverObsidianVault();
|
|
34
50
|
const notices: string[] = [];
|
|
35
51
|
if (vault.isSimulated) {
|
|
@@ -75,13 +91,15 @@ export function buildKnowledgeQueryTool(): LLMToolSpec {
|
|
|
75
91
|
return {
|
|
76
92
|
name: 'KnowledgeQuery',
|
|
77
93
|
description:
|
|
78
|
-
'Search the Obsidian knowledge vault (or simulated fallback) for notes matching tags, fulltext regex, '
|
|
94
|
+
'Search an explicitly installed knowledge pack by pack_id and question for cited cards, or search the Obsidian knowledge vault (or simulated fallback) for notes matching tags, fulltext regex, '
|
|
79
95
|
+ 'or kind. Returns paths + parsed frontmatter + excerpts (and optionally full body). Use this to look '
|
|
80
96
|
+ 'up prior incident analyses, tool docs, repo maps, or any markdown you or another agent wrote earlier. '
|
|
81
97
|
+ 'For writing, use KnowledgeWrite.',
|
|
82
98
|
parameters: {
|
|
83
99
|
type: 'object',
|
|
84
100
|
properties: {
|
|
101
|
+
pack_id: { type: 'string', description: 'Installed pack id, e.g. pack:semiconductor-process-public@0.1.0. Requires question.' },
|
|
102
|
+
question: { type: 'string', description: 'Search words when pack_id is provided.' },
|
|
85
103
|
tags: {
|
|
86
104
|
type: 'array',
|
|
87
105
|
items: { type: 'string' },
|
package/src/knowledge/write.ts
CHANGED
|
@@ -7,14 +7,21 @@
|
|
|
7
7
|
// - automatic tag / kind merge into frontmatter
|
|
8
8
|
// - Poka-Yoke validation → atomic-write ONLY on pass
|
|
9
9
|
|
|
10
|
-
import { existsSync,
|
|
11
|
-
import {
|
|
10
|
+
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { gunzipSync } from 'node:zlib';
|
|
13
|
+
import { isAbsolute, join, resolve, sep } from 'node:path';
|
|
14
|
+
import { packDirDeterministic } from '../market/tgz.js';
|
|
15
|
+
import { verifyIndex } from '../market/signed-index.js';
|
|
12
16
|
import {
|
|
13
17
|
writeNote,
|
|
14
18
|
type ObsidianVault,
|
|
15
19
|
} from '../auto-research/obsidian-bridge.js';
|
|
16
20
|
import type { PokaSchema, ValidationFailure } from '../cft/pokayoke.js';
|
|
17
21
|
import { validate } from '../cft/pokayoke.js';
|
|
22
|
+
import { isPackSlug, isPackVersion, packIdString, type Pack, type PackId } from './kgs/pack.js';
|
|
23
|
+
import { isKnowledgeKind, type KnowledgeCard } from './kgs/types.js';
|
|
24
|
+
import { kgsStoreSingleton, type KgsSqliteStore } from './kgs/sqlite-store.js';
|
|
18
25
|
import type {
|
|
19
26
|
KnowledgeKind,
|
|
20
27
|
KnowledgeWriteInput,
|
|
@@ -141,6 +148,231 @@ export function knowledgeWrite(
|
|
|
141
148
|
return { ok: true, path: abs, relPath: rel };
|
|
142
149
|
}
|
|
143
150
|
|
|
151
|
+
/** KPACK1 directory manifest. Market signatures belong to the index, not this file. */
|
|
152
|
+
export interface KnowledgePackManifest {
|
|
153
|
+
kind: 'knowledge-pack';
|
|
154
|
+
name: string;
|
|
155
|
+
version: string;
|
|
156
|
+
description: string;
|
|
157
|
+
signature: { alg: 'ed25519'; keyId: string };
|
|
158
|
+
dependencies: readonly { market: string; name: string; version: string }[];
|
|
159
|
+
license: string;
|
|
160
|
+
visibility: 'public' | 'internal';
|
|
161
|
+
content: readonly { type: 'document' | 'glossary' | 'procedure' | 'rule' | 'qa'; path: string }[];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Verified marketplace evidence is required when installing from a market. The URL→key binding is caller-owned. */
|
|
165
|
+
export interface KnowledgePackMarketProof {
|
|
166
|
+
marketplaceBytes: Uint8Array;
|
|
167
|
+
signatureText: string;
|
|
168
|
+
trustedKeys: ReadonlyArray<{ keyId: string; publicKey: string }>;
|
|
169
|
+
artifactBytes: Uint8Array;
|
|
170
|
+
lastSequence?: number;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export type KnowledgePackStore = Pick<KgsSqliteStore, 'readPack' | 'writePack' | 'deletePack' | 'replacePack'>;
|
|
174
|
+
|
|
175
|
+
function object(value: unknown): value is Record<string, unknown> {
|
|
176
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function requiredString(value: unknown, field: string): asserts value is string {
|
|
180
|
+
if (typeof value !== 'string' || !value.trim()) throw new Error(`KPACK1: ${field} must be a non-empty string`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Never follow a symlink, including any ancestor of an enumerated content file. */
|
|
184
|
+
function safePackFile(root: string, path: string): string {
|
|
185
|
+
if (!path || isAbsolute(path) || path.includes('\\') || path.split('/').some(part => !part || part === '.' || part === '..')) {
|
|
186
|
+
throw new Error(`KPACK1: unsafe path: ${path}`);
|
|
187
|
+
}
|
|
188
|
+
let current = root;
|
|
189
|
+
for (const part of path.split('/')) {
|
|
190
|
+
current = join(current, part);
|
|
191
|
+
const stat = lstatSync(current);
|
|
192
|
+
if (stat.isSymbolicLink()) throw new Error(`KPACK1: symbolic link: ${path}`);
|
|
193
|
+
}
|
|
194
|
+
if (!lstatSync(current).isFile()) throw new Error(`KPACK1: not a file: ${path}`);
|
|
195
|
+
return current;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Validate the manifest and all listed content before any store mutation. */
|
|
199
|
+
export function validateKnowledgePack(directory: string): { manifest: KnowledgePackManifest; pack: Pack } {
|
|
200
|
+
if (!lstatSync(directory).isDirectory() || lstatSync(directory).isSymbolicLink()) throw new Error('KPACK1: not a directory');
|
|
201
|
+
// The packer traverses the whole directory and refuses even unlisted symlinks/special files.
|
|
202
|
+
packDirDeterministic(directory);
|
|
203
|
+
return validatePackFiles(path => readFileSync(safePackFile(directory, path), 'utf8'));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Read the regular files of a deterministic ustar gzip archive (as produced by packDirDeterministic). */
|
|
207
|
+
const MAX_ARCHIVE_BYTES = 32 * 1024 * 1024;
|
|
208
|
+
|
|
209
|
+
function archiveFiles(archive: Uint8Array): Map<string, string> {
|
|
210
|
+
if (archive.byteLength > MAX_ARCHIVE_BYTES) throw new Error('KPACK1: archive too large');
|
|
211
|
+
let tar: Buffer;
|
|
212
|
+
// Bound the inflated size so a small compressed bomb cannot exhaust memory.
|
|
213
|
+
try { tar = gunzipSync(archive, { maxOutputLength: MAX_ARCHIVE_BYTES }); }
|
|
214
|
+
catch (error) { throw new Error(`KPACK1: archive unreadable or larger than ${MAX_ARCHIVE_BYTES} bytes: ${String(error)}`); }
|
|
215
|
+
const files = new Map<string, string>();
|
|
216
|
+
const field = (header: Buffer, offset: number, width: number) => {
|
|
217
|
+
const raw = header.subarray(offset, offset + width);
|
|
218
|
+
const end = raw.indexOf(0);
|
|
219
|
+
return raw.subarray(0, end < 0 ? width : end).toString('utf8');
|
|
220
|
+
};
|
|
221
|
+
for (let offset = 0; offset + 512 <= tar.length;) {
|
|
222
|
+
const header = tar.subarray(offset, offset + 512);
|
|
223
|
+
if (header.every(byte => byte === 0)) break;
|
|
224
|
+
const type = field(header, 156, 1);
|
|
225
|
+
if (type !== '0' && type !== '') throw new Error('KPACK1: archive contains a non-regular entry');
|
|
226
|
+
const size = Number.parseInt(field(header, 124, 12).trim(), 8);
|
|
227
|
+
if (!Number.isSafeInteger(size) || size < 0 || offset + 512 + size > tar.length) throw new Error('KPACK1: malformed archive');
|
|
228
|
+
const name = field(header, 0, 100);
|
|
229
|
+
const prefix = field(header, 345, 155);
|
|
230
|
+
const path = prefix ? `${prefix}/${name}` : name;
|
|
231
|
+
if (files.has(path)) throw new Error(`KPACK1: duplicate archive entry: ${path}`);
|
|
232
|
+
files.set(path, tar.subarray(offset + 512, offset + 512 + size).toString('utf8'));
|
|
233
|
+
offset += 512 + Math.ceil(size / 512) * 512;
|
|
234
|
+
}
|
|
235
|
+
return files;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Validate from verified archive bytes, so what is stored is exactly what the signature covered. */
|
|
239
|
+
export function validateKnowledgePackArchive(archive: Uint8Array): { manifest: KnowledgePackManifest; pack: Pack } {
|
|
240
|
+
const files = archiveFiles(archive);
|
|
241
|
+
return validatePackFiles((path) => {
|
|
242
|
+
const content = files.get(path);
|
|
243
|
+
if (content === undefined) throw new Error(`KPACK1: missing from archive: ${path}`);
|
|
244
|
+
return content;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function validatePackFiles(read: (path: string) => string): { manifest: KnowledgePackManifest; pack: Pack } {
|
|
249
|
+
const value: unknown = JSON.parse(read('knowledge-pack.json'));
|
|
250
|
+
if (!object(value) || value.kind !== 'knowledge-pack') throw new Error('KPACK1: invalid kind');
|
|
251
|
+
if (!isPackSlug(value.name) || !isPackVersion(value.version)) throw new Error('KPACK1: invalid name or version');
|
|
252
|
+
requiredString(value.description, 'description');
|
|
253
|
+
requiredString(value.license, 'license');
|
|
254
|
+
if (!object(value.signature) || value.signature.alg !== 'ed25519' || typeof value.signature.keyId !== 'string' || !/^[a-fA-F0-9]{8}$/.test(value.signature.keyId)) throw new Error('KPACK1: invalid signature declaration');
|
|
255
|
+
if (value.visibility !== 'public' && value.visibility !== 'internal') throw new Error('KPACK1: invalid visibility');
|
|
256
|
+
if (!Array.isArray(value.dependencies) || !Array.isArray(value.content) || value.content.length === 0 || value.content.length > 200) throw new Error('KPACK1: invalid dependencies or content');
|
|
257
|
+
for (const dep of value.dependencies) {
|
|
258
|
+
if (!object(dep) || typeof dep.market !== 'string' || !/^https:\/\//.test(dep.market) || !isPackSlug(dep.name) || typeof dep.version !== 'string' || !dep.version.trim()) throw new Error('KPACK1: invalid dependency');
|
|
259
|
+
}
|
|
260
|
+
// No dependency resolver is available in standalone storage; never silently install an incomplete pack.
|
|
261
|
+
if (value.dependencies.length) throw new Error('KPACK1: dependencies require a verified resolver');
|
|
262
|
+
const seen = new Set<string>();
|
|
263
|
+
const cards: KnowledgeCard[] = [];
|
|
264
|
+
for (const entry of value.content) {
|
|
265
|
+
if (!object(entry) || !['document', 'glossary', 'procedure', 'rule', 'qa'].includes(entry.type as string) || typeof entry.path !== 'string' || !entry.path.startsWith('content/') || !entry.path.endsWith('.json')) throw new Error('KPACK1: invalid content entry');
|
|
266
|
+
if (seen.has(entry.path)) throw new Error(`KPACK1: duplicate content: ${entry.path}`);
|
|
267
|
+
seen.add(entry.path);
|
|
268
|
+
const item: unknown = JSON.parse(read(entry.path));
|
|
269
|
+
if (!object(item) || item.type !== entry.type) throw new Error(`KPACK1: invalid content: ${entry.path}`);
|
|
270
|
+
requiredString(item.title, `${entry.path}.title`);
|
|
271
|
+
requiredString(item.source, `${entry.path}.source`);
|
|
272
|
+
if (item.kind !== undefined && !isKnowledgeKind(item.kind)) throw new Error(`KPACK1: invalid content kind: ${entry.path}`);
|
|
273
|
+
const fields: Record<string, readonly string[]> = {
|
|
274
|
+
document: ['body'], glossary: ['term', 'definition'], procedure: ['preconditions'],
|
|
275
|
+
rule: ['scope', 'basis'], qa: ['question', 'answer'],
|
|
276
|
+
};
|
|
277
|
+
for (const field of fields[entry.type as string]!) requiredString(item[field], `${entry.path}.${field}`);
|
|
278
|
+
if (entry.type === 'procedure' && (!Array.isArray(item.steps) || !item.steps.length || !item.steps.every((step: unknown) => typeof step === 'string' && step.trim()))) throw new Error(`KPACK1: ${entry.path}.steps must be non-empty strings`);
|
|
279
|
+
const body = entry.type === 'document' ? item.body as string : entry.type === 'procedure'
|
|
280
|
+
? `${item.preconditions}\n${(item.steps as string[]).join('\n')}`
|
|
281
|
+
: fields[entry.type as string]!.map(field => item[field]).join('\n');
|
|
282
|
+
const id = `card:${createHash('sha256').update(entry.path).digest('hex').slice(0, 16)}`;
|
|
283
|
+
const timestamp = '1970-01-01T00:00:00.000Z';
|
|
284
|
+
cards.push({ schema_version: 2, id, title: item.title, body, kind: isKnowledgeKind(item.kind) ? item.kind : 'card',
|
|
285
|
+
nature: 'fact', reliability: 'self-reported', author: value.name,
|
|
286
|
+
createdAt: timestamp, updatedAt: timestamp, source: { kind: 'external', url: item.source }, tags: [] });
|
|
287
|
+
}
|
|
288
|
+
const manifest = value as unknown as KnowledgePackManifest;
|
|
289
|
+
return { manifest, pack: {
|
|
290
|
+
schema_version: 2,
|
|
291
|
+
metadata: { id: { slug: manifest.name, version: manifest.version }, title: manifest.name,
|
|
292
|
+
intent: manifest.description, audience: manifest.visibility === 'public' ? 'public' : 'team',
|
|
293
|
+
kind: 'generic', createdAt: '1970-01-01T00:00:00.000Z', updatedAt: '1970-01-01T00:00:00.000Z',
|
|
294
|
+
author: manifest.name, tags: [] }, cards,
|
|
295
|
+
} };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Market path: verify the signed index and artifact first, then build the pack
|
|
300
|
+
* from those verified bytes (never from a second read of the directory).
|
|
301
|
+
*/
|
|
302
|
+
function verifiedMarketPack(directory: string, proof: KnowledgePackMarketProof): { manifest: KnowledgePackManifest; pack: Pack } {
|
|
303
|
+
const verified = verifyIndex(proof);
|
|
304
|
+
if (!verified.ok) throw new Error(`KPACK1: index ${verified.reason}: ${verified.detail}`);
|
|
305
|
+
const artifact = Buffer.from(proof.artifactBytes);
|
|
306
|
+
const sha256 = createHash('sha256').update(artifact).digest('hex');
|
|
307
|
+
const listed = verified.index.knowledgePacks?.filter(pack => pack.artifact.bytes === artifact.byteLength && pack.artifact.sha256.toLowerCase() === sha256) ?? [];
|
|
308
|
+
if (!listed.length) throw new Error('KPACK1: artifact hash or size mismatch');
|
|
309
|
+
const result = validateKnowledgePackArchive(artifact);
|
|
310
|
+
const { manifest } = result;
|
|
311
|
+
if (verified.keyId !== manifest.signature.keyId) throw new Error('KPACK1: manifest keyId differs from signed index');
|
|
312
|
+
const entry = listed.find(pack => pack.name === manifest.name && pack.version === manifest.version);
|
|
313
|
+
if (!entry || entry.visibility !== manifest.visibility || (entry.visibility === 'internal' && !entry.enterpriseId)) throw new Error('KPACK1: pack absent from signed index');
|
|
314
|
+
// The local directory must still be the extraction of this artifact.
|
|
315
|
+
validateKnowledgePack(directory);
|
|
316
|
+
if (Buffer.compare(Buffer.from(packDirDeterministic(directory)), artifact) !== 0) throw new Error('KPACK1: extracted directory differs from verified artifact');
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Local-path installs validate content; market installs additionally require signed-index and archive proof. */
|
|
321
|
+
export function installKnowledgePack(directory: string, store: KnowledgePackStore = kgsStoreSingleton(), proof?: KnowledgePackMarketProof): string {
|
|
322
|
+
const { manifest, pack } = proof ? verifiedMarketPack(directory, proof) : validateKnowledgePack(directory);
|
|
323
|
+
if (store.readPack(manifest.name, manifest.version)) throw new Error(`KPACK1: already installed: ${packIdString(pack.metadata.id)}`);
|
|
324
|
+
store.writePack(pack);
|
|
325
|
+
return packIdString(pack.metadata.id);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function removeKnowledgePack(id: PackId, store: KnowledgePackStore = kgsStoreSingleton()): boolean {
|
|
329
|
+
if (!isPackSlug(id.slug) || !isPackVersion(id.version)) throw new Error('KPACK1: invalid pack id');
|
|
330
|
+
return store.deletePack(id.slug, id.version);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function comparePackVersions(next: string, previous: string): number {
|
|
334
|
+
if (!isPackVersion(next) || !isPackVersion(previous)) throw new Error('KPACK1: invalid pack version');
|
|
335
|
+
const nextSeparator = next.indexOf('-');
|
|
336
|
+
const previousSeparator = previous.indexOf('-');
|
|
337
|
+
const nextCore = nextSeparator < 0 ? next : next.slice(0, nextSeparator);
|
|
338
|
+
const previousCore = previousSeparator < 0 ? previous : previous.slice(0, previousSeparator);
|
|
339
|
+
const nextPre = nextSeparator < 0 ? undefined : next.slice(nextSeparator + 1);
|
|
340
|
+
const previousPre = previousSeparator < 0 ? undefined : previous.slice(previousSeparator + 1);
|
|
341
|
+
const left = nextCore.split('.').map(BigInt);
|
|
342
|
+
const right = previousCore.split('.').map(BigInt);
|
|
343
|
+
for (let i = 0; i < 3; i++) {
|
|
344
|
+
if (left[i] !== right[i]) return left[i]! > right[i]! ? 1 : -1;
|
|
345
|
+
}
|
|
346
|
+
if (nextPre === previousPre) return 0;
|
|
347
|
+
if (!nextPre) return 1;
|
|
348
|
+
if (!previousPre) return -1;
|
|
349
|
+
const nextIdentifiers = nextPre.split('.');
|
|
350
|
+
const previousIdentifiers = previousPre.split('.');
|
|
351
|
+
for (let i = 0; i < Math.min(nextIdentifiers.length, previousIdentifiers.length); i++) {
|
|
352
|
+
const nextIdentifier = nextIdentifiers[i]!;
|
|
353
|
+
const previousIdentifier = previousIdentifiers[i]!;
|
|
354
|
+
if (nextIdentifier === previousIdentifier) continue;
|
|
355
|
+
const nextNumeric = /^\d+$/.test(nextIdentifier);
|
|
356
|
+
const previousNumeric = /^\d+$/.test(previousIdentifier);
|
|
357
|
+
if (nextNumeric && previousNumeric) {
|
|
358
|
+
return BigInt(nextIdentifier) > BigInt(previousIdentifier) ? 1 : -1;
|
|
359
|
+
}
|
|
360
|
+
if (nextNumeric) return -1;
|
|
361
|
+
if (previousNumeric) return 1;
|
|
362
|
+
return nextIdentifier > previousIdentifier ? 1 : -1;
|
|
363
|
+
}
|
|
364
|
+
return Math.sign(nextIdentifiers.length - previousIdentifiers.length);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Atomically switch one installed version after the replacement has passed validation. */
|
|
368
|
+
export function upgradeKnowledgePack(previous: PackId, directory: string, store: KnowledgePackStore = kgsStoreSingleton(), proof?: KnowledgePackMarketProof): string {
|
|
369
|
+
if (!isPackSlug(previous.slug) || !isPackVersion(previous.version)) throw new Error('KPACK1: invalid previous pack id');
|
|
370
|
+
const { manifest, pack } = proof ? verifiedMarketPack(directory, proof) : validateKnowledgePack(directory);
|
|
371
|
+
if (manifest.name !== previous.slug || comparePackVersions(manifest.version, previous.version) <= 0) throw new Error('KPACK1: upgrade requires a newer version of the same pack');
|
|
372
|
+
store.replacePack(previous, pack);
|
|
373
|
+
return packIdString(pack.metadata.id);
|
|
374
|
+
}
|
|
375
|
+
|
|
144
376
|
/** Test helper — size of the KIND_SCHEMAS dict for assertion. */
|
|
145
377
|
export function _kindSchemaCountForTest(): number {
|
|
146
378
|
return Object.keys(KIND_SCHEMAS).length;
|