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
|
@@ -302,6 +302,103 @@ h2 { font-size: 13px; }
|
|
|
302
302
|
.quick-btn.action-open { text-decoration: none; color: var(--text-secondary); }
|
|
303
303
|
.quick-btn.action-open:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--border-subtle)); }
|
|
304
304
|
.quick-btn:disabled, .quick-btn.is-disabled { opacity: 0.35; pointer-events: none; }
|
|
305
|
+
.quick-btn.action-sessions[aria-expanded="true"] {
|
|
306
|
+
color: var(--accent);
|
|
307
|
+
border-color: color-mix(in srgb, var(--accent) 40%, var(--border-subtle));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* ─── Active-row session disclosure (devlog 260806 D2) ─── */
|
|
311
|
+
.instance-session-list {
|
|
312
|
+
display: grid;
|
|
313
|
+
gap: 2px;
|
|
314
|
+
margin: -2px 0 8px;
|
|
315
|
+
padding: 6px;
|
|
316
|
+
border: 1px solid var(--border-subtle);
|
|
317
|
+
border-radius: 8px;
|
|
318
|
+
background: var(--row-bg);
|
|
319
|
+
animation: session-list-in 0.12s ease;
|
|
320
|
+
}
|
|
321
|
+
@keyframes session-list-in {
|
|
322
|
+
from { opacity: 0; transform: translateY(-2px); }
|
|
323
|
+
to { opacity: 1; transform: none; }
|
|
324
|
+
}
|
|
325
|
+
@media (prefers-reduced-motion: reduce) {
|
|
326
|
+
.instance-session-list { animation: none; }
|
|
327
|
+
}
|
|
328
|
+
.instance-session-row {
|
|
329
|
+
display: flex;
|
|
330
|
+
align-items: center;
|
|
331
|
+
justify-content: space-between;
|
|
332
|
+
gap: 8px;
|
|
333
|
+
width: 100%;
|
|
334
|
+
padding: 5px 8px;
|
|
335
|
+
border: 0;
|
|
336
|
+
border-radius: 6px;
|
|
337
|
+
background: transparent;
|
|
338
|
+
color: var(--text-secondary);
|
|
339
|
+
font-size: 12px;
|
|
340
|
+
text-align: left;
|
|
341
|
+
cursor: pointer;
|
|
342
|
+
}
|
|
343
|
+
.instance-session-row:hover:not(:disabled) { background: var(--row-bg-hover); color: var(--text-primary); }
|
|
344
|
+
.instance-session-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
345
|
+
.instance-session-row:disabled { cursor: default; opacity: 0.6; }
|
|
346
|
+
.instance-session-row.is-active {
|
|
347
|
+
color: var(--text-primary);
|
|
348
|
+
box-shadow: inset 3px 0 0 var(--accent);
|
|
349
|
+
background: color-mix(in srgb, var(--accent) 5%, transparent);
|
|
350
|
+
}
|
|
351
|
+
.instance-session-title {
|
|
352
|
+
min-width: 0;
|
|
353
|
+
display: flex;
|
|
354
|
+
align-items: baseline;
|
|
355
|
+
gap: 6px;
|
|
356
|
+
overflow: hidden;
|
|
357
|
+
text-overflow: ellipsis;
|
|
358
|
+
white-space: nowrap;
|
|
359
|
+
}
|
|
360
|
+
.session-source-badge {
|
|
361
|
+
flex-shrink: 0;
|
|
362
|
+
padding: 1px 5px;
|
|
363
|
+
border: 1px solid var(--border-subtle);
|
|
364
|
+
border-radius: 999px;
|
|
365
|
+
font-size: 10px;
|
|
366
|
+
color: var(--text-tertiary, var(--text-secondary));
|
|
367
|
+
text-transform: lowercase;
|
|
368
|
+
}
|
|
369
|
+
.instance-session-meta {
|
|
370
|
+
flex-shrink: 0;
|
|
371
|
+
font-size: 11px;
|
|
372
|
+
color: var(--text-tertiary, var(--text-secondary));
|
|
373
|
+
font-variant-numeric: tabular-nums;
|
|
374
|
+
}
|
|
375
|
+
.instance-session-error, .instance-session-empty {
|
|
376
|
+
padding: 5px 8px;
|
|
377
|
+
font-size: 11px;
|
|
378
|
+
color: var(--text-secondary);
|
|
379
|
+
}
|
|
380
|
+
.instance-session-error {
|
|
381
|
+
display: flex;
|
|
382
|
+
align-items: center;
|
|
383
|
+
justify-content: space-between;
|
|
384
|
+
gap: 8px;
|
|
385
|
+
color: var(--status-error);
|
|
386
|
+
}
|
|
387
|
+
.instance-session-retry {
|
|
388
|
+
flex: 0 0 auto;
|
|
389
|
+
padding: 2px 7px;
|
|
390
|
+
border: 1px solid var(--border-subtle);
|
|
391
|
+
border-radius: 5px;
|
|
392
|
+
background: var(--row-bg);
|
|
393
|
+
color: var(--text-secondary);
|
|
394
|
+
font: inherit;
|
|
395
|
+
cursor: pointer;
|
|
396
|
+
}
|
|
397
|
+
.instance-session-retry:hover {
|
|
398
|
+
color: var(--text-primary);
|
|
399
|
+
background: var(--surface-raised);
|
|
400
|
+
}
|
|
401
|
+
.instance-session-retry:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
305
402
|
.instance-row-title { min-width: 0; display: grid; gap: 3px; }
|
|
306
403
|
.instance-row-title-line {
|
|
307
404
|
min-width: 0;
|
|
@@ -34,7 +34,17 @@ export function validateImportPayload(text: string): { ok: true; value: Record<s
|
|
|
34
34
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
35
35
|
return { ok: false, error: 'Import payload must be a JSON object.' };
|
|
36
36
|
}
|
|
37
|
-
return { ok: true, value: parsed as Record<string, unknown> };
|
|
37
|
+
return { ok: true, value: stripServerOwnedSettingsFields(parsed as Record<string, unknown>) };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function stripServerOwnedSettingsFields(settings: Record<string, unknown>): Record<string, unknown> {
|
|
41
|
+
const {
|
|
42
|
+
settingsSchemaVersion: _schema,
|
|
43
|
+
runtimeDefaultMigration: _migration,
|
|
44
|
+
multiSessionDefaultMigration: _sessionMigration,
|
|
45
|
+
...userOwned
|
|
46
|
+
} = settings;
|
|
47
|
+
return userOwned;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
export default function AdvancedExport({ port, client, triggerDownload }: ExportImportProps) {
|
|
@@ -55,7 +65,7 @@ export default function AdvancedExport({ port, client, triggerDownload }: Export
|
|
|
55
65
|
const onExport = useCallback(() => {
|
|
56
66
|
if (state.kind !== 'ready') return;
|
|
57
67
|
const filename = `cli-jaw-settings-${port}.json`;
|
|
58
|
-
download(filename, JSON.stringify(state.data, null, 2));
|
|
68
|
+
download(filename, JSON.stringify(stripServerOwnedSettingsFields(state.data), null, 2));
|
|
59
69
|
}, [state, port, download]);
|
|
60
70
|
|
|
61
71
|
const onImport = useCallback(async () => {
|
|
@@ -35,6 +35,8 @@ import {
|
|
|
35
35
|
splitAgentSaveBundle,
|
|
36
36
|
type AgentSettingsSnapshot,
|
|
37
37
|
} from './components/agent/agent-save';
|
|
38
|
+
import { SettingsRequestError } from '../settings-client';
|
|
39
|
+
import { describeError } from '../components/error-normalize';
|
|
38
40
|
|
|
39
41
|
export { splitAgentSaveBundle };
|
|
40
42
|
|
|
@@ -44,8 +46,30 @@ type AgentSnapshot = AgentSettingsSnapshot & {
|
|
|
44
46
|
permissions?: 'auto' | string[] | unknown;
|
|
45
47
|
perCli?: Record<string, PerCliEntry>;
|
|
46
48
|
activeOverrides?: Record<string, ActiveOverride>;
|
|
49
|
+
runtimeDefaultMigration?: {
|
|
50
|
+
id: string;
|
|
51
|
+
state: 'pending' | 'accepted' | 'kept' | 'already-codex-app';
|
|
52
|
+
fromCli: string;
|
|
53
|
+
toCli: 'codex-app';
|
|
54
|
+
} | null;
|
|
47
55
|
};
|
|
48
56
|
|
|
57
|
+
type CliStatusInfo = {
|
|
58
|
+
available: boolean | null;
|
|
59
|
+
capabilityReady: boolean | null;
|
|
60
|
+
probeState: 'checking' | 'fresh' | 'stale';
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function conflictSettingsFromError(error: unknown): AgentSnapshot | null {
|
|
64
|
+
if (!(error instanceof SettingsRequestError) || error.status !== 409) return null;
|
|
65
|
+
try {
|
|
66
|
+
const payload = JSON.parse(error.detail) as { settings?: AgentSnapshot };
|
|
67
|
+
return payload.settings ?? null;
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
49
73
|
type FlushSnapshot = {
|
|
50
74
|
cli?: string;
|
|
51
75
|
model?: string;
|
|
@@ -80,6 +104,11 @@ export default function Agent({ port, client, dirty, registerSave }: SettingsPag
|
|
|
80
104
|
const [employeeLoading, setEmployeeLoading] = useState(true);
|
|
81
105
|
const [employeeError, setEmployeeError] = useState<string | null>(null);
|
|
82
106
|
const [cliMeta, setCliMeta] = useState<Record<string, CliMeta> | null>(null);
|
|
107
|
+
const [cliStatus, setCliStatus] = useState<Record<string, CliStatusInfo>>({});
|
|
108
|
+
const [migrationBusy, setMigrationBusy] = useState(false);
|
|
109
|
+
const [migrationError, setMigrationError] = useState<string | null>(null);
|
|
110
|
+
const [sessionMigrationBusy, setSessionMigrationBusy] = useState(false);
|
|
111
|
+
const [sessionMigrationError, setSessionMigrationError] = useState<string | null>(null);
|
|
83
112
|
|
|
84
113
|
const loadCliMeta = useCallback(async () => {
|
|
85
114
|
try {
|
|
@@ -93,6 +122,11 @@ export default function Agent({ port, client, dirty, registerSave }: SettingsPag
|
|
|
93
122
|
}
|
|
94
123
|
}, [client]);
|
|
95
124
|
|
|
125
|
+
const loadCliStatus = useCallback(async () => {
|
|
126
|
+
try { setCliStatus(await client.get<Record<string, CliStatusInfo>>('/api/cli-status')); }
|
|
127
|
+
catch { setCliStatus({}); }
|
|
128
|
+
}, [client]);
|
|
129
|
+
|
|
96
130
|
const loadFlush = useCallback(async () => {
|
|
97
131
|
setFlushLoading(true);
|
|
98
132
|
setFlushError(null);
|
|
@@ -125,9 +159,10 @@ export default function Agent({ port, client, dirty, registerSave }: SettingsPag
|
|
|
125
159
|
|
|
126
160
|
useEffect(() => {
|
|
127
161
|
void loadCliMeta();
|
|
162
|
+
void loadCliStatus();
|
|
128
163
|
void loadFlush();
|
|
129
164
|
void loadEmployees();
|
|
130
|
-
}, [loadCliMeta, loadEmployees, loadFlush]);
|
|
165
|
+
}, [loadCliMeta, loadCliStatus, loadEmployees, loadFlush]);
|
|
131
166
|
|
|
132
167
|
useEffect(() => {
|
|
133
168
|
if (state.kind !== 'ready') return;
|
|
@@ -199,6 +234,58 @@ export default function Agent({ port, client, dirty, registerSave }: SettingsPag
|
|
|
199
234
|
: effortChoicesForModel(activeMeta, draft.model);
|
|
200
235
|
const workingDirError = draft.workingDir.trim() ? null : 'Required';
|
|
201
236
|
|
|
237
|
+
const resolveMigration = useCallback(async (action: 'accept' | 'keep') => {
|
|
238
|
+
setMigrationBusy(true);
|
|
239
|
+
setMigrationError(null);
|
|
240
|
+
try {
|
|
241
|
+
const response = await client.post<AgentSnapshot | { data?: AgentSnapshot; settings?: AgentSnapshot }>(
|
|
242
|
+
'/api/settings/runtime-default-migration',
|
|
243
|
+
{ action },
|
|
244
|
+
);
|
|
245
|
+
let next: AgentSnapshot;
|
|
246
|
+
if ('settings' in response && response.settings) next = response.settings as AgentSnapshot;
|
|
247
|
+
else if ('data' in response && response.data) next = response.data as AgentSnapshot;
|
|
248
|
+
else next = response as AgentSnapshot;
|
|
249
|
+
setData(next);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
const conflictSettings = conflictSettingsFromError(error);
|
|
252
|
+
if (conflictSettings) {
|
|
253
|
+
setData(conflictSettings);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
setMigrationError(describeError(error));
|
|
257
|
+
} finally {
|
|
258
|
+
setMigrationBusy(false);
|
|
259
|
+
}
|
|
260
|
+
}, [client, setData]);
|
|
261
|
+
|
|
262
|
+
// Same shape, its own endpoint and its own busy state, because a v1 install has both
|
|
263
|
+
// migrations pending and answering one must not look like answering the other.
|
|
264
|
+
const resolveSessionMigration = useCallback(async (action: 'accept' | 'keep') => {
|
|
265
|
+
setSessionMigrationBusy(true);
|
|
266
|
+
setSessionMigrationError(null);
|
|
267
|
+
try {
|
|
268
|
+
const response = await client.post<AgentSnapshot | { data?: AgentSnapshot; settings?: AgentSnapshot }>(
|
|
269
|
+
'/api/settings/multi-session-default-migration',
|
|
270
|
+
{ action },
|
|
271
|
+
);
|
|
272
|
+
let next: AgentSnapshot;
|
|
273
|
+
if ('settings' in response && response.settings) next = response.settings as AgentSnapshot;
|
|
274
|
+
else if ('data' in response && response.data) next = response.data as AgentSnapshot;
|
|
275
|
+
else next = response as AgentSnapshot;
|
|
276
|
+
setData(next);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
const conflictSettings = conflictSettingsFromError(error);
|
|
279
|
+
if (conflictSettings) {
|
|
280
|
+
setData(conflictSettings);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
setSessionMigrationError(describeError(error));
|
|
284
|
+
} finally {
|
|
285
|
+
setSessionMigrationBusy(false);
|
|
286
|
+
}
|
|
287
|
+
}, [client, setData]);
|
|
288
|
+
|
|
202
289
|
if (state.kind === 'loading') return <PageLoading />;
|
|
203
290
|
if (state.kind === 'offline') return <PageOffline port={port} />;
|
|
204
291
|
if (state.kind === 'error') return <PageError message={state.message} />;
|
|
@@ -221,6 +308,31 @@ export default function Agent({ port, client, dirty, registerSave }: SettingsPag
|
|
|
221
308
|
void onSave();
|
|
222
309
|
}}
|
|
223
310
|
>
|
|
311
|
+
{settingsData.runtimeDefaultMigration?.state === 'pending' ? (
|
|
312
|
+
<div className="settings-inline-notice" role="status">
|
|
313
|
+
<strong>기본 런타임 변경 안내</strong>
|
|
314
|
+
<p>기존 선택은 유지됩니다. Codex App으로 전환하거나 현재 런타임을 계속 사용할 수 있습니다.</p>
|
|
315
|
+
<div className="settings-inline-actions">
|
|
316
|
+
<button type="button" className="settings-action settings-action-save" disabled={migrationBusy} onClick={() => void resolveMigration('accept')}>Codex App 사용</button>
|
|
317
|
+
<button type="button" className="settings-action settings-action-secondary" disabled={migrationBusy} onClick={() => void resolveMigration('keep')}>현재 런타임 유지</button>
|
|
318
|
+
</div>
|
|
319
|
+
{migrationError ? <span className="settings-field-error" role="alert">{migrationError}</span> : null}
|
|
320
|
+
</div>
|
|
321
|
+
) : null}
|
|
322
|
+
{(settingsData['multiSessionDefaultMigration'] as Record<string, unknown> | undefined)?.['state'] === 'pending' ? (
|
|
323
|
+
<div className="settings-inline-notice" role="status">
|
|
324
|
+
<strong>다중 세션 안내</strong>
|
|
325
|
+
<p>대화 세션을 여러 개 열 수 있습니다. 켜면 동시 실행도 2로 올라가서, 두 번째 세션이 첫 번째가 끝나기를 기다리지 않습니다. 지금 설정은 그대로 유지됩니다.</p>
|
|
326
|
+
<div className="settings-inline-actions">
|
|
327
|
+
<button type="button" className="settings-action settings-action-save" disabled={sessionMigrationBusy} onClick={() => void resolveSessionMigration('accept')}>다중 세션 켜기</button>
|
|
328
|
+
<button type="button" className="settings-action settings-action-secondary" disabled={sessionMigrationBusy} onClick={() => void resolveSessionMigration('keep')}>지금 설정 유지</button>
|
|
329
|
+
</div>
|
|
330
|
+
{sessionMigrationError ? <span className="settings-field-error" role="alert">{sessionMigrationError}</span> : null}
|
|
331
|
+
</div>
|
|
332
|
+
) : null}
|
|
333
|
+
{cliStatus[draft.cli]?.probeState === 'checking' ? (
|
|
334
|
+
<div className="settings-inline-notice" role="status" aria-live="polite">상태 확인 중</div>
|
|
335
|
+
) : null}
|
|
224
336
|
<RuntimeHeader
|
|
225
337
|
cli={draft.cli}
|
|
226
338
|
cliOptions={cliOptions.length > 0 ? cliOptions : [draft.cli || 'claude']}
|
|
@@ -102,7 +102,7 @@ export const CLI_META: Record<string, CliMeta> = {
|
|
|
102
102
|
// parsed by Claude Code (stripped before send, enables 1M context
|
|
103
103
|
// on Fable 5 + Sonnet 5 + Opus 5 + Opus 4.8/4.7/4.6 + Sonnet 4.6). Mirrors getDefaultClaudeChoices()
|
|
104
104
|
// in src/cli/claude-models.ts. Verified via Grok web research
|
|
105
|
-
// 2026-05-01 (devlog/
|
|
105
|
+
// 2026-05-01 (devlog/_fin/260501_claude_model_passthrough/).
|
|
106
106
|
models: [
|
|
107
107
|
'opus',
|
|
108
108
|
'sonnet',
|
|
@@ -111,6 +111,16 @@ fi
|
|
|
111
111
|
echo "Rebuilding better-sqlite3 for bundled Node $NODE_VERSION..."
|
|
112
112
|
while IFS= read -r pkg_json; do
|
|
113
113
|
pkg_dir="$(dirname "$pkg_json")"
|
|
114
|
+
# better-sqlite3 >= 13 is Node-API: it ships prebuilds/ inside the package,
|
|
115
|
+
# has NO scripts.install (`npm run install` dies with "Missing script"), and
|
|
116
|
+
# the prebuild is ABI-independent, so no per-Node rebuild is needed at all.
|
|
117
|
+
# v12 keeps the old install script ("prebuild-install || node-gyp rebuild").
|
|
118
|
+
# The verification step below opens the DB with the bundled Node either way.
|
|
119
|
+
has_install_script="$("$NODE_BIN" -e 'const p=require(process.argv[1]);process.stdout.write(p.scripts&&p.scripts.install?"yes":"no")' "$pkg_json")"
|
|
120
|
+
if [ "$has_install_script" = "no" ]; then
|
|
121
|
+
echo " skip rebuild (v13+ bundled prebuilds): ${pkg_dir#$SIDECAR_DIR/}"
|
|
122
|
+
continue
|
|
123
|
+
fi
|
|
114
124
|
echo " rebuild: ${pkg_dir#$SIDECAR_DIR/}"
|
|
115
125
|
(
|
|
116
126
|
cd "$pkg_dir"
|
|
@@ -126,8 +136,23 @@ done < <(find "$SIDECAR_DIR/node_modules" -path '*/better-sqlite3/package.json'
|
|
|
126
136
|
|
|
127
137
|
echo "Verifying better-sqlite3 opens with bundled Node..."
|
|
128
138
|
"$NODE_BIN" -e "const Database = require('better-sqlite3'); new Database(':memory:').close()" && echo " better-sqlite3 OK" || {
|
|
129
|
-
echo "
|
|
130
|
-
|
|
139
|
+
echo " bundled prebuild failed to load — building from source (v13 build-release)..."
|
|
140
|
+
sidecar_bsql_dir="$SIDECAR_DIR/node_modules/better-sqlite3"
|
|
141
|
+
if [ -d "$sidecar_bsql_dir" ]; then
|
|
142
|
+
(
|
|
143
|
+
cd "$sidecar_bsql_dir"
|
|
144
|
+
PYTHON="$PYTHON_BIN" \
|
|
145
|
+
npm_config_python="$PYTHON_BIN" \
|
|
146
|
+
npm_config_runtime=node \
|
|
147
|
+
npm_config_target="$NODE_VERSION" \
|
|
148
|
+
npm_config_disturl="https://nodejs.org/dist" \
|
|
149
|
+
npm run build-release --foreground-scripts
|
|
150
|
+
)
|
|
151
|
+
fi
|
|
152
|
+
"$NODE_BIN" -e "const Database = require('better-sqlite3'); new Database(':memory:').close()" && echo " better-sqlite3 OK (source build)" || {
|
|
153
|
+
echo "ERROR: better-sqlite3 failed to open with bundled Node"
|
|
154
|
+
exit 1
|
|
155
|
+
}
|
|
131
156
|
}
|
|
132
157
|
|
|
133
158
|
echo "Cleaning up Node extract..."
|
|
@@ -173,5 +198,28 @@ node "$PROJECT_ROOT/scripts/check-electron-sidecar-no-jwc.cjs" --server-root "$S
|
|
|
173
198
|
# Telegram bot could load.
|
|
174
199
|
node "$PROJECT_ROOT/scripts/check-sidecar-smoke.mjs" --server-root "$SIDECAR_DIR"
|
|
175
200
|
|
|
201
|
+
# Sidecar install-state receipt. The sidecar is deliberately built with
|
|
202
|
+
# --ignore-scripts, so postinstall-guard never runs here and its receipt would
|
|
203
|
+
# be absent — which the runtime integrity check would misread as a blocked
|
|
204
|
+
# install and nag every desktop user. This is a controlled build: writing the
|
|
205
|
+
# receipt ourselves, with the sidecar's own package version, is the honest
|
|
206
|
+
# record of what happened.
|
|
207
|
+
echo "Writing sidecar install-state receipt..."
|
|
208
|
+
"$NODE_BIN" -e '
|
|
209
|
+
const fs = require("fs"), path = require("path");
|
|
210
|
+
const root = process.argv[1];
|
|
211
|
+
const packageVersion = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")).version;
|
|
212
|
+
fs.writeFileSync(path.join(root, ".jaw-install-state.json"), JSON.stringify({
|
|
213
|
+
schema: 1,
|
|
214
|
+
state: "completed",
|
|
215
|
+
sidecar: true,
|
|
216
|
+
packageVersion,
|
|
217
|
+
ranAt: new Date().toISOString(),
|
|
218
|
+
node: process.version,
|
|
219
|
+
platform: process.platform,
|
|
220
|
+
arch: process.arch,
|
|
221
|
+
}, null, 2));
|
|
222
|
+
' "$SIDECAR_DIR"
|
|
223
|
+
|
|
176
224
|
echo "=== Sidecar ready ==="
|
|
177
225
|
du -sh "$SIDECAR_DIR"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Burst measurement for the 260806 rate-limit hardening unit (devlog 050).
|
|
2
|
+
// Three sequential phases so before/after runs are deterministic:
|
|
3
|
+
// 0. fetch + validate the Bearer token BEFORE any load (429-impossible here)
|
|
4
|
+
// 1. "sacrificial" lane: 350 unheadered (browser-class) GETs, concurrency 20
|
|
5
|
+
// — exceeds the browser poll budget (300/min) to force the 429 branch
|
|
6
|
+
// 2. "protected" lane: Bearer (cli-class) chat-sessions/switch/goal traffic
|
|
7
|
+
// — must see zero 429s after hardening; deterministically 429s before it
|
|
8
|
+
// (the old single 120/min bucket is already exhausted by phase 1).
|
|
9
|
+
// Usage: node scripts/burst-scenario.mjs --port <P> --switch-seq <N> [--sacrificial-count 350]
|
|
10
|
+
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
function argOf(name, fallback) {
|
|
13
|
+
const i = args.indexOf(name);
|
|
14
|
+
return i >= 0 ? args[i + 1] : fallback;
|
|
15
|
+
}
|
|
16
|
+
const PORT = Number(argOf('--port'));
|
|
17
|
+
const SWITCH_SEQ = argOf('--switch-seq', '');
|
|
18
|
+
const SACRIFICIAL = Number(argOf('--sacrificial-count', '350'));
|
|
19
|
+
if (!PORT) { console.error('usage: burst-scenario.mjs --port <P> --switch-seq <N>'); process.exit(1); }
|
|
20
|
+
const BASE = `http://127.0.0.1:${PORT}`;
|
|
21
|
+
|
|
22
|
+
// Phase 0 — token first: after phase 1 exhausts the shared bucket, a
|
|
23
|
+
// pre-hardening server would 429 the token endpoint itself.
|
|
24
|
+
const tokenRes = await fetch(`${BASE}/api/auth/token`);
|
|
25
|
+
const token = tokenRes.ok ? (await tokenRes.json()).token || '' : '';
|
|
26
|
+
if (!token) { console.error('token fetch failed — aborting'); process.exit(1); }
|
|
27
|
+
const AUTH = { Authorization: `Bearer ${token}` };
|
|
28
|
+
|
|
29
|
+
async function fire(url, init = {}) {
|
|
30
|
+
try {
|
|
31
|
+
const res = await fetch(url, init);
|
|
32
|
+
return { status: res.status, retryAfter: res.headers.get('retry-after') };
|
|
33
|
+
} catch {
|
|
34
|
+
return { status: 0, retryAfter: null };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Phase 1 — sacrificial burst, bounded concurrency 20, single-window guard.
|
|
39
|
+
const phase1Start = Date.now();
|
|
40
|
+
const sacrificial = { total: 0, s429: 0, retryAfterSeen: false };
|
|
41
|
+
let inFlight = [];
|
|
42
|
+
for (let i = 0; i < SACRIFICIAL; i++) {
|
|
43
|
+
inFlight.push(fire(`${BASE}/api/messages/count`).then(r => {
|
|
44
|
+
sacrificial.total++;
|
|
45
|
+
if (r.status === 429) {
|
|
46
|
+
sacrificial.s429++;
|
|
47
|
+
if (r.retryAfter) sacrificial.retryAfterSeen = true;
|
|
48
|
+
}
|
|
49
|
+
}));
|
|
50
|
+
if (inFlight.length >= 20) { await Promise.all(inFlight); inFlight = []; }
|
|
51
|
+
}
|
|
52
|
+
await Promise.all(inFlight);
|
|
53
|
+
const phase1ElapsedMs = Date.now() - phase1Start;
|
|
54
|
+
if (phase1ElapsedMs > 45_000) {
|
|
55
|
+
console.error(`phase 1 took ${phase1ElapsedMs}ms — crossed the window boundary, scenario invalid`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Phase 2 — protected lane (cli class via Bearer).
|
|
60
|
+
const protectedLane = { total: 0, s429: 0 };
|
|
61
|
+
function track(promise) {
|
|
62
|
+
return promise.then(r => { protectedLane.total++; if (r.status === 429) protectedLane.s429++; });
|
|
63
|
+
}
|
|
64
|
+
const protectedCalls = [];
|
|
65
|
+
for (let i = 0; i < 20; i++) protectedCalls.push(track(fire(`${BASE}/api/chat-sessions`, { headers: AUTH })));
|
|
66
|
+
for (let i = 0; i < 5; i++) {
|
|
67
|
+
protectedCalls.push(track(fire(`${BASE}/api/chat-sessions/${SWITCH_SEQ}/switch`, { method: 'POST', headers: AUTH })));
|
|
68
|
+
}
|
|
69
|
+
for (let i = 0; i < 10; i++) protectedCalls.push(track(fire(`${BASE}/api/goal`, { headers: AUTH })));
|
|
70
|
+
await Promise.all(protectedCalls);
|
|
71
|
+
|
|
72
|
+
console.log(JSON.stringify({ tokenOk: true, phase1ElapsedMs, sacrificial, protected: protectedLane }, null, 2));
|
|
@@ -83,6 +83,7 @@ const ALLOWLIST = [
|
|
|
83
83
|
{ contains: '이 토픽은 인스턴스에 연결되지', why: 'fixed string' },
|
|
84
84
|
{ contains: 'ctx.answerCallbackQuery(ack', why: 'ack is masked where it is built' },
|
|
85
85
|
{ contains: 'ctx.reply(syncText)', why: 'syncText is masked where it is built' },
|
|
86
|
+
{ contains: "persist failed:", why: "a Node.js Error.message from fs write, not a credential" },
|
|
86
87
|
{ contains: 'await ctx.reply(syncText)', why: 'syncText is masked where it is built' },
|
|
87
88
|
{ contains: 'Chat ID: <code>', why: 'a chat id the user just asked for' },
|
|
88
89
|
];
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @file scripts/check-strict-baseline.mjs
|
|
3
3
|
// Strict-migration regression gate (AST-aware).
|
|
4
4
|
//
|
|
5
|
-
// Per R2.2 (devlog/
|
|
5
|
+
// Per R2.2 (devlog/_fin/strict-migration/07-pro-review-r2.md), this scanner
|
|
6
6
|
// uses the TypeScript Compiler API to walk source files and count AST nodes
|
|
7
7
|
// of kind `AnyKeyword` plus any-typed `TypeReference` (Array<any>, Promise<any>,
|
|
8
8
|
// Record<string, any>, etc.). Comments and string literals are automatically
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* rebuild it in-place before build/test steps continue.
|
|
8
8
|
*/
|
|
9
9
|
const { execFileSync } = require('child_process');
|
|
10
|
-
const { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } = require('fs');
|
|
10
|
+
const { accessSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } = require('fs');
|
|
11
11
|
const { delimiter, dirname, join } = require('path');
|
|
12
12
|
const { createRequire } = require('module');
|
|
13
13
|
const { createHash } = require('crypto');
|
|
@@ -58,7 +58,13 @@ function rebuildBetterSqlite3() {
|
|
|
58
58
|
const betterSqliteDir = join(root, 'node_modules', 'better-sqlite3');
|
|
59
59
|
if (existsSync(join(betterSqliteDir, 'package.json'))) {
|
|
60
60
|
rmSync(join(betterSqliteDir, 'build'), { recursive: true, force: true });
|
|
61
|
-
|
|
61
|
+
// v12 has scripts.install ("prebuild-install || node-gyp rebuild").
|
|
62
|
+
// v13+ removed it (prebuilds ship in the package), and `npm rebuild`
|
|
63
|
+
// returns a no-op success there, so the real source-build script is
|
|
64
|
+
// build-release. Pick by reading the installed package's manifest.
|
|
65
|
+
const manifest = JSON.parse(readFileSync(join(betterSqliteDir, 'package.json'), 'utf8'));
|
|
66
|
+
const script = manifest.scripts && manifest.scripts.install ? 'install' : 'build-release';
|
|
67
|
+
runNpm(['run', script, '--foreground-scripts'], {
|
|
62
68
|
stdio: 'inherit',
|
|
63
69
|
cwd: betterSqliteDir,
|
|
64
70
|
env: nativeBuildEnv(),
|
|
@@ -239,10 +245,51 @@ function releaseRepairLock() {
|
|
|
239
245
|
try { rmSync(LOCK_DIR, { recursive: true, force: true }); } catch { /* best effort */ }
|
|
240
246
|
}
|
|
241
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Can this process write into the install tree at all? A global npm prefix is
|
|
250
|
+
* often root-owned; telling that user to "rebuild" is advice that cannot work.
|
|
251
|
+
*/
|
|
252
|
+
function canWriteInstallTree() {
|
|
253
|
+
try {
|
|
254
|
+
accessSync(join(root, 'node_modules'), constants.W_OK);
|
|
255
|
+
return true;
|
|
256
|
+
} catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Package-manager-aware recovery commands. npm >= 12 blocks unreviewed
|
|
263
|
+
* dependency install scripts, which is the likeliest reason a fresh global
|
|
264
|
+
* install is missing its native addon. npm's own printed remediation omits
|
|
265
|
+
* the package argument (npm/cli#9835), so we print the working form.
|
|
266
|
+
*/
|
|
267
|
+
function recoveryHints() {
|
|
268
|
+
const lines = [];
|
|
269
|
+
if (/[\\/]\.bun[\\/]/.test(root)) {
|
|
270
|
+
lines.push('[jaw:native] reinstall with lifecycle scripts trusted (bun):');
|
|
271
|
+
lines.push('[jaw:native] bun add -g --trust cli-jaw');
|
|
272
|
+
} else if (/[\\/]pnpm[\\/]|[\\/]\.pnpm[\\/]/.test(root)) {
|
|
273
|
+
lines.push('[jaw:native] reinstall with build scripts allowed (pnpm 11+):');
|
|
274
|
+
lines.push('[jaw:native] pnpm add -g --allow-build=cli-jaw cli-jaw');
|
|
275
|
+
lines.push('[jaw:native] (pnpm <= 10: pnpm approve-builds -g)');
|
|
276
|
+
} else {
|
|
277
|
+
lines.push('[jaw:native] reinstall with install scripts allowed (npm >= 11.16):');
|
|
278
|
+
lines.push('[jaw:native] npm install -g cli-jaw --allow-scripts=cli-jaw');
|
|
279
|
+
lines.push('[jaw:native] npm config set allow-scripts=cli-jaw --location=user');
|
|
280
|
+
}
|
|
281
|
+
return lines;
|
|
282
|
+
}
|
|
283
|
+
|
|
242
284
|
function reportMissing() {
|
|
243
285
|
console.error('[jaw:native] ❌ dependencies are not installed (cannot resolve better-sqlite3).');
|
|
244
286
|
console.error(`[jaw:native] install root: ${root}`);
|
|
245
|
-
|
|
287
|
+
if (!canWriteInstallTree()) {
|
|
288
|
+
console.error('[jaw:native] install tree is not writable — a rebuild cannot help here.');
|
|
289
|
+
for (const line of recoveryHints()) console.error(line);
|
|
290
|
+
} else {
|
|
291
|
+
console.error('[jaw:native] run: npm install');
|
|
292
|
+
}
|
|
246
293
|
}
|
|
247
294
|
|
|
248
295
|
module.exports = {
|
|
@@ -67,6 +67,7 @@ function runPackageContentsCheck() {
|
|
|
67
67
|
const required = [
|
|
68
68
|
'scripts/install.sh',
|
|
69
69
|
'scripts/install-wsl.sh',
|
|
70
|
+
'scripts/install.ps1',
|
|
70
71
|
'scripts/verify-fresh-install.sh',
|
|
71
72
|
'scripts/collect-fresh-install-evidence.sh',
|
|
72
73
|
'scripts/audit-fresh-install-evidence.mjs',
|
|
@@ -94,6 +95,13 @@ function runPackageContentsCheck() {
|
|
|
94
95
|
return false;
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
// The install-state receipt is written at install time; if it ever ships in
|
|
99
|
+
// the tarball it always exists, which makes blocked-install detection blind.
|
|
100
|
+
if ([...files].some((file) => file.endsWith('.jaw-install-state.json'))) {
|
|
101
|
+
console.error(`[install-risk] FAIL ${label}: .jaw-install-state.json must never ship in the package`);
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
97
105
|
console.log(`[install-risk] PASS ${label}`);
|
|
98
106
|
return true;
|
|
99
107
|
}
|
package/scripts/install-wsl.sh
CHANGED
|
@@ -37,6 +37,29 @@ HAS_SUDO=false
|
|
|
37
37
|
NPM_PREFIX="$HOME/.local"
|
|
38
38
|
NPM_PATH_LINE='export PATH="$HOME/.local/bin:$PATH"'
|
|
39
39
|
|
|
40
|
+
# npm >= 11.16 understands --allow-scripts; npm 12 blocks unreviewed dependency
|
|
41
|
+
# lifecycle scripts by default, so without this flag a global install can
|
|
42
|
+
# succeed while cli-jaw's postinstall silently never runs. Older npm rejects
|
|
43
|
+
# unknown config, so the flag is attached conditionally. (Duplicated from
|
|
44
|
+
# install.sh — both files are standalone curl-run scripts.)
|
|
45
|
+
JAW_ALLOW_SCRIPTS="cli-jaw"
|
|
46
|
+
|
|
47
|
+
jaw_npm_supports_allow_scripts() {
|
|
48
|
+
local npm_version major minor
|
|
49
|
+
npm_version="$(npm --version 2>/dev/null || true)"
|
|
50
|
+
major="$(printf '%s' "$npm_version" | cut -d. -f1)"
|
|
51
|
+
minor="$(printf '%s' "$npm_version" | cut -d. -f2)"
|
|
52
|
+
case "$major" in (''|*[!0-9]*) return 1 ;; esac
|
|
53
|
+
case "$minor" in (''|*[!0-9]*) minor=0 ;; esac
|
|
54
|
+
[ "$major" -gt 11 ] || { [ "$major" -eq 11 ] && [ "$minor" -ge 16 ]; }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
jaw_allow_scripts_flag() {
|
|
58
|
+
if jaw_npm_supports_allow_scripts; then
|
|
59
|
+
printf '%s' "--allow-scripts=${JAW_ALLOW_SCRIPTS}"
|
|
60
|
+
fi
|
|
61
|
+
}
|
|
62
|
+
|
|
40
63
|
# Guard: reject Windows HOME (e.g. /mnt/c/Users/...)
|
|
41
64
|
case "$HOME" in
|
|
42
65
|
/mnt/*) fail "HOME points to Windows path: $HOME — launch a proper WSL shell (wsl.exe -d Ubuntu)" ;;
|
|
@@ -315,15 +338,17 @@ verify_jaw_command() {
|
|
|
315
338
|
# Step 3: Install cli-jaw
|
|
316
339
|
# ═══════════════════════════════════════
|
|
317
340
|
install_jaw() {
|
|
341
|
+
local allow_flag
|
|
342
|
+
allow_flag="$(jaw_allow_scripts_flag)"
|
|
318
343
|
if command -v jaw &>/dev/null; then
|
|
319
344
|
ok "cli-jaw already installed ($(jaw --version 2>/dev/null || echo 'unknown version'))"
|
|
320
345
|
info "Updating to latest..."
|
|
321
346
|
CLI_JAW_INSTALL_CLI_TOOLS=1 \
|
|
322
|
-
npm install -g cli-jaw@latest
|
|
347
|
+
npm install -g cli-jaw@latest ${allow_flag:+$allow_flag}
|
|
323
348
|
else
|
|
324
349
|
info "Installing cli-jaw globally..."
|
|
325
350
|
CLI_JAW_INSTALL_CLI_TOOLS=1 \
|
|
326
|
-
npm install -g cli-jaw
|
|
351
|
+
npm install -g cli-jaw ${allow_flag:+$allow_flag}
|
|
327
352
|
fi
|
|
328
353
|
|
|
329
354
|
verify_jaw_command
|