@songsid/agend 2.3.3 → 2.3.4-beta.10
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 +3 -3
- package/README.zh-TW.md +3 -3
- package/THIRD_PARTY_NOTICES.md +37 -0
- package/dist/agend-home.d.ts +13 -0
- package/dist/agend-home.js +42 -0
- package/dist/agend-home.js.map +1 -1
- package/dist/agent-cli-instructions.md +2 -2
- package/dist/agent-credentials.d.ts +24 -0
- package/dist/agent-credentials.js +66 -0
- package/dist/agent-credentials.js.map +1 -0
- package/dist/agent-endpoint.d.ts +3 -1
- package/dist/agent-endpoint.js +13 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/auth-api.d.ts +16 -3
- package/dist/auth-api.js +32 -8
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +28 -4
- package/dist/authority/session-authorizations.js +63 -17
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +15 -1
- package/dist/authority/web-authority.js +27 -10
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/antigravity.js +3 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +3 -0
- package/dist/backend/claude-code.js +100 -5
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-footer-hints.d.ts +4 -0
- package/dist/backend/codex-footer-hints.js +27 -0
- package/dist/backend/codex-footer-hints.js.map +1 -0
- package/dist/backend/codex-session-lookup.d.ts +35 -0
- package/dist/backend/codex-session-lookup.js +93 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.d.ts +27 -0
- package/dist/backend/codex.js +136 -23
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro-identity.d.ts +2 -0
- package/dist/backend/kiro-identity.js +13 -6
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -0
- package/dist/backend/kiro.js +68 -5
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +5 -3
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +13 -1
- package/dist/backend/types.js +3 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-availability.d.ts +6 -0
- package/dist/backend-availability.js +13 -5
- package/dist/backend-availability.js.map +1 -1
- package/dist/cache-ledger.d.ts +85 -0
- package/dist/cache-ledger.js +236 -1
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +5 -0
- package/dist/cache-service.js +16 -4
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.js +27 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +51 -0
- package/dist/channel/adapters/telegram.js +238 -18
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/inbox-temp-name.d.ts +9 -0
- package/dist/channel/inbox-temp-name.js +13 -0
- package/dist/channel/inbox-temp-name.js.map +1 -0
- package/dist/channel/mcp-tools.js +3 -3
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +2 -0
- package/dist/chat-log-ids.d.ts +48 -0
- package/dist/chat-log-ids.js +182 -0
- package/dist/chat-log-ids.js.map +1 -0
- package/dist/classic-channel-manager.d.ts +8 -1
- package/dist/classic-channel-manager.js +24 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +18 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +10 -0
- package/dist/cross-instance-notice.js +67 -5
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +52 -0
- package/dist/daemon.js +538 -35
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +23 -1
- package/dist/delivery-consumed-watch.js +30 -3
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +7 -0
- package/dist/delivery-reconciliation.js +9 -1
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/dialog-screen-text.d.ts +16 -0
- package/dist/dialog-screen-text.js +51 -0
- package/dist/dialog-screen-text.js.map +1 -0
- package/dist/env-file.d.ts +2 -0
- package/dist/env-file.js +13 -8
- package/dist/env-file.js.map +1 -1
- package/dist/export-import.d.ts +7 -0
- package/dist/export-import.js +44 -10
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-context.d.ts +2 -0
- package/dist/fleet-manager.d.ts +172 -12
- package/dist/fleet-manager.js +897 -139
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-yaml-patch.d.ts +3 -0
- package/dist/fleet-yaml-patch.js +103 -0
- package/dist/fleet-yaml-patch.js.map +1 -0
- package/dist/general-knowledge/skills/concepts/SKILL.md +393 -0
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +2 -1
- package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +41 -4
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +2 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +14 -4
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/install-stream.d.ts +53 -0
- package/dist/install-stream.js +134 -0
- package/dist/install-stream.js.map +1 -0
- package/dist/instance-config-impact.js +1 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +22 -2
- package/dist/instance-lifecycle.js +103 -19
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-topic-delete.d.ts +77 -0
- package/dist/instance-topic-delete.js +123 -0
- package/dist/instance-topic-delete.js.map +1 -0
- package/dist/instructions.d.ts +2 -2
- package/dist/instructions.js +2 -2
- package/dist/instructions.js.map +1 -1
- package/dist/interaction-observation.d.ts +1 -0
- package/dist/interaction-observation.js +1 -1
- package/dist/interaction-observation.js.map +1 -1
- package/dist/kiro-engine-status.d.ts +11 -0
- package/dist/kiro-engine-status.js +6 -0
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/kiro-resume-summary.d.ts +37 -0
- package/dist/kiro-resume-summary.js +85 -0
- package/dist/kiro-resume-summary.js.map +1 -0
- package/dist/locale.js +130 -6
- package/dist/locale.js.map +1 -1
- package/dist/log-service.d.ts +30 -0
- package/dist/log-service.js +36 -3
- package/dist/log-service.js.map +1 -1
- package/dist/log-steps.d.ts +4 -3
- package/dist/log-steps.js +32 -7
- package/dist/log-steps.js.map +1 -1
- package/dist/logger.d.ts +12 -0
- package/dist/logger.js +43 -1
- package/dist/logger.js.map +1 -1
- package/dist/login-controller.js +9 -1
- package/dist/login-controller.js.map +1 -1
- package/dist/login-flows.d.ts +2 -0
- package/dist/login-flows.js +5 -2
- package/dist/login-flows.js.map +1 -1
- package/dist/login-manager.d.ts +6 -0
- package/dist/login-manager.js +10 -1
- package/dist/login-manager.js.map +1 -1
- package/dist/missed-offline.d.ts +25 -0
- package/dist/missed-offline.js +79 -0
- package/dist/missed-offline.js.map +1 -0
- package/dist/needs-you-hub.d.ts +6 -1
- package/dist/needs-you-hub.js +31 -8
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +22 -2
- package/dist/needs-you.js +17 -3
- package/dist/needs-you.js.map +1 -1
- package/dist/next-steps.d.ts +12 -2
- package/dist/next-steps.js +19 -3
- package/dist/next-steps.js.map +1 -1
- package/dist/office-share-page.d.ts +1 -1
- package/dist/office-share-page.js +6 -2
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share-service.d.ts +57 -0
- package/dist/office-share-service.js +76 -11
- package/dist/office-share-service.js.map +1 -1
- package/dist/office-share.d.ts +8 -0
- package/dist/office-share.js +34 -0
- package/dist/office-share.js.map +1 -1
- package/dist/outbound-handlers.js +59 -3
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +1 -0
- package/dist/outbound-schemas.js +10 -4
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/package-preimage.js +27 -2
- package/dist/package-preimage.js.map +1 -1
- package/dist/page-share.d.ts +122 -0
- package/dist/page-share.js +199 -0
- package/dist/page-share.js.map +1 -0
- package/dist/public-preview.d.ts +4 -0
- package/dist/public-preview.js +5 -4
- package/dist/public-preview.js.map +1 -1
- package/dist/public-web-gateway.js +5 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/queued-handoffs.d.ts +33 -0
- package/dist/queued-handoffs.js +75 -0
- package/dist/queued-handoffs.js.map +1 -0
- package/dist/quickstart-api.d.ts +5 -0
- package/dist/quickstart-api.js +1 -1
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +40 -0
- package/dist/quickstart.js +174 -28
- package/dist/quickstart.js.map +1 -1
- package/dist/remote-card-answer.js +2 -0
- package/dist/remote-card-answer.js.map +1 -1
- package/dist/remote-card-prompt.js +4 -2
- package/dist/remote-card-prompt.js.map +1 -1
- package/dist/reply-buttons-controller.js +10 -0
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/scheduler/db.d.ts +2 -1
- package/dist/scheduler/db.js +23 -9
- package/dist/scheduler/db.js.map +1 -1
- package/dist/selection-card.d.ts +20 -0
- package/dist/selection-card.js +202 -0
- package/dist/selection-card.js.map +1 -0
- package/dist/settings-api.d.ts +13 -0
- package/dist/settings-api.js +16 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +5 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +2 -0
- package/dist/settings-effect.js.map +1 -1
- package/dist/setup-host.js +2 -2
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +2 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/stall-reporter.d.ts +21 -0
- package/dist/stall-reporter.js +82 -0
- package/dist/stall-reporter.js.map +1 -0
- package/dist/tmux-control.d.ts +2 -2
- package/dist/tmux-control.js +4 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.d.ts +6 -3
- package/dist/tmux-exec-helper.js +115 -53
- package/dist/tmux-exec-helper.js.map +1 -1
- package/dist/tmux-manager.d.ts +6 -0
- package/dist/tmux-manager.js +17 -0
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.d.ts +5 -2
- package/dist/tool-permissions.js +6 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.d.ts +2 -0
- package/dist/tool-progress.js +19 -3
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-commands.js +4 -0
- package/dist/topic-commands.js.map +1 -1
- package/dist/tunnel/cloudflared-install.d.ts +4 -0
- package/dist/tunnel/cloudflared-install.js +20 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/cloudflared.d.ts +8 -1
- package/dist/tunnel/cloudflared.js +34 -6
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/lease.d.ts +3 -3
- package/dist/tunnel/lease.js +23 -19
- package/dist/tunnel/lease.js.map +1 -1
- package/dist/tunnel/manager.js +6 -7
- package/dist/tunnel/manager.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/ui/chat-store.js +28 -4
- package/dist/ui/chat-strings.js +40 -4
- package/dist/ui/chat-thread.js +52 -10
- package/dist/ui/fleet-canvas.js +4 -3
- package/dist/ui/fleet-office-model.js +55 -22
- package/dist/ui/fleet-office-overview.js +6 -38
- package/dist/ui/fleet-office-pack.js +4 -3
- package/dist/ui/fleet-office-skin.js +114 -21
- package/dist/ui/fleet-office-store.js +5 -0
- package/dist/ui/fleet-office-zones.js +2 -2
- package/dist/ui/fleet-office.js +41 -9
- package/dist/ui/fleet-usage.js +90 -27
- package/dist/ui/page-share-dialog.js +191 -0
- package/dist/ui/panel-chat.js +16 -0
- package/dist/ui/panel-log.js +7 -1
- package/dist/ui/panel-needs.js +17 -8
- package/dist/ui/panel-notices.js +98 -0
- package/dist/ui/panel-settings.js +9 -2
- package/dist/ui/preview-pages.js +41 -0
- package/dist/ui/preview-panel-actions.js +161 -0
- package/dist/ui/preview-panel.js +209 -28
- package/dist/ui/preview-versions.js +155 -0
- package/dist/ui/preview.js +88 -3
- package/dist/ui/settings-registry.js +1 -0
- package/dist/ui/settings-strings.js +6 -2
- package/dist/ui/shared/app-i18n.js +6 -6
- package/dist/ui/shared/app-needs.js +1 -1
- package/dist/ui/shared/app-route.js +4 -0
- package/dist/ui/shared/app-shell.js +9 -5
- package/dist/ui/shared/app-store.js +71 -1
- package/dist/ui/shared/app-stream.js +27 -1
- package/dist/ui/shared/app.css +94 -4
- package/dist/ui/shared/app.js +22 -1
- package/dist/ui/shared/office/guild.png +0 -0
- package/dist/ui/shared/office/school.png +0 -0
- package/dist/ui/shared/panel-view.js +339 -17
- package/dist/ui/shared/signin.js +12 -1
- package/dist/ui/shared/ui-icons.js +3 -0
- package/dist/ui/shared/usage-dialog.js +18 -1
- package/dist/ui/shared/view-history.css +17 -0
- package/dist/ui/shared/view-history.js +438 -0
- package/dist/ui/shared/view-strings.js +42 -0
- package/dist/ui/shared/web-authorize.js +3 -1
- package/dist/unattended-install.d.ts +6 -0
- package/dist/unattended-install.js +79 -0
- package/dist/unattended-install.js.map +1 -0
- package/dist/usage/capacity.d.ts +69 -0
- package/dist/usage/capacity.js +119 -0
- package/dist/usage/capacity.js.map +1 -0
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +3 -0
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/profile-timeline.d.ts +16 -0
- package/dist/usage/profile-timeline.js +58 -0
- package/dist/usage/profile-timeline.js.map +1 -0
- package/dist/usage/quota-history.d.ts +43 -0
- package/dist/usage/quota-history.js +168 -0
- package/dist/usage/quota-history.js.map +1 -0
- package/dist/usage/usage-api.d.ts +31 -0
- package/dist/usage/usage-api.js +80 -1
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.d.ts +25 -1
- package/dist/usage-report.js +55 -4
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.d.ts +4 -1
- package/dist/usage-rollup.js +12 -3
- package/dist/usage-rollup.js.map +1 -1
- package/dist/view-api.d.ts +31 -0
- package/dist/view-api.js +186 -41
- package/dist/view-api.js.map +1 -1
- package/dist/view-history.d.ts +84 -0
- package/dist/view-history.js +116 -0
- package/dist/view-history.js.map +1 -0
- package/dist/web-api.d.ts +32 -0
- package/dist/web-api.js +195 -5
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +7 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-chat-history.d.ts +20 -0
- package/dist/web-chat-history.js +21 -0
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-guest-access.js +5 -1
- package/dist/web-guest-access.js.map +1 -1
- package/dist/web-login.d.ts +6 -3
- package/dist/web-login.js +26 -15
- package/dist/web-login.js.map +1 -1
- package/dist/web-notices.d.ts +51 -0
- package/dist/web-notices.js +118 -0
- package/dist/web-notices.js.map +1 -0
- package/dist/web-office-pack-tools.d.ts +1 -1
- package/dist/web-office-pack-tools.js +1 -1
- package/dist/web-office-pack-tools.js.map +1 -1
- package/dist/web-only-fleet.d.ts +22 -0
- package/dist/web-only-fleet.js +13 -0
- package/dist/web-only-fleet.js.map +1 -0
- package/dist/web-preview.d.ts +32 -3
- package/dist/web-preview.js +52 -19
- package/dist/web-preview.js.map +1 -1
- package/dist/web-session-authorization.d.ts +13 -2
- package/dist/web-session-authorization.js +10 -3
- package/dist/web-session-authorization.js.map +1 -1
- package/dist/web-session.d.ts +12 -0
- package/dist/web-session.js +22 -8
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -1
- package/dist/web-settings-patch.js +4 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +2 -0
- package/dist/web-shell-routes.js +3 -0
- package/dist/web-shell-routes.js.map +1 -1
- package/launcher/agend-install.cjs +16 -2
- package/launcher/private-home.cjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude history in the View (the user, hmsg-a8947a2c / hmsg-b4c7ccdf; leader cid-claude-history-build). Claude Code
|
|
3
|
+
* draws on the alternate screen, so tmux keeps nothing above it: the View shows the conversation's earlier part from the
|
|
4
|
+
* instance's own transcript instead, drawn like Claude's own Ctrl+O view above the live screen (view-history.js).
|
|
5
|
+
*
|
|
6
|
+
* Read with the Log's reader (LogService.readBack: ClaudeStepParser, masked and cut) — the instance's own transcript,
|
|
7
|
+
* only when the person scrolls up in its View, a page at a time:
|
|
8
|
+
* - `GET /api/pane/<name>?transcript=1` — the newest VIEW_HISTORY_PAGE steps; `&before=<n>&key=<k>` — the page before
|
|
9
|
+
* that offset of that transcript;
|
|
10
|
+
* - `?transcript=1&step=<id>&end=<n>&key=<k>` — one step whole (a folded one, clicked): the page it came in is read
|
|
11
|
+
* again (its range ends at `end`; step ids depend on the bytes, not on the range) and the step answered unfolded.
|
|
12
|
+
* Access is the View's own (view-api.ts answers it on the pane's route, behind the pane's gate). Claude only: any other
|
|
13
|
+
* backend answers `supported: false` (Codex keeps tmux's scrollback). Thinking never shows (the parser has none); a
|
|
14
|
+
* turn's end and the fleet's state lines are left out.
|
|
15
|
+
*
|
|
16
|
+
* Folding happens here, so a page stays small: a long tool result or error keeps its first lines and says how many
|
|
17
|
+
* more there are; an edit's diff its first rows. Prompts and replies come whole (the parser already bounds them).
|
|
18
|
+
*/
|
|
19
|
+
import type { LogStep } from "./log-steps.js";
|
|
20
|
+
import type { ReadBack } from "./log-service.js";
|
|
21
|
+
export declare const VIEW_HISTORY_PAGE = 100;
|
|
22
|
+
/** A result over `lines` lines keeps `keep`; a diff over `diffRows` rows keeps `diffKeep`; kept text at most `chars`. */
|
|
23
|
+
export declare const VIEW_FOLD: {
|
|
24
|
+
readonly lines: 5;
|
|
25
|
+
readonly keep: 3;
|
|
26
|
+
readonly diffRows: 10;
|
|
27
|
+
readonly diffKeep: 6;
|
|
28
|
+
readonly chars: 600;
|
|
29
|
+
};
|
|
30
|
+
export interface ViewStep {
|
|
31
|
+
id: string;
|
|
32
|
+
kind: "user" | "assistant" | "tool" | "error";
|
|
33
|
+
/** tool: the CLI's tool name (the page shows Claude's word for it). */
|
|
34
|
+
tool?: string;
|
|
35
|
+
/** tool: what it acts on (a path, a command, a pattern). */
|
|
36
|
+
subject?: string;
|
|
37
|
+
status?: "running" | "done" | "failed" | "interrupted";
|
|
38
|
+
body?: string;
|
|
39
|
+
/** An edit's change as removed / added lines, hunk by hunk (instead of its result's sentence). */
|
|
40
|
+
diff?: Array<{
|
|
41
|
+
del: string[];
|
|
42
|
+
add: string[];
|
|
43
|
+
}>;
|
|
44
|
+
/** Folded: how many more lines (or diff rows) the whole step has. */
|
|
45
|
+
more?: number;
|
|
46
|
+
/** Characters the transcript reader itself cut (they are not in the whole step either). */
|
|
47
|
+
cut?: number;
|
|
48
|
+
}
|
|
49
|
+
export type ViewHistoryAnswer = {
|
|
50
|
+
view_history: 1;
|
|
51
|
+
supported: false;
|
|
52
|
+
reason: string;
|
|
53
|
+
} | {
|
|
54
|
+
view_history: 1;
|
|
55
|
+
supported: true;
|
|
56
|
+
key: string;
|
|
57
|
+
steps: ViewStep[];
|
|
58
|
+
before: number | null;
|
|
59
|
+
end: number;
|
|
60
|
+
reset?: boolean;
|
|
61
|
+
} | {
|
|
62
|
+
view_history: 1;
|
|
63
|
+
supported: true;
|
|
64
|
+
key: string;
|
|
65
|
+
step: ViewStep | null;
|
|
66
|
+
};
|
|
67
|
+
export interface ViewHistoryQuery {
|
|
68
|
+
before?: number;
|
|
69
|
+
key?: string;
|
|
70
|
+
step?: string;
|
|
71
|
+
end?: number;
|
|
72
|
+
}
|
|
73
|
+
/** Reads an instance's steps backwards (LogService.readBack). */
|
|
74
|
+
export type ReadBackFn = (name: string, q: {
|
|
75
|
+
end?: number;
|
|
76
|
+
key?: string;
|
|
77
|
+
limit: number;
|
|
78
|
+
}) => Promise<ReadBack | null>;
|
|
79
|
+
/** The query's own parts from a URL's search params (anything malformed is left out: the newest page). */
|
|
80
|
+
export declare function viewHistoryQuery(params: URLSearchParams): ViewHistoryQuery;
|
|
81
|
+
/** Null: no such instance. */
|
|
82
|
+
export declare function viewHistory(read: ReadBackFn, name: string, q: ViewHistoryQuery): Promise<ViewHistoryAnswer | null>;
|
|
83
|
+
/** A Log step as the View draws it (null: not drawn); `fold`: long results and diffs keep their start. */
|
|
84
|
+
export declare function viewStep(s: LogStep, fold: boolean): ViewStep | null;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export const VIEW_HISTORY_PAGE = 100;
|
|
2
|
+
/** A result over `lines` lines keeps `keep`; a diff over `diffRows` rows keeps `diffKeep`; kept text at most `chars`. */
|
|
3
|
+
export const VIEW_FOLD = { lines: 5, keep: 3, diffRows: 10, diffKeep: 6, chars: 600 };
|
|
4
|
+
/** The query's own parts from a URL's search params (anything malformed is left out: the newest page). */
|
|
5
|
+
export function viewHistoryQuery(params) {
|
|
6
|
+
const offset = (v) => (v !== null && /^\d{1,15}$/.test(v) ? Number(v) : undefined);
|
|
7
|
+
const q = {};
|
|
8
|
+
const before = offset(params.get("before")), end = offset(params.get("end"));
|
|
9
|
+
const key = params.get("key"), step = params.get("step");
|
|
10
|
+
if (before !== undefined)
|
|
11
|
+
q.before = before;
|
|
12
|
+
if (end !== undefined)
|
|
13
|
+
q.end = end;
|
|
14
|
+
if (key && /^\d{1,20}-\d{1,20}$/.test(key))
|
|
15
|
+
q.key = key;
|
|
16
|
+
if (step && step.length <= 200 && /^[\w.:-]+$/.test(step))
|
|
17
|
+
q.step = step;
|
|
18
|
+
return q;
|
|
19
|
+
}
|
|
20
|
+
/** Null: no such instance. */
|
|
21
|
+
export async function viewHistory(read, name, q) {
|
|
22
|
+
if (q.step !== undefined) {
|
|
23
|
+
if (q.end === undefined)
|
|
24
|
+
return { view_history: 1, supported: false, reason: "bad_request" };
|
|
25
|
+
const back = await read(name, { end: q.end, ...(q.key !== undefined ? { key: q.key } : {}), limit: VIEW_HISTORY_PAGE });
|
|
26
|
+
if (!back)
|
|
27
|
+
return null;
|
|
28
|
+
if (back.format !== "claude" || back.steps === undefined)
|
|
29
|
+
return { view_history: 1, supported: false, reason: back.reason ?? "unsupported" };
|
|
30
|
+
// Another transcript now (a new session), or past its end: the step is not there to give whole.
|
|
31
|
+
if (back.reset)
|
|
32
|
+
return { view_history: 1, supported: true, key: back.key, step: null };
|
|
33
|
+
const found = back.steps.find((s) => s.id === q.step);
|
|
34
|
+
return { view_history: 1, supported: true, key: back.key, step: found ? viewStep(found, false) : null };
|
|
35
|
+
}
|
|
36
|
+
const back = await read(name, { ...(q.before !== undefined ? { end: q.before } : {}), ...(q.key !== undefined ? { key: q.key } : {}), limit: VIEW_HISTORY_PAGE });
|
|
37
|
+
if (!back)
|
|
38
|
+
return null;
|
|
39
|
+
if (back.format !== "claude" || back.steps === undefined)
|
|
40
|
+
return { view_history: 1, supported: false, reason: back.reason ?? "unsupported" };
|
|
41
|
+
const steps = back.steps.map((s) => viewStep(s, true)).filter((s) => s !== null);
|
|
42
|
+
return { view_history: 1, supported: true, key: back.key, steps, before: back.before, end: back.end, ...(back.reset ? { reset: true } : {}) };
|
|
43
|
+
}
|
|
44
|
+
/** A Log step as the View draws it (null: not drawn); `fold`: long results and diffs keep their start. */
|
|
45
|
+
export function viewStep(s, fold) {
|
|
46
|
+
if (s.kind === "user" || s.kind === "assistant") {
|
|
47
|
+
if (!s.body)
|
|
48
|
+
return null;
|
|
49
|
+
return { id: s.id, kind: s.kind, body: s.body, ...(s.bodyCut ? { cut: s.bodyCut } : {}) };
|
|
50
|
+
}
|
|
51
|
+
if (s.kind === "error")
|
|
52
|
+
return { id: s.id, kind: "error", ...folded(s.body ?? s.note ?? "", fold), ...(s.bodyCut ? { cut: s.bodyCut } : {}) };
|
|
53
|
+
if (s.kind !== "tool")
|
|
54
|
+
return null;
|
|
55
|
+
const step = { id: s.id, kind: "tool", tool: s.tool ?? "", ...(s.subject ? { subject: s.subject } : {}), ...(s.status ? { status: s.status } : {}) };
|
|
56
|
+
const diff = s.status !== "failed" ? diffOf(s.tool ?? "", s.input) : null;
|
|
57
|
+
if (diff) {
|
|
58
|
+
const rows = diff.reduce((n, h) => n + h.del.length + h.add.length, 0);
|
|
59
|
+
if (!fold || rows <= VIEW_FOLD.diffRows)
|
|
60
|
+
return { ...step, diff };
|
|
61
|
+
let left = VIEW_FOLD.diffKeep;
|
|
62
|
+
const kept = [];
|
|
63
|
+
for (const h of diff) {
|
|
64
|
+
if (left <= 0)
|
|
65
|
+
break;
|
|
66
|
+
const del = h.del.slice(0, left);
|
|
67
|
+
left -= del.length;
|
|
68
|
+
const add = h.add.slice(0, Math.max(0, left));
|
|
69
|
+
left -= add.length;
|
|
70
|
+
kept.push({ del, add });
|
|
71
|
+
}
|
|
72
|
+
return { ...step, diff: kept, more: rows - VIEW_FOLD.diffKeep };
|
|
73
|
+
}
|
|
74
|
+
const body = clean(s.body ?? "");
|
|
75
|
+
return { ...step, ...(body ? folded(body, fold) : {}), ...(s.bodyCut ? { cut: s.bodyCut } : {}) };
|
|
76
|
+
}
|
|
77
|
+
/** A tool's error comes wrapped (`<tool_use_error>…</tool_use_error>`): the page shows its words. */
|
|
78
|
+
function clean(text) { return text.replace(/^<tool_use_error>([\s\S]*?)<\/tool_use_error>$/, "$1").replace(/\n+$/, ""); }
|
|
79
|
+
function folded(text, fold) {
|
|
80
|
+
const lines = text.split("\n");
|
|
81
|
+
if (!fold)
|
|
82
|
+
return { body: text };
|
|
83
|
+
let keep = lines.length > VIEW_FOLD.lines ? lines.slice(0, VIEW_FOLD.keep) : lines;
|
|
84
|
+
let more = lines.length - keep.length;
|
|
85
|
+
let body = keep.join("\n");
|
|
86
|
+
if (body.length > VIEW_FOLD.chars) {
|
|
87
|
+
body = body.slice(0, VIEW_FOLD.chars);
|
|
88
|
+
keep = body.split("\n");
|
|
89
|
+
more = Math.max(1, lines.length - keep.length + 1);
|
|
90
|
+
}
|
|
91
|
+
return { body, ...(more > 0 ? { more } : {}) };
|
|
92
|
+
}
|
|
93
|
+
/** An edit's change from its arguments (Edit, MultiEdit, Write), or null — also when the arguments were cut. */
|
|
94
|
+
function diffOf(tool, input) {
|
|
95
|
+
if (!input || !["Edit", "MultiEdit", "Write"].includes(tool))
|
|
96
|
+
return null;
|
|
97
|
+
let args;
|
|
98
|
+
try {
|
|
99
|
+
args = JSON.parse(input);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const lines = (v) => (typeof v === "string" && v !== "" ? v.replace(/\n$/, "").split("\n") : []);
|
|
105
|
+
if (tool === "Write")
|
|
106
|
+
return typeof args.content === "string" ? [{ del: [], add: lines(args.content) }] : null;
|
|
107
|
+
const edits = tool === "MultiEdit" ? (Array.isArray(args.edits) ? args.edits : null) : [args];
|
|
108
|
+
if (!edits)
|
|
109
|
+
return null;
|
|
110
|
+
const hunks = edits
|
|
111
|
+
.filter((e) => !!e && typeof e === "object")
|
|
112
|
+
.map((e) => ({ del: lines(e.old_string), add: lines(e.new_string) }))
|
|
113
|
+
.filter((h) => h.del.length || h.add.length);
|
|
114
|
+
return hunks.length ? hunks : null;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=view-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-history.js","sourceRoot":"","sources":["../src/view-history.ts"],"names":[],"mappings":"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"}
|
package/dist/web-api.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { type WebPrefsStore } from "./web-prefs.js";
|
|
|
24
24
|
import { type WebAccount } from "./web-profile.js";
|
|
25
25
|
import { type MentionNames, type MentionQuery } from "./web-mentions.js";
|
|
26
26
|
import type { ExplicitInstanceRemoval } from "./instance-removal.js";
|
|
27
|
+
import { type TopicDeleteOutcome } from "./instance-topic-delete.js";
|
|
27
28
|
/**
|
|
28
29
|
* #1920 §5.2: one event for the guests' streams only, each as projected for it — a message that has just become what
|
|
29
30
|
* its channel saw (an admin's page already has it, unchanged).
|
|
@@ -216,7 +217,23 @@ export interface WebApiContext {
|
|
|
216
217
|
owner: string;
|
|
217
218
|
}): Promise<import("./office-share-service.js").OfficeShareMade>;
|
|
218
219
|
revoke(id: string): number;
|
|
220
|
+
/** #2911: page share links on the same tunnel (page-share.ts); absent: /ui/page-share is not offered. */
|
|
221
|
+
pagesEnabled?(): boolean;
|
|
222
|
+
pagesCdn?(): boolean;
|
|
223
|
+
listPages?(): import("./page-share.js").PageShare[];
|
|
224
|
+
createPage?(opts: {
|
|
225
|
+
html: string;
|
|
226
|
+
instance: string;
|
|
227
|
+
title: string;
|
|
228
|
+
owner: string;
|
|
229
|
+
from?: import("./page-share.js").PageShare["from"];
|
|
230
|
+
minutes?: number;
|
|
231
|
+
stillAllowed?(): boolean;
|
|
232
|
+
}): Promise<import("./office-share-service.js").PageShareMade>;
|
|
233
|
+
revokePage?(id: string): import("./page-share.js").PageShare[];
|
|
219
234
|
};
|
|
235
|
+
/** #2911: a page share was made — said in that instance's channel (who, which page, for how long; never its URL). */
|
|
236
|
+
pageShareNotice?(who: string, share: import("./page-share.js").PageShare): void;
|
|
220
237
|
/** #2636: a share was made or ended from the page — said in General (who, which office, until when). */
|
|
221
238
|
officeShareNotice?(event: "created" | "revoked", who: string, share: import("./office-share.js").OfficeShare | null, count: number): void;
|
|
222
239
|
/** #2692: the agents' skin-pack changes (approval mode, pending changes, log); absent: /ui/office-pack-changes is not offered. */
|
|
@@ -326,6 +343,16 @@ export interface WebApiContext {
|
|
|
326
343
|
status: number;
|
|
327
344
|
message: string;
|
|
328
345
|
};
|
|
346
|
+
/** #2910 D2: a web-only fleet's Notices (web-notices.ts); null on a fleet whose General says them. */
|
|
347
|
+
webNoticesFeed?(): {
|
|
348
|
+
view(): {
|
|
349
|
+
items: unknown[];
|
|
350
|
+
seen: number;
|
|
351
|
+
unread: number;
|
|
352
|
+
};
|
|
353
|
+
markSeen(id: number): number;
|
|
354
|
+
unread(): number;
|
|
355
|
+
} | null;
|
|
329
356
|
/** Answer one of them, exactly as a click on its platform button would. */
|
|
330
357
|
/** `text`: #2675 — the typed answer, for the one action the page shows a text box for. */
|
|
331
358
|
clickWebPrompt?(instance: string, nonce: string, action: string, text?: string): Promise<{
|
|
@@ -350,6 +377,11 @@ export interface WebApiContext {
|
|
|
350
377
|
explicit?: boolean;
|
|
351
378
|
}): Promise<void>;
|
|
352
379
|
removeInstance(name: string, authorization: ExplicitInstanceRemoval, execution?: SettingsExecution): Promise<void>;
|
|
380
|
+
/** delete_instance's removal: the agent, then its own topic (by default), with the platform's answer. */
|
|
381
|
+
removeInstanceAndTopic?(name: string, authorization: ExplicitInstanceRemoval, opts: {
|
|
382
|
+
deleteTopic: boolean;
|
|
383
|
+
execution?: SettingsExecution;
|
|
384
|
+
}): Promise<TopicDeleteOutcome>;
|
|
353
385
|
lastInboundUser: Map<string, string>;
|
|
354
386
|
saveFleetConfig(): void;
|
|
355
387
|
readonly lifecycle: {
|
package/dist/web-api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CANVAS_WORKER_EXPERIMENTAL_MESSAGE } from "./web-experimental.js";
|
|
2
|
+
import { daemonTopicMode } from "./web-only-fleet.js";
|
|
2
3
|
import { webHumanOrigin } from "./human-delivery-receipts.js";
|
|
3
4
|
import { classifyWebPeer, confirmAfterBody, noAuthority } from "./authority/web-authority.js";
|
|
4
5
|
import { guestChatRefusal, guestCommandText, guestDeliveries, GUEST_PREF_MAX_BYTES, GUEST_SEARCHES, guestFrameData, guestHistory, guestMessages, guestOwnPrefs, guestPollBody, guestPrefs, guestRequestOf, guestSeesMessage, guestStatus } from "./web-guest-access.js";
|
|
@@ -39,7 +40,8 @@ import { readStatuslineModel, resolveInstanceContext } from "./topic-commands.js
|
|
|
39
40
|
import { z } from "zod";
|
|
40
41
|
import { evaluateWebRequest, isPassiveWebRead, isSecureRequest, isWebRequestAuthorized, WEB_TOKEN_INVALID_MESSAGE } from "./web-auth.js";
|
|
41
42
|
import { dashboardOriginFor } from "./web-preview.js";
|
|
42
|
-
import { WEB_CHAT_CARDS_OVERFLOW, newWebMessageId, parseLastEventId, webChatReplyRef, webChatReplyText } from "./web-chat-history.js";
|
|
43
|
+
import { WEB_CHAT_CARDS_OVERFLOW, catchUpWindow, newWebMessageId, parseLastEventId, webChatReplyRef, webChatReplyText } from "./web-chat-history.js";
|
|
44
|
+
import { PAGE_SHARE_LIMITS, htmlFences, htmlTitle } from "./page-share.js";
|
|
43
45
|
import { attachmentDelivery, createPartFile, displayName, fileTooLargeText, INLINE_MIME, isFileId, MEDIA_RANGE_MAX, publicAttachment, UPLOAD_LIMITS, UPLOAD_MAX_MS, UPLOAD_STALL_MS, UploadSniffer, uploadLimits, wellFormed } from "./web-upload.js";
|
|
44
46
|
import { getAgendHome } from "./paths.js";
|
|
45
47
|
import { OPERATOR, isOwnerEffectKey } from "./web-prefs.js";
|
|
@@ -52,6 +54,7 @@ import { resolveTz } from "./tz-utils.js";
|
|
|
52
54
|
import { QUERY_MAX_CHARS, RESULT_MAX, SEARCH_SOURCES } from "./search/search-store.js";
|
|
53
55
|
import { xmsgShown } from "./search/search-docs.js";
|
|
54
56
|
import { WebSendDedupe } from "./web-send-dedupe.js";
|
|
57
|
+
import { topicFields } from "./instance-topic-delete.js";
|
|
55
58
|
// ── Strict public-facing schemas ────────────────────────────────────────────
|
|
56
59
|
// web-api endpoints must reject unknown fields so the dashboard cannot inject
|
|
57
60
|
// internal-only flags that would reach handleCreate/scheduler/config writers.
|
|
@@ -539,6 +542,140 @@ function handleOfficeShare(req, res, url, ctx, path, method) {
|
|
|
539
542
|
});
|
|
540
543
|
return true;
|
|
541
544
|
}
|
|
545
|
+
/**
|
|
546
|
+
* #2911 item 8: page share links — GET /ui/page-share (the open ones, and whether this fleet offers them), POST
|
|
547
|
+
* { instance, boot, id, fence | att, minutes? } (a new one: the server reads the HTML itself — the n-th complete ```html
|
|
548
|
+
* fence of that agent message, or its .html attachment — and answers the URL once the tunnel is up), DELETE
|
|
549
|
+
* /ui/page-share/<id|all>. The same admin check as the Office share's (handleOfficeShare): an admin session, directly
|
|
550
|
+
* or over the /web public link; never the CLI token, a read-only session or a guest. Asked again once the body is in.
|
|
551
|
+
*/
|
|
552
|
+
function handlePageShare(req, res, url, ctx, path, method) {
|
|
553
|
+
const service = ctx.officeShares;
|
|
554
|
+
if (!service?.createPage || !service.listPages || !service.revokePage || !service.pagesEnabled) {
|
|
555
|
+
json(res, 404, { error: "Page share links are not kept on this fleet" });
|
|
556
|
+
return true;
|
|
557
|
+
}
|
|
558
|
+
const one = /^\/ui\/page-share\/([0-9a-f]{8}|all)$/.exec(path);
|
|
559
|
+
const known = (method === "GET" && path === "/ui/page-share") || (method === "POST" && path === "/ui/page-share") || (method === "DELETE" && !!one);
|
|
560
|
+
if (!known) {
|
|
561
|
+
json(res, 404, { error: "not found" });
|
|
562
|
+
return true;
|
|
563
|
+
}
|
|
564
|
+
const who = () => {
|
|
565
|
+
const verdict = evaluateWebRequest(req, url, ctx.webToken ?? null, ctx.webSessions, { touch: false });
|
|
566
|
+
if (verdict.kind !== "allow")
|
|
567
|
+
return { status: 401 };
|
|
568
|
+
if (verdict.via !== "session" || verdict.session?.tier !== "admin")
|
|
569
|
+
return { status: 403 };
|
|
570
|
+
const owner = verdict.session.owner;
|
|
571
|
+
return { person: owner ? webPersonKey(owner) : "admin-session", name: owner ? ctx.webPerson?.(owner)?.name ?? owner.userId : "admin" };
|
|
572
|
+
};
|
|
573
|
+
const refuse = (status) => json(res, status, { error: status === 401 ? WEB_TOKEN_INVALID_MESSAGE : "page_share_needs_an_admin_session" });
|
|
574
|
+
const first = who();
|
|
575
|
+
if ("status" in first) {
|
|
576
|
+
refuse(first.status);
|
|
577
|
+
return true;
|
|
578
|
+
}
|
|
579
|
+
res.setHeader("Cache-Control", "no-store");
|
|
580
|
+
// `cdn`: whether a share made now may load the preview's CDN libraries (the confirm dialog says so).
|
|
581
|
+
if (method === "GET") {
|
|
582
|
+
json(res, 200, { enabled: service.pagesEnabled(), cdn: service.pagesCdn?.() === true, shares: service.listPages() });
|
|
583
|
+
return true;
|
|
584
|
+
}
|
|
585
|
+
if (method === "DELETE") {
|
|
586
|
+
// Its end is said in the instance's channel by the service's change listener (as an expiry is).
|
|
587
|
+
const n = service.revokePage(one[1]).length;
|
|
588
|
+
json(res, n ? 200 : 404, n ? { revoked: n } : { error: "not_found" });
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
(async () => {
|
|
592
|
+
let body;
|
|
593
|
+
try {
|
|
594
|
+
body = await parseBody(req);
|
|
595
|
+
}
|
|
596
|
+
catch {
|
|
597
|
+
json(res, 400, { error: "Invalid JSON" });
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (!permitWebContinuation(req, res, ctx))
|
|
601
|
+
return;
|
|
602
|
+
const now = who();
|
|
603
|
+
if ("status" in now) {
|
|
604
|
+
refuse(now.status);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const fence = body?.fence, att = body?.att;
|
|
608
|
+
if (!body || typeof body !== "object" || Array.isArray(body) || typeof body.instance !== "string" || !body.instance
|
|
609
|
+
|| typeof body.boot !== "string" || !/^[0-9a-f]{1,32}$/.test(body.boot) || !Number.isSafeInteger(body.id) || body.id < 1
|
|
610
|
+
|| (fence === undefined) === (att === undefined)
|
|
611
|
+
|| (fence !== undefined && (!Number.isInteger(fence) || fence < 0 || fence > 999))
|
|
612
|
+
|| (att !== undefined && (typeof att !== "string" || !isFileId(att)))
|
|
613
|
+
|| (body.minutes !== undefined && typeof body.minutes !== "number")) {
|
|
614
|
+
json(res, 400, { error: "instance, boot, id, and fence (number) or att (file id); minutes? (number)" });
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
const msg = ctx.webChatHistory?.find(body.instance, body.boot, body.id) ?? null;
|
|
618
|
+
if (!msg || msg.instance !== body.instance) {
|
|
619
|
+
json(res, 404, { error: "message_gone" });
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
if (msg.role !== "agent") {
|
|
623
|
+
json(res, 400, { error: "not_an_agent_page" });
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
let html, name = "";
|
|
627
|
+
if (fence !== undefined) {
|
|
628
|
+
const f = htmlFences(msg.text)[fence];
|
|
629
|
+
if (!f || !f.terminated) {
|
|
630
|
+
json(res, 404, { error: "page_gone" });
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
html = f.code;
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
const a = (msg.attachments ?? []).find((x) => !("gone" in x) && x.id === att);
|
|
637
|
+
if (!a || a.kind === "photo" || !/\.html?$/i.test(a.name.trim())) {
|
|
638
|
+
json(res, 404, { error: "page_gone" });
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const served = ctx.webFiles?.servedFile?.(a.id) ?? null;
|
|
642
|
+
if (!served) {
|
|
643
|
+
json(res, 404, { error: "page_gone" });
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (served.size > PAGE_SHARE_LIMITS.maxBytes) {
|
|
647
|
+
json(res, 413, { error: "too_large" });
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
const read = ctx.webFiles?.read?.(a.id) ?? null;
|
|
651
|
+
if (!read) {
|
|
652
|
+
json(res, 404, { error: "page_gone" });
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
html = read.bytes.toString("utf8");
|
|
656
|
+
name = a.name;
|
|
657
|
+
}
|
|
658
|
+
const from = { boot: body.boot, id: body.id, ...(fence !== undefined ? { fence: fence } : { att: att }) };
|
|
659
|
+
// The caller is asked again once the tunnel is up (#2917 review P2): the same admin, the session still live.
|
|
660
|
+
const stillAllowed = () => { const currentCaller = who(); return !("status" in currentCaller) && currentCaller.person === now.person; };
|
|
661
|
+
const made = await service.createPage({ html, instance: body.instance, title: htmlTitle(html) || name, owner: now.person, from, stillAllowed,
|
|
662
|
+
...(typeof body.minutes === "number" ? { minutes: body.minutes } : {}) });
|
|
663
|
+
if (!made.ok) {
|
|
664
|
+
const status = made.error === "disabled" ? 404 : made.error === "tunnel" ? 503 : made.error === "too_many" ? 409 : made.error === "too_large" ? 413 : made.error === "not_allowed" ? 403 : 400;
|
|
665
|
+
json(res, status, { error: made.error, ...(made.reason ? { reason: made.reason } : {}) });
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
ctx.pageShareNotice?.(now.name, made.share);
|
|
669
|
+
json(res, 200, { share: made.share, url: made.url });
|
|
670
|
+
})().catch(err => {
|
|
671
|
+
ctx.logger.error({ err: err.message }, "Page share failed");
|
|
672
|
+
try {
|
|
673
|
+
json(res, 500, { error: "Page share failed" });
|
|
674
|
+
}
|
|
675
|
+
catch { /* already answered */ }
|
|
676
|
+
});
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
542
679
|
/**
|
|
543
680
|
* #2513: the Office view's skin packs (web-office-skins.ts). The reads are the offices' (GET /ui/offices): whoever may
|
|
544
681
|
* open the org chart, the public link too (its manifest lists them; a guest's routes do not): the list, a pack's
|
|
@@ -1855,7 +1992,12 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
1855
1992
|
json(res, 200, {
|
|
1856
1993
|
status: ctx.getUiStatus(),
|
|
1857
1994
|
// #2341 review: over the public link, without a summary line that names a card hidden there.
|
|
1858
|
-
|
|
1995
|
+
// M-2260: the newest within the catch-up budget; `truncated` when older ones were left out (the page re-reads its
|
|
1996
|
+
// chats' newest history, as a reload would) — never megabytes that a slow link cannot bring in time.
|
|
1997
|
+
...(() => {
|
|
1998
|
+
const w = catchUpWindow(history ? visibleMessages(ctx, !!gatewayRequestContext(req), fresh ? history.after(0) : history.replayFor(parseLastEventId(after))) : []);
|
|
1999
|
+
return w.truncated ? { messages: w.messages, truncated: true } : { messages: w.messages };
|
|
2000
|
+
})(),
|
|
1859
2001
|
// The ticks too, so polling never has to re-read a chat's history — that read would count as the person's
|
|
1860
2002
|
// activity; this poll does not (isPassiveWebRead).
|
|
1861
2003
|
deliveries: history ? history.deliveries() : [],
|
|
@@ -2400,6 +2542,8 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
2400
2542
|
return handleOfficePackChanges(req, res, url, ctx, path, method);
|
|
2401
2543
|
if (path === "/ui/office-share" || path.startsWith("/ui/office-share/"))
|
|
2402
2544
|
return handleOfficeShare(req, res, url, ctx, path, method);
|
|
2545
|
+
if (path === "/ui/page-share" || path.startsWith("/ui/page-share/"))
|
|
2546
|
+
return handlePageShare(req, res, url, ctx, path, method);
|
|
2403
2547
|
// ── #1630: avatars and Discord server emoji, same-origin (the page never loads a platform's CDN; img-src stays 'self') ──
|
|
2404
2548
|
const imageMatch = path.match(/^\/ui\/img\/(bot|avatar|emoji)\/([^/]+)$/);
|
|
2405
2549
|
if (method === "GET" && imageMatch) {
|
|
@@ -2741,6 +2885,47 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
2741
2885
|
return handleBackendLogin(req, res, url, ctx, path, method);
|
|
2742
2886
|
// #1386: Acknowledge a "Needs you" delivery item — a session write (CSRF, checked by the gate) or the CLI's header
|
|
2743
2887
|
// token. Who did it is recorded by principal: the session's public handle, never the session id or a credential.
|
|
2888
|
+
// #2910 D2: a web-only fleet's Notices — what General would have said. Admins only (never a guest: not in
|
|
2889
|
+
// GUEST_ROUTES). GET /ui/notices/list lists them; POST /ui/notices/seen {id} marks everything up to it read (a session write).
|
|
2890
|
+
if (path === "/ui/notices/list" && method === "GET") {
|
|
2891
|
+
const feed = ctx.webNoticesFeed?.() ?? null;
|
|
2892
|
+
res.setHeader("Cache-Control", "no-store");
|
|
2893
|
+
json(res, 200, feed ? { enabled: true, ...feed.view() } : { enabled: false, items: [], seen: 0, unread: 0 });
|
|
2894
|
+
return true;
|
|
2895
|
+
}
|
|
2896
|
+
if (path === "/ui/notices/seen" && method === "POST") {
|
|
2897
|
+
(async () => {
|
|
2898
|
+
let body;
|
|
2899
|
+
try {
|
|
2900
|
+
body = await parseBody(req);
|
|
2901
|
+
}
|
|
2902
|
+
catch {
|
|
2903
|
+
json(res, 400, { error: "Invalid JSON" });
|
|
2904
|
+
return;
|
|
2905
|
+
}
|
|
2906
|
+
if (!permitWebContinuation(req, res, ctx))
|
|
2907
|
+
return;
|
|
2908
|
+
const id = body && typeof body === "object" ? body.id : undefined;
|
|
2909
|
+
if (typeof id !== "number" || !Number.isSafeInteger(id) || id < 0) {
|
|
2910
|
+
json(res, 400, { error: "id required" });
|
|
2911
|
+
return;
|
|
2912
|
+
}
|
|
2913
|
+
const feed = ctx.webNoticesFeed?.() ?? null;
|
|
2914
|
+
if (!feed) {
|
|
2915
|
+
json(res, 404, { error: "No notices here" });
|
|
2916
|
+
return;
|
|
2917
|
+
}
|
|
2918
|
+
const seen = feed.markSeen(id);
|
|
2919
|
+
json(res, 200, { seen, unread: feed.unread() });
|
|
2920
|
+
})().catch(err => {
|
|
2921
|
+
ctx.logger.error({ err: err.message }, "Notices mark-read failed");
|
|
2922
|
+
try {
|
|
2923
|
+
json(res, 500, { error: "Mark read failed" });
|
|
2924
|
+
}
|
|
2925
|
+
catch { /* already answered */ }
|
|
2926
|
+
});
|
|
2927
|
+
return true;
|
|
2928
|
+
}
|
|
2744
2929
|
if (method === "POST" && path === "/ui/needs/ack") {
|
|
2745
2930
|
if (!ctx.acknowledgeNeedsItem) {
|
|
2746
2931
|
json(res, 404, { error: "Nothing to acknowledge here" });
|
|
@@ -2979,7 +3164,7 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
2979
3164
|
json(res, 404, { error: `Instance not found: ${name}` });
|
|
2980
3165
|
return true;
|
|
2981
3166
|
}
|
|
2982
|
-
const topicMode = ctx.fleetConfig
|
|
3167
|
+
const topicMode = daemonTopicMode(ctx.fleetConfig);
|
|
2983
3168
|
(async () => {
|
|
2984
3169
|
let held = false;
|
|
2985
3170
|
try {
|
|
@@ -3014,12 +3199,17 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
3014
3199
|
return;
|
|
3015
3200
|
}
|
|
3016
3201
|
const execution = settingsRequestExecution(req);
|
|
3017
|
-
|
|
3202
|
+
// The same removal as delete_instance: the agent, then its own topic (the user's default), said truthfully.
|
|
3203
|
+
let topic = null;
|
|
3204
|
+
if (ctx.removeInstanceAndTopic) {
|
|
3205
|
+
topic = await ctx.removeInstanceAndTopic(name, authorizeExplicitInstanceRemoval("dashboard-confirmed"), { deleteTopic: true, ...(execution ? { execution } : {}) });
|
|
3206
|
+
}
|
|
3207
|
+
else if (execution)
|
|
3018
3208
|
await ctx.removeInstance(name, authorizeExplicitInstanceRemoval("dashboard-confirmed"), execution);
|
|
3019
3209
|
else
|
|
3020
3210
|
await ctx.removeInstance(name, authorizeExplicitInstanceRemoval("dashboard-confirmed"));
|
|
3021
3211
|
ctx.emitSseEvent("status", ctx.getUiStatus());
|
|
3022
|
-
json(res, 200, { deleted: name });
|
|
3212
|
+
json(res, 200, { deleted: name, ...topicFields(name, topic) });
|
|
3023
3213
|
}
|
|
3024
3214
|
catch (err) {
|
|
3025
3215
|
json(res, 500, { error: err.message });
|