elanous 0.2.6 → 0.2.8
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/.env.example +10 -7
- package/README.md +4 -0
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3995-bee512a7063036ce.js → 2375-cb6debea56cce4fb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +25 -0
- package/apps/pwa/out/_next/static/chunks/{8d0d9faf-97887ff99713b84e.js → 2ea96958-e8c7e112de50b067.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5329.8b7e4bca684b6eec.js → 3403.4bc97b4066945a94.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7633.0654fe6ea259c1ee.js → 4323.c5dfb6f503304775.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4836-3084c58c1725a40b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2984-977cfa339fcd65a5.js → 5080-1613752891fcadb4.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{763-7d0e1913b5074e98.js → 5791-bb82743fa6299562.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4240-7153881b0b377306.js → 6062-73e68343a9814f6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{91ff6dda-3b33d42d20657429.js → 8046cadf-211ca3c0e00f2b72.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8894-7317998f6cb97d8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9454-a3e0953307216c58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-9aa47b0bc6d570ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f4d2ecbbae6088d6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-2053e49930c82748.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-d4b6df905f185055.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a70ba27c33003dd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-186fc6952f027acc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-18166f885d831d3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1c9d6cfe68b121c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-cbbe03c0da7b081a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c108ff1fdb665c97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-147a328753d983e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-799395a9df7d95aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-6a8158b71d1fe9d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9567560270857531.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e7ed3d010153d818.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-c0c0d19d51342d3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2e002ad8faa43291.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b672e02e4bec8deb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-1ba4a5d857276334.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-9db2226f38c542fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-70ee65f5f7a151dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-0bb8e43203efb23b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-092e1bcf27d751cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-eb52580c4b75b905.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7464c1987dd76e6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-e573437b0a1c728f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-294300625e49e4d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-085847b088675978.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-9fe9d38c36999eb4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-d8ab4d1489223459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6141f67f531d8b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-295a02b1026b8255.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1eb9a0e1e054209d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-82efa177a30f3741.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d0be51cec4f62606.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-2e367075ffdbc062.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-647ed2b66c1d49f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ba058c56e38f2792.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{webpack-37b8bf78a3c6eec5.js → webpack-e5bea36f183b25e6.js} +1 -1
- package/apps/pwa/out/_next/static/css/5ef72a618a8994f3.css +1 -0
- package/apps/pwa/out/_next/static/lywc8m_HDzH9MKSDQhyEj/_buildManifest.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -0
- package/apps/pwa/out/consult/index.txt +32 -0
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -0
- package/apps/pwa/out/exec/index.txt +32 -0
- package/apps/pwa/out/field/index.html +1 -0
- package/apps/pwa/out/field/index.txt +32 -0
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.cjs +107 -0
- package/graphs/field/field-feed.yaml +24 -0
- package/graphs/field/recipes.yaml +12 -0
- package/graphs/landing/landing-heal.yaml +3 -1
- package/graphs/landing/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +10 -0
- package/graphs/release/release-loop.yaml +10 -3
- package/graphs/test-diet/recipes.yaml +9 -0
- package/graphs/test-diet/test-diet.yaml +22 -0
- package/package.json +6 -5
- package/persona-presets/_index.yaml +10 -0
- package/persona-presets/_schema.json +146 -0
- package/persona-presets/dana.yaml +26 -0
- package/persona-presets/haru.yaml +27 -0
- package/persona-presets/kai.yaml +27 -0
- package/persona-presets/leo.yaml +27 -0
- package/persona-presets/mira.yaml +30 -0
- package/persona-presets/nari.yaml +27 -0
- package/persona-presets/sora.yaml +27 -0
- package/persona-presets/yuna.yaml +27 -0
- package/plugins/card-followup/README.md +13 -4
- package/plugins/card-followup/graphs/card-followup.yaml +3 -1
- package/plugins/card-followup/graphs/recipes.yaml +5 -1
- package/plugins/card-followup/graphs/run-step.ts +122 -18
- package/plugins/card-followup/graphs/sales-strategy.ts +173 -0
- package/plugins/card-followup/plugin.json +1 -1
- package/plugins/doc-draft/README.md +13 -0
- package/plugins/doc-draft/examples/brief-sample.json +8 -0
- package/plugins/doc-draft/graphs/doc-draft.yaml +14 -0
- package/plugins/doc-draft/graphs/recipes.yaml +9 -0
- package/plugins/doc-draft/graphs/run-step.ts +113 -0
- package/plugins/doc-draft/plugin.json +24 -0
- package/plugins/geo-check/README.md +3 -1
- package/plugins/geo-check/graphs/run-step.ts +58 -13
- package/plugins/geo-check/plugin.json +1 -1
- package/plugins/job-coach/.codex-plugin/plugin.json +1 -1
- package/plugins/job-coach/README.md +1 -1
- package/plugins/job-coach/graphs/run-step.ts +2 -2
- package/plugins/job-coach/plugin.json +1 -1
- package/plugins/job-coach/plugin.ts +1 -1
- package/scripts/affinity/endcard.sh +3 -2
- package/scripts/affinity/reframe.sh +3 -1
- package/scripts/ci-public-export-leak-gate.ts +48 -0
- package/scripts/codex-quota-alert.ts +122 -258
- package/scripts/coord-tracks.json +4 -4
- package/scripts/field-feed/deliver-node.ts +57 -0
- package/scripts/field-feed/feed-node.ts +67 -0
- package/scripts/field-feed/lib.ts +164 -0
- package/scripts/field-feed/reel-node.ts +24 -0
- package/scripts/field-feed/start.ts +62 -0
- package/scripts/fixtures/vflow-sample.ndjson +6 -0
- package/scripts/install.sh +109 -21
- package/scripts/landing-heal/clean-checkout.ts +114 -0
- package/scripts/landing-heal/run-mission.ts +38 -3
- package/scripts/lib/pwa-scenarios/scenarios.ts +2 -1
- package/scripts/persona-presets/lint.ts +79 -0
- package/scripts/public-export.ts +8 -4
- package/scripts/release-loop/baseline-from-logs.ts +92 -0
- package/scripts/release-loop/checklist-gate-node.ts +2 -2
- package/scripts/release-loop/env-known-failures.ts +31 -0
- package/scripts/release-loop/gate-node.ts +108 -22
- package/scripts/release-loop/known-issues-node.ts +159 -0
- package/scripts/release-loop/npm-publish-node.ts +124 -0
- package/scripts/release-loop/ops-upgrade-node.ts +95 -0
- package/scripts/release-loop/publish-node.ts +23 -1
- package/scripts/release-loop/release-readiness.ts +58 -0
- package/scripts/release-loop/shard-plan.ts +17 -0
- package/scripts/release-loop/unattended-release.ts +93 -0
- package/scripts/storyboard/storyboard.ts +167 -0
- package/scripts/test-diet/lib.ts +88 -0
- package/scripts/test-diet/node.ts +102 -0
- package/scripts/ux/measure-first-text.ts +102 -0
- package/scripts/vflow-collect.ts +20 -7
- package/scripts/vflow-search.ts +73 -0
- package/scripts/video-free-line-test-walker.ts +36 -0
- package/scripts/video-pipeline.ts +2 -2
- package/skills/explainer-video/SKILL.md +12 -9
- package/skills/explainer-video/engine/build.mjs +1 -1
- package/skills/explainer-video/engine/reel.mjs +138 -31
- package/skills/explainer-video/engine/reel.sh +2 -1
- package/skills/explainer-video/examples/elanous-0.2.5/script.json +1 -1
- package/skills/grill-me/SKILL.md +1 -1
- package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +1 -1
- package/src/a2a/server.ts +2 -0
- package/src/acp/auth-methods.ts +30 -0
- package/src/acp/elanous-aware-peers.ts +30 -0
- package/src/acp/server.ts +96 -20
- package/src/agent/monad-agent-turn.ts +25 -6
- package/src/agent/shared-app-tools.ts +5 -3
- package/src/agent-substrate/review-intent.ts +6 -2
- package/src/agent-substrate/shard-boundary-intent.ts +70 -0
- package/src/auth/github-app-token.ts +4 -1
- package/src/autopilot/track-agent-shadow.ts +151 -0
- package/src/autopilot/track-agent.ts +23 -3
- package/src/boot/acp-server-help.ts +16 -0
- package/src/boot/daemon-prompt-turn.ts +31 -10
- package/src/boot/daemon-tools/index.ts +7 -1
- package/src/budget/codex-credit-pace.ts +84 -0
- package/src/budget/codex-credit-plan.ts +154 -0
- package/src/budget/codex-reset-credit-state.ts +2 -0
- package/src/channel-import/detect.ts +191 -0
- package/src/channel-import/run.ts +111 -0
- package/src/chat/chat-cli.ts +4 -1
- package/src/chat/short-question.ts +40 -0
- package/src/cli/agent-cli.ts +24 -15
- package/src/cli/ask-bare.ts +42 -0
- package/src/cli/cli-user-error.ts +25 -0
- package/src/cli/codex-credit-plan-view.ts +25 -0
- package/src/cli/config-test-sync.ts +4 -0
- package/src/cli/decisions-cli.ts +13 -3
- package/src/cli/dependence-gauge.ts +237 -0
- package/src/cli/doctor-bundle.ts +128 -0
- package/src/cli/doctor-cli.ts +41 -1
- package/src/cli/doctor-local-llm.ts +95 -0
- package/src/cli/doctor-modes.ts +48 -0
- package/src/cli/import-cli.ts +60 -0
- package/src/cli/intake-cli.ts +12 -2
- package/src/cli/intake-source-cli.ts +58 -0
- package/src/cli/machine-cli.ts +23 -0
- package/src/cli/mcp-login.ts +13 -4
- package/src/cli/msg-cli.ts +137 -0
- package/src/cli/persona-cli.ts +116 -0
- package/src/cli/plugin-cli.ts +25 -0
- package/src/cli/pr-cli.ts +36 -0
- package/src/cli/provider-cli.ts +5 -0
- package/src/cli/release-cli.ts +50 -8
- package/src/cli/release-run-if-ready.ts +48 -0
- package/src/cli/setup-cli.ts +27 -6
- package/src/cli/setup-recommend.ts +8 -0
- package/src/cli/skills-cli.ts +173 -0
- package/src/cli/start-cli.ts +13 -4
- package/src/cli/usage-cli.ts +11 -1
- package/src/codex/setup.ts +37 -16
- package/src/dashboard/index.ts +18 -2
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +2 -2
- package/src/dashboard/slash-runtime/help-from-registry.ts +4 -2
- package/src/decisions/decision-cards.ts +291 -0
- package/src/decisions/decision-ledger.ts +5 -2
- package/src/decisions/discord-decision-cards.ts +133 -0
- package/src/decisions/telegram-decision-cards.ts +100 -0
- package/src/directives/version-at.ts +77 -0
- package/src/discord.ts +73 -6
- package/src/domains/core-tools.ts +37 -14
- package/src/domains/outbound-alert.ts +94 -12
- package/src/domains/repeated-failure.ts +1 -1
- package/src/error-report/report.ts +200 -0
- package/src/exec-requests/planner.ts +146 -0
- package/src/exec-requests/runner.ts +378 -0
- package/src/exec-requests/store.ts +78 -0
- package/src/field/field-feed-auto.ts +48 -0
- package/src/field/field-media.ts +8 -3
- package/src/field/field-reel.ts +203 -0
- package/src/grok/credential.ts +7 -5
- package/src/harness/aside-run-status.ts +33 -0
- package/src/harness/browser-verify.ts +48 -17
- package/src/harness/harness-cli-command.ts +25 -3
- package/src/harness/image-load-state.ts +21 -0
- package/src/harness/process-garbage.ts +45 -0
- package/src/hooks/error-report.ts +210 -0
- package/src/hooks/receiver.ts +41 -1
- package/src/import/apply.ts +128 -0
- package/src/import/plan.ts +197 -0
- package/src/index.ts +168 -21
- package/src/input-core/text-entry.ts +13 -5
- package/src/instance/leader.ts +13 -1
- package/src/intake-plane/collect-github.ts +5 -3
- package/src/intake-plane/collect-telegram-saved.ts +15 -3
- package/src/intake-plane/discord-seat-work.ts +56 -0
- package/src/intake-plane/intake-sources.ts +202 -0
- package/src/intake-plane/items.ts +28 -12
- package/src/intake-plane/seat-answer.ts +96 -0
- package/src/intake-plane/seat-doc-route.ts +221 -0
- package/src/intake-plane/submit-intake-work.ts +9 -1
- package/src/intake-plane/telegram-seat-work.ts +72 -0
- package/src/llm/model-defaults.ts +24 -1
- package/src/llm.ts +5 -4
- package/src/machines/machine-ledger.ts +127 -0
- package/src/market/pack-internal-refs.ts +28 -0
- package/src/market/publish.ts +31 -4
- package/src/maturity/feature-maturity.ts +65 -0
- package/src/model-tier/turn-tier.ts +24 -0
- package/src/msg/msg-store.ts +149 -0
- package/src/native-tool-catalog.ts +2 -1
- package/src/nexus/api/chat-fast-path-config.ts +28 -0
- package/src/nexus/api/consult-requests.ts +128 -0
- package/src/nexus/api/discord-trigger-bot.ts +3 -0
- package/src/nexus/api/error-reports.ts +108 -0
- package/src/nexus/api/exec-requests.ts +51 -0
- package/src/nexus/api/field-uploads.ts +40 -3
- package/src/nexus/api/graph-approvals-feed.ts +140 -0
- package/src/nexus/api/graph-approvals.ts +71 -4
- package/src/nexus/api/http-server.ts +82 -8
- package/src/nexus/api/outbound-report.ts +7 -0
- package/src/nexus/api/running-runs-background.ts +68 -0
- package/src/nexus/api/running-runs-child.ts +6 -0
- package/src/nexus/api/seat-requests.ts +254 -0
- package/src/nexus/api/share-captures.ts +91 -0
- package/src/nexus/api/skill-problems.ts +56 -0
- package/src/nexus/api/terminals.ts +24 -8
- package/src/nexus/api/trace-run-scan.ts +37 -0
- package/src/nexus/api/trace.ts +19 -3
- package/src/nexus/index.ts +28 -1
- package/src/nexus/setup-status.ts +11 -7
- package/src/notify/llm-budget-alert.ts +16 -10
- package/src/oauth/browser-availability.ts +14 -0
- package/src/oauth/codex-account-rotation.ts +26 -4
- package/src/oauth/codex-account-store.ts +20 -2
- package/src/oauth/codex-browser-login.ts +173 -0
- package/src/oauth/codex-quota-policy.ts +16 -0
- package/src/oauth/codex.ts +4 -1
- package/src/oauth/fallback-chain.ts +5 -5
- package/src/oauth/store.ts +42 -5
- package/src/onboarding/continue-here.ts +34 -0
- package/src/onboarding/entry-hints.ts +8 -0
- package/src/onboarding/full-screen-io.ts +35 -3
- package/src/onboarding/help/skills.md +1 -1
- package/src/onboarding/non-interactive.ts +1 -0
- package/src/onboarding/subscription-hint.ts +27 -0
- package/src/onboarding/web-first.ts +90 -0
- package/src/onboarding.ts +287 -26
- package/src/persona/presets.ts +105 -0
- package/src/plugins/maker/node-install.ts +92 -0
- package/src/plugins/maker/node-maker.ts +139 -0
- package/src/plugins/maker/plugin-maker.ts +19 -7
- package/src/policy/llm-policy.ts +268 -0
- package/src/prompt-library/session-guidance.ts +7 -1
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/relay/relay-cli.ts +20 -0
- package/src/relay/relay-server.ts +220 -0
- package/src/release-loop/checklist.ts +37 -13
- package/src/self-dev/decompose.ts +1 -0
- package/src/self-dev/dev-pipeline.ts +6 -3
- package/src/self-dev/orchestrate.ts +18 -11
- package/src/self-dev/run-record-mirror.ts +44 -0
- package/src/self-dev/run-store.ts +12 -3
- package/src/self-implement/harness-policy-gates.ts +4 -1
- package/src/self-implement/report-origin.ts +12 -1
- package/src/session/chat.ts +17 -5
- package/src/shell-env-bootstrap.ts +44 -7
- package/src/skills/connect-claude-plugin.ts +142 -0
- package/src/skills/connect.ts +70 -0
- package/src/skills/index.ts +29 -1
- package/src/skills/repair.ts +124 -0
- package/src/skills/runner.ts +11 -2
- package/src/skills/shared-agent-skill-roots.ts +25 -0
- package/src/skills/trigger-extract.ts +1 -1
- package/src/steward/failure-streak.ts +78 -0
- package/src/steward/steward-cards.ts +24 -0
- package/src/steward/triage-budget.ts +127 -0
- package/src/steward/triage-plan.ts +75 -0
- package/src/steward/triage.ts +244 -42
- package/src/task-cards/card-store.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +16 -8
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +11 -5
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +68 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +78 -4
- package/src/telegram-commands.ts +13 -0
- package/src/telegram.ts +72 -2
- package/src/tool-runtime/elanous-skills-list-runtime.ts +3 -3
- package/src/tool-runtime/self-cognition-runtimes.ts +160 -2
- package/src/user-config.ts +189 -15
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/character.ts +42 -5
- package/src/video-pipeline/recipes/ffmpeg.ts +1 -1
- package/src/video-pipeline/recipes/free-line.ts +16 -3
- package/src/video-pipeline/recipes/remote.ts +7 -1
- package/src/video-pipeline/vflow-reference.ts +109 -0
- package/apps/pwa/out/_next/static/chunks/1169-696263ac7af8c4d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1883.c91a2648af4842fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1947-9d64872eeb9cfdec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2808-dc06482994b40f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3165-95515ca5f299a120.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3190-e9282753e7ebde85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4259-99614149577e77cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4283-329eabeaf233e6cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4328-cb5058b1acc2de5e.js +0 -25
- package/apps/pwa/out/_next/static/chunks/4801-ecee6ef62b349b18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5110-8058791dd25a2e14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5330-c41e9670f594c38f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5423-e95fd125d1794349.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5478-b5eae07dc79ea619.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5787-96ee6642b9a661e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6448-79d72368589f98bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6522-9866c002b5531836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6729-b4a558b7aa891e0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6969-cb03f9410b7d2e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7007-3b9861091bb8dd21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7930-8dc7e20fc6fc19ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8071-187edbc22a86741f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8198-d4101ad70cb9a579.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8250.4a2c5553a07cdf47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8293-123b91e7b0330dc0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8296-d6d5d87dfa911d41.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8305-603963c33ee8eec3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8612-4a0066f20951b8fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9181-cf4e1b61c4783f92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9262-26c2ecbd5a67e4a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9328-45abdebce4fbecb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9355-dbc67205adf8745f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9763.255b90dd69875689.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9933-66d31ec25c0231af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-bd06fb55f4da0381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4e586142da455a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-889ad5cddcf45b0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-47ba401d56572c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-0b54f9c83458e038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-4fcc296ef6c8ed90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fe9fda494a87f4e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-f9642e25ce129590.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e1063e8ba5f3e2e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-9d0df30027d8aa9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-bd06fb55f4da0381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-d97adf2c9455b8d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-236b80d202110362.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-21a30f35f1a276ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-b1a5be357c4fa25d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1705a60303f7f573.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-76b337c11ad0e237.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-7c0f85fbb56f64c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-65ca16b20617b44d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-e7f9b8fc29411c1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-92ea6213d1aeec04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-a913a005aacb5476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2d78804a40dfdef6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-08a99148e780ac00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-deb674e7ed36f815.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-49f8de0534d192d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-bd06fb55f4da0381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-ba162a28d2176e18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-1ff1a37b550ab41a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-ccaa698f56c0fbdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-53b944082de1d7db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9b70adf1552789bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-30d482aa63241fe8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aecf786f54651d8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6ab9b62c7b6e08f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-08949735455e0c9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-a1479005234a46c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3890e90bd232732.js +0 -1
- package/apps/pwa/out/_next/static/chunks/beb5cf10-9adcc10b83930090.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-d68d41c88e05c801.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-11c63971b7a9593b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-d09452353bd0d9cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-184d727cebeca767.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-21bbbbac99b720b1.js +0 -1
- package/apps/pwa/out/_next/static/css/eaa74e8bb2f62269.css +0 -1
- package/apps/pwa/out/_next/static/qMI0jnlZaBjjm4aIDYNGM/_buildManifest.js +0 -1
- /package/apps/pwa/out/_next/static/{qMI0jnlZaBjjm4aIDYNGM → lywc8m_HDzH9MKSDQhyEj}/_ssgManifest.js +0 -0
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
// Field reel — a folder of phone photos / short clips → one vertical
|
|
2
|
-
// Usage: node reel.mjs <folder> [--title "마케터의 밤"] [--sub "2026.10.02 · 서울"] [--max 60] [--min
|
|
1
|
+
// Field reel — a folder of phone photos / short clips → one vertical HyperFrames composition (EV10 · EV10b).
|
|
2
|
+
// Usage: node reel.mjs <folder> [--title "마케터의 밤"] [--sub "2026.10.02 · 서울"] [--max 60] [--min 24] [--part full|body]
|
|
3
3
|
// <folder>/captions.txt (optional): one line per item — `파일명 | 자막` (a line without « | » is ignored).
|
|
4
|
+
// Photos without a caption get one line from a vision model (codex · parallel · FIELD_REEL_VISION=0 turns it off);
|
|
5
|
+
// if that fails the caption is «현장 N». A slug-like title (`field-2026-10-01`) is replaced by a vision headline.
|
|
6
|
+
// BGM: FIELD_REEL_BGM=<wav/mp3> or ~/.cache/elanous-explainer/bgm/field.wav — cut to length, faded and leveled here.
|
|
7
|
+
// --part body: photos only, no intro/end cards and no music (the instant version stitches cached cards around it).
|
|
4
8
|
// Output: <folder>/reel/hf/ (HyperFrames project) ⊕ reel/timeline.json. Render: npx hyperframes render --fps 30 in reel/hf.
|
|
5
9
|
// Look = Elanvital CI: Real Black ground · Icarus Red single accent · V6 mark · Pretendard. Order = capture time (then name).
|
|
6
10
|
import { readFileSync, writeFileSync, mkdirSync, copyFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
7
11
|
import { join, dirname, resolve, extname, basename } from "node:path";
|
|
8
12
|
import { homedir } from "node:os";
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
10
14
|
import { fileURLToPath } from "node:url";
|
|
11
15
|
|
|
12
16
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
17
|
const argv = process.argv.slice(2);
|
|
14
18
|
const opt = (k, d) => { const i = argv.indexOf(`--${k}`); return i >= 0 ? argv[i + 1] : d; };
|
|
15
19
|
const folder = resolve(argv.find((a, i) => !a.startsWith("--") && !(i > 0 && argv[i - 1].startsWith("--"))) ?? ".");
|
|
16
|
-
const
|
|
17
|
-
const
|
|
20
|
+
const PART = opt("part", "full");
|
|
21
|
+
const MAX = Number(opt("max", 60)), MIN = Number(opt("min", 24));
|
|
22
|
+
const W = 1080, H = 1920, PHOTO = 4.2, CLIP_MAX = 5, XF = 0.5;
|
|
23
|
+
const INTRO = PART === "body" ? 0 : 3.0, END = PART === "body" ? 0 : 3.4;
|
|
18
24
|
const out = join(folder, "reel"), hf = join(out, "hf"), media = join(hf, "assets", "media");
|
|
19
25
|
mkdirSync(media, { recursive: true }); mkdirSync(join(hf, "assets", "fonts"), { recursive: true });
|
|
26
|
+
const T0 = Date.now(), lap = (s) => console.log(`reel: ${s} · ${((Date.now() - T0) / 1000).toFixed(1)}s`);
|
|
20
27
|
|
|
21
28
|
// ── collect & order ────────────────────────────────────────────────────────────
|
|
22
29
|
const IMG = [".jpg", ".jpeg", ".png", ".heic", ".webp"], VID = [".mp4", ".mov", ".m4v"];
|
|
@@ -41,9 +48,9 @@ if (!items.length) throw new Error(`no photos or clips in ${folder}`);
|
|
|
41
48
|
for (const it of items) it.dur = it.video ? Math.min(CLIP_MAX, Math.max(1.5, probeDur(it.p))) : PHOTO;
|
|
42
49
|
const body = () => items.reduce((a, it) => a + it.dur, 0);
|
|
43
50
|
while (INTRO + body() + END > MAX && items.length > 1) items.splice(Math.floor(items.length / 2), 1); // drop from the middle, keep first & last
|
|
44
|
-
if (INTRO + body() + END < MIN) { const photos = items.filter((i) => !i.video); const need = MIN - (INTRO + body() + END); for (const p of photos) p.dur += need / Math.max(1, photos.length); }
|
|
51
|
+
if (PART !== "body" && INTRO + body() + END < MIN) { const photos = items.filter((i) => !i.video); const need = MIN - (INTRO + body() + END); for (const p of photos) p.dur += need / Math.max(1, photos.length); }
|
|
45
52
|
|
|
46
|
-
// ── media prep: HEIC → jpg · big photos down to 2160 · clips re-encoded short & muted ──
|
|
53
|
+
// ── media prep: HEIC → jpg · big photos down to 2160 · a small copy for the vision model · clips re-encoded short & muted ──
|
|
47
54
|
let t = INTRO;
|
|
48
55
|
items.forEach((it, i) => {
|
|
49
56
|
it.start = +t.toFixed(3); t += it.dur;
|
|
@@ -55,10 +62,49 @@ items.forEach((it, i) => {
|
|
|
55
62
|
it.src = `m${i}.jpg`;
|
|
56
63
|
const r = run("sips", ["-s", "format", "jpeg", "-Z", "2160", it.p, "--out", join(media, it.src)]);
|
|
57
64
|
if (r.status !== 0) throw new Error(`photo ${it.f}: ${r.stderr.slice(0, 200)}`);
|
|
65
|
+
const dim = run("sips", ["-g", "pixelWidth", "-g", "pixelHeight", join(media, it.src)]).stdout;
|
|
66
|
+
const pw = Number(/pixelWidth: (\d+)/.exec(dim)?.[1]), ph = Number(/pixelHeight: (\d+)/.exec(dim)?.[1]);
|
|
67
|
+
it.wide = pw > 0 && ph > 0 && pw / ph > 0.75; // anything wider than 3:4 is shown whole over a blurred fill
|
|
68
|
+
run("sips", ["-s", "format", "jpeg", "-Z", "1024", it.p, "--out", join(out, `v${i}.jpg`)]);
|
|
58
69
|
}
|
|
59
|
-
it.cap = caps[it.f] ?? "";
|
|
60
70
|
});
|
|
61
71
|
const TOTAL = +(t + END).toFixed(3);
|
|
72
|
+
lap(`${items.length} items prepared`);
|
|
73
|
+
|
|
74
|
+
// ── vision: one caption line per photo, in parallel; a headline when the title is only a slug ──
|
|
75
|
+
const CODEX = process.env.FIELD_REEL_CODEX_BIN || "codex";
|
|
76
|
+
const VISION = process.env.FIELD_REEL_VISION !== "0";
|
|
77
|
+
const ask = (prompt, images, ms = 30000) => new Promise((done) => {
|
|
78
|
+
const args = ["exec", "--skip-git-repo-check", "-c", "model_reasoning_effort=low", prompt, ...images.flatMap((im) => ["-i", im])];
|
|
79
|
+
let buf = "", settled = false;
|
|
80
|
+
const finish = (v) => { if (!settled) { settled = true; done(v); } };
|
|
81
|
+
let child;
|
|
82
|
+
try { child = spawn(CODEX, args, { stdio: ["ignore", "pipe", "ignore"] }); } catch { return finish(""); }
|
|
83
|
+
const timer = setTimeout(() => { child.kill("SIGKILL"); finish(""); }, ms);
|
|
84
|
+
child.stdout.on("data", (d) => { buf += d; });
|
|
85
|
+
child.on("error", () => { clearTimeout(timer); finish(""); });
|
|
86
|
+
child.on("close", (code) => { clearTimeout(timer); finish(code === 0 ? buf : ""); });
|
|
87
|
+
});
|
|
88
|
+
const oneLine = (s, max) => {
|
|
89
|
+
const line = s.split("\n").map((l) => l.trim().replace(/^["'«“]|["'»”]$/g, "")).filter(Boolean).pop() ?? "";
|
|
90
|
+
return line.length >= 2 && line.length <= max ? line.replace(/[.。]$/, "") : "";
|
|
91
|
+
};
|
|
92
|
+
const CAP_PROMPT = "행사 현장 사진이다. 세로 영상 자막으로 쓸 한국어 한 줄을 출력하라 — 18자 이내 · 마침표 없이 · 보이는 장면만 · 사람 이름·외모 묘사·추측 금지 · 화면 속 글자(행사명·회사명)는 읽히면 써도 된다. 그 한 줄만.";
|
|
93
|
+
const HEAD_PROMPT = "같은 행사에서 찍은 사진들이다. 영상 첫 화면 제목으로 쓸 한국어 행사 이름 한 줄을 출력하라 — 16자 이내 · 화면 속 글자에서 읽히는 행사·회사 이름을 우선 · 읽히지 않으면 장면을 짧게(예: «상장 기념식 현장») · 추측 금지. 그 한 줄만.";
|
|
94
|
+
const slugTitle = (s) => !s || /^[a-z0-9]+(?:-[a-z0-9]+)*$/i.test(s);
|
|
95
|
+
let TITLE = opt("title", ""), SUB = opt("sub", "");
|
|
96
|
+
const photos = items.filter((it) => !it.video);
|
|
97
|
+
const VT0 = Date.now();
|
|
98
|
+
const jobs = VISION ? [
|
|
99
|
+
...photos.filter((it) => !caps[it.f]).map(async (it) => { it.vcap = oneLine(await ask(CAP_PROMPT, [join(out, `v${items.indexOf(it)}.jpg`)]), 22); }),
|
|
100
|
+
...(PART !== "body" && slugTitle(TITLE) && photos.length ? [(async () => { TITLE = oneLine(await ask(HEAD_PROMPT, photos.slice(0, 3).map((it) => join(out, `v${items.indexOf(it)}.jpg`))), 20) || TITLE; })()] : []),
|
|
101
|
+
] : [];
|
|
102
|
+
await Promise.all(jobs);
|
|
103
|
+
const visionMs = Date.now() - VT0;
|
|
104
|
+
items.forEach((it, i) => { it.cap = caps[it.f] || it.vcap || (it.video ? "" : `현장 ${i + 1}`); });
|
|
105
|
+
if (slugTitle(TITLE)) TITLE = "현장 스케치";
|
|
106
|
+
if (!SUB) { const d = new Date(items[0].t + 9 * 3600e3); SUB = `${d.getUTCFullYear()}.${String(d.getUTCMonth() + 1).padStart(2, "0")}.${String(d.getUTCDate()).padStart(2, "0")}`; }
|
|
107
|
+
lap(`vision ${jobs.length ? `${items.filter((i) => i.vcap).length}/${photos.filter((p) => !caps[p.f]).length} captions` : "off"} · title «${TITLE}»`);
|
|
62
108
|
|
|
63
109
|
// ── assets (same cache as build.mjs) ───────────────────────────────────────────
|
|
64
110
|
const CACHE = process.env.EXPLAINER_CACHE ?? join(homedir(), ".cache", "elanous-explainer");
|
|
@@ -69,54 +115,114 @@ for (const [rel, url] of Object.entries(ASSETS)) {
|
|
|
69
115
|
if (!existsSync(c)) { const res = await fetch(url); if (!res.ok) throw new Error(`asset ${rel}: HTTP ${res.status}`); mkdirSync(dirname(c), { recursive: true }); writeFileSync(c, Buffer.from(await res.arrayBuffer())); }
|
|
70
116
|
copyFileSync(c, join(hf, "assets", rel));
|
|
71
117
|
}
|
|
118
|
+
|
|
119
|
+
// ── music: cut to length · fade in/out · level to about -16 LUFS (the whole mix is music) ──
|
|
120
|
+
const BGM = process.env.FIELD_REEL_BGM || join(CACHE, "bgm", "field.wav");
|
|
121
|
+
let music = "";
|
|
122
|
+
if (PART !== "body" && existsSync(BGM)) {
|
|
123
|
+
const r = run("ffmpeg", ["-v", "error", "-y", "-i", BGM, "-t", String(TOTAL), "-af", `afade=t=in:d=0.4,afade=t=out:st=${f(TOTAL - 1.6)}:d=1.6,loudnorm=I=-16:TP=-1.5:LRA=9`, "-ar", "48000", "-ac", "2", join(media, "bgm.wav")]);
|
|
124
|
+
if (r.status === 0) music = "bgm.wav"; else console.error(`reel: music skipped — ${r.stderr.slice(0, 160)}`);
|
|
125
|
+
}
|
|
126
|
+
function f(x) { return +x.toFixed(3); }
|
|
127
|
+
|
|
72
128
|
const markPaths = [...readFileSync(join(here, "brand", "elanous-mark-on-dark.svg"), "utf8").matchAll(/<path d="([^"]*)"/g)].map((m) => m[1]);
|
|
73
129
|
const mark = (s, cls = "") => `<svg class="${cls}" width="${s}" height="${s}" viewBox="150 150 724 724">${markPaths.map((d) => `<path d="${d}" fill="#F2F1EE"/>`).join("")}<circle cx="512" cy="512" r="76" fill="#E95047"/></svg>`;
|
|
74
130
|
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<");
|
|
75
|
-
const
|
|
131
|
+
const words = (s, cls) => s.split(/\s+/).filter(Boolean).map((w) => `<span class="${cls}">${esc(w)}</span>`).join(" ");
|
|
76
132
|
|
|
77
133
|
// ── composition ────────────────────────────────────────────────────────────────
|
|
134
|
+
// Each photo: blurred fill + the whole photo (wide) or a full-bleed crop (tall) · slow push · a cross-move into the next ·
|
|
135
|
+
// a red wipe on the cut · counter «0N / 0M» · caption words rising one by one.
|
|
78
136
|
const tw = [];
|
|
137
|
+
const n = items.length;
|
|
79
138
|
const clips = items.map((it, i) => {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
if (it.
|
|
139
|
+
const s = it.start, d = it.dur, last = i === n - 1;
|
|
140
|
+
const span = last ? d : d + XF; // overlap the next item so the move reads as one motion
|
|
141
|
+
let vis;
|
|
142
|
+
if (it.video) {
|
|
143
|
+
vis = `<video id="v${i}" class="clip med" src="assets/media/${it.src}" muted playsinline data-start="${f(s)}" data-duration="${f(d)}" data-track-index="1"></video>`;
|
|
144
|
+
} else if (it.wide) {
|
|
145
|
+
vis = `<div class="clip med" data-start="${f(s)}" data-duration="${f(span)}" data-track-index="${1 + (i % 2)}"><div class="g g${i}">`
|
|
146
|
+
+ `<img class="fill" src="assets/media/${it.src}"/><div class="dim"></div>`
|
|
147
|
+
+ `<div class="frame fr${i}"><img src="assets/media/${it.src}"/></div></div></div>`;
|
|
148
|
+
tw.push(`tl.fromTo(".fr${i}", {scale:1.0, x:${i % 2 ? 30 : -30}}, {scale:1.12, x:${i % 2 ? -30 : 30}, duration:${f(span)}, ease:"none"}, ${f(s)});`);
|
|
149
|
+
tw.push(`tl.fromTo(".g${i} .fill", {scale:1.25}, {scale:1.4, duration:${f(span)}, ease:"none"}, ${f(s)});`);
|
|
150
|
+
} else {
|
|
151
|
+
vis = `<div class="clip med" data-start="${f(s)}" data-duration="${f(span)}" data-track-index="${1 + (i % 2)}"><div class="g g${i}"><img class="kb k${i}" src="assets/media/${it.src}"/></div></div>`;
|
|
152
|
+
tw.push(`tl.fromTo(".k${i}", {scale:1.02, x:0}, {scale:1.12, x:${i % 2 ? -28 : 28}, duration:${f(span)}, ease:"none"}, ${f(s)});`);
|
|
153
|
+
}
|
|
154
|
+
if (!it.video && i > 0) tw.push(`tl.fromTo(".g${i}", {opacity:0, xPercent:${i % 2 ? 14 : -14}}, {opacity:1, xPercent:0, duration:${XF}, ease:"power3.out"}, ${f(s - XF)});`);
|
|
155
|
+
if (i > 0) tw.push(`tl.fromTo(".wipe", {scaleY:0, transformOrigin:"50% 100%"}, {scaleY:1, duration:${XF / 2}, ease:"power2.in", immediateRender:false}, ${f(s - XF / 2)});`
|
|
156
|
+
+ `tl.to(".wipe", {scaleY:0, transformOrigin:"50% 0%", duration:${XF / 2}, ease:"power2.out"}, ${f(s)});`);
|
|
157
|
+
const no = `${String(i + 1).padStart(2, "0")} <i>/ ${String(n).padStart(2, "0")}</i>`;
|
|
158
|
+
const cap = it.cap ? `<div class="clip capw" data-start="${f(s)}" data-duration="${f(d)}" data-track-index="4"><div class="no n${i}">${no}</div><div class="cap c${i}">${words(it.cap, `w w${i}`)}</div><div class="rule r${i}"></div></div>` : "";
|
|
159
|
+
if (it.cap) {
|
|
160
|
+
tw.push(`tl.fromTo(".n${i}", {opacity:0, x:-24}, {opacity:1, x:0, duration:0.35, ease:"power3.out"}, ${f(s + 0.2)});`);
|
|
161
|
+
tw.push(`tl.fromTo(".r${i}", {scaleX:0}, {scaleX:1, duration:0.5, ease:"power3.out"}, ${f(s + 0.25)});`);
|
|
162
|
+
tw.push(`tl.fromTo(".w${i}", {opacity:0, y:46}, {opacity:1, y:0, duration:0.45, stagger:0.09, ease:"power3.out"}, ${f(s + 0.35)});`);
|
|
163
|
+
if (!last) tw.push(`tl.to(".c${i}, .n${i}, .r${i}", {opacity:0, duration:0.25}, ${f(s + d - 0.3)});`);
|
|
164
|
+
}
|
|
86
165
|
return vis + cap;
|
|
87
166
|
}).join("\n");
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
167
|
+
|
|
168
|
+
const intro = PART === "body" ? "" : `<section class="clip card" data-start="0" data-duration="${INTRO}" data-track-index="6">`
|
|
169
|
+
+ `<div class="kick ik">현장 스케치</div>${mark(200, "im")}<h1>${words(TITLE, "it")}</h1><div class="line il"></div><p class="is">${esc(SUB)}</p></section>`;
|
|
170
|
+
const end = PART === "body" ? "" : `<section class="clip card" data-start="${f(t)}" data-duration="${END}" data-track-index="6">`
|
|
171
|
+
+ `${mark(230, "em")}<h1 class="et">Elanous</h1><p class="et">사진을 올리면, 영상이 됩니다</p><p class="et red">elanous.ai</p></section>`;
|
|
172
|
+
if (PART !== "body") {
|
|
173
|
+
tw.push(`tl.fromTo(".ik", {opacity:0, letterSpacing:"0.6em"}, {opacity:1, letterSpacing:"0.28em", duration:0.8, ease:"power3.out"}, 0.1);`);
|
|
174
|
+
tw.push(`tl.fromTo(".im", {rotation:-160, scale:0.6, opacity:0}, {rotation:0, scale:1, opacity:1, duration:1.0, ease:"power3.out"}, 0.0);`);
|
|
175
|
+
tw.push(`tl.fromTo(".it", {opacity:0, y:50}, {opacity:1, y:0, duration:0.55, stagger:0.1, ease:"power3.out"}, 0.45);`);
|
|
176
|
+
tw.push(`tl.fromTo(".il", {scaleX:0}, {scaleX:1, duration:0.6, ease:"power3.inOut"}, 0.9);`);
|
|
177
|
+
tw.push(`tl.fromTo(".is", {opacity:0, y:16}, {opacity:1, y:0, duration:0.45, ease:"power3.out"}, 1.15);`);
|
|
178
|
+
tw.push(`tl.fromTo(".em", {rotation:-200, scale:0.5}, {rotation:0, scale:1, duration:1.2, ease:"power3.out"}, ${f(t)});`);
|
|
179
|
+
tw.push(`tl.fromTo(".et", {opacity:0, y:20}, {opacity:1, y:0, duration:0.5, stagger:0.14, ease:"power3.out"}, ${f(t + 0.5)});`);
|
|
180
|
+
}
|
|
181
|
+
tw.unshift(`tl.set(".wipe", {scaleY:0}, 0);`);
|
|
92
182
|
tw.push(`tl.fromTo(".bar i", {scaleX:0}, {scaleX:1, duration:${TOTAL}, ease:"none"}, 0);`);
|
|
183
|
+
const audio = music ? `<audio id="bgm" src="assets/media/${music}" data-start="0" data-duration="${TOTAL}" data-track-index="9"></audio>` : "";
|
|
93
184
|
const html = `<!doctype html><html lang="ko"><head><meta charset="UTF-8"/><meta name="viewport" content="width=${W}, height=${H}"/><title>${esc(TITLE)}</title><script src="assets/gsap.min.js"></script><style>
|
|
94
185
|
@font-face{font-family:"Pretendard";src:url("assets/fonts/Pretendard-Bold.woff2") format("woff2");font-weight:700}
|
|
95
186
|
@font-face{font-family:"Pretendard";src:url("assets/fonts/Pretendard-ExtraBold.woff2") format("woff2");font-weight:800}
|
|
96
187
|
@font-face{font-family:"Pretendard";src:url("assets/fonts/Pretendard-Black.woff2") format("woff2");font-weight:900}
|
|
97
188
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
98
189
|
#root{position:relative;width:100%;height:100%;overflow:hidden;background:#000;font-family:"Pretendard",sans-serif;color:#F2F1EE;word-break:keep-all}
|
|
99
|
-
.med{position:absolute;inset:0;width:100%;height:100%;
|
|
190
|
+
.med{position:absolute;inset:0;width:100%;height:100%;overflow:hidden}
|
|
191
|
+
.g{position:absolute;inset:0;overflow:hidden}
|
|
100
192
|
.kb{width:100%;height:100%;object-fit:cover;display:block}
|
|
101
|
-
.
|
|
193
|
+
.fill{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:blur(42px) saturate(1.2);opacity:.85}
|
|
194
|
+
.dim{position:absolute;inset:0;background:rgba(0,0,0,.42)}
|
|
195
|
+
.frame{position:absolute;left:0;right:0;top:420px;height:960px;overflow:hidden;box-shadow:0 30px 80px rgba(0,0,0,.55)}
|
|
196
|
+
.frame img{width:100%;height:100%;object-fit:cover;display:block}
|
|
197
|
+
.shade{z-index:3;position:absolute;left:0;right:0;bottom:0;height:42%;background:linear-gradient(to top,rgba(0,0,0,.82),rgba(0,0,0,0));pointer-events:none}
|
|
102
198
|
.top{z-index:5;position:absolute;left:56px;right:56px;top:72px;display:flex;align-items:center;gap:18px;font-weight:800;font-size:34px;text-shadow:0 2px 12px rgba(0,0,0,.6)}
|
|
103
199
|
.top b{color:#E95047;font-weight:800}
|
|
104
|
-
.capw{z-index:4;position:absolute;left:64px;right:64px;bottom:
|
|
105
|
-
.
|
|
106
|
-
.
|
|
107
|
-
.
|
|
108
|
-
.
|
|
200
|
+
.capw{z-index:4;position:absolute;left:64px;right:64px;bottom:210px}
|
|
201
|
+
.no{font-weight:800;font-size:34px;letter-spacing:.12em;color:#E95047}
|
|
202
|
+
.no i{font-style:normal;color:rgba(242,241,238,.55)}
|
|
203
|
+
.cap{margin-top:18px;font-weight:900;font-size:76px;line-height:1.18;letter-spacing:-0.03em;text-shadow:0 3px 18px rgba(0,0,0,.7)}
|
|
204
|
+
.w{display:inline-block}
|
|
205
|
+
.rule{margin-top:26px;width:120px;height:8px;background:#E95047;transform-origin:0 50%}
|
|
206
|
+
.wipe{z-index:8;position:absolute;inset:0;background:#E95047}
|
|
207
|
+
.card{z-index:7;position:absolute;inset:0;background:#000;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:0 80px}
|
|
208
|
+
.kick{margin-bottom:56px;font-weight:800;font-size:32px;letter-spacing:.28em;color:#E95047}
|
|
209
|
+
.card h1{margin-top:56px;font-weight:900;font-size:100px;line-height:1.12;letter-spacing:-0.03em}
|
|
210
|
+
.card h1 span{display:inline-block}
|
|
211
|
+
.line{margin-top:40px;width:160px;height:8px;background:#E95047}
|
|
212
|
+
.card p{margin-top:28px;font-weight:700;font-size:42px;color:rgba(242,241,238,.66)}
|
|
109
213
|
.card .red{color:#E95047}
|
|
110
|
-
.bar{z-index:
|
|
214
|
+
.bar{z-index:9;position:absolute;left:0;right:0;bottom:0;height:10px;background:rgba(242,241,238,.12)}
|
|
111
215
|
.bar i{position:absolute;inset:0;background:#E95047;transform-origin:0 50%;display:block}
|
|
112
216
|
</style></head><body>
|
|
113
217
|
<div id="root" data-composition-id="main" data-start="0" data-width="${W}" data-height="${H}" data-duration="${TOTAL}">
|
|
114
|
-
|
|
218
|
+
${intro}
|
|
115
219
|
${clips}
|
|
116
220
|
<div class="shade"></div>
|
|
117
221
|
<div class="top">${mark(60)}<span>Elanous <b>·</b> ${esc(TITLE)}</span></div>
|
|
118
|
-
<
|
|
222
|
+
<div class="wipe"></div>
|
|
223
|
+
${end}
|
|
119
224
|
<div class="bar"><i></i></div>
|
|
225
|
+
${audio}
|
|
120
226
|
</div>
|
|
121
227
|
<script>const tl = gsap.timeline({ paused: true });
|
|
122
228
|
${tw.join("\n")}
|
|
@@ -124,5 +230,6 @@ window.__timelines["main"] = tl;</script></body></html>`;
|
|
|
124
230
|
writeFileSync(join(hf, "index.html"), html);
|
|
125
231
|
writeFileSync(join(hf, "hyperframes.json"), JSON.stringify({ $schema: "https://hyperframes.heygen.com/schema/hyperframes.json", paths: { assets: "assets" }, media: { autoProxy: true } }, null, 2) + "\n");
|
|
126
232
|
writeFileSync(join(hf, "meta.json"), JSON.stringify({ id: "reel", name: "reel" }, null, 2) + "\n");
|
|
127
|
-
writeFileSync(join(out, "timeline.json"), JSON.stringify({ total: TOTAL,
|
|
128
|
-
|
|
233
|
+
writeFileSync(join(out, "timeline.json"), JSON.stringify({ total: TOTAL, part: PART, title: TITLE, sub: SUB, music: Boolean(music),
|
|
234
|
+
vision: { enabled: VISION, calls: jobs.length, captioned: items.filter((i) => i.vcap).length, fallback: items.filter((i) => !i.video && !caps[i.f] && !i.vcap).length, ms: visionMs }, items: items.map(({ f: file, video, start, dur, cap, vcap }) => ({ file, video, start, dur: f(dur), cap, vision: Boolean(vcap) })) }, null, 2));
|
|
235
|
+
console.log(`reel: ${items.length} items · ${TOTAL}s · ${items.filter((i) => i.vcap).length} vision captions · music ${music ? "on" : "off"} → ${hf}`);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/bin/zsh
|
|
2
2
|
# Field reel in one command: folder of phone photos/clips → <folder>/reel/<name>-9x16.mp4 · prints the elapsed seconds.
|
|
3
|
+
# The layout/contrast check is advisory: phone photos behind captions often miss 3:1, and a failed check must not stop the reel.
|
|
3
4
|
# Usage: zsh reel.sh <folder> [--title "…"] [--sub "…"] (captions: <folder>/captions.txt — `파일 | 자막`)
|
|
4
5
|
E=${0:A:h}; F=${1:A}; shift
|
|
5
6
|
[[ -d $F ]] || { print -u2 "reel: no folder $F"; exit 2 }
|
|
6
7
|
T0=$(date +%s)
|
|
7
|
-
rm -rf $F/reel && node $E/reel.mjs $F "$@" && (cd $F/reel/hf && npx -y hyperframes@${HYPERFRAMES_VERSION:-0.8.95} check >../render.log 2>&1
|
|
8
|
+
rm -rf $F/reel && node $E/reel.mjs $F "$@" && (cd $F/reel/hf && { npx -y hyperframes@${HYPERFRAMES_VERSION:-0.8.95} check >../render.log 2>&1 || print "reel: check reported issues (continuing — user photos vary; see above)" >>../render.log }; npx -y hyperframes@${HYPERFRAMES_VERSION:-0.8.95} render --fps 30 --workers 4 --output ../reel-9x16.mp4 >>../render.log 2>&1) || { print -u2 "reel: FAILED — see $F/reel/render.log"; exit 1 }
|
|
8
9
|
print "reel: $F/reel/reel-9x16.mp4 · $(( $(date +%s) - T0 ))s"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Seulki",
|
|
6
6
|
"model": "eleven_v3"
|
|
7
7
|
},
|
|
8
|
-
"sources": "
|
|
8
|
+
"sources": "elanous 0.2.5 release notes — https://github.com/ElanvitalAI/elanous/releases/tag/v0.2.5",
|
|
9
9
|
"intro": {
|
|
10
10
|
"beats": [
|
|
11
11
|
{
|
package/skills/grill-me/SKILL.md
CHANGED
|
@@ -123,7 +123,7 @@ requires: []
|
|
|
123
123
|
| 다음 | 언제 | 어떻게 |
|
|
124
124
|
|---|---|---|
|
|
125
125
|
| 🧹 **`first-principles`** | 요구가 많이 나왔을 때 | ⭐ ***캐낸 다음엔 «지운다»*** — 5단계 ①의심 ②삭제 가 순서상 여기다 |
|
|
126
|
-
| 🎯 **골 문면** (
|
|
126
|
+
| 🎯 **골 문면** (골 파일) | 하니스가 구현할 일일 때 | 카드의 `S`·`C`·`Q` 가 그대로 ask 의 세 칸이 된다 |
|
|
127
127
|
| 📄 **문서** (`docs/`) | 결정을 남길 일일 때 | `## ✅ 정해진 것` 표가 그대로 결정 기록이다 |
|
|
128
128
|
| 🧑🤝🧑 **팀 짜기** | 일이 여럿으로 갈릴 때 | ⭐ 목표를 심은 뒤 *"이 일을 할 팀을 짜 보라"* — 인터뷰의 «응용»이다 |
|
|
129
129
|
|
|
@@ -14,7 +14,7 @@ flowchart TD
|
|
|
14
14
|
H{nonCodeOutcome exists?}:::gate
|
|
15
15
|
I[observe deploy-no-changes<br/>return { ok:false, kind:none }]:::fail
|
|
16
16
|
J{Evidence is artifact-created?}:::gate
|
|
17
|
-
K{
|
|
17
|
+
K{2026-08-13<br/>existsSync(resolve(cwd, ref))?}:::gate
|
|
18
18
|
L[observe deploy-noncode-blocked<br/>reason: artifact-created-ref-missing<br/>then deploy-no-changes]:::fail
|
|
19
19
|
M[Do not treat ref as a file<br/>published-url / execution-completed]:::data
|
|
20
20
|
N[observe deploy-noncode<br/>return terminal:<br/>published or executed]:::pass
|
package/src/a2a/server.ts
CHANGED
|
@@ -91,6 +91,8 @@ export function startA2AServer(opts: A2AServerOptions): Bun.Server<undefined> {
|
|
|
91
91
|
history ??= new DaemonSessionHistory();
|
|
92
92
|
const result = await (opts.runDaemonTurn ?? runDaemonPromptTurn)({
|
|
93
93
|
history,
|
|
94
|
+
// A peer agent delegates work, not small talk: never drop its tools for a short message (#22430 fast path).
|
|
95
|
+
fastPathEnabled: false,
|
|
94
96
|
request: {
|
|
95
97
|
sessionId: contextId,
|
|
96
98
|
userText: text,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// EN10a — ACP auth methods: a client that runs terminals gets a `terminal` method (it re-launches `elanous --acp-server --login`);
|
|
2
|
+
// an older client gets an agent method carrying Zed's `terminal-auth` meta, so «sign-in needed → run elanous login in a terminal» shows either way.
|
|
3
|
+
import type { AuthMethod, ClientCapabilities } from '@agentclientprotocol/sdk';
|
|
4
|
+
|
|
5
|
+
export const ACP_LOGIN_METHOD_ID = 'elanous-login';
|
|
6
|
+
/** Appended to the configured agent invocation (`elanous --acp-server`) by a terminal-auth client. */
|
|
7
|
+
export const ACP_LOGIN_ARG = '--login';
|
|
8
|
+
/** What the login step runs (the ChatGPT/Codex subscription sign-in). */
|
|
9
|
+
export const ACP_LOGIN_SUBCOMMAND = ['login', 'openai-codex'] as const;
|
|
10
|
+
|
|
11
|
+
export interface AcpLaunch { command: string; args: string[] }
|
|
12
|
+
|
|
13
|
+
/** How this process was started (bun + script, or a compiled binary) so a client can start the same thing. */
|
|
14
|
+
export function currentLaunch(argv: readonly string[] = process.argv, execPath = process.execPath): AcpLaunch {
|
|
15
|
+
const script = argv[1];
|
|
16
|
+
return script && /\.(?:m?js|ts)$/.test(script) ? { command: execPath, args: [script] } : { command: execPath, args: [] };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function acpAuthMethods(client: ClientCapabilities | null | undefined, launch: AcpLaunch = currentLaunch()): AuthMethod[] {
|
|
20
|
+
const name = 'Sign in to elanous';
|
|
21
|
+
if (client?.auth?.terminal === true) {
|
|
22
|
+
return [{ type: 'terminal', id: ACP_LOGIN_METHOD_ID, name, description: 'Opens a terminal to sign in with your ChatGPT (Codex) subscription', args: [ACP_LOGIN_ARG] }];
|
|
23
|
+
}
|
|
24
|
+
return [{
|
|
25
|
+
id: ACP_LOGIN_METHOD_ID,
|
|
26
|
+
name,
|
|
27
|
+
description: `Run \`elanous ${ACP_LOGIN_SUBCOMMAND.join(' ')}\` in a terminal, then try again`,
|
|
28
|
+
_meta: { 'terminal-auth': { command: launch.command, args: [...launch.args, ...ACP_LOGIN_SUBCOMMAND], label: 'elanous login' } },
|
|
29
|
+
}];
|
|
30
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ClientCapabilities } from '@agentclientprotocol/sdk';
|
|
2
|
+
|
|
3
|
+
/** The server's sessionPeers registry remains the source of truth for which
|
|
4
|
+
* connections are attached to a session. Awareness belongs to the connection,
|
|
5
|
+
* not the session: a plain client can load an aware client's session. */
|
|
6
|
+
export class ElanousAwarePeers<Peer extends object> {
|
|
7
|
+
private readonly aware = new WeakSet<Peer>();
|
|
8
|
+
|
|
9
|
+
constructor(private readonly sessionPeers: ReadonlyMap<string, ReadonlySet<Peer>>) {}
|
|
10
|
+
|
|
11
|
+
markPeer(connectionOrSessionId: Peer, clientCapabilities: ClientCapabilities | undefined | null): void {
|
|
12
|
+
const elanous = (clientCapabilities?._meta as Record<string, unknown> | undefined)?.elanous;
|
|
13
|
+
if (elanous !== null && typeof elanous === 'object' && !Array.isArray(elanous)) {
|
|
14
|
+
this.aware.add(connectionOrSessionId);
|
|
15
|
+
} else {
|
|
16
|
+
this.aware.delete(connectionOrSessionId);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
isPeerAware(peer: Peer): boolean {
|
|
21
|
+
return this.aware.has(peer);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
isElanousAware(sessionId: string): boolean {
|
|
25
|
+
for (const peer of this.sessionPeers.get(sessionId) ?? []) {
|
|
26
|
+
if (this.isPeerAware(peer)) return true;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|