cli-jaw 2.2.15 → 2.2.17
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/README.md +23 -2
- package/dist/bin/cli-jaw.js +39 -0
- package/dist/bin/cli-jaw.js.map +1 -1
- package/dist/bin/commands/_shared/dashboard-client.js +42 -0
- package/dist/bin/commands/_shared/dashboard-client.js.map +1 -0
- package/dist/bin/commands/_shared/search-format.js +40 -0
- package/dist/bin/commands/_shared/search-format.js.map +1 -0
- package/dist/bin/commands/chat-search.js +5 -3
- package/dist/bin/commands/chat-search.js.map +1 -1
- package/dist/bin/commands/dashboard-chat.js +14 -31
- package/dist/bin/commands/dashboard-chat.js.map +1 -1
- package/dist/bin/commands/dashboard-memory.js +12 -49
- package/dist/bin/commands/dashboard-memory.js.map +1 -1
- package/dist/bin/commands/doctor.js +56 -11
- package/dist/bin/commands/doctor.js.map +1 -1
- package/dist/bin/commands/init.js +31 -1
- package/dist/bin/commands/init.js.map +1 -1
- package/dist/bin/commands/memory.js +5 -1
- package/dist/bin/commands/memory.js.map +1 -1
- package/dist/bin/commands/provider.js +23 -0
- package/dist/bin/commands/provider.js.map +1 -1
- package/dist/bin/commands/slack.js +57 -3
- package/dist/bin/commands/slack.js.map +1 -1
- package/dist/bin/commands/tui/input-handler.js +1 -1
- package/dist/bin/commands/tui/input-handler.js.map +1 -1
- package/dist/bin/commands/tui/slash-command-runner.js +4 -5
- package/dist/bin/commands/tui/slash-command-runner.js.map +1 -1
- package/dist/bin/postinstall.js +16 -18
- package/dist/bin/postinstall.js.map +1 -1
- package/dist/lib/media-kind.js +28 -0
- package/dist/lib/media-kind.js.map +1 -0
- package/dist/lib/upload.js +27 -10
- package/dist/lib/upload.js.map +1 -1
- package/dist/server.js +35 -51
- package/dist/server.js.map +1 -1
- package/dist/src/agent/args.js +34 -0
- package/dist/src/agent/args.js.map +1 -1
- package/dist/src/agent/codex-app-client.js +1016 -135
- package/dist/src/agent/codex-app-client.js.map +1 -1
- package/dist/src/agent/codex-app-events.js +72 -1
- package/dist/src/agent/codex-app-events.js.map +1 -1
- package/dist/src/agent/codex-host-pool.js +617 -0
- package/dist/src/agent/codex-host-pool.js.map +1 -0
- package/dist/src/agent/jwc-runtime.js +12 -4
- package/dist/src/agent/jwc-runtime.js.map +1 -1
- package/dist/src/agent/kiro-auth.js +10 -4
- package/dist/src/agent/kiro-auth.js.map +1 -1
- package/dist/src/agent/kiro-runtime.js +45 -8
- package/dist/src/agent/kiro-runtime.js.map +1 -1
- package/dist/src/agent/lifecycle-handler.js +75 -52
- package/dist/src/agent/lifecycle-handler.js.map +1 -1
- package/dist/src/agent/memory-flush-controller.js +241 -33
- package/dist/src/agent/memory-flush-controller.js.map +1 -1
- package/dist/src/agent/prompt-context.js +4 -0
- package/dist/src/agent/prompt-context.js.map +1 -1
- package/dist/src/agent/runtime-pool.js +64 -34
- package/dist/src/agent/runtime-pool.js.map +1 -1
- package/dist/src/agent/session-persistence.js +71 -15
- package/dist/src/agent/session-persistence.js.map +1 -1
- package/dist/src/agent/spawn/queue.js +319 -162
- package/dist/src/agent/spawn/queue.js.map +1 -1
- package/dist/src/agent/spawn.js +581 -268
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/bgtask/types.js +1 -1
- package/dist/src/bgtask/types.js.map +1 -1
- package/dist/src/browser/adaptive-fetch/safety.js +25 -0
- package/dist/src/browser/adaptive-fetch/safety.js.map +1 -1
- package/dist/src/browser/connection.js +2 -8
- package/dist/src/browser/connection.js.map +1 -1
- package/dist/src/cli/capability-probe-worker.js +172 -0
- package/dist/src/cli/capability-probe-worker.js.map +1 -0
- package/dist/src/cli/capability-probe.js +83 -0
- package/dist/src/cli/capability-probe.js.map +1 -0
- package/dist/src/cli/claude-models.js +2 -2
- package/dist/src/cli/claude-models.js.map +1 -1
- package/dist/src/cli/cli-status-worker.js +296 -0
- package/dist/src/cli/cli-status-worker.js.map +1 -0
- package/dist/src/cli/cli-status.js +81 -0
- package/dist/src/cli/cli-status.js.map +1 -0
- package/dist/src/cli/command-context.js +17 -5
- package/dist/src/cli/command-context.js.map +1 -1
- package/dist/src/cli/compact.js +56 -19
- package/dist/src/cli/compact.js.map +1 -1
- package/dist/src/cli/handlers-runtime.js +6 -4
- package/dist/src/cli/handlers-runtime.js.map +1 -1
- package/dist/src/cli/handlers.js +7 -2
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/opencodex-models.js +5 -32
- package/dist/src/cli/opencodex-models.js.map +1 -1
- package/dist/src/cli/opencodex-runtime.js +82 -0
- package/dist/src/cli/opencodex-runtime.js.map +1 -0
- package/dist/src/cli/readiness.js +35 -18
- package/dist/src/cli/readiness.js.map +1 -1
- package/dist/src/cli/registry-live.js +8 -2
- package/dist/src/cli/registry-live.js.map +1 -1
- package/dist/src/cli/registry.js +1 -1
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/core/browser-open-default.js +6 -4
- package/dist/src/core/browser-open-default.js.map +1 -1
- package/dist/src/core/browser-open.js +11 -15
- package/dist/src/core/browser-open.js.map +1 -1
- package/dist/src/core/bus.js +7 -1
- package/dist/src/core/bus.js.map +1 -1
- package/dist/src/core/chat-sessions.js +121 -12
- package/dist/src/core/chat-sessions.js.map +1 -1
- package/dist/src/core/cli-detect.js +148 -4
- package/dist/src/core/cli-detect.js.map +1 -1
- package/dist/src/core/codex-config.js +21 -0
- package/dist/src/core/codex-config.js.map +1 -1
- package/dist/src/core/compact.js +73 -21
- package/dist/src/core/compact.js.map +1 -1
- package/dist/src/core/config.js +449 -20
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/db.js +225 -0
- package/dist/src/core/db.js.map +1 -1
- package/dist/src/core/event-bus.js +49 -4
- package/dist/src/core/event-bus.js.map +1 -1
- package/dist/src/core/event-scope.js +100 -0
- package/dist/src/core/event-scope.js.map +1 -0
- package/dist/src/core/install-integrity.js +176 -0
- package/dist/src/core/install-integrity.js.map +1 -0
- package/dist/src/core/main-session.js +64 -21
- package/dist/src/core/main-session.js.map +1 -1
- package/dist/src/core/message-summary.js +12 -2
- package/dist/src/core/message-summary.js.map +1 -1
- package/dist/src/core/platform-kind.js +139 -0
- package/dist/src/core/platform-kind.js.map +1 -0
- package/dist/src/core/rate-limit.js +156 -0
- package/dist/src/core/rate-limit.js.map +1 -0
- package/dist/src/core/runtime-settings.js +165 -17
- package/dist/src/core/runtime-settings.js.map +1 -1
- package/dist/src/core/session-context.js +7 -0
- package/dist/src/core/session-context.js.map +1 -0
- package/dist/src/core/session-ops.js +53 -9
- package/dist/src/core/session-ops.js.map +1 -1
- package/dist/src/core/settings-merge.js +105 -3
- package/dist/src/core/settings-merge.js.map +1 -1
- package/dist/src/core/settings-watch.js +29 -5
- package/dist/src/core/settings-watch.js.map +1 -1
- package/dist/src/core/widget-watcher.js +15 -2
- package/dist/src/core/widget-watcher.js.map +1 -1
- package/dist/src/discord/bot.js +5 -2
- package/dist/src/discord/bot.js.map +1 -1
- package/dist/src/discord/commands.js +4 -4
- package/dist/src/discord/commands.js.map +1 -1
- package/dist/src/goal/heartbeat.js +1 -1
- package/dist/src/goal/heartbeat.js.map +1 -1
- package/dist/src/goal/runtime.js +1 -1
- package/dist/src/goal/runtime.js.map +1 -1
- package/dist/src/goal-run/controller.js +2 -2
- package/dist/src/goal-run/controller.js.map +1 -1
- package/dist/src/manager/internal-fetch.js +15 -0
- package/dist/src/manager/internal-fetch.js.map +1 -0
- package/dist/src/manager/logs.js +2 -1
- package/dist/src/manager/logs.js.map +1 -1
- package/dist/src/manager/memory/chat-federation.js +104 -11
- package/dist/src/manager/memory/chat-federation.js.map +1 -1
- package/dist/src/manager/memory/federation.js +100 -0
- package/dist/src/manager/memory/federation.js.map +1 -1
- package/dist/src/manager/metadata.js +4 -1
- package/dist/src/manager/metadata.js.map +1 -1
- package/dist/src/manager/notes/assets.js +1 -1
- package/dist/src/manager/notes/assets.js.map +1 -1
- package/dist/src/manager/notes/frontmatter.js +5 -49
- package/dist/src/manager/notes/frontmatter.js.map +1 -1
- package/dist/src/manager/notes/link-resolver.js +2 -2
- package/dist/src/manager/notes/link-resolver.js.map +1 -1
- package/dist/src/manager/notes/remote-assets.js +1 -1
- package/dist/src/manager/notes/remote-assets.js.map +1 -1
- package/dist/src/manager/notes/routes.js +2 -2
- package/dist/src/manager/notes/routes.js.map +1 -1
- package/dist/src/manager/notes/store.js +2 -2
- package/dist/src/manager/notes/store.js.map +1 -1
- package/dist/src/manager/notes/trash.js +1 -1
- package/dist/src/manager/notes/trash.js.map +1 -1
- package/dist/src/manager/notes/vault-index.js +2 -2
- package/dist/src/manager/notes/vault-index.js.map +1 -1
- package/dist/src/manager/notes/wiki-links.js +1 -1
- package/dist/src/manager/notes/wiki-links.js.map +1 -1
- package/dist/src/manager/notes/wiki-routes.js +84 -0
- package/dist/src/manager/notes/wiki-routes.js.map +1 -0
- package/dist/src/manager/proxy.js +1 -0
- package/dist/src/manager/proxy.js.map +1 -1
- package/dist/src/manager/routes/dashboard-memory.js +24 -1
- package/dist/src/manager/routes/dashboard-memory.js.map +1 -1
- package/dist/src/manager/routes/runtime-monitor.js +1 -1
- package/dist/src/manager/routes/runtime-monitor.js.map +1 -1
- package/dist/src/manager/scan.js +5 -3
- package/dist/src/manager/scan.js.map +1 -1
- package/dist/src/manager/server.js +20 -6
- package/dist/src/manager/server.js.map +1 -1
- package/dist/src/manager/telegram-hub/hub-bot.js +4 -3
- package/dist/src/manager/telegram-hub/hub-bot.js.map +1 -1
- package/dist/src/manager/worker-events.js +2 -1
- package/dist/src/manager/worker-events.js.map +1 -1
- package/dist/src/memory/heartbeat.js +6 -5
- package/dist/src/memory/heartbeat.js.map +1 -1
- package/dist/src/memory/indexing.js +162 -45
- package/dist/src/memory/indexing.js.map +1 -1
- package/dist/src/messaging/channel-validate.js +14 -1
- package/dist/src/messaging/channel-validate.js.map +1 -1
- package/dist/src/messaging/redact.js +2 -1
- package/dist/src/messaging/redact.js.map +1 -1
- package/dist/src/messaging/session-key.js +21 -2
- package/dist/src/messaging/session-key.js.map +1 -1
- package/dist/src/notes/constants.js.map +1 -0
- package/dist/src/notes/frontmatter.js +59 -0
- package/dist/src/notes/frontmatter.js.map +1 -0
- package/dist/src/notes/path-guards.js.map +1 -0
- package/dist/src/notes/search.js.map +1 -0
- package/dist/src/orchestrator/attestation.js +1 -1
- package/dist/src/orchestrator/attestation.js.map +1 -1
- package/dist/src/orchestrator/gateway.js +135 -31
- package/dist/src/orchestrator/gateway.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +53 -21
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/scope.js +36 -2
- package/dist/src/orchestrator/scope.js.map +1 -1
- package/dist/src/orchestrator/session-lanes.js +87 -0
- package/dist/src/orchestrator/session-lanes.js.map +1 -0
- package/dist/src/orchestrator/session-work.js +25 -0
- package/dist/src/orchestrator/session-work.js.map +1 -0
- package/dist/src/orchestrator/state-machine.js +1 -5
- package/dist/src/orchestrator/state-machine.js.map +1 -1
- package/dist/src/orchestrator/worker-registry.js +20 -10
- package/dist/src/orchestrator/worker-registry.js.map +1 -1
- package/dist/src/prompt/builder.js +40 -2
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +8 -1
- package/dist/src/routes/agent-control.js +44 -8
- package/dist/src/routes/agent-control.js.map +1 -1
- package/dist/src/routes/chat-sessions.js +34 -6
- package/dist/src/routes/chat-sessions.js.map +1 -1
- package/dist/src/routes/command.js +63 -8
- package/dist/src/routes/command.js.map +1 -1
- package/dist/src/routes/events.js +11 -2
- package/dist/src/routes/events.js.map +1 -1
- package/dist/src/routes/link-preview.js +1 -27
- package/dist/src/routes/link-preview.js.map +1 -1
- package/dist/src/routes/messages.js +6 -5
- package/dist/src/routes/messages.js.map +1 -1
- package/dist/src/routes/messaging.js +45 -1
- package/dist/src/routes/messaging.js.map +1 -1
- package/dist/src/routes/orchestrate.js +53 -33
- package/dist/src/routes/orchestrate.js.map +1 -1
- package/dist/src/routes/search.js +84 -0
- package/dist/src/routes/search.js.map +1 -0
- package/dist/src/routes/session-request.js +29 -0
- package/dist/src/routes/session-request.js.map +1 -0
- package/dist/src/routes/settings.js +110 -3
- package/dist/src/routes/settings.js.map +1 -1
- package/dist/src/routes/static.js +30 -8
- package/dist/src/routes/static.js.map +1 -1
- package/dist/src/routes/system.js +1 -1
- package/dist/src/routes/system.js.map +1 -1
- package/dist/src/routes/wiki.js +122 -0
- package/dist/src/routes/wiki.js.map +1 -0
- package/dist/src/search/contract.js +2 -0
- package/dist/src/search/contract.js.map +1 -0
- package/dist/src/search/coordinator.js +153 -0
- package/dist/src/search/coordinator.js.map +1 -0
- package/dist/src/search/provider.js +40 -0
- package/dist/src/search/provider.js.map +1 -0
- package/dist/src/search/providers/chat.js +115 -0
- package/dist/src/search/providers/chat.js.map +1 -0
- package/dist/src/search/providers/memory.js +53 -0
- package/dist/src/search/providers/memory.js.map +1 -0
- package/dist/src/search/providers/wiki.js +80 -0
- package/dist/src/search/providers/wiki.js.map +1 -0
- package/dist/src/slack/api.js +10 -1
- package/dist/src/slack/api.js.map +1 -1
- package/dist/src/slack/attachment-recovery.js +42 -0
- package/dist/src/slack/attachment-recovery.js.map +1 -0
- package/dist/src/slack/bot.js +120 -41
- package/dist/src/slack/bot.js.map +1 -1
- package/dist/src/slack/commands.js +24 -8
- package/dist/src/slack/commands.js.map +1 -1
- package/dist/src/slack/events.js +12 -1
- package/dist/src/slack/events.js.map +1 -1
- package/dist/src/slack/history.js +108 -0
- package/dist/src/slack/history.js.map +1 -0
- package/dist/src/slack/inbound-file.js +242 -0
- package/dist/src/slack/inbound-file.js.map +1 -0
- package/dist/src/slack/inbound-url.js +39 -0
- package/dist/src/slack/inbound-url.js.map +1 -0
- package/dist/src/slack/ingress.js +140 -0
- package/dist/src/slack/ingress.js.map +1 -0
- package/dist/src/slack/manifest.js +3 -0
- package/dist/src/slack/manifest.js.map +1 -1
- package/dist/src/slack/socket.js +1 -1
- package/dist/src/slack/socket.js.map +1 -1
- package/dist/src/slack/thread-tracker.js +86 -0
- package/dist/src/slack/thread-tracker.js.map +1 -0
- package/dist/src/telegram/bot.js +21 -11
- package/dist/src/telegram/bot.js.map +1 -1
- package/dist/src/wiki/config.js +193 -0
- package/dist/src/wiki/config.js.map +1 -0
- package/dist/src/wiki/entities.js +61 -0
- package/dist/src/wiki/entities.js.map +1 -0
- package/dist/src/wiki/ontology.js +72 -0
- package/dist/src/wiki/ontology.js.map +1 -0
- package/dist/src/wiki/prompt.js +172 -0
- package/dist/src/wiki/prompt.js.map +1 -0
- package/dist/src/wiki/safe-traversal.js +198 -0
- package/dist/src/wiki/safe-traversal.js.map +1 -0
- package/dist/src/wiki/scaffold.js +77 -0
- package/dist/src/wiki/scaffold.js.map +1 -0
- package/package.json +6 -5
- package/public/css/session-hub.css +266 -0
- package/public/dist/assets/AdvancedExport-DYGcCAUq.js +1 -0
- package/public/dist/assets/Agent-CNNQ7KkJ.js +1 -0
- package/public/dist/assets/{DesignPanel-BGMPhZSx.js → DesignPanel-DcL369nB.js} +1 -1
- package/public/dist/assets/{DocPanel-Dz-J_l5M.js → DocPanel-K8A2pm_1.js} +1 -1
- package/public/dist/assets/{FolderPanel-DbPhzzvi.js → FolderPanel-CV52EzwG.js} +1 -1
- package/public/dist/assets/{MilkdownWysiwygEditor-Em7iC6y9.js → MilkdownWysiwygEditor-BKOCDI4Z.js} +1 -1
- package/public/dist/assets/api-B25zNNFJ.js +1 -0
- package/public/dist/assets/{app-DX4e6isX.css → app-DjgGeXhJ.css} +1 -1
- package/public/dist/assets/app-Dsgp4xpU.js +55 -0
- package/public/dist/assets/bgtask-badge-C6h5C-o4.js +1 -0
- package/public/dist/assets/{bgtask-badge-qMkKOZx0.js → bgtask-badge-CpavV0Jc.js} +4 -4
- package/public/dist/assets/{employees-BnobWM_2.js → employees-BJyEgim7.js} +4 -4
- package/public/dist/assets/idb-cache-B5PX63p7.js +1 -0
- package/public/dist/assets/{idb-cache-BzzftUET.js → idb-cache-lOntwU3S.js} +1 -1
- package/public/dist/assets/{iframe-renderer-C5vRbbl9.js → iframe-renderer-B8k3AvTv.js} +12 -12
- package/public/dist/assets/iframe-renderer-BO_GgCTR.js +1 -0
- package/public/dist/assets/manager-LkGs6qEJ.css +1 -0
- package/public/dist/assets/manager-kXYQyMhR.js +13 -0
- package/public/dist/assets/{memory-DF4kPwwC.js → memory-D2RbBVO-.js} +11 -11
- package/public/dist/assets/memory-amsvg4Ey.js +1 -0
- package/public/dist/assets/message-history-BGHZxvgV.js +1 -0
- package/public/dist/assets/message-history-Bw2E_b8L.js +1 -0
- package/public/dist/assets/pi-settings-5HVg1sXJ.js +1 -0
- package/public/dist/assets/render-BkGcpH7z.js +157 -0
- package/public/dist/assets/settings-B1FPORO2.js +56 -0
- package/public/dist/assets/settings-CMN-zN4Q.js +1 -0
- package/public/dist/assets/settings-core-B_OjGYVN.js +1 -0
- package/public/dist/assets/settings-core-CxRwqx86.js +144 -0
- package/public/dist/assets/sidebar-DW78DANx.js +49 -0
- package/public/dist/assets/skills-Dz-9Yrxr.js +1 -0
- package/public/dist/assets/{skills-IGquen_j.js → skills-lWi0ZFiV.js} +6 -6
- package/public/dist/assets/{slash-commands-ZRDOL99E.js → slash-commands-DYOI6nKj.js} +1 -1
- package/public/dist/assets/slash-commands-xJFCdTTM.js +1 -0
- package/public/dist/assets/{trace-drawer-D8To8fYt.js → trace-drawer-DBX9xzmt.js} +1 -1
- package/public/dist/assets/{ui-Hx_mNoDf.js → ui-Bx7eqnXt.js} +1 -1
- package/public/dist/assets/ui-JOcrYeG-.js +1 -0
- package/public/dist/assets/{wiki-link-suggestions-DZQc78gj.js → wiki-link-suggestions-Dp6kBQVu.js} +1 -1
- package/public/dist/index.html +4 -4
- package/public/dist/manager/index.html +2 -2
- package/public/index.html +3 -2
- package/public/js/event-channel.ts +25 -0
- package/public/js/features/channel-onboarding-flow.ts +16 -1
- package/public/js/features/channel-onboarding.ts +20 -2
- package/public/js/features/chat-messages.ts +3 -1
- package/public/js/features/chat-search.ts +2 -1
- package/public/js/features/chat.ts +56 -18
- package/public/js/features/elicitation.ts +15 -0
- package/public/js/features/idb-cache.ts +34 -0
- package/public/js/features/message-history.ts +2 -1
- package/public/js/features/session-hub.ts +334 -0
- package/public/js/features/settings-cli-status-render.ts +1 -1
- package/public/js/features/settings-cli-status.ts +25 -11
- package/public/js/features/settings-core.ts +72 -3
- package/public/js/features/settings-types.ts +32 -0
- package/public/js/features/ui-status.ts +2 -1
- package/public/js/main.ts +20 -0
- package/public/js/render/compose-block.ts +7 -0
- package/public/js/ws.ts +22 -2
- package/public/locales/en.json +46 -4
- package/public/locales/ja.json +46 -4
- package/public/locales/ko.json +46 -4
- package/public/locales/zh.json +46 -4
- package/public/manager/src/App.tsx +1 -1
- package/public/manager/src/InstancePreview.tsx +5 -1
- package/public/manager/src/api.ts +2 -1
- package/public/manager/src/components/InstanceGroups.tsx +10 -0
- package/public/manager/src/components/InstanceListContent.tsx +24 -1
- package/public/manager/src/components/InstanceRow.tsx +33 -3
- package/public/manager/src/components/InstanceSessionList.tsx +132 -0
- package/public/manager/src/hooks/useActiveSessionDisclosure.ts +45 -0
- package/public/manager/src/lib/resilient-fetch.ts +93 -0
- package/public/manager/src/lib/session-store.ts +216 -0
- package/public/manager/src/manager-components.css +97 -0
- package/public/manager/src/settings/pages/AdvancedExport.tsx +12 -2
- package/public/manager/src/settings/pages/Agent.tsx +113 -1
- package/public/manager/src/settings/pages/components/agent/agent-meta.ts +1 -1
- package/scripts/bundle-sidecar.sh +50 -2
- package/scripts/burst-scenario.mjs +72 -0
- package/scripts/check-redaction-sinks.mjs +1 -0
- package/scripts/check-strict-baseline.mjs +1 -1
- package/scripts/ensure-native-modules.cjs +50 -3
- package/scripts/install-risk-gate.mjs +8 -0
- package/scripts/install-wsl.sh +27 -2
- package/scripts/install.ps1 +121 -0
- package/scripts/install.sh +28 -2
- package/scripts/postinstall-guard.cjs +44 -2
- package/scripts/release-gates.mjs +12 -0
- package/dist/src/manager/notes/constants.js.map +0 -1
- package/dist/src/manager/notes/path-guards.js.map +0 -1
- package/dist/src/manager/notes/search.js.map +0 -1
- package/public/dist/assets/AdvancedExport-DsDpqXoH.js +0 -1
- package/public/dist/assets/Agent-BjbZVZ9p.js +0 -1
- package/public/dist/assets/api-C9dOxby7.js +0 -1
- package/public/dist/assets/app-BzD_ZLvt.js +0 -55
- package/public/dist/assets/bgtask-badge-Dqbp-Y4e.js +0 -1
- package/public/dist/assets/idb-cache-ZH6lOebk.js +0 -1
- package/public/dist/assets/iframe-renderer-Df4KIVyx.js +0 -1
- package/public/dist/assets/manager-C4eNDNFt.css +0 -1
- package/public/dist/assets/manager-DaN201mN.js +0 -13
- package/public/dist/assets/memory-D-bULTHl.js +0 -1
- package/public/dist/assets/message-history-C4WOisGx.js +0 -1
- package/public/dist/assets/message-history-ZBoza6ew.js +0 -1
- package/public/dist/assets/pi-settings-CBUGDAuT.js +0 -1
- package/public/dist/assets/render-DYX6GRQ0.js +0 -122
- package/public/dist/assets/settings-DbJpGoaX.js +0 -55
- package/public/dist/assets/settings-SreihUje.js +0 -1
- package/public/dist/assets/settings-core-B1Y5Nb4Z.js +0 -1
- package/public/dist/assets/settings-core-DobZWIZ7.js +0 -140
- package/public/dist/assets/sidebar-Cp22g0Gv.js +0 -49
- package/public/dist/assets/skills-DwPIP08e.js +0 -1
- package/public/dist/assets/slash-commands-BBVfwcnW.js +0 -1
- package/public/dist/assets/ui-CAicpUZc.js +0 -1
- /package/dist/src/{manager/notes → notes}/constants.js +0 -0
- /package/dist/src/{manager/notes → notes}/path-guards.js +0 -0
- /package/dist/src/{manager/notes → notes}/search.js +0 -0
- /package/public/dist/assets/{pi-settings-Dh5lgb87.js → pi-settings-DEuKgvIj.js} +0 -0
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<link rel="icon" type="image/png" href="/dist/assets/icon-192-CwXPIYF5.png">
|
|
7
7
|
<title>Jaw Manager</title>
|
|
8
8
|
<script src="/manager/theme-boot.js"></script>
|
|
9
|
-
<script type="module" crossorigin src="/dist/assets/manager-
|
|
9
|
+
<script type="module" crossorigin src="/dist/assets/manager-kXYQyMhR.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/dist/assets/vendor-render-Bjnw0wQ6.css">
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/dist/assets/manager-
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/dist/assets/manager-LkGs6qEJ.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="manager-root"></div>
|
package/public/index.html
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
<link rel="stylesheet" href="/css/tool-ui.css">
|
|
43
43
|
<link rel="stylesheet" href="/css/trace-drawer.css">
|
|
44
44
|
<link rel="stylesheet" href="/css/diagram.css">
|
|
45
|
+
<link rel="stylesheet" href="/css/session-hub.css">
|
|
45
46
|
<!-- Vite handles module bundling in dev (HMR) and production (build) -->
|
|
46
47
|
</head>
|
|
47
48
|
|
|
@@ -583,7 +584,7 @@
|
|
|
583
584
|
<span class="slack-step-num">1</span>
|
|
584
585
|
<div class="slack-step-body">
|
|
585
586
|
<div class="slack-step-title" data-i18n="settings.slack.guide.step1Title">Slack 앱 만들기</div>
|
|
586
|
-
<div class="slack-step-desc" data-i18n="settings.slack.guide.step1Desc">Create an App → From an app manifest → 워크스페이스 선택 →
|
|
587
|
+
<div class="slack-step-desc" data-i18n="settings.slack.guide.step1Desc">Create an App → From an app manifest → 워크스페이스 선택 → 붙여넣기 (기존 앱은 files:read 추가)</div>
|
|
587
588
|
<div class="slack-step-actions">
|
|
588
589
|
<button id="slack-copy-manifest" class="perm-btn" type="button" data-i18n="settings.slack.guide.copyManifest">매니페스트 복사</button>
|
|
589
590
|
<button id="slack-open-apps" class="perm-btn" type="button" data-i18n="settings.slack.guide.openApps">앱 페이지 열기</button>
|
|
@@ -594,7 +595,7 @@
|
|
|
594
595
|
<span class="slack-step-num">2</span>
|
|
595
596
|
<div class="slack-step-body">
|
|
596
597
|
<div class="slack-step-title" data-i18n="settings.slack.guide.step2Title">봇 토큰 붙여넣기</div>
|
|
597
|
-
<div class="slack-step-desc" data-i18n="settings.slack.guide.step2Desc">앱 설정 → OAuth & Permissions →
|
|
598
|
+
<div class="slack-step-desc" data-i18n="settings.slack.guide.step2Desc">앱 설정 → OAuth & Permissions → files:read 확인 → Reinstall to Workspace → Bot User OAuth Token 복사</div>
|
|
598
599
|
<input type="password" id="slBotToken" placeholder="xoxb-..." class="input-sm">
|
|
599
600
|
<div class="slack-field-error" id="slack-bot-token-error" style="display:none" data-i18n="settings.slack.guide.botTokenError">xoxb-로 시작하는 봇 토큰이어야 합니다</div>
|
|
600
601
|
</div>
|
|
@@ -39,6 +39,30 @@ let lastMessageAt = 0;
|
|
|
39
39
|
let pingCapable = false;
|
|
40
40
|
let stallTimer: ReturnType<typeof setInterval> | null = null;
|
|
41
41
|
|
|
42
|
+
// ── Per-tab scope (072 §1.3a) ──
|
|
43
|
+
// A tab viewing one session subscribes to that session's scope so another
|
|
44
|
+
// session's output never lands in it. Injected rather than imported: the scope
|
|
45
|
+
// comes from the session view, which imports the API layer, and reading it
|
|
46
|
+
// through a provider keeps this module free of that cycle and picks up the
|
|
47
|
+
// current value on every reconnect rather than freezing the boot-time one.
|
|
48
|
+
let scopeProvider: (() => string | null) | null = null;
|
|
49
|
+
|
|
50
|
+
export function setEventChannelScopeProvider(provider: (() => string | null) | null): void {
|
|
51
|
+
scopeProvider = provider;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function currentScopeParam(): string {
|
|
55
|
+
let scope: string | null = null;
|
|
56
|
+
try {
|
|
57
|
+
scope = scopeProvider?.() ?? null;
|
|
58
|
+
} catch {
|
|
59
|
+
// A broken provider must not take the whole channel down; an unscoped
|
|
60
|
+
// connection still receives everything, which is the old behaviour.
|
|
61
|
+
scope = null;
|
|
62
|
+
}
|
|
63
|
+
return scope ? `&scope=${encodeURIComponent(scope)}` : '';
|
|
64
|
+
}
|
|
65
|
+
|
|
42
66
|
function armStallWatchdog(): void {
|
|
43
67
|
if (stallTimer) return;
|
|
44
68
|
stallTimer = setInterval(() => {
|
|
@@ -111,6 +135,7 @@ export function connectEventChannel(lang: string): void {
|
|
|
111
135
|
if (source) source.close();
|
|
112
136
|
|
|
113
137
|
const url = `${API_BASE}/api/events?lang=${encodeURIComponent(lang)}` +
|
|
138
|
+
currentScopeParam() +
|
|
114
139
|
(lastEventId ? `&lastEventId=${lastEventId}` : '');
|
|
115
140
|
openedThisAttempt = false;
|
|
116
141
|
unavailableFiredThisAttempt = false;
|
|
@@ -60,6 +60,8 @@ export type FlowState = {
|
|
|
60
60
|
error: string | null;
|
|
61
61
|
/** Scopes the provider reported as missing, shown with the error. */
|
|
62
62
|
missingScopes: string[];
|
|
63
|
+
/** Optional feature scopes; warnings only, never a step-3 blocker. */
|
|
64
|
+
missingCapabilities: string[];
|
|
63
65
|
saved: boolean;
|
|
64
66
|
};
|
|
65
67
|
|
|
@@ -72,6 +74,7 @@ export function createFlow(channel: OnboardChannel, draft: Draft = {}): FlowStat
|
|
|
72
74
|
validatedTeamId: '',
|
|
73
75
|
error: null,
|
|
74
76
|
missingScopes: [],
|
|
77
|
+
missingCapabilities: [],
|
|
75
78
|
saved: false,
|
|
76
79
|
};
|
|
77
80
|
}
|
|
@@ -139,12 +142,20 @@ export function setField(state: FlowState, key: string, value: string): FlowStat
|
|
|
139
142
|
validatedTeamId: '',
|
|
140
143
|
error: null,
|
|
141
144
|
missingScopes: [],
|
|
145
|
+
missingCapabilities: [],
|
|
142
146
|
};
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
export function applyValidation(
|
|
146
150
|
state: FlowState,
|
|
147
|
-
result: {
|
|
151
|
+
result: {
|
|
152
|
+
ok?: boolean;
|
|
153
|
+
identity?: string;
|
|
154
|
+
teamId?: string;
|
|
155
|
+
error?: string;
|
|
156
|
+
missing?: string[];
|
|
157
|
+
missingCapabilities?: string[];
|
|
158
|
+
},
|
|
148
159
|
): FlowState {
|
|
149
160
|
if (result?.ok) {
|
|
150
161
|
return {
|
|
@@ -153,6 +164,9 @@ export function applyValidation(
|
|
|
153
164
|
validatedTeamId: result.teamId || '',
|
|
154
165
|
error: null,
|
|
155
166
|
missingScopes: [],
|
|
167
|
+
missingCapabilities: Array.isArray(result.missingCapabilities)
|
|
168
|
+
? result.missingCapabilities
|
|
169
|
+
: [],
|
|
156
170
|
};
|
|
157
171
|
}
|
|
158
172
|
return {
|
|
@@ -161,6 +175,7 @@ export function applyValidation(
|
|
|
161
175
|
validatedTeamId: '',
|
|
162
176
|
error: result?.error || 'network',
|
|
163
177
|
missingScopes: Array.isArray(result?.missing) ? result.missing : [],
|
|
178
|
+
missingCapabilities: [],
|
|
164
179
|
};
|
|
165
180
|
}
|
|
166
181
|
|
|
@@ -119,6 +119,7 @@ function stepBody(state: FlowState): string {
|
|
|
119
119
|
if (state.step === 1) {
|
|
120
120
|
return `
|
|
121
121
|
<p class="onboarding-guide">${escapeHtml(t(`onboarding.guide.${state.channel}`))}</p>
|
|
122
|
+
${state.channel === 'slack' ? `<p class="onboarding-guide">${escapeHtml(t('onboarding.slackExistingApp'))}</p>` : ''}
|
|
122
123
|
<div class="onboarding-actions">
|
|
123
124
|
<button type="button" class="perm-btn" data-onboard-issuer="1">
|
|
124
125
|
${escapeHtml(t('onboarding.openIssuer'))}
|
|
@@ -126,7 +127,7 @@ function stepBody(state: FlowState): string {
|
|
|
126
127
|
</div>`;
|
|
127
128
|
}
|
|
128
129
|
if (state.step === 2) {
|
|
129
|
-
|
|
130
|
+
const fields = fieldsFor(state.channel).map((field) => {
|
|
130
131
|
const label = t(`onboarding.token.${field.key}`) + (field.optional ? ` (${t('onboarding.optional')})` : '');
|
|
131
132
|
return `
|
|
132
133
|
<div class="onboarding-field">
|
|
@@ -139,6 +140,9 @@ function stepBody(state: FlowState): string {
|
|
|
139
140
|
<span class="onboarding-hint">${escapeHtml(t(`onboarding.hint.${state.channel}.${field.key}`))}</span>
|
|
140
141
|
</div>`;
|
|
141
142
|
}).join('');
|
|
143
|
+
return `${fields}${state.channel === 'slack'
|
|
144
|
+
? `<p class="onboarding-guide">${escapeHtml(t('onboarding.slackExistingApp'))}</p>`
|
|
145
|
+
: ''}`;
|
|
142
146
|
}
|
|
143
147
|
if (state.step === 3) {
|
|
144
148
|
const status = validating
|
|
@@ -194,6 +198,13 @@ function render(): void {
|
|
|
194
198
|
${state.error ? escapeHtml(t(`onboarding.error.${state.error}`)) : ''}
|
|
195
199
|
${state.missingScopes.length ? `<span class="onboarding-scopes">${escapeHtml(state.missingScopes.join(', '))}</span>` : ''}
|
|
196
200
|
</div>
|
|
201
|
+
<div class="onboarding-capability-warning" role="status" style="display:${state.missingCapabilities.length ? '' : 'none'}">
|
|
202
|
+
${state.missingCapabilities.length
|
|
203
|
+
? escapeHtml(t('onboarding.warning.missingCapabilities', {
|
|
204
|
+
capabilities: state.missingCapabilities.join(', '),
|
|
205
|
+
}))
|
|
206
|
+
: ''}
|
|
207
|
+
</div>
|
|
197
208
|
<div class="onboarding-actions onboarding-footer">${footer(state)}</div>
|
|
198
209
|
</div>`;
|
|
199
210
|
|
|
@@ -273,7 +284,14 @@ async function runValidation(): Promise<void> {
|
|
|
273
284
|
const generation = flowGeneration;
|
|
274
285
|
validating = true;
|
|
275
286
|
render();
|
|
276
|
-
const res = await api<{
|
|
287
|
+
const res = await api<{
|
|
288
|
+
ok?: boolean;
|
|
289
|
+
identity?: string;
|
|
290
|
+
teamId?: string;
|
|
291
|
+
error?: string;
|
|
292
|
+
missing?: string[];
|
|
293
|
+
missingCapabilities?: string[];
|
|
294
|
+
}>(
|
|
277
295
|
'/api/channels/validate',
|
|
278
296
|
{
|
|
279
297
|
method: 'POST',
|
|
@@ -74,7 +74,9 @@ export function formatUserPrompt(text: string): string {
|
|
|
74
74
|
const userMsg = userMsgMatch ? ' ' + userMsgMatch[1].trim() : '';
|
|
75
75
|
return `📎 [${count} files]${userMsg}`;
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
// ja/zh 변형이 빠지면 해당 로케일 사용자는 인라인 미리보기를 잃고 원문이
|
|
78
|
+
// 그대로 노출된다. zh 는 전각 콜론(:)을 쓰므로 구분자를 일반화한다.
|
|
79
|
+
const fileMatch = text.match(/^\[(?:사용자가 파일을 보냈습니다|사용자가 이미지를 보냈습니다|사용자가 동영상을 보냈습니다|User sent a file|User sent an image|User sent a video|ユーザーがファイルを送信しました|ユーザーが画像を送信しました|ユーザーが動画を送信しました|用户发送了文件|用户发送了图片|用户发送了视频)[::]\s*([^\]]+)\]/);
|
|
78
80
|
if (fileMatch) {
|
|
79
81
|
const fullPath = fileMatch[1];
|
|
80
82
|
const fileName = fullPath.split('/').pop() || fullPath;
|
|
@@ -2,6 +2,7 @@ import { api } from '../api.js';
|
|
|
2
2
|
import { getVirtualScroll } from '../virtual-scroll.js';
|
|
3
3
|
import { escapeHtml } from '../render.js';
|
|
4
4
|
import { bootMessageQuery } from './message-history.js';
|
|
5
|
+
import { withCurrentSessionQuery } from './session-hub.js';
|
|
5
6
|
|
|
6
7
|
const IS_IFRAME = window.parent !== window;
|
|
7
8
|
|
|
@@ -111,7 +112,7 @@ function buildMessageIndexMap(): void {
|
|
|
111
112
|
|
|
112
113
|
async function runSearch(q: string, resultsEl: HTMLElement, countEl: HTMLElement): Promise<void> {
|
|
113
114
|
lastQuery = q;
|
|
114
|
-
const data = await api<SearchResult[]>(`/api/messages/search?q=${encodeURIComponent(q)}&limit=20`);
|
|
115
|
+
const data = await api<SearchResult[]>(withCurrentSessionQuery(`/api/messages/search?q=${encodeURIComponent(q)}&limit=20`));
|
|
115
116
|
if (!data || lastQuery !== q) return;
|
|
116
117
|
countEl.textContent = data.length > 0 ? `${data.length} found` : 'no results';
|
|
117
118
|
if (data.length === 0) {
|
|
@@ -16,6 +16,8 @@ import { tryCommandInfo } from './command-info.js';
|
|
|
16
16
|
import { isChatNearBottom, markFollowingBottom, reconcileChatBottomAfterLayout } from './chat-scroll.js';
|
|
17
17
|
import { copyText } from './copy-text.js';
|
|
18
18
|
import { isLocalPreviewRelayOrigin, previewParentOrigin } from '../preview-parent-origin.js';
|
|
19
|
+
import { canSendFromCurrentView, showReadOnlySwitchAffordance, withCurrentSessionBody } from './session-hub.js';
|
|
20
|
+
import { mediaKindFromPath, type MediaKind } from '../../../lib/media-kind.js';
|
|
19
21
|
|
|
20
22
|
let activeObjectURLs: string[] = [];
|
|
21
23
|
|
|
@@ -50,13 +52,25 @@ function getCommandTimeoutMs(text: string): number {
|
|
|
50
52
|
return /^\/compact(?:\s|$)/i.test(String(text || '').trim()) ? 5 * 60 * 1000 : 10_000;
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
// 첨부 프롬프트는 파일 종류를 유지해야 한다. 고정 "파일" 문구만 쓰면 이미지를
|
|
56
|
+
// 올려도 에이전트가 Read 도구로 열려다 실패한다 (devlog 260806_slack_multifile_ingest/001 §4 D2).
|
|
57
|
+
const ATTACHMENT_KEY: Record<MediaKind, string> = {
|
|
58
|
+
image: 'chat.file.sentImage',
|
|
59
|
+
video: 'chat.file.sentVideo',
|
|
60
|
+
file: 'chat.file.sent',
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
function attachmentLine(path: string): string {
|
|
64
|
+
return t(ATTACHMENT_KEY[mediaKindFromPath(path)], { path });
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
function buildAttachmentPrompt(paths: string[], text = ''): string {
|
|
54
|
-
const prompt = paths.map(
|
|
68
|
+
const prompt = paths.map(attachmentLine).join('\n');
|
|
55
69
|
return text ? `${prompt}${t('chat.file.sentWithMsg', { text })}` : prompt;
|
|
56
70
|
}
|
|
57
71
|
|
|
58
72
|
function buildSlashCommandAttachmentText(text: string, paths: string[]): string {
|
|
59
|
-
const fileContext = paths.map(
|
|
73
|
+
const fileContext = paths.map(attachmentLine).join('\n');
|
|
60
74
|
return fileContext ? `${text}\n\n${fileContext}` : text;
|
|
61
75
|
}
|
|
62
76
|
|
|
@@ -91,7 +105,13 @@ function sendPreviewMessageViaParent(prompt: string): Promise<MessagePostResult
|
|
|
91
105
|
const timeout = window.setTimeout(() => settle(null), PREVIEW_SEND_RELAY_TIMEOUT_MS);
|
|
92
106
|
window.addEventListener('message', onMessage);
|
|
93
107
|
try {
|
|
94
|
-
|
|
108
|
+
// The session travels with the relay too. Without it the manager forwards a
|
|
109
|
+
// bare prompt and the instance writes to whichever session is globally
|
|
110
|
+
// active, which is not the one this preview is showing (072 §1.1).
|
|
111
|
+
window.parent.postMessage(
|
|
112
|
+
withCurrentSessionBody({ type: 'jaw-preview-send-message', requestId, prompt }),
|
|
113
|
+
targetOrigin,
|
|
114
|
+
);
|
|
95
115
|
} catch {
|
|
96
116
|
settle(null);
|
|
97
117
|
}
|
|
@@ -105,7 +125,7 @@ async function postChatMessage(prompt: string): Promise<MessagePostResult> {
|
|
|
105
125
|
const res = await fetch(`${API_BASE}/api/message`, {
|
|
106
126
|
method: 'POST',
|
|
107
127
|
headers: { 'Content-Type': 'application/json' },
|
|
108
|
-
body: JSON.stringify({ prompt }),
|
|
128
|
+
body: JSON.stringify(withCurrentSessionBody({ prompt })),
|
|
109
129
|
});
|
|
110
130
|
const data: MessageResult = await res.json().catch(() => ({}));
|
|
111
131
|
return { ok: res.ok, status: res.status, data };
|
|
@@ -133,7 +153,7 @@ async function postSlashCommand(text: string): Promise<{ ok: boolean; status: nu
|
|
|
133
153
|
'Accept-Language': locale,
|
|
134
154
|
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
|
135
155
|
},
|
|
136
|
-
body: JSON.stringify({ text, locale }),
|
|
156
|
+
body: JSON.stringify(withCurrentSessionBody({ text, locale })),
|
|
137
157
|
signal,
|
|
138
158
|
});
|
|
139
159
|
if (timer) clearTimeout(timer);
|
|
@@ -155,7 +175,7 @@ async function handleSlashCommandResponse(
|
|
|
155
175
|
}
|
|
156
176
|
addMessage('user', originalText);
|
|
157
177
|
upsertMessage({ role: 'user', content: originalText, timestamp: Date.now() });
|
|
158
|
-
await apiJson('/api/message', 'POST', { prompt: originalText });
|
|
178
|
+
await apiJson('/api/message', 'POST', withCurrentSessionBody({ prompt: originalText }));
|
|
159
179
|
return;
|
|
160
180
|
}
|
|
161
181
|
if (!response.ok && !result?.text) throw new Error(`HTTP ${response.status}`);
|
|
@@ -167,7 +187,7 @@ async function handleSlashCommandResponse(
|
|
|
167
187
|
}
|
|
168
188
|
if (result?.text || result?.recovery) addSystemMsg(renderCommandRecovery(result), '', result.type);
|
|
169
189
|
if (result?.steerPrompt) {
|
|
170
|
-
await apiJson('/api/message', 'POST', { prompt: result.steerPrompt });
|
|
190
|
+
await apiJson('/api/message', 'POST', withCurrentSessionBody({ prompt: result.steerPrompt }));
|
|
171
191
|
}
|
|
172
192
|
}
|
|
173
193
|
|
|
@@ -216,7 +236,7 @@ document.addEventListener('click', async (event) => {
|
|
|
216
236
|
|
|
217
237
|
// In-flight guard: prevents double-send from rapid clicks / Enter-bursts while the
|
|
218
238
|
// POST to /api/message is outstanding. Server-side dedup in gateway.ts is the
|
|
219
|
-
// second line of defense. See devlog/
|
|
239
|
+
// second line of defense. See devlog/_fin/260417_message_duplication/.
|
|
220
240
|
let __chatSending = false;
|
|
221
241
|
|
|
222
242
|
export type SendSource = 'button' | 'enter' | 'cmd-execute';
|
|
@@ -226,12 +246,24 @@ export async function sendMessage(source: SendSource = 'enter'): Promise<void> {
|
|
|
226
246
|
const btn = document.getElementById('btnSend');
|
|
227
247
|
if (!input || !btn) return;
|
|
228
248
|
|
|
249
|
+
const text = input.value.trim();
|
|
250
|
+
// A stop-mode button click is not a message send, so it carries no command
|
|
251
|
+
// text and the read-only guard must judge it on its own. Every other path —
|
|
252
|
+
// including an ordinary button click on `/switch 1` — must pass the text,
|
|
253
|
+
// or the escape commands that let a user leave a read-only session would be
|
|
254
|
+
// rejected through the button while still working via Enter.
|
|
255
|
+
const isStopClick = source === 'button' && btn.classList.contains('stop-mode');
|
|
256
|
+
if (!canSendFromCurrentView(isStopClick ? '' : text)) {
|
|
257
|
+
showReadOnlySwitchAffordance();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
229
261
|
// Stop-mode click policy (devlog 260501_chat_pause_and_unread_badge):
|
|
230
262
|
// - any stop-mode button click → fire /api/stop and return.
|
|
231
|
-
// /api/stop
|
|
232
|
-
// intent ("실제로 정지가 안돼").
|
|
233
|
-
// text and attachments — typing is
|
|
234
|
-
// just-killed run.
|
|
263
|
+
// /api/stop stops this session's run when the tab names one, and every
|
|
264
|
+
// run otherwise, which is the user's intent ("실제로 정지가 안돼").
|
|
265
|
+
// The early `return` preserves typed text and attachments — typing is
|
|
266
|
+
// never auto-steered into the just-killed run.
|
|
235
267
|
// - Enter key and slash-command execute do NOT enter this branch
|
|
236
268
|
// (source !== 'button'), so they keep their normal behavior even
|
|
237
269
|
// while the agent is busy.
|
|
@@ -240,14 +272,16 @@ export async function sendMessage(source: SendSource = 'enter'): Promise<void> {
|
|
|
240
272
|
// SendSource keeps detection deterministic across cross-frame clicks.
|
|
241
273
|
const stopByExplicitButton = source === 'button';
|
|
242
274
|
if (btn.classList.contains('stop-mode') && stopByExplicitButton) {
|
|
243
|
-
|
|
275
|
+
// On /:seq this stops only that session. Elsewhere the body carries no
|
|
276
|
+
// session and the server falls back to stopping everything, which is what
|
|
277
|
+
// the single-session view has always done.
|
|
278
|
+
apiFire('/api/stop', 'POST', withCurrentSessionBody({}));
|
|
244
279
|
return;
|
|
245
280
|
}
|
|
246
281
|
|
|
247
282
|
// Double-submit guard: if a previous send is still in flight, drop this call.
|
|
248
283
|
if (__chatSending) return;
|
|
249
284
|
|
|
250
|
-
const text = input.value.trim();
|
|
251
285
|
if (!text && !state.attachedFiles.length) return;
|
|
252
286
|
clearUnreadResponses();
|
|
253
287
|
|
|
@@ -298,7 +332,7 @@ export async function sendMessage(source: SendSource = 'enter'): Promise<void> {
|
|
|
298
332
|
const commandText = buildSlashCommandAttachmentText(text, paths);
|
|
299
333
|
const commandResponse = await postSlashCommand(commandText);
|
|
300
334
|
await handleSlashCommandResponse(commandText, commandResponse, async () => {
|
|
301
|
-
await apiJson('/api/message', 'POST', { prompt });
|
|
335
|
+
await apiJson('/api/message', 'POST', withCurrentSessionBody({ prompt }));
|
|
302
336
|
});
|
|
303
337
|
} catch (err) {
|
|
304
338
|
addSystemMsg(t('chat.cmd.fail', { msg: (err as Error).message }), '', 'error');
|
|
@@ -307,7 +341,7 @@ export async function sendMessage(source: SendSource = 'enter'): Promise<void> {
|
|
|
307
341
|
}
|
|
308
342
|
return;
|
|
309
343
|
}
|
|
310
|
-
await apiJson('/api/message', 'POST', { prompt });
|
|
344
|
+
await apiJson('/api/message', 'POST', withCurrentSessionBody({ prompt }));
|
|
311
345
|
} catch (err) {
|
|
312
346
|
addSystemMsg(t('chat.file.uploadFail', { msg: (err as Error).message }));
|
|
313
347
|
clearAttachedFiles();
|
|
@@ -539,6 +573,10 @@ export function initDragDrop(): void {
|
|
|
539
573
|
|
|
540
574
|
/** Upload recorded voice blob, combine with pending text/files, send unified message */
|
|
541
575
|
export async function sendVoiceToServer(blob: Blob, ext: string, mime: string): Promise<void> {
|
|
576
|
+
if (!canSendFromCurrentView()) {
|
|
577
|
+
showReadOnlySwitchAffordance();
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
542
580
|
const input = document.getElementById('chatInput') as HTMLTextAreaElement | null;
|
|
543
581
|
const pendingText = input?.value.trim() || '';
|
|
544
582
|
const pendingFiles = [...state.attachedFiles];
|
|
@@ -583,12 +621,12 @@ export async function sendVoiceToServer(blob: Blob, ext: string, mime: string):
|
|
|
583
621
|
// Step 3: Build combined prompt and send via /api/message
|
|
584
622
|
const promptParts: string[] = [];
|
|
585
623
|
for (const p of filePaths) {
|
|
586
|
-
promptParts.push(
|
|
624
|
+
promptParts.push(attachmentLine(p));
|
|
587
625
|
}
|
|
588
626
|
promptParts.push(`🎤 ${sttResult.text}`);
|
|
589
627
|
if (pendingText) promptParts.push(pendingText);
|
|
590
628
|
|
|
591
|
-
await apiJson('/api/message', 'POST', { prompt: promptParts.join('\n') });
|
|
629
|
+
await apiJson('/api/message', 'POST', withCurrentSessionBody({ prompt: promptParts.join('\n') }));
|
|
592
630
|
} catch (err) {
|
|
593
631
|
addSystemMsg(t('voice.sttFail', { msg: (err as Error).message }), '', 'error');
|
|
594
632
|
}
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
type NormalizedSpec,
|
|
9
9
|
} from './elicitation-state.js';
|
|
10
10
|
import { escapeHtml } from '../render/html.js';
|
|
11
|
+
import { canSendFromCurrentView, showReadOnlySwitchAffordance } from './session-hub.js';
|
|
12
|
+
import { t } from './i18n.js';
|
|
11
13
|
|
|
12
14
|
type ElicitationKind = 'elicitation' | 'choice-buttons';
|
|
13
15
|
|
|
@@ -262,6 +264,19 @@ function createInputEvent(input: Element, type: string): Event {
|
|
|
262
264
|
|
|
263
265
|
function submitComposedPrompt(block: HTMLElement, state: ElicitationState): void {
|
|
264
266
|
if (block.dataset['elicitationState'] === SUBMITTING_STATE) return;
|
|
267
|
+
if (!canSendFromCurrentView()) {
|
|
268
|
+
showReadOnlySwitchAffordance();
|
|
269
|
+
block.classList.add('elicitation-error');
|
|
270
|
+
let notice = block.querySelector<HTMLElement>('.elicitation-readonly-notice');
|
|
271
|
+
if (!notice) {
|
|
272
|
+
notice = document.createElement('div');
|
|
273
|
+
notice.className = 'elicitation-readonly-notice';
|
|
274
|
+
notice.setAttribute('role', 'status');
|
|
275
|
+
block.appendChild(notice);
|
|
276
|
+
}
|
|
277
|
+
notice.textContent = t('sessionReadonly.elicitationRejected');
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
265
280
|
block.dataset['elicitationState'] = SUBMITTING_STATE;
|
|
266
281
|
const input = document.getElementById('chatInput') as HTMLTextAreaElement | HTMLInputElement | null;
|
|
267
282
|
if (!input) {
|
|
@@ -223,3 +223,37 @@ export async function clearCache(): Promise<void> {
|
|
|
223
223
|
console.warn('[idb-cache] clearCache failed:', e);
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
+
|
|
227
|
+
// Clearing one session's screen must not erase another session's offline fallback:
|
|
228
|
+
// with several tabs open, a global wipe makes every other tab re-fetch its whole
|
|
229
|
+
// history for a clear it did not ask for (072 §1.3a).
|
|
230
|
+
//
|
|
231
|
+
// It takes no scope on purpose. This store is keyed by location and working directory
|
|
232
|
+
// (message-history.ts), which is a different namespace from the execution scopes the
|
|
233
|
+
// server puts on events, and a caller passing one of those would name a key that was
|
|
234
|
+
// never written and silently delete nothing.
|
|
235
|
+
export async function clearScopedCache(): Promise<void> {
|
|
236
|
+
const targetScope = currentScope;
|
|
237
|
+
if (!targetScope) {
|
|
238
|
+
await clearCache();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
const db = await openDB();
|
|
243
|
+
const tx = db.transaction(STORE, 'readwrite');
|
|
244
|
+
const store = tx.objectStore(STORE);
|
|
245
|
+
const cursorReq = store.index('scope').openCursor(IDBKeyRange.only(targetScope));
|
|
246
|
+
cursorReq.onsuccess = () => {
|
|
247
|
+
const cursor = cursorReq.result;
|
|
248
|
+
if (!cursor) return;
|
|
249
|
+
cursor.delete();
|
|
250
|
+
cursor.continue();
|
|
251
|
+
};
|
|
252
|
+
await new Promise<void>((resolve, reject) => {
|
|
253
|
+
tx.oncomplete = () => resolve();
|
|
254
|
+
tx.onerror = () => reject(tx.error);
|
|
255
|
+
});
|
|
256
|
+
} catch (e) {
|
|
257
|
+
console.warn('[idb-cache] clearScopedCache failed:', e);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -21,6 +21,7 @@ import { normalizeMessageToolLog, parseToolLog, toProcessSteps, type MessageItem
|
|
|
21
21
|
import { canFollowAfterRestore, ensureScrollTracking, markFollowingBottom, settleChatBottomAfterInitialLoad } from './chat-scroll.js';
|
|
22
22
|
import { updateStatMsgs } from './ui-status.js';
|
|
23
23
|
import { seedCompletedElicitationsFromMessages } from './elicitation-state.js';
|
|
24
|
+
import { withCurrentSessionQuery } from './session-hub.js';
|
|
24
25
|
|
|
25
26
|
export function buildVirtualHistoryItems(msgs: MessageItem[]): VirtualItem[] {
|
|
26
27
|
return msgs.map((m, index) => buildLazyVirtualMessageItem(normalizeMessageToolLog(m), index));
|
|
@@ -37,7 +38,7 @@ export function buildVirtualHistoryItems(msgs: MessageItem[]): VirtualItem[] {
|
|
|
37
38
|
const BOOT_MESSAGE_WINDOW = 3000;
|
|
38
39
|
|
|
39
40
|
export function bootMessageQuery(): string {
|
|
40
|
-
return `?limit=${BOOT_MESSAGE_WINDOW}
|
|
41
|
+
return withCurrentSessionQuery(`?limit=${BOOT_MESSAGE_WINDOW}`);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
function normalizeMessageScopePart(value: string | null | undefined): string {
|