@xopcai/xopc 0.0.83 → 0.0.85
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 +2 -0
- package/README.zh-CN.md +3 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/plugin.d.ts +2 -0
- package/dist/extensions/feishu/src/plugin.js +10 -0
- package/dist/extensions/feishu/src/plugin.js.map +1 -1
- package/dist/extensions/feishu/src/workflow-progress.d.ts +27 -0
- package/dist/extensions/feishu/src/workflow-progress.js +99 -0
- package/dist/extensions/feishu/src/workflow-progress.js.map +1 -0
- package/dist/extensions/telegram/src/plugin.d.ts +2 -0
- package/dist/extensions/telegram/src/plugin.js +11 -1
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.d.ts +24 -0
- package/dist/extensions/telegram/src/workflow-progress.js +73 -0
- package/dist/extensions/telegram/src/workflow-progress.js.map +1 -0
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +158 -0
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -0
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.d.ts +2 -0
- package/dist/extensions/weixin/src/plugin.js +11 -1
- package/dist/extensions/weixin/src/plugin.js.map +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.d.ts +26 -0
- package/dist/extensions/weixin/src/workflow-progress.js +99 -0
- package/dist/extensions/weixin/src/workflow-progress.js.map +1 -0
- package/dist/gateway/static/root/assets/agents-D3_-kNlZ.js +222 -0
- package/dist/gateway/static/root/assets/apps-page-D7v7649T.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-nCaMb0a7.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-C1gZBcJV.js +8 -0
- package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +1 -0
- package/dist/gateway/static/root/assets/cron-api-CoYK0hlm.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-DeGo-Vjc.js +1 -0
- package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +45 -0
- package/dist/gateway/static/root/assets/{dist-BpQxde0t.js → dist-DaK4dsss.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CY27wj_p.js → extension-debug-page-BZngZWbO.js} +1 -1
- package/dist/gateway/static/root/assets/extension-page-D6JSyV27.js +1 -0
- package/dist/gateway/static/root/assets/extension-settings-page-8PZcmWI7.js +1 -0
- package/dist/gateway/static/root/assets/fetch-B2MYHbWg.js +1 -0
- package/dist/gateway/static/root/assets/{field-primitives-fa_hiQcX.js → field-primitives-Zzl22MvN.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-BtIcpG0O.js +1 -0
- package/dist/gateway/static/root/assets/index-D4vM3-P7.js +4700 -0
- package/dist/gateway/static/root/assets/index-ew_2L2We.css +1 -0
- package/dist/gateway/static/root/assets/logs-page-_d4UJ-qQ.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-5N4aF2Wk.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-section-D_tgb8r2.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-C18xBt4X.js +3 -0
- package/dist/gateway/static/root/assets/share-preview-page-D4EG_vM1.js +2 -0
- package/dist/gateway/static/root/assets/skills-page-sPAXhh8w.js +2 -0
- package/dist/gateway/static/root/assets/theme-store-DryYl3qD.js +1 -0
- package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +3 -0
- package/dist/gateway/static/root/assets/utils-CYO9eTCM.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-Ds51havm.js +1 -0
- package/dist/gateway/static/root/index.html +7 -6
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +3 -3
- package/dist/src/agent/embedded/map-stream-events.js +6 -0
- package/dist/src/agent/embedded/map-stream-events.js.map +1 -1
- package/dist/src/agent/embedded/subscribe-session.js +24 -0
- package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
- package/dist/src/agent/embedded/types.d.ts +19 -0
- package/dist/src/agent/goals/goal-locale.js +2 -2
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/startup-context.d.ts +3 -0
- package/dist/src/agent/reply/startup-context.js +25 -2
- package/dist/src/agent/reply/startup-context.js.map +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service.d.ts +1 -0
- package/dist/src/agent/service.js +10 -4
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +3 -3
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/create-share-tool.d.ts +27 -0
- package/dist/src/agent/tools/create-share-tool.js +237 -0
- package/dist/src/agent/tools/create-share-tool.js.map +1 -0
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +35 -1
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/index.d.ts +2 -0
- package/dist/src/agent/tools/index.js +3 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.d.ts +41 -0
- package/dist/src/agent/tools/workflow-tool.js +271 -0
- package/dist/src/agent/tools/workflow-tool.js.map +1 -0
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +9 -0
- package/dist/src/agent/workflow/builtins/audit-repo.js +115 -0
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +15 -0
- package/dist/src/agent/workflow/builtins/index.js +28 -0
- package/dist/src/agent/workflow/builtins/index.js.map +1 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +9 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +113 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -0
- package/dist/src/agent/workflow/builtins/research.d.ts +9 -0
- package/dist/src/agent/workflow/builtins/research.js +129 -0
- package/dist/src/agent/workflow/builtins/research.js.map +1 -0
- package/dist/src/agent/workflow/catalog.d.ts +51 -0
- package/dist/src/agent/workflow/catalog.js +155 -0
- package/dist/src/agent/workflow/catalog.js.map +1 -0
- package/dist/src/agent/workflow/channel-capability.d.ts +76 -0
- package/dist/src/agent/workflow/channel-capability.js +1 -0
- package/dist/src/agent/workflow/index.d.ts +11 -0
- package/dist/src/agent/workflow/index.js +10 -0
- package/dist/src/agent/workflow/last-run-memory.d.ts +42 -0
- package/dist/src/agent/workflow/last-run-memory.js +60 -0
- package/dist/src/agent/workflow/last-run-memory.js.map +1 -0
- package/dist/src/agent/workflow/parser.d.ts +20 -0
- package/dist/src/agent/workflow/parser.js +137 -0
- package/dist/src/agent/workflow/parser.js.map +1 -0
- package/dist/src/agent/workflow/progress-broker.d.ts +80 -0
- package/dist/src/agent/workflow/progress-broker.js +263 -0
- package/dist/src/agent/workflow/progress-broker.js.map +1 -0
- package/dist/src/agent/workflow/runtime.d.ts +31 -0
- package/dist/src/agent/workflow/runtime.js +301 -0
- package/dist/src/agent/workflow/runtime.js.map +1 -0
- package/dist/src/agent/workflow/snapshot.d.ts +18 -0
- package/dist/src/agent/workflow/snapshot.js +144 -0
- package/dist/src/agent/workflow/snapshot.js.map +1 -0
- package/dist/src/agent/workflow/structured-output-tool.d.ts +33 -0
- package/dist/src/agent/workflow/structured-output-tool.js +58 -0
- package/dist/src/agent/workflow/structured-output-tool.js.map +1 -0
- package/dist/src/agent/workflow/subagent-runner.d.ts +42 -0
- package/dist/src/agent/workflow/subagent-runner.js +104 -0
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -0
- package/dist/src/agent/workflow/types.d.ts +137 -0
- package/dist/src/agent/workflow/types.js +1 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/builtins/model.js +40 -23
- package/dist/src/chat-commands/builtins/model.js.map +1 -1
- package/dist/src/chat-commands/builtins/system.js +30 -15
- package/dist/src/chat-commands/builtins/system.js.map +1 -1
- package/dist/src/chat-commands/builtins/workflow.d.ts +18 -0
- package/dist/src/chat-commands/builtins/workflow.js +167 -0
- package/dist/src/chat-commands/builtins/workflow.js.map +1 -0
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/chat-commands/format-output.d.ts +28 -0
- package/dist/src/chat-commands/format-output.js +45 -0
- package/dist/src/chat-commands/format-output.js.map +1 -0
- package/dist/src/chat-commands/index.d.ts +1 -0
- package/dist/src/chat-commands/index.js +3 -1
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/cli/command-catalog.js +110 -8
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +2 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +9 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/config.js +71 -20
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/cron-cli.d.ts +2 -0
- package/dist/src/cli/commands/cron-cli.js +15 -0
- package/dist/src/cli/commands/cron-cli.js.map +1 -0
- package/dist/src/cli/commands/cron.d.ts +4 -1
- package/dist/src/cli/commands/cron.js +76 -41
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-service.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +2 -2
- package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +4 -4
- package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/index.d.ts +1 -1
- package/dist/src/cli/commands/gateway/index.js +2 -2
- package/dist/src/cli/commands/gateway/lifecycle.js +10 -4
- package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -1
- package/dist/src/cli/commands/gateway/service.d.ts +4 -0
- package/dist/src/cli/commands/gateway/service.js +17 -2
- package/dist/src/cli/commands/gateway/service.js.map +1 -1
- package/dist/src/cli/commands/gateway/shared.js +1 -1
- package/dist/src/cli/commands/gateway/subcommands.js +1 -4
- package/dist/src/cli/commands/gateway/subcommands.js.map +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +31 -4
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/models.d.ts +4 -1
- package/dist/src/cli/commands/models.js +86 -74
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +4 -2
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/profile.d.ts +3 -5
- package/dist/src/cli/commands/profile.js +31 -31
- package/dist/src/cli/commands/profile.js.map +1 -1
- package/dist/src/cli/commands/setup.js +6 -1
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/commands/tunnel.js +2 -2
- package/dist/src/cli/gateway-run-argv.js +15 -5
- package/dist/src/cli/gateway-run-argv.js.map +1 -1
- package/dist/src/cli/utils/gateway-client.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/public-url.d.ts +28 -0
- package/dist/src/config/public-url.js +103 -0
- package/dist/src/config/public-url.js.map +1 -0
- package/dist/src/config/schema.d.ts +82 -0
- package/dist/src/config/schema.js +130 -1
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +3 -3
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +38 -1
- package/dist/src/daemon/schtasks.js.map +1 -1
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +33 -2
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +631 -34
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/site-shares.d.ts +3 -0
- package/dist/src/gateway/hono/routes/site-shares.js +228 -0
- package/dist/src/gateway/hono/routes/site-shares.js.map +1 -0
- package/dist/src/gateway/hono/routes/tunnel.js +97 -8
- package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +5 -5
- package/dist/src/gateway/hono/sse.js +2 -2
- package/dist/src/gateway/host.d.ts +3 -1
- package/dist/src/gateway/host.js +3 -1
- package/dist/src/gateway/host.js.map +1 -1
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.d.ts +6 -0
- package/dist/src/gateway/ports.js +38 -2
- package/dist/src/gateway/ports.js.map +1 -1
- package/dist/src/gateway/public-url.d.ts +8 -0
- package/dist/src/gateway/public-url.js +10 -0
- package/dist/src/gateway/public-url.js.map +1 -0
- package/dist/src/gateway/security/origin-check.d.ts +9 -1
- package/dist/src/gateway/security/origin-check.js +4 -0
- package/dist/src/gateway/security/origin-check.js.map +1 -1
- package/dist/src/gateway/server.js +15 -0
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +2 -2
- package/dist/src/gateway/service.js +3 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/i18n/goals-bundle.js +1 -1
- package/dist/src/i18n/index.d.ts +1 -0
- package/dist/src/i18n/index.js +2 -1
- package/dist/src/i18n/locales/share-tool.en.js +15 -0
- package/dist/src/i18n/locales/share-tool.en.js.map +1 -0
- package/dist/src/i18n/locales/share-tool.zh.js +15 -0
- package/dist/src/i18n/locales/share-tool.zh.js.map +1 -0
- package/dist/src/i18n/share-tool-bundle.d.ts +20 -0
- package/dist/src/i18n/share-tool-bundle.js +56 -0
- package/dist/src/i18n/share-tool-bundle.js.map +1 -0
- package/dist/src/infra/gateway-processes.js +1 -0
- package/dist/src/infra/gateway-processes.js.map +1 -1
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +3 -2
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.js +5 -5
- package/dist/src/share/share-auto.d.ts +74 -0
- package/dist/src/share/share-auto.js +247 -0
- package/dist/src/share/share-auto.js.map +1 -0
- package/dist/src/share/share-config.js +63 -4
- package/dist/src/share/share-config.js.map +1 -1
- package/dist/src/share/share-landing.d.ts +28 -2
- package/dist/src/share/share-landing.js +155 -34
- package/dist/src/share/share-landing.js.map +1 -1
- package/dist/src/share/share-store.d.ts +48 -4
- package/dist/src/share/share-store.js +322 -51
- package/dist/src/share/share-store.js.map +1 -1
- package/dist/src/share/share-thumbnail.d.ts +35 -0
- package/dist/src/share/share-thumbnail.js +277 -0
- package/dist/src/share/share-thumbnail.js.map +1 -0
- package/dist/src/share/share-types.d.ts +68 -10
- package/dist/src/share/share-types.js +18 -1
- package/dist/src/share/share-types.js.map +1 -1
- package/dist/src/share/share-url.js +1 -1
- package/dist/src/share/share-zip.d.ts +35 -0
- package/dist/src/share/share-zip.js +303 -0
- package/dist/src/share/share-zip.js.map +1 -0
- package/dist/src/share/site-proxy.d.ts +35 -0
- package/dist/src/share/site-proxy.js +234 -0
- package/dist/src/share/site-proxy.js.map +1 -0
- package/dist/src/share/site-share-config.d.ts +11 -0
- package/dist/src/share/site-share-config.js +103 -0
- package/dist/src/share/site-share-config.js.map +1 -0
- package/dist/src/share/site-share-router.d.ts +23 -0
- package/dist/src/share/site-share-router.js +147 -0
- package/dist/src/share/site-share-router.js.map +1 -0
- package/dist/src/share/site-share-store.d.ts +53 -0
- package/dist/src/share/site-share-store.js +400 -0
- package/dist/src/share/site-share-store.js.map +1 -0
- package/dist/src/share/site-share-types.d.ts +103 -0
- package/dist/src/share/site-share-types.js +41 -0
- package/dist/src/share/site-share-types.js.map +1 -0
- package/dist/src/share/site-static-serve.d.ts +10 -0
- package/dist/src/share/site-static-serve.js +145 -0
- package/dist/src/share/site-static-serve.js.map +1 -0
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-commands.js +18 -0
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-workflow-slash.d.ts +32 -0
- package/dist/src/tui/tui-workflow-slash.js +63 -0
- package/dist/src/tui/tui-workflow-slash.js.map +1 -0
- package/dist/src/tui/tui.js +2 -2
- package/dist/src/tunnel/enable-lan-pairing.js +1 -1
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/index.js +2 -2
- package/dist/src/tunnel/pair-context.d.ts +7 -1
- package/dist/src/tunnel/pair-context.js +25 -9
- package/dist/src/tunnel/pair-context.js.map +1 -1
- package/dist/src/tunnel/pair-url.d.ts +14 -1
- package/dist/src/tunnel/pair-url.js +14 -1
- package/dist/src/tunnel/pair-url.js.map +1 -1
- package/dist/src/tunnel/tunnel-service.js +2 -2
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/package.json +3 -2
- package/dist/gateway/static/root/assets/agents-CrpYTHJS.js +0 -222
- package/dist/gateway/static/root/assets/apps-page-1mcKh5Rh.js +0 -1
- package/dist/gateway/static/root/assets/button-KafIU8dx.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-zd6QNKPx.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-uRAuhiUo.js +0 -8
- package/dist/gateway/static/root/assets/cron-api-O2Q_ruV6.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-By09AQD-.js +0 -1
- package/dist/gateway/static/root/assets/dist-C57OMHW8.js +0 -48
- package/dist/gateway/static/root/assets/extension-page-C-Ed5ZmP.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-raLux7E7.js +0 -1
- package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +0 -3
- package/dist/gateway/static/root/assets/heartbeat-config-api-BVl5VHvL.js +0 -1
- package/dist/gateway/static/root/assets/index-BuFldCsB.css +0 -1
- package/dist/gateway/static/root/assets/index-Y-iqo-gL.js +0 -4693
- package/dist/gateway/static/root/assets/logs-page-BdH2n7ZW.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Vpchzdp-.js +0 -1
- package/dist/gateway/static/root/assets/settings-form-section-Kk1yAGBl.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-KBm0u6Dz.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-BjeXXaOn.js +0 -2
- package/dist/gateway/static/root/assets/theme-store-D01dJt95.js +0 -1
- package/dist/gateway/static/root/assets/utils-DpTxN4AF.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CwO8Cf01.js +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import shareToolEn from './locales/share-tool.en.json';
|
|
2
|
+
import { type ServerLocale } from './locale.js';
|
|
3
|
+
export type ShareToolMessages = typeof shareToolEn;
|
|
4
|
+
export declare function shareToolMessages(locale: ServerLocale): ShareToolMessages;
|
|
5
|
+
/**
|
|
6
|
+
* Best-effort locale resolution for tools that don't yet receive an explicit
|
|
7
|
+
* locale signal. Order: explicit arg → env (LANG / LC_ALL / LANGUAGE) → default.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveToolLocale(explicit?: string | null): ServerLocale;
|
|
10
|
+
export declare function shareToolSuccessLines(locale: ServerLocale, vars: {
|
|
11
|
+
kind: string;
|
|
12
|
+
shareUrl: string;
|
|
13
|
+
title: string;
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
thumbnailUrl: string;
|
|
16
|
+
reachability: string;
|
|
17
|
+
reachabilityHint: string;
|
|
18
|
+
isPublic: boolean;
|
|
19
|
+
}): string[];
|
|
20
|
+
export declare function shareToolErrorLine(locale: ServerLocale, message: string): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import share_tool_en_default from "./locales/share-tool.en.js";
|
|
2
|
+
import share_tool_zh_default from "./locales/share-tool.zh.js";
|
|
3
|
+
import { formatI18n } from "./format.js";
|
|
4
|
+
import { normalizeServerLocale, serverLocaleOrFallback } from "./locale.js";
|
|
5
|
+
//#region src/i18n/share-tool-bundle.ts
|
|
6
|
+
const byLocale = {
|
|
7
|
+
en: share_tool_en_default,
|
|
8
|
+
zh: share_tool_zh_default
|
|
9
|
+
};
|
|
10
|
+
function shareToolMessages(locale) {
|
|
11
|
+
return byLocale[serverLocaleOrFallback(locale)];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Best-effort locale resolution for tools that don't yet receive an explicit
|
|
15
|
+
* locale signal. Order: explicit arg → env (LANG / LC_ALL / LANGUAGE) → default.
|
|
16
|
+
*/
|
|
17
|
+
function resolveToolLocale(explicit) {
|
|
18
|
+
if (explicit) {
|
|
19
|
+
const n = normalizeServerLocale(explicit);
|
|
20
|
+
if (n) return n;
|
|
21
|
+
}
|
|
22
|
+
for (const key of [
|
|
23
|
+
"LC_ALL",
|
|
24
|
+
"LANG",
|
|
25
|
+
"LANGUAGE"
|
|
26
|
+
]) {
|
|
27
|
+
const v = process.env[key];
|
|
28
|
+
if (!v) continue;
|
|
29
|
+
const n = normalizeServerLocale(v.split(".")[0].replace(/_/g, "-"));
|
|
30
|
+
if (n) return n;
|
|
31
|
+
}
|
|
32
|
+
return "en";
|
|
33
|
+
}
|
|
34
|
+
function shareToolSuccessLines(locale, vars) {
|
|
35
|
+
const m = shareToolMessages(locale).success;
|
|
36
|
+
return [
|
|
37
|
+
formatI18n(m.headline, {
|
|
38
|
+
kind: vars.kind,
|
|
39
|
+
shareUrl: vars.shareUrl
|
|
40
|
+
}),
|
|
41
|
+
vars.isPublic ? "" : formatI18n(m.reachabilityWarning, {
|
|
42
|
+
reachability: vars.reachability,
|
|
43
|
+
hint: vars.reachabilityHint
|
|
44
|
+
}),
|
|
45
|
+
formatI18n(m.title, { title: vars.title }),
|
|
46
|
+
formatI18n(m.expiresAt, { expiresAt: vars.expiresAt }),
|
|
47
|
+
formatI18n(m.thumbnail, { thumbnailUrl: vars.thumbnailUrl })
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
function shareToolErrorLine(locale, message) {
|
|
51
|
+
return formatI18n(shareToolMessages(locale).error.prefix, { message });
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { resolveToolLocale, shareToolErrorLine, shareToolMessages, shareToolSuccessLines };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=share-tool-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-tool-bundle.js","names":["shareToolEn","shareToolZh"],"sources":["../../../src/i18n/share-tool-bundle.ts"],"sourcesContent":["import shareToolEn from './locales/share-tool.en.json';\nimport shareToolZh from './locales/share-tool.zh.json';\n\nimport { formatI18n } from './format.js';\nimport {\n DEFAULT_SERVER_LOCALE,\n normalizeServerLocale,\n serverLocaleOrFallback,\n type ServerLocale,\n} from './locale.js';\n\nexport type ShareToolMessages = typeof shareToolEn;\n\nconst byLocale: Record<ServerLocale, ShareToolMessages> = {\n en: shareToolEn,\n zh: shareToolZh,\n};\n\nexport function shareToolMessages(locale: ServerLocale): ShareToolMessages {\n return byLocale[serverLocaleOrFallback(locale)];\n}\n\n/**\n * Best-effort locale resolution for tools that don't yet receive an explicit\n * locale signal. Order: explicit arg → env (LANG / LC_ALL / LANGUAGE) → default.\n */\nexport function resolveToolLocale(explicit?: string | null): ServerLocale {\n if (explicit) {\n const n = normalizeServerLocale(explicit);\n if (n) return n;\n }\n for (const key of ['LC_ALL', 'LANG', 'LANGUAGE'] as const) {\n const v = process.env[key];\n if (!v) continue;\n // Unix env vars use `zh_CN.UTF-8`; normalizer expects `zh-CN`.\n const stripped = v.split('.')[0].replace(/_/g, '-');\n const n = normalizeServerLocale(stripped);\n if (n) return n;\n }\n return DEFAULT_SERVER_LOCALE;\n}\n\nexport function shareToolSuccessLines(\n locale: ServerLocale,\n vars: {\n kind: string;\n shareUrl: string;\n title: string;\n expiresAt: string;\n thumbnailUrl: string;\n reachability: string;\n reachabilityHint: string;\n isPublic: boolean;\n },\n): string[] {\n const m = shareToolMessages(locale).success;\n return [\n formatI18n(m.headline, { kind: vars.kind, shareUrl: vars.shareUrl }),\n vars.isPublic\n ? ''\n : formatI18n(m.reachabilityWarning, {\n reachability: vars.reachability,\n hint: vars.reachabilityHint,\n }),\n formatI18n(m.title, { title: vars.title }),\n formatI18n(m.expiresAt, { expiresAt: vars.expiresAt }),\n formatI18n(m.thumbnail, { thumbnailUrl: vars.thumbnailUrl }),\n ];\n}\n\nexport function shareToolErrorLine(locale: ServerLocale, message: string): string {\n return formatI18n(shareToolMessages(locale).error.prefix, { message });\n}\n"],"mappings":";;;;;AAaA,MAAM,WAAoD;CACxD,IAAIA;CACJ,IAAIC;CACL;AAED,SAAgB,kBAAkB,QAAyC;AACzE,QAAO,SAAS,uBAAuB,OAAO;;;;;;AAOhD,SAAgB,kBAAkB,UAAwC;AACxE,KAAI,UAAU;EACZ,MAAM,IAAI,sBAAsB,SAAS;AACzC,MAAI,EAAG,QAAO;;AAEhB,MAAK,MAAM,OAAO;EAAC;EAAU;EAAQ;EAAW,EAAW;EACzD,MAAM,IAAI,QAAQ,IAAI;AACtB,MAAI,CAAC,EAAG;EAGR,MAAM,IAAI,sBADO,EAAE,MAAM,IAAI,CAAC,GAAG,QAAQ,MAAM,IACP,CAAC;AACzC,MAAI,EAAG,QAAO;;AAEhB,QAAA;;AAGF,SAAgB,sBACd,QACA,MAUU;CACV,MAAM,IAAI,kBAAkB,OAAO,CAAC;AACpC,QAAO;EACL,WAAW,EAAE,UAAU;GAAE,MAAM,KAAK;GAAM,UAAU,KAAK;GAAU,CAAC;EACpE,KAAK,WACD,KACA,WAAW,EAAE,qBAAqB;GAChC,cAAc,KAAK;GACnB,MAAM,KAAK;GACZ,CAAC;EACN,WAAW,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;EAC1C,WAAW,EAAE,WAAW,EAAE,WAAW,KAAK,WAAW,CAAC;EACtD,WAAW,EAAE,WAAW,EAAE,cAAc,KAAK,cAAc,CAAC;EAC7D;;AAGH,SAAgB,mBAAmB,QAAsB,SAAyB;AAChF,QAAO,WAAW,kBAAkB,OAAO,CAAC,MAAM,QAAQ,EAAE,SAAS,CAAC"}
|
|
@@ -41,6 +41,7 @@ function readGatewayProcessArgsSync(pid) {
|
|
|
41
41
|
function signalVerifiedGatewayPidSync(pid, signal) {
|
|
42
42
|
const args = readGatewayProcessArgsSync(pid);
|
|
43
43
|
if (!args || !isGatewayArgv(args, { allowGatewayBinary: true })) throw new Error(`refusing to signal non-gateway process pid ${pid}`);
|
|
44
|
+
if (signal === "SIGUSR1" && process.platform === "win32") throw new Error("SIGUSR1 is not supported on Windows; use SIGTERM with a restart intent file instead");
|
|
44
45
|
process.kill(pid, signal);
|
|
45
46
|
}
|
|
46
47
|
function findGatewayPidsOnPortSync(port) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-processes.js","names":[],"sources":["../../../src/infra/gateway-processes.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport fsSync from 'node:fs';\nimport { listPortListeners } from '../gateway/ports.js';\nimport { isGatewayArgv, parseProcCmdline } from './gateway-process-argv.js';\n\nexport function readGatewayProcessArgsSync(pid: number): string[] | null {\n if (process.platform === 'linux') {\n try {\n return parseProcCmdline(fsSync.readFileSync(`/proc/${pid}/cmdline`, 'utf8'));\n } catch {\n return null;\n }\n }\n if (process.platform === 'darwin') {\n const ps = spawnSync('ps', ['-o', 'command=', '-p', String(pid)], {\n encoding: 'utf8',\n timeout: 1000,\n });\n if (ps.error || ps.status !== 0) {\n return null;\n }\n const command = ps.stdout.trim();\n return command ? command.split(/\\s+/) : null;\n }\n if (process.platform === 'win32') {\n const ps = spawnSync(\n 'powershell',\n [\n '-NoProfile',\n '-Command',\n `(Get-CimInstance Win32_Process -Filter \"ProcessId=${pid}\").CommandLine`,\n ],\n { encoding: 'utf8', timeout: 3000 },\n );\n if (ps.error || ps.status !== 0) {\n return null;\n }\n const command = ps.stdout.trim();\n return command ? command.split(/\\s+/) : null;\n }\n return null;\n}\n\nexport function signalVerifiedGatewayPidSync(pid: number, signal: 'SIGTERM' | 'SIGUSR1'): void {\n const args = readGatewayProcessArgsSync(pid);\n if (!args || !isGatewayArgv(args, { allowGatewayBinary: true })) {\n throw new Error(`refusing to signal non-gateway process pid ${pid}`);\n }\n process.kill(pid, signal);\n}\n\nexport function findGatewayPidsOnPortSync(port: number): number[] {\n try {\n return listPortListeners(port)\n .map((entry) => entry.pid)\n .filter((pid): pid is number => Number.isFinite(pid) && pid > 0);\n } catch {\n return [];\n }\n}\n\nexport function findVerifiedGatewayListenerPidsOnPortSync(port: number): number[] {\n return Array.from(new Set(findGatewayPidsOnPortSync(port)))\n .filter((pid) => pid !== process.pid)\n .filter((pid) => {\n const args = readGatewayProcessArgsSync(pid);\n return args != null && isGatewayArgv(args, { allowGatewayBinary: true });\n });\n}\n\nexport function formatGatewayPidList(pids: number[]): string {\n return pids.join(', ');\n}\n"],"mappings":";;;;;AAKA,SAAgB,2BAA2B,KAA8B;AACvE,KAAI,QAAQ,aAAa,QACvB,KAAI;AACF,SAAO,iBAAiB,OAAO,aAAa,SAAS,IAAI,WAAW,OAAO,CAAC;SACtE;AACN,SAAO;;AAGX,KAAI,QAAQ,aAAa,UAAU;EACjC,MAAM,KAAK,UAAU,MAAM;GAAC;GAAM;GAAY;GAAM,OAAO,IAAI;GAAC,EAAE;GAChE,UAAU;GACV,SAAS;GACV,CAAC;AACF,MAAI,GAAG,SAAS,GAAG,WAAW,EAC5B,QAAO;EAET,MAAM,UAAU,GAAG,OAAO,MAAM;AAChC,SAAO,UAAU,QAAQ,MAAM,MAAM,GAAG;;AAE1C,KAAI,QAAQ,aAAa,SAAS;EAChC,MAAM,KAAK,UACT,cACA;GACE;GACA;GACA,qDAAqD,IAAI;GAC1D,EACD;GAAE,UAAU;GAAQ,SAAS;GAAM,CACpC;AACD,MAAI,GAAG,SAAS,GAAG,WAAW,EAC5B,QAAO;EAET,MAAM,UAAU,GAAG,OAAO,MAAM;AAChC,SAAO,UAAU,QAAQ,MAAM,MAAM,GAAG;;AAE1C,QAAO;;AAGT,SAAgB,6BAA6B,KAAa,QAAqC;CAC7F,MAAM,OAAO,2BAA2B,IAAI;AAC5C,KAAI,CAAC,QAAQ,CAAC,cAAc,MAAM,EAAE,oBAAoB,MAAM,CAAC,CAC7D,OAAM,IAAI,MAAM,8CAA8C,MAAM;AAEtE,SAAQ,KAAK,KAAK,OAAO;;AAG3B,SAAgB,0BAA0B,MAAwB;AAChE,KAAI;AACF,SAAO,kBAAkB,KAAK,CAC3B,KAAK,UAAU,MAAM,IAAI,CACzB,QAAQ,QAAuB,OAAO,SAAS,IAAI,IAAI,MAAM,EAAE;SAC5D;AACN,SAAO,EAAE;;;AAIb,SAAgB,0CAA0C,MAAwB;AAChF,QAAO,MAAM,KAAK,IAAI,IAAI,0BAA0B,KAAK,CAAC,CAAC,CACxD,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CACpC,QAAQ,QAAQ;EACf,MAAM,OAAO,2BAA2B,IAAI;AAC5C,SAAO,QAAQ,QAAQ,cAAc,MAAM,EAAE,oBAAoB,MAAM,CAAC;GACxE;;AAGN,SAAgB,qBAAqB,MAAwB;AAC3D,QAAO,KAAK,KAAK,KAAK"}
|
|
1
|
+
{"version":3,"file":"gateway-processes.js","names":[],"sources":["../../../src/infra/gateway-processes.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport fsSync from 'node:fs';\nimport { listPortListeners } from '../gateway/ports.js';\nimport { isGatewayArgv, parseProcCmdline } from './gateway-process-argv.js';\n\nexport function readGatewayProcessArgsSync(pid: number): string[] | null {\n if (process.platform === 'linux') {\n try {\n return parseProcCmdline(fsSync.readFileSync(`/proc/${pid}/cmdline`, 'utf8'));\n } catch {\n return null;\n }\n }\n if (process.platform === 'darwin') {\n const ps = spawnSync('ps', ['-o', 'command=', '-p', String(pid)], {\n encoding: 'utf8',\n timeout: 1000,\n });\n if (ps.error || ps.status !== 0) {\n return null;\n }\n const command = ps.stdout.trim();\n return command ? command.split(/\\s+/) : null;\n }\n if (process.platform === 'win32') {\n const ps = spawnSync(\n 'powershell',\n [\n '-NoProfile',\n '-Command',\n `(Get-CimInstance Win32_Process -Filter \"ProcessId=${pid}\").CommandLine`,\n ],\n { encoding: 'utf8', timeout: 3000 },\n );\n if (ps.error || ps.status !== 0) {\n return null;\n }\n const command = ps.stdout.trim();\n return command ? command.split(/\\s+/) : null;\n }\n return null;\n}\n\nexport function signalVerifiedGatewayPidSync(pid: number, signal: 'SIGTERM' | 'SIGUSR1'): void {\n const args = readGatewayProcessArgsSync(pid);\n if (!args || !isGatewayArgv(args, { allowGatewayBinary: true })) {\n throw new Error(`refusing to signal non-gateway process pid ${pid}`);\n }\n if (signal === 'SIGUSR1' && process.platform === 'win32') {\n throw new Error(\n 'SIGUSR1 is not supported on Windows; use SIGTERM with a restart intent file instead',\n );\n }\n process.kill(pid, signal);\n}\n\nexport function findGatewayPidsOnPortSync(port: number): number[] {\n try {\n return listPortListeners(port)\n .map((entry) => entry.pid)\n .filter((pid): pid is number => Number.isFinite(pid) && pid > 0);\n } catch {\n return [];\n }\n}\n\nexport function findVerifiedGatewayListenerPidsOnPortSync(port: number): number[] {\n return Array.from(new Set(findGatewayPidsOnPortSync(port)))\n .filter((pid) => pid !== process.pid)\n .filter((pid) => {\n const args = readGatewayProcessArgsSync(pid);\n return args != null && isGatewayArgv(args, { allowGatewayBinary: true });\n });\n}\n\nexport function formatGatewayPidList(pids: number[]): string {\n return pids.join(', ');\n}\n"],"mappings":";;;;;AAKA,SAAgB,2BAA2B,KAA8B;AACvE,KAAI,QAAQ,aAAa,QACvB,KAAI;AACF,SAAO,iBAAiB,OAAO,aAAa,SAAS,IAAI,WAAW,OAAO,CAAC;SACtE;AACN,SAAO;;AAGX,KAAI,QAAQ,aAAa,UAAU;EACjC,MAAM,KAAK,UAAU,MAAM;GAAC;GAAM;GAAY;GAAM,OAAO,IAAI;GAAC,EAAE;GAChE,UAAU;GACV,SAAS;GACV,CAAC;AACF,MAAI,GAAG,SAAS,GAAG,WAAW,EAC5B,QAAO;EAET,MAAM,UAAU,GAAG,OAAO,MAAM;AAChC,SAAO,UAAU,QAAQ,MAAM,MAAM,GAAG;;AAE1C,KAAI,QAAQ,aAAa,SAAS;EAChC,MAAM,KAAK,UACT,cACA;GACE;GACA;GACA,qDAAqD,IAAI;GAC1D,EACD;GAAE,UAAU;GAAQ,SAAS;GAAM,CACpC;AACD,MAAI,GAAG,SAAS,GAAG,WAAW,EAC5B,QAAO;EAET,MAAM,UAAU,GAAG,OAAO,MAAM;AAChC,SAAO,UAAU,QAAQ,MAAM,MAAM,GAAG;;AAE1C,QAAO;;AAGT,SAAgB,6BAA6B,KAAa,QAAqC;CAC7F,MAAM,OAAO,2BAA2B,IAAI;AAC5C,KAAI,CAAC,QAAQ,CAAC,cAAc,MAAM,EAAE,oBAAoB,MAAM,CAAC,CAC7D,OAAM,IAAI,MAAM,8CAA8C,MAAM;AAEtE,KAAI,WAAW,aAAa,QAAQ,aAAa,QAC/C,OAAM,IAAI,MACR,sFACD;AAEH,SAAQ,KAAK,KAAK,OAAO;;AAG3B,SAAgB,0BAA0B,MAAwB;AAChE,KAAI;AACF,SAAO,kBAAkB,KAAK,CAC3B,KAAK,UAAU,MAAM,IAAI,CACzB,QAAQ,QAAuB,OAAO,SAAS,IAAI,IAAI,MAAM,EAAE;SAC5D;AACN,SAAO,EAAE;;;AAIb,SAAgB,0CAA0C,MAAwB;AAChF,QAAO,MAAM,KAAK,IAAI,IAAI,0BAA0B,KAAK,CAAC,CAAC,CACxD,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CACpC,QAAQ,QAAQ;EACf,MAAM,OAAO,2BAA2B,IAAI;AAC5C,SAAO,QAAQ,QAAQ,cAAc,MAAM,EAAE,oBAAoB,MAAM,CAAC;GACxE;;AAGN,SAAgB,qBAAqB,MAAwB;AAC3D,QAAO,KAAK,KAAK,KAAK"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
|
|
1
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
|
|
4
|
-
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
4
|
import path from "node:path";
|
|
5
|
+
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
//#region src/infra/restart.ts
|
|
7
7
|
/**
|
|
8
8
|
* Gateway restart coordination — OpenClaw-aligned SIGUSR1 authorization and restart intent.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
|
|
2
2
|
import { channelToNpmTag } from "./update-channels.js";
|
|
3
|
-
import { access, readFile } from "node:fs/promises";
|
|
4
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { access, readFile } from "node:fs/promises";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
//#region src/infra/update-check.ts
|
|
7
7
|
init_package_version();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { init_paths_state, resolveUpdateLockPath } from "../config/paths-state.js";
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
|
-
import {
|
|
5
|
-
import { mkdir, readFile, unlink } from "node:fs/promises";
|
|
4
|
+
import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
|
|
6
5
|
import { dirname } from "node:path";
|
|
6
|
+
import { mkdir, readFile, unlink } from "node:fs/promises";
|
|
7
7
|
//#region src/infra/update-lock.ts
|
|
8
8
|
init_write_file_atomic();
|
|
9
9
|
init_paths_state();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { access, readdir, unlink } from "node:fs/promises";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { access, readdir, unlink } from "node:fs/promises";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
//#region src/infra/update-runner.ts
|
|
7
7
|
init_logger();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
|
|
2
|
-
import {
|
|
2
|
+
import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-state.js";
|
|
3
3
|
import { createLogger } from "../utils/logger/index.js";
|
|
4
4
|
import { init_logger } from "../utils/logger.js";
|
|
5
|
-
import {
|
|
5
|
+
import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
|
|
6
6
|
import { acquireUpdateLock } from "./update-lock.js";
|
|
7
7
|
import { normalizeUpdateChannel } from "./update-channels.js";
|
|
8
8
|
import { compareSemver, detectInstallKind, resolveNpmChannelTag, resolvePackageRoot } from "./update-check.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
import { chmodSync, closeSync, copyFileSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
4
5
|
import { chmod, copyFile, mkdir, open, rename, rm } from "node:fs/promises";
|
|
5
|
-
import path from "node:path";
|
|
6
6
|
//#region src/infra/write-file-atomic.ts
|
|
7
7
|
/**
|
|
8
8
|
* Durable single-file writes: temp file → fsync → rename to target.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
5
5
|
//#region src/providers/auth-runtime/auth-profile-store.ts
|
|
6
6
|
/**
|
|
7
7
|
* {@link AuthProfileStore} implementations.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
3
|
-
import { CredentialResolver, hasCredentials, init_credentials, resolveApiKey } from "../auth/credentials.js";
|
|
4
2
|
import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
|
|
3
|
+
import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
5
4
|
import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
|
|
5
|
+
import { CredentialResolver, hasCredentials, init_credentials, resolveApiKey } from "../auth/credentials.js";
|
|
6
6
|
import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
|
|
7
7
|
import { getModel, getModels, getProviders } from "@earendil-works/pi-ai";
|
|
8
8
|
//#region src/providers/index.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
|
-
import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
5
4
|
import { resolveModelsJsonPath } from "../config/paths.js";
|
|
6
5
|
import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
|
|
7
6
|
import { getDefaultModelValues, init_models_json, validateModelsConfig } from "../config/models-json.js";
|
|
7
|
+
import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
8
8
|
import { existsSync, readFileSync } from "fs";
|
|
9
9
|
import { getModels, getProviders } from "@earendil-works/pi-ai";
|
|
10
10
|
//#region src/providers/model-registry.ts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
|
|
2
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../utils/logger.js";
|
|
4
|
-
import {
|
|
3
|
+
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
|
|
5
4
|
import { join } from "path";
|
|
6
5
|
import { existsSync } from "fs";
|
|
6
|
+
import { mkdir, readFile } from "fs/promises";
|
|
7
7
|
//#region src/session/config-store.ts
|
|
8
8
|
/**
|
|
9
9
|
* Session Config Store
|
|
@@ -3,9 +3,9 @@ import { loadEntriesFromFile } from "./load-jsonl-entries.js";
|
|
|
3
3
|
import { withTranscriptFileLock } from "./transcript-file-lock.js";
|
|
4
4
|
import { emitSessionTranscriptUpdate } from "../transcript-events.js";
|
|
5
5
|
import { buildSessionContextForLlm, isTranscriptContextEntry } from "../session-context-for-llm.js";
|
|
6
|
-
import { randomUUID } from "node:crypto";
|
|
7
|
-
import { existsSync } from "node:fs";
|
|
8
6
|
import path from "node:path";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
9
|
import { CURRENT_SESSION_VERSION, SessionManager } from "@earendil-works/pi-coding-agent";
|
|
10
10
|
//#region src/session/parity/jsonl-transcript-io.ts
|
|
11
11
|
init_write_file_atomic();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
|
|
2
2
|
import { readSessionsJsonFileRaw } from "./sessions-json-file-read.js";
|
|
3
3
|
import { commitSessionsJsonWrite, getSessionsJsonWriteStats, invalidateSessionsJsonCache, noteSessionsJsonWritten, readSessionsJsonCached, resetSessionsJsonCacheForTest } from "./sessions-json-cache.js";
|
|
4
|
+
import { dirname } from "node:path";
|
|
4
5
|
import { existsSync } from "node:fs";
|
|
5
6
|
import { mkdir } from "node:fs/promises";
|
|
6
|
-
import { dirname } from "node:path";
|
|
7
7
|
import lockfile from "proper-lockfile";
|
|
8
8
|
//#region src/session/parity/sessions-json-file.ts
|
|
9
9
|
init_write_file_atomic();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
3
4
|
import { mkdir, open, readFile, rm, stat } from "node:fs/promises";
|
|
4
|
-
import path from "node:path";
|
|
5
5
|
//#region src/session/parity/transcript-file-lock.ts
|
|
6
6
|
/**
|
|
7
7
|
* Cross-process (and re-entrant same-process) advisory lock for session transcript JSONL.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { formatSessionArchiveTimestamp, init_artifacts } from "./artifacts.js";
|
|
3
3
|
import { init_session_id, validateSessionId } from "./session-id.js";
|
|
4
|
-
import fsSync from "node:fs";
|
|
5
4
|
import { dirname, relative, resolve } from "node:path";
|
|
5
|
+
import fsSync from "node:fs";
|
|
6
6
|
//#region src/session/parity/transcript-paths.ts
|
|
7
7
|
function resolveSessionsDir(opts) {
|
|
8
8
|
const sessionsDir = opts?.sessionsDir?.trim();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FILENAMES, init_paths } from "../config/paths.js";
|
|
2
2
|
import { SessionSearchIndex } from "./search-index.js";
|
|
3
|
-
import { stat } from "node:fs/promises";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { stat } from "node:fs/promises";
|
|
5
5
|
//#region src/session/search-index-cache.ts
|
|
6
6
|
/**
|
|
7
7
|
* Shared cache for {@link SessionSearchIndex} builds (invalidated on session writes).
|
|
@@ -2,8 +2,8 @@ import { init_transcript_paths, resolveSessionFilePath } from "./parity/transcri
|
|
|
2
2
|
import { FILENAMES, init_paths } from "../config/paths.js";
|
|
3
3
|
import { isTranscriptContextEntry } from "./session-context-for-llm.js";
|
|
4
4
|
import { readTranscriptRowsFromFile, rowsToLlmMessages } from "./parity/jsonl-transcript-io.js";
|
|
5
|
-
import { readFile } from "node:fs/promises";
|
|
6
5
|
import { join } from "node:path";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
7
|
//#region src/session/search-index.ts
|
|
8
8
|
/**
|
|
9
9
|
* In-memory inverted index over session transcripts (`sessions.json` + JSONL).
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { init_session_key, isCronSessionKey, parseSessionKey } from "../routing/session-key.js";
|
|
1
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { init_session_key, isCronSessionKey, parseSessionKey } from "../routing/session-key.js";
|
|
4
4
|
import { init_providers, resolveModel } from "../providers/index.js";
|
|
5
5
|
import { readAgentMessageContent } from "../agent/memory/agent-message-access.js";
|
|
6
|
+
import { stripSessionStartupContextFromUserText } from "../agent/reply/startup-context.js";
|
|
6
7
|
import { stripInboundFileMetadataFromText } from "../channels/attachments/inbound-persist.js";
|
|
7
8
|
import { stripEnvelopeTimestampPrefix } from "../channels/envelope-timestamp.js";
|
|
8
9
|
import { complete } from "@earendil-works/pi-ai";
|
|
@@ -31,7 +32,7 @@ function extractTextFromMessage(m) {
|
|
|
31
32
|
function firstUserText(messages) {
|
|
32
33
|
const u = messages.find((m) => m.role === "user");
|
|
33
34
|
if (!u) return "";
|
|
34
|
-
return stripInboundFileMetadataFromText(stripEnvelopeTimestampPrefix(extractTextFromMessage(u)));
|
|
35
|
+
return stripInboundFileMetadataFromText(stripEnvelopeTimestampPrefix(stripSessionStartupContextFromUserText(extractTextFromMessage(u))));
|
|
35
36
|
}
|
|
36
37
|
/** First assistant message that has visible text (skips tool-only assistant rows). */
|
|
37
38
|
function firstAssistantText(messages) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-title.js","names":[],"sources":["../../../src/session/session-title.ts"],"sourcesContent":["/**\n * LLM-generated session titles (webchat and any path using SessionStore).\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport { complete, type UserMessage } from '@earendil-works/pi-ai';\n\nimport { stripInboundFileMetadataFromText } from '../channels/attachments/inbound-persist.js';\nimport { stripEnvelopeTimestampPrefix } from '../channels/envelope-timestamp.js';\nimport { isCronSessionKey, parseSessionKey } from '../routing/session-key.js';\nimport { resolveModel } from '../providers/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { readAgentMessageContent } from '../agent/memory/agent-message-access.js';\nimport type { SessionStore } from './store.js';\n\nconst log = createLogger('SessionAutoTitle');\n\nconst MAX_TITLE_LEN = 80;\n\n/** Collect visible text from any content block that exposes `text` (pi-ai / OpenAI / Anthropic shapes). */\nfunction extractTextFromMessage(m: AgentMessage): string {\n const raw = readAgentMessageContent(m);\n if (typeof raw === 'string') return raw.trim();\n if (Array.isArray(raw)) {\n const parts: string[] = [];\n for (const c of raw) {\n if (c && typeof c === 'object') {\n const o = c as unknown as Record<string, unknown>;\n const type = typeof o.type === 'string' ? o.type : '';\n if (type === 'toolCall' || type === 'tool_use' || type === 'tool_result') continue;\n if (typeof o.text === 'string' && o.text.trim()) {\n parts.push(o.text.trim());\n }\n }\n }\n return parts.join(' ').trim();\n }\n return '';\n}\n\nfunction firstUserText(messages: AgentMessage[]): string {\n const u = messages.find((m) => m.role === 'user');\n if (!u) return '';\n const raw = extractTextFromMessage(u);\n // User turns include `formatInboundFileTextBlock` text blocks; do not feed [File:…] into title LLM / fallback.\n // Inbound pipeline / webchat prepends `[YYYY-MM-DD HH:MM TZ]`; strip so titles are not timestamp-led.\n return stripInboundFileMetadataFromText(stripEnvelopeTimestampPrefix(raw));\n}\n\n/** First assistant message that has visible text (skips tool-only assistant rows). */\nfunction firstAssistantText(messages: AgentMessage[]): string {\n for (const m of messages) {\n if (m.role === 'assistant') {\n const t = extractTextFromMessage(m);\n if (t.length > 0) return t;\n }\n }\n return '';\n}\n\nexport function isWebchatSessionKey(sessionKey: string): boolean {\n const p = parseSessionKey(sessionKey);\n if (p?.source === 'webchat') return true;\n return sessionKey.includes(':webchat:');\n}\n\n/** Whether to run LLM/fallback session naming for this key (excludes cron, heartbeat). */\nexport function shouldAutoTitleSessionKey(sessionKey: string): boolean {\n const raw = (sessionKey ?? '').trim();\n if (!raw) return false;\n if (isCronSessionKey(raw)) return false;\n if (raw.toLowerCase().startsWith('heartbeat:')) return false;\n return true;\n}\n\nexport function sanitizeSessionTitle(raw: string): string {\n let s = raw.trim();\n if ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\"))) {\n s = s.slice(1, -1).trim();\n }\n const lineBreak = s.indexOf('\\n');\n if (lineBreak !== -1) s = s.slice(0, lineBreak).trim();\n if (s.length > MAX_TITLE_LEN) s = s.slice(0, MAX_TITLE_LEN - 1).trimEnd() + '…';\n return s;\n}\n\n/** Non-LLM title: first line of first user text, else first assistant line. */\nexport function fallbackTitleFromMessages(messages: AgentMessage[]): string | null {\n const u = firstUserText(messages);\n if (u) {\n const line = u.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n const a = firstAssistantText(messages);\n if (a) {\n const line = a.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n return null;\n}\n\n/**\n * Returns a title string, or null if generation should be skipped or failed.\n */\nexport async function generateSessionTitleFromMessages(\n modelRef: string,\n messages: AgentMessage[],\n signal?: AbortSignal,\n): Promise<string | null> {\n const userText = firstUserText(messages);\n const assistantText = firstAssistantText(messages);\n if (!userText && !assistantText) return null;\n\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(modelRef);\n } catch (err) {\n log.warn({ err, modelRef }, 'Cannot resolve model for session title');\n return null;\n }\n\n const prompt =\n userText && assistantText\n ? `You label chat sessions. Given the first user message and the start of the assistant reply, output ONE short title (max 8 words). No quotes. No punctuation at the end. Use the same language as the user when possible.\n\nUser: ${userText.slice(0, 2000)}\n\nAssistant: ${assistantText.slice(0, 2000)}\n\nTitle:`\n : userText\n ? `The assistant reply only used tools (no visible text yet). Output ONE short title (max 8 words) based only on the user's first message. No quotes. No punctuation at the end. Use the same language as the user.\n\nUser: ${userText.slice(0, 2000)}\n\nTitle:`\n : `Output ONE short title (max 8 words) for this assistant reply. No quotes. No punctuation at the end.\n\nAssistant: ${assistantText!.slice(0, 2000)}\n\nTitle:`;\n\n const userMsg: UserMessage = { role: 'user', content: prompt, timestamp: Date.now() };\n\n try {\n const result = await complete(\n model,\n { messages: [userMsg] },\n {\n maxTokens: 64,\n temperature: 0.35,\n signal: signal as AbortSignal,\n },\n );\n\n let text = '';\n if (Array.isArray(result.content)) {\n for (const c of result.content) {\n if (c && typeof c === 'object' && (c as { type?: string }).type === 'text') {\n text += String((c as { text?: string }).text || '');\n }\n }\n }\n\n const cleaned = sanitizeSessionTitle(text);\n return cleaned.length > 0 ? cleaned : null;\n } catch (err) {\n log.warn({ err }, 'Session title LLM call failed');\n return null;\n }\n}\n\n/**\n * If the session is still unnamed, set `name` (LLM when possible, else first-line fallback).\n * Skips cron/heartbeat keys. Ensures index row exists by re-saving when metadata is missing (fixes index lag).\n */\nexport async function maybeAutoTitleSessionStore(\n sessionStore: SessionStore,\n sessionKey: string,\n modelRef: string | undefined,\n): Promise<void> {\n if (!shouldAutoTitleSessionKey(sessionKey)) return;\n\n let messages = await sessionStore.load(sessionKey);\n if (!messages.length) return;\n\n let meta = await sessionStore.getMetadata(sessionKey);\n if (!meta) {\n await sessionStore.save(sessionKey, messages);\n meta = await sessionStore.getMetadata(sessionKey);\n }\n if (!meta) {\n log.warn({ sessionKey }, 'Session title: metadata missing after save');\n return;\n }\n if (meta.name && meta.name.trim().length > 0) return;\n\n let title: string | null = null;\n const ref = modelRef?.trim();\n if (ref) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 25_000);\n try {\n title = await generateSessionTitleFromMessages(ref, messages, controller.signal);\n } finally {\n clearTimeout(timeout);\n }\n }\n if (!title) {\n title = fallbackTitleFromMessages(messages);\n }\n if (!title) return;\n\n try {\n await sessionStore.updateMetadata(sessionKey, { name: title });\n } catch (err) {\n log.warn({ err, sessionKey }, 'Session title: updateMetadata failed');\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-title.js","names":[],"sources":["../../../src/session/session-title.ts"],"sourcesContent":["/**\n * LLM-generated session titles (webchat and any path using SessionStore).\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport { complete, type UserMessage } from '@earendil-works/pi-ai';\n\nimport { stripSessionStartupContextFromUserText } from '../agent/reply/startup-context.js';\nimport { stripInboundFileMetadataFromText } from '../channels/attachments/inbound-persist.js';\nimport { stripEnvelopeTimestampPrefix } from '../channels/envelope-timestamp.js';\nimport { isCronSessionKey, parseSessionKey } from '../routing/session-key.js';\nimport { resolveModel } from '../providers/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { readAgentMessageContent } from '../agent/memory/agent-message-access.js';\nimport type { SessionStore } from './store.js';\n\nconst log = createLogger('SessionAutoTitle');\n\nconst MAX_TITLE_LEN = 80;\n\n/** Collect visible text from any content block that exposes `text` (pi-ai / OpenAI / Anthropic shapes). */\nfunction extractTextFromMessage(m: AgentMessage): string {\n const raw = readAgentMessageContent(m);\n if (typeof raw === 'string') return raw.trim();\n if (Array.isArray(raw)) {\n const parts: string[] = [];\n for (const c of raw) {\n if (c && typeof c === 'object') {\n const o = c as unknown as Record<string, unknown>;\n const type = typeof o.type === 'string' ? o.type : '';\n if (type === 'toolCall' || type === 'tool_use' || type === 'tool_result') continue;\n if (typeof o.text === 'string' && o.text.trim()) {\n parts.push(o.text.trim());\n }\n }\n }\n return parts.join(' ').trim();\n }\n return '';\n}\n\nfunction firstUserText(messages: AgentMessage[]): string {\n const u = messages.find((m) => m.role === 'user');\n if (!u) return '';\n const raw = extractTextFromMessage(u);\n // User turns include `formatInboundFileTextBlock` text blocks; do not feed [File:…] into title LLM / fallback.\n // Inbound pipeline / webchat prepends `[YYYY-MM-DD HH:MM TZ]`; strip so titles are not timestamp-led.\n return stripInboundFileMetadataFromText(\n stripEnvelopeTimestampPrefix(stripSessionStartupContextFromUserText(raw)),\n );\n}\n\n/** First assistant message that has visible text (skips tool-only assistant rows). */\nfunction firstAssistantText(messages: AgentMessage[]): string {\n for (const m of messages) {\n if (m.role === 'assistant') {\n const t = extractTextFromMessage(m);\n if (t.length > 0) return t;\n }\n }\n return '';\n}\n\nexport function isWebchatSessionKey(sessionKey: string): boolean {\n const p = parseSessionKey(sessionKey);\n if (p?.source === 'webchat') return true;\n return sessionKey.includes(':webchat:');\n}\n\n/** Whether to run LLM/fallback session naming for this key (excludes cron, heartbeat). */\nexport function shouldAutoTitleSessionKey(sessionKey: string): boolean {\n const raw = (sessionKey ?? '').trim();\n if (!raw) return false;\n if (isCronSessionKey(raw)) return false;\n if (raw.toLowerCase().startsWith('heartbeat:')) return false;\n return true;\n}\n\nexport function sanitizeSessionTitle(raw: string): string {\n let s = raw.trim();\n if ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\"))) {\n s = s.slice(1, -1).trim();\n }\n const lineBreak = s.indexOf('\\n');\n if (lineBreak !== -1) s = s.slice(0, lineBreak).trim();\n if (s.length > MAX_TITLE_LEN) s = s.slice(0, MAX_TITLE_LEN - 1).trimEnd() + '…';\n return s;\n}\n\n/** Non-LLM title: first line of first user text, else first assistant line. */\nexport function fallbackTitleFromMessages(messages: AgentMessage[]): string | null {\n const u = firstUserText(messages);\n if (u) {\n const line = u.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n const a = firstAssistantText(messages);\n if (a) {\n const line = a.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n return null;\n}\n\n/**\n * Returns a title string, or null if generation should be skipped or failed.\n */\nexport async function generateSessionTitleFromMessages(\n modelRef: string,\n messages: AgentMessage[],\n signal?: AbortSignal,\n): Promise<string | null> {\n const userText = firstUserText(messages);\n const assistantText = firstAssistantText(messages);\n if (!userText && !assistantText) return null;\n\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(modelRef);\n } catch (err) {\n log.warn({ err, modelRef }, 'Cannot resolve model for session title');\n return null;\n }\n\n const prompt =\n userText && assistantText\n ? `You label chat sessions. Given the first user message and the start of the assistant reply, output ONE short title (max 8 words). No quotes. No punctuation at the end. Use the same language as the user when possible.\n\nUser: ${userText.slice(0, 2000)}\n\nAssistant: ${assistantText.slice(0, 2000)}\n\nTitle:`\n : userText\n ? `The assistant reply only used tools (no visible text yet). Output ONE short title (max 8 words) based only on the user's first message. No quotes. No punctuation at the end. Use the same language as the user.\n\nUser: ${userText.slice(0, 2000)}\n\nTitle:`\n : `Output ONE short title (max 8 words) for this assistant reply. No quotes. No punctuation at the end.\n\nAssistant: ${assistantText!.slice(0, 2000)}\n\nTitle:`;\n\n const userMsg: UserMessage = { role: 'user', content: prompt, timestamp: Date.now() };\n\n try {\n const result = await complete(\n model,\n { messages: [userMsg] },\n {\n maxTokens: 64,\n temperature: 0.35,\n signal: signal as AbortSignal,\n },\n );\n\n let text = '';\n if (Array.isArray(result.content)) {\n for (const c of result.content) {\n if (c && typeof c === 'object' && (c as { type?: string }).type === 'text') {\n text += String((c as { text?: string }).text || '');\n }\n }\n }\n\n const cleaned = sanitizeSessionTitle(text);\n return cleaned.length > 0 ? cleaned : null;\n } catch (err) {\n log.warn({ err }, 'Session title LLM call failed');\n return null;\n }\n}\n\n/**\n * If the session is still unnamed, set `name` (LLM when possible, else first-line fallback).\n * Skips cron/heartbeat keys. Ensures index row exists by re-saving when metadata is missing (fixes index lag).\n */\nexport async function maybeAutoTitleSessionStore(\n sessionStore: SessionStore,\n sessionKey: string,\n modelRef: string | undefined,\n): Promise<void> {\n if (!shouldAutoTitleSessionKey(sessionKey)) return;\n\n let messages = await sessionStore.load(sessionKey);\n if (!messages.length) return;\n\n let meta = await sessionStore.getMetadata(sessionKey);\n if (!meta) {\n await sessionStore.save(sessionKey, messages);\n meta = await sessionStore.getMetadata(sessionKey);\n }\n if (!meta) {\n log.warn({ sessionKey }, 'Session title: metadata missing after save');\n return;\n }\n if (meta.name && meta.name.trim().length > 0) return;\n\n let title: string | null = null;\n const ref = modelRef?.trim();\n if (ref) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 25_000);\n try {\n title = await generateSessionTitleFromMessages(ref, messages, controller.signal);\n } finally {\n clearTimeout(timeout);\n }\n }\n if (!title) {\n title = fallbackTitleFromMessages(messages);\n }\n if (!title) return;\n\n try {\n await sessionStore.updateMetadata(sessionKey, { name: title });\n } catch (err) {\n log.warn({ err, sessionKey }, 'Session title: updateMetadata failed');\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { init_agent_scope, listAgentEntries, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
2
|
+
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
3
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
1
4
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
5
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { init_agent_scope, listAgentEntries, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
4
6
|
import { init_artifacts, parseCompactionCheckpointTranscriptFileName } from "./parity/artifacts.js";
|
|
5
7
|
import { init_session_id, validateSessionId } from "./parity/session-id.js";
|
|
6
8
|
import { archiveFileOnDisk, init_transcript_paths, resolveSessionFilePath, resolveSessionTranscriptPathInDir } from "./parity/transcript-paths.js";
|
|
7
9
|
import { FILENAMES, init_paths, resolveSessionsDir } from "../config/paths.js";
|
|
8
|
-
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
9
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
10
10
|
import { loadEntriesFromFile } from "./parity/load-jsonl-entries.js";
|
|
11
11
|
import { mergeLlmMessagesPreservingContextRows } from "./session-context-for-llm.js";
|
|
12
12
|
import { appendPiTranscriptContextEntry, persistMergedTranscriptRows, readTranscriptRowsFromFile, rowsToLlmMessages, writeTranscriptJsonl } from "./parity/jsonl-transcript-io.js";
|
|
@@ -19,10 +19,10 @@ import "./types.js";
|
|
|
19
19
|
import { readSessionsJsonFile, withSessionsJsonLock } from "./parity/sessions-json-file.js";
|
|
20
20
|
import { buildSessionsJsonStatsPatch, incrementSessionsJsonStatsForAppend, isAppendOnlyLlmTranscriptMessage, patchSessionsJsonEntryStats } from "./parity/sessions-json-patch.js";
|
|
21
21
|
import { countTranscriptMessageRows, readDisplayMessagePageFromTranscriptFile } from "./parity/transcript-pagination.js";
|
|
22
|
-
import { copyFile, mkdir, readdir, stat, unlink } from "fs/promises";
|
|
23
|
-
import { randomUUID } from "node:crypto";
|
|
24
22
|
import { join } from "path";
|
|
25
23
|
import { existsSync } from "fs";
|
|
24
|
+
import { copyFile, mkdir, readdir, stat, unlink } from "fs/promises";
|
|
25
|
+
import { randomUUID } from "node:crypto";
|
|
26
26
|
//#region src/session/store.ts
|
|
27
27
|
init_paths();
|
|
28
28
|
init_agent_scope();
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export type ShareAudience = 'friend' | 'colleague' | 'public';
|
|
2
|
+
export type ShareAutoMode = 'auto' | 'force-file' | 'force-site' | 'force-zip';
|
|
3
|
+
export type ShareAutoKind = 'file' | 'site' | 'zip';
|
|
4
|
+
export interface ShareAutoDecision {
|
|
5
|
+
kind: ShareAutoKind;
|
|
6
|
+
isDirectory: boolean;
|
|
7
|
+
reason: 'html-single-file' | 'html-with-assets' | 'small-image' | 'large-binary' | 'directory-zip' | 'directory-browse' | 'forced';
|
|
8
|
+
hint: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ShareAutoProbe {
|
|
11
|
+
absolutePath: string;
|
|
12
|
+
kind: 'file' | 'directory';
|
|
13
|
+
size: number;
|
|
14
|
+
mimeType: string;
|
|
15
|
+
hasIndexHtml: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ShareAutoDefaults {
|
|
18
|
+
ttlMs: number;
|
|
19
|
+
maxViews: number | null;
|
|
20
|
+
}
|
|
21
|
+
/** Convert an audience hint into TTL/maxViews defaults. */
|
|
22
|
+
export declare function audienceDefaults(audience: ShareAudience | undefined): ShareAutoDefaults;
|
|
23
|
+
/** Run filesystem probes needed by the routing logic. */
|
|
24
|
+
export declare function probeShareTarget(workspaceRoot: string, relPath: string): Promise<ShareAutoProbe>;
|
|
25
|
+
/** Pure decision function — exported for tests. */
|
|
26
|
+
export declare function decideShareKind(probe: ShareAutoProbe, mode: ShareAutoMode | undefined): ShareAutoDecision;
|
|
27
|
+
/** Build the user-facing title (trimmed, no extension). */
|
|
28
|
+
export declare function makeTitle(fileName: string, override?: string): string;
|
|
29
|
+
/** Build the user-facing description (audience + TTL hint baked in). */
|
|
30
|
+
export declare function makeDescription(opts: {
|
|
31
|
+
audience: ShareAudience | undefined;
|
|
32
|
+
expiresAt: string;
|
|
33
|
+
override?: string;
|
|
34
|
+
}): string;
|
|
35
|
+
/** Subfolder under the workspace where single-HTML site shares are staged. */
|
|
36
|
+
export declare const STAGING_DIR_NAME = ".xopc-share-staging";
|
|
37
|
+
export interface StagedSite {
|
|
38
|
+
/** Absolute path of the freshly-created staging directory. */
|
|
39
|
+
stagingDir: string;
|
|
40
|
+
/** Workspace-relative path to feed into SiteShareStore.create({ path }). */
|
|
41
|
+
relativePath: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Copy a single HTML file into `<workspaceRoot>/.xopc-share-staging/<uuid>/index.html`
|
|
45
|
+
* so it can be served as a site (SiteShareStore needs a directory root).
|
|
46
|
+
*
|
|
47
|
+
* The caller must register a cleanup that calls `cleanupStagedSite(stagingDir)`
|
|
48
|
+
* when the underlying site share is revoked / expires.
|
|
49
|
+
*/
|
|
50
|
+
export declare function stageSingleHtmlAsSite(workspaceRoot: string, absoluteHtmlPath: string): Promise<StagedSite>;
|
|
51
|
+
/** Best-effort cleanup; never throws. */
|
|
52
|
+
export declare function cleanupStagedSite(stagingDir: string): Promise<void>;
|
|
53
|
+
export declare function rememberStagedSite(recordId: string, stagingDir: string): void;
|
|
54
|
+
export declare function forgetStagedSite(recordId: string): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Walk `<workspaceRoot>/.xopc-share-staging/` and drop directories that are
|
|
57
|
+
* no longer referenced by any live site-share record. Call at gateway boot.
|
|
58
|
+
*/
|
|
59
|
+
export declare function sweepOrphanedStagingDirs(workspaceRoot: string, liveStagingDirs: Set<string>): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Boot-time housekeeping:
|
|
62
|
+
* 1. Walk active static site shares whose source lives under STAGING_DIR_NAME
|
|
63
|
+
* (i.e. created via `stageSingleHtmlAsSite`).
|
|
64
|
+
* 2. Re-register them in the in-process registry so the SiteShareStore
|
|
65
|
+
* cleanup hook still wipes the right directory on revoke/expire after a
|
|
66
|
+
* restart.
|
|
67
|
+
* 3. Sweep each workspace's `.xopc-share-staging/` for entries that are not
|
|
68
|
+
* referenced by any live record — these are leftovers from a previous
|
|
69
|
+
* process death between create-staging and persist.
|
|
70
|
+
*
|
|
71
|
+
* Safe to call multiple times; idempotent. Best invoked from gateway.start().
|
|
72
|
+
*/
|
|
73
|
+
export declare function runStagingSweep(): Promise<void>;
|
|
74
|
+
export declare function resetStagedSiteRegistryForTests(): void;
|