@sagmans/dsh-tui 0.12.1 → 0.14.0
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/.agents/skills/dsh-tui-dogfood/SKILL.md +18 -2
- package/.agents/skills/dsh-tui-dogfood/references/home-state.md +4 -4
- package/.agents/skills/dsh-tui-dogfood/scripts/clone-links.mjs +19 -11
- package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +31 -9
- package/.agents/skills/dsh-tui-update-models/SKILL.md +1 -1
- package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +6 -6
- package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +21 -13
- package/README.md +61 -23
- package/cordis.patch.yml +2 -0
- package/lib/agent/fork.d.ts +3 -1
- package/lib/agent/fork.d.ts.map +1 -1
- package/lib/agent/fork.js +2 -0
- package/lib/agent/fork.js.map +1 -1
- package/lib/agent/history.d.ts +14 -22
- package/lib/agent/history.d.ts.map +1 -1
- package/lib/agent/history.js +20 -14
- package/lib/agent/history.js.map +1 -1
- package/lib/agent/host.d.ts.map +1 -1
- package/lib/agent/host.js +6 -0
- package/lib/agent/host.js.map +1 -1
- package/lib/agent/model.d.ts +10 -8
- package/lib/agent/model.d.ts.map +1 -1
- package/lib/agent/model.js +9 -7
- package/lib/agent/model.js.map +1 -1
- package/lib/agent/present.d.ts +1 -1
- package/lib/agent/present.d.ts.map +1 -1
- package/lib/agent/present.js +1 -1
- package/lib/agent/present.js.map +1 -1
- package/lib/agent/presets.d.ts +4 -1
- package/lib/agent/presets.d.ts.map +1 -1
- package/lib/agent/presets.js +9 -2
- package/lib/agent/presets.js.map +1 -1
- package/lib/agent/projections.d.ts +8 -2
- package/lib/agent/projections.d.ts.map +1 -1
- package/lib/agent/projections.js +8 -2
- package/lib/agent/projections.js.map +1 -1
- package/lib/agent/prompt-history.d.ts +8 -48
- package/lib/agent/prompt-history.d.ts.map +1 -1
- package/lib/agent/prompt-history.js +34 -15
- package/lib/agent/prompt-history.js.map +1 -1
- package/lib/agent/status.d.ts +9 -24
- package/lib/agent/status.d.ts.map +1 -1
- package/lib/agent/status.js +7 -2
- package/lib/agent/status.js.map +1 -1
- package/lib/agent/undo.d.ts +2 -4
- package/lib/agent/undo.d.ts.map +1 -1
- package/lib/agent/undo.js +10 -5
- package/lib/agent/undo.js.map +1 -1
- package/lib/cards/composition.d.ts +7 -7
- package/lib/cards/composition.d.ts.map +1 -1
- package/lib/cards/composition.js +13 -12
- package/lib/cards/composition.js.map +1 -1
- package/lib/cards/presenter.d.ts +11 -14
- package/lib/cards/presenter.d.ts.map +1 -1
- package/lib/cards/presenter.js +40 -19
- package/lib/cards/presenter.js.map +1 -1
- package/lib/cards/preview.d.ts.map +1 -1
- package/lib/cards/preview.js +5 -1
- package/lib/cards/preview.js.map +1 -1
- package/lib/cards.d.ts +17 -23
- package/lib/cards.d.ts.map +1 -1
- package/lib/cards.js +27 -12
- package/lib/cards.js.map +1 -1
- package/lib/compat/probe.d.ts +2 -5
- package/lib/compat/probe.d.ts.map +1 -1
- package/lib/compat/probe.js +2 -2
- package/lib/compat/probe.js.map +1 -1
- package/lib/compat/section.d.ts +5 -4
- package/lib/compat/section.d.ts.map +1 -1
- package/lib/compat/section.js +4 -0
- package/lib/compat/section.js.map +1 -1
- package/lib/config.d.ts +0 -3
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +7 -1
- package/lib/config.js.map +1 -1
- package/lib/export.d.ts +5 -7
- package/lib/export.d.ts.map +1 -1
- package/lib/export.js +48 -10
- package/lib/export.js.map +1 -1
- package/lib/fold-cursor.d.ts +3 -3
- package/lib/fold-cursor.d.ts.map +1 -1
- package/lib/fold-cursor.js +5 -3
- package/lib/fold-cursor.js.map +1 -1
- package/lib/gates/question-card.d.ts +3 -38
- package/lib/gates/question-card.d.ts.map +1 -1
- package/lib/gates/question-card.js +13 -10
- package/lib/gates/question-card.js.map +1 -1
- package/lib/gates/questions.d.ts +14 -8
- package/lib/gates/questions.d.ts.map +1 -1
- package/lib/gates/questions.js +25 -18
- package/lib/gates/questions.js.map +1 -1
- package/lib/gates.d.ts +17 -25
- package/lib/gates.d.ts.map +1 -1
- package/lib/gates.js +2 -4
- package/lib/gates.js.map +1 -1
- package/lib/herdr/client.d.ts +10 -12
- package/lib/herdr/client.d.ts.map +1 -1
- package/lib/herdr/client.js +9 -8
- package/lib/herdr/client.js.map +1 -1
- package/lib/herdr/constants.d.ts +3 -2
- package/lib/herdr/constants.d.ts.map +1 -1
- package/lib/herdr/constants.js +3 -2
- package/lib/herdr/constants.js.map +1 -1
- package/lib/herdr/reporter.d.ts +4 -39
- package/lib/herdr/reporter.d.ts.map +1 -1
- package/lib/herdr/reporter.js +13 -19
- package/lib/herdr/reporter.js.map +1 -1
- package/lib/herdr/state.d.ts +4 -3
- package/lib/herdr/state.d.ts.map +1 -1
- package/lib/herdr/state.js +6 -5
- package/lib/herdr/state.js.map +1 -1
- package/lib/host/preset-files.d.ts +0 -17
- package/lib/host/preset-files.d.ts.map +1 -1
- package/lib/host/preset-files.js +7 -2
- package/lib/host/preset-files.js.map +1 -1
- package/lib/host/roster.d.ts +1 -1
- package/lib/host/roster.d.ts.map +1 -1
- package/lib/host/roster.js +3 -3
- package/lib/host/roster.js.map +1 -1
- package/lib/host/runner.d.ts +2 -5
- package/lib/host/runner.d.ts.map +1 -1
- package/lib/host/runner.js +2 -5
- package/lib/host/runner.js.map +1 -1
- package/lib/identity.d.ts +6 -3
- package/lib/identity.d.ts.map +1 -1
- package/lib/identity.js +18 -3
- package/lib/identity.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +42 -14
- package/lib/index.js.map +1 -1
- package/lib/injection.d.ts.map +1 -1
- package/lib/injection.js +1 -0
- package/lib/injection.js.map +1 -1
- package/lib/input/action-catalog.d.ts.map +1 -1
- package/lib/input/action-catalog.js +4 -0
- package/lib/input/action-catalog.js.map +1 -1
- package/lib/input/actions.d.ts +4 -3
- package/lib/input/actions.d.ts.map +1 -1
- package/lib/input/actions.js +8 -3
- package/lib/input/actions.js.map +1 -1
- package/lib/input/completion.d.ts +3 -11
- package/lib/input/completion.d.ts.map +1 -1
- package/lib/input/completion.js +8 -6
- package/lib/input/completion.js.map +1 -1
- package/lib/input/file-index.d.ts +1 -12
- package/lib/input/file-index.d.ts.map +1 -1
- package/lib/input/file-index.js +21 -17
- package/lib/input/file-index.js.map +1 -1
- package/lib/input/file-search.d.ts +6 -3
- package/lib/input/file-search.d.ts.map +1 -1
- package/lib/input/file-search.js +29 -10
- package/lib/input/file-search.js.map +1 -1
- package/lib/input/fuzzy.d.ts +6 -12
- package/lib/input/fuzzy.d.ts.map +1 -1
- package/lib/input/fuzzy.js +18 -27
- package/lib/input/fuzzy.js.map +1 -1
- package/lib/input/ghost.d.ts +5 -5
- package/lib/input/ghost.d.ts.map +1 -1
- package/lib/input/ghost.js +4 -3
- package/lib/input/ghost.js.map +1 -1
- package/lib/input/key-press.d.ts +8 -7
- package/lib/input/key-press.d.ts.map +1 -1
- package/lib/input/key-press.js +8 -6
- package/lib/input/key-press.js.map +1 -1
- package/lib/input/keymap-conflicts.d.ts +6 -6
- package/lib/input/keymap-conflicts.d.ts.map +1 -1
- package/lib/input/keymap-conflicts.js +6 -6
- package/lib/input/keymap-conflicts.js.map +1 -1
- package/lib/input/keymap.d.ts +6 -18
- package/lib/input/keymap.d.ts.map +1 -1
- package/lib/input/keymap.js +7 -10
- package/lib/input/keymap.js.map +1 -1
- package/lib/input/match.js +4 -4
- package/lib/input/match.js.map +1 -1
- package/lib/input/submission.d.ts +7 -3
- package/lib/input/submission.d.ts.map +1 -1
- package/lib/input/submission.js +2 -2
- package/lib/input/submission.js.map +1 -1
- package/lib/input/workspace-files.d.ts +1 -2
- package/lib/input/workspace-files.d.ts.map +1 -1
- package/lib/input/workspace-files.js +20 -11
- package/lib/input/workspace-files.js.map +1 -1
- package/lib/input.d.ts +6 -0
- package/lib/input.d.ts.map +1 -1
- package/lib/input.js +34 -1
- package/lib/input.js.map +1 -1
- package/lib/install-skills.d.ts +5 -22
- package/lib/install-skills.d.ts.map +1 -1
- package/lib/install-skills.js +18 -18
- package/lib/install-skills.js.map +1 -1
- package/lib/jobs.d.ts +10 -5
- package/lib/jobs.d.ts.map +1 -1
- package/lib/jobs.js +39 -13
- package/lib/jobs.js.map +1 -1
- package/lib/keymaps.d.ts.map +1 -1
- package/lib/keymaps.js +2 -0
- package/lib/keymaps.js.map +1 -1
- package/lib/keys-command.d.ts +1 -1
- package/lib/keys-command.d.ts.map +1 -1
- package/lib/model-list.d.ts +0 -27
- package/lib/model-list.d.ts.map +1 -1
- package/lib/model-list.js +1 -1
- package/lib/model-list.js.map +1 -1
- package/lib/moshi.d.ts +13 -0
- package/lib/moshi.d.ts.map +1 -0
- package/lib/moshi.js +130 -0
- package/lib/moshi.js.map +1 -0
- package/lib/spacing.d.ts +0 -7
- package/lib/spacing.d.ts.map +1 -1
- package/lib/spacing.js +1 -1
- package/lib/spacing.js.map +1 -1
- package/lib/startup.d.ts +1 -1
- package/lib/startup.d.ts.map +1 -1
- package/lib/startup.js +9 -1
- package/lib/startup.js.map +1 -1
- package/lib/stash/lock.d.ts +1 -37
- package/lib/stash/lock.d.ts.map +1 -1
- package/lib/stash/lock.js +41 -35
- package/lib/stash/lock.js.map +1 -1
- package/lib/stash/paths.d.ts +8 -7
- package/lib/stash/paths.d.ts.map +1 -1
- package/lib/stash/paths.js +21 -17
- package/lib/stash/paths.js.map +1 -1
- package/lib/stash/private-fs.d.ts +14 -5
- package/lib/stash/private-fs.d.ts.map +1 -1
- package/lib/stash/private-fs.js +30 -8
- package/lib/stash/private-fs.js.map +1 -1
- package/lib/stash/schema.d.ts +3 -6
- package/lib/stash/schema.d.ts.map +1 -1
- package/lib/stash/schema.js +11 -9
- package/lib/stash/schema.js.map +1 -1
- package/lib/stash/store.d.ts +9 -40
- package/lib/stash/store.d.ts.map +1 -1
- package/lib/stash/store.js +26 -24
- package/lib/stash/store.js.map +1 -1
- package/lib/stash.d.ts +7 -11
- package/lib/stash.d.ts.map +1 -1
- package/lib/stash.js +18 -11
- package/lib/stash.js.map +1 -1
- package/lib/subagents.d.ts +9 -9
- package/lib/subagents.d.ts.map +1 -1
- package/lib/subagents.js +19 -18
- package/lib/subagents.js.map +1 -1
- package/lib/surface/appearance-preferences.d.ts.map +1 -1
- package/lib/surface/appearance-preferences.js +7 -0
- package/lib/surface/appearance-preferences.js.map +1 -1
- package/lib/surface/appearance.d.ts.map +1 -1
- package/lib/surface/appearance.js +7 -2
- package/lib/surface/appearance.js.map +1 -1
- package/lib/surface/background-work.d.ts +2 -0
- package/lib/surface/background-work.d.ts.map +1 -1
- package/lib/surface/background-work.js +45 -36
- package/lib/surface/background-work.js.map +1 -1
- package/lib/surface/commands.d.ts.map +1 -1
- package/lib/surface/commands.js +17 -9
- package/lib/surface/commands.js.map +1 -1
- package/lib/surface/modal-input.d.ts +4 -0
- package/lib/surface/modal-input.d.ts.map +1 -1
- package/lib/surface/modal-input.js +81 -46
- package/lib/surface/modal-input.js.map +1 -1
- package/lib/surface/model-choice.d.ts.map +1 -1
- package/lib/surface/model-choice.js +10 -8
- package/lib/surface/model-choice.js.map +1 -1
- package/lib/surface/plugin-actions.d.ts.map +1 -1
- package/lib/surface/plugin-actions.js +4 -0
- package/lib/surface/plugin-actions.js.map +1 -1
- package/lib/surface/preset-choice.d.ts.map +1 -1
- package/lib/surface/preset-choice.js +15 -17
- package/lib/surface/preset-choice.js.map +1 -1
- package/lib/surface/prompt-input.js +1 -1
- package/lib/surface/prompt-input.js.map +1 -1
- package/lib/surface/prompt-memory.d.ts +7 -6
- package/lib/surface/prompt-memory.d.ts.map +1 -1
- package/lib/surface/prompt-memory.js +3 -3
- package/lib/surface/session-lifecycle.d.ts +7 -1
- package/lib/surface/session-lifecycle.d.ts.map +1 -1
- package/lib/surface/session-lifecycle.js +17 -12
- package/lib/surface/session-lifecycle.js.map +1 -1
- package/lib/surface/session-picker.js +1 -1
- package/lib/surface/session-picker.js.map +1 -1
- package/lib/surface/session-view.d.ts +1 -1
- package/lib/surface/session-view.d.ts.map +1 -1
- package/lib/surface/session-view.js +4 -5
- package/lib/surface/session-view.js.map +1 -1
- package/lib/surface/staged-turns.d.ts.map +1 -1
- package/lib/surface/staged-turns.js +8 -4
- package/lib/surface/staged-turns.js.map +1 -1
- package/lib/surface/terminal-lifecycle.d.ts +1 -1
- package/lib/surface/terminal-lifecycle.d.ts.map +1 -1
- package/lib/surface/terminal-lifecycle.js +8 -5
- package/lib/surface/terminal-lifecycle.js.map +1 -1
- package/lib/terminal/bell.d.ts +0 -2
- package/lib/terminal/bell.d.ts.map +1 -1
- package/lib/terminal/bell.js +2 -1
- package/lib/terminal/bell.js.map +1 -1
- package/lib/terminal/clipboard.d.ts +4 -4
- package/lib/terminal/clipboard.js +4 -4
- package/lib/terminal/external-editor.d.ts +4 -60
- package/lib/terminal/external-editor.d.ts.map +1 -1
- package/lib/terminal/external-editor.js +28 -40
- package/lib/terminal/external-editor.js.map +1 -1
- package/lib/terminal/host-writes.d.ts +7 -18
- package/lib/terminal/host-writes.d.ts.map +1 -1
- package/lib/terminal/host-writes.js +19 -18
- package/lib/terminal/host-writes.js.map +1 -1
- package/lib/terminal/input.d.ts +6 -0
- package/lib/terminal/input.d.ts.map +1 -0
- package/lib/terminal/input.js +15 -0
- package/lib/terminal/input.js.map +1 -0
- package/lib/terminal/restore.d.ts +2 -1
- package/lib/terminal/restore.d.ts.map +1 -1
- package/lib/terminal/signals.d.ts +2 -1
- package/lib/terminal/signals.d.ts.map +1 -1
- package/lib/terminal/signals.js +1 -1
- package/lib/terminal/signals.js.map +1 -1
- package/lib/terminal/title.d.ts +1 -11
- package/lib/terminal/title.d.ts.map +1 -1
- package/lib/terminal/title.js +5 -4
- package/lib/terminal/title.js.map +1 -1
- package/lib/terminal/warning-screen.d.ts +11 -2
- package/lib/terminal/warning-screen.d.ts.map +1 -1
- package/lib/terminal/warning-screen.js +166 -22
- package/lib/terminal/warning-screen.js.map +1 -1
- package/lib/terminal-text/scan.d.ts +4 -5
- package/lib/terminal-text/scan.d.ts.map +1 -1
- package/lib/terminal-text/scan.js +16 -9
- package/lib/terminal-text/scan.js.map +1 -1
- package/lib/terminal-text/sgr.d.ts +4 -3
- package/lib/terminal-text/sgr.d.ts.map +1 -1
- package/lib/terminal-text/sgr.js +9 -14
- package/lib/terminal-text/sgr.js.map +1 -1
- package/lib/terminal-text.d.ts +7 -12
- package/lib/terminal-text.d.ts.map +1 -1
- package/lib/terminal-text.js +32 -23
- package/lib/terminal-text.js.map +1 -1
- package/lib/text.d.ts +8 -14
- package/lib/text.d.ts.map +1 -1
- package/lib/text.js +14 -15
- package/lib/text.js.map +1 -1
- package/lib/theme-capability.d.ts +3 -15
- package/lib/theme-capability.d.ts.map +1 -1
- package/lib/theme-capability.js +18 -15
- package/lib/theme-capability.js.map +1 -1
- package/lib/theme-defaults.d.ts +3 -57
- package/lib/theme-defaults.d.ts.map +1 -1
- package/lib/theme-defaults.js +25 -14
- package/lib/theme-defaults.js.map +1 -1
- package/lib/theme-files.d.ts +16 -32
- package/lib/theme-files.d.ts.map +1 -1
- package/lib/theme-files.js +43 -27
- package/lib/theme-files.js.map +1 -1
- package/lib/theme-resolver.d.ts +3 -3
- package/lib/theme-resolver.d.ts.map +1 -1
- package/lib/theme-resolver.js +9 -6
- package/lib/theme-resolver.js.map +1 -1
- package/lib/theme-schema.d.ts +7 -42
- package/lib/theme-schema.d.ts.map +1 -1
- package/lib/theme-schema.js +9 -11
- package/lib/theme-schema.js.map +1 -1
- package/lib/theme-settings.d.ts +19 -10
- package/lib/theme-settings.d.ts.map +1 -1
- package/lib/theme-settings.js +23 -17
- package/lib/theme-settings.js.map +1 -1
- package/lib/theme-tokens.d.ts +6 -12
- package/lib/theme-tokens.d.ts.map +1 -1
- package/lib/theme-tokens.js +2 -2
- package/lib/theme-tokens.js.map +1 -1
- package/lib/theme.d.ts +5 -10
- package/lib/theme.d.ts.map +1 -1
- package/lib/theme.js +11 -18
- package/lib/theme.js.map +1 -1
- package/lib/todo-guard.d.ts +8 -4
- package/lib/todo-guard.d.ts.map +1 -1
- package/lib/todo-guard.js +17 -6
- package/lib/todo-guard.js.map +1 -1
- package/lib/tokens.d.ts +0 -2
- package/lib/tokens.d.ts.map +1 -1
- package/lib/tokens.js +1 -1
- package/lib/tokens.js.map +1 -1
- package/lib/tool-display.d.ts +1 -13
- package/lib/tool-display.d.ts.map +1 -1
- package/lib/tool-display.js +4 -4
- package/lib/tool-display.js.map +1 -1
- package/lib/transcript/message-content.d.ts.map +1 -1
- package/lib/transcript/message-content.js +31 -9
- package/lib/transcript/message-content.js.map +1 -1
- package/lib/transcript/tool-calls.d.ts +9 -7
- package/lib/transcript/tool-calls.d.ts.map +1 -1
- package/lib/transcript/tool-calls.js +27 -20
- package/lib/transcript/tool-calls.js.map +1 -1
- package/lib/transcript.d.ts +15 -18
- package/lib/transcript.d.ts.map +1 -1
- package/lib/transcript.js +70 -41
- package/lib/transcript.js.map +1 -1
- package/lib/ui/copy.d.ts +5 -4
- package/lib/ui/copy.d.ts.map +1 -1
- package/lib/ui/copy.js +9 -6
- package/lib/ui/copy.js.map +1 -1
- package/lib/ui/diff.d.ts +0 -30
- package/lib/ui/diff.d.ts.map +1 -1
- package/lib/ui/diff.js +16 -9
- package/lib/ui/diff.js.map +1 -1
- package/lib/ui/dock.d.ts +12 -10
- package/lib/ui/dock.d.ts.map +1 -1
- package/lib/ui/dock.js +27 -14
- package/lib/ui/dock.js.map +1 -1
- package/lib/ui/editor.d.ts +5 -4
- package/lib/ui/editor.d.ts.map +1 -1
- package/lib/ui/editor.js +17 -9
- package/lib/ui/editor.js.map +1 -1
- package/lib/ui/frame.d.ts +4 -12
- package/lib/ui/frame.d.ts.map +1 -1
- package/lib/ui/frame.js +6 -6
- package/lib/ui/frame.js.map +1 -1
- package/lib/ui/gap.d.ts +0 -4
- package/lib/ui/gap.d.ts.map +1 -1
- package/lib/ui/gap.js +4 -3
- package/lib/ui/gap.js.map +1 -1
- package/lib/ui/gate-input.d.ts +3 -3
- package/lib/ui/gate-input.d.ts.map +1 -1
- package/lib/ui/gate-input.js +9 -9
- package/lib/ui/gate-input.js.map +1 -1
- package/lib/ui/layout.d.ts +1 -8
- package/lib/ui/layout.d.ts.map +1 -1
- package/lib/ui/layout.js +10 -11
- package/lib/ui/layout.js.map +1 -1
- package/lib/ui/markdown.d.ts +3 -5
- package/lib/ui/markdown.d.ts.map +1 -1
- package/lib/ui/markdown.js +18 -7
- package/lib/ui/markdown.js.map +1 -1
- package/lib/ui/mermaid.d.ts +0 -11
- package/lib/ui/mermaid.d.ts.map +1 -1
- package/lib/ui/mermaid.js +32 -17
- package/lib/ui/mermaid.js.map +1 -1
- package/lib/ui/picker-card.d.ts +4 -8
- package/lib/ui/picker-card.d.ts.map +1 -1
- package/lib/ui/picker-card.js +17 -15
- package/lib/ui/picker-card.js.map +1 -1
- package/lib/ui/picker.d.ts +11 -17
- package/lib/ui/picker.d.ts.map +1 -1
- package/lib/ui/picker.js +36 -17
- package/lib/ui/picker.js.map +1 -1
- package/lib/ui/queue.d.ts.map +1 -1
- package/lib/ui/queue.js +11 -1
- package/lib/ui/queue.js.map +1 -1
- package/lib/ui/stash-picker.d.ts +1 -10
- package/lib/ui/stash-picker.d.ts.map +1 -1
- package/lib/ui/stash-picker.js +4 -4
- package/lib/ui/stash-picker.js.map +1 -1
- package/lib/ui/status.d.ts +2 -19
- package/lib/ui/status.d.ts.map +1 -1
- package/lib/ui/status.js +15 -17
- package/lib/ui/status.js.map +1 -1
- package/lib/ui/view/document.d.ts +33 -0
- package/lib/ui/view/document.d.ts.map +1 -0
- package/lib/ui/view/document.js +96 -0
- package/lib/ui/view/document.js.map +1 -0
- package/lib/ui/view/gate-card.d.ts +2 -0
- package/lib/ui/view/gate-card.d.ts.map +1 -1
- package/lib/ui/view/gate-card.js +12 -10
- package/lib/ui/view/gate-card.js.map +1 -1
- package/lib/ui/view/tool-card.d.ts +7 -4
- package/lib/ui/view/tool-card.d.ts.map +1 -1
- package/lib/ui/view/tool-card.js +12 -17
- package/lib/ui/view/tool-card.js.map +1 -1
- package/lib/ui/view/transcript-message.d.ts +7 -7
- package/lib/ui/view/transcript-message.d.ts.map +1 -1
- package/lib/ui/view/transcript-message.js +19 -10
- package/lib/ui/view/transcript-message.js.map +1 -1
- package/lib/ui/view.d.ts +53 -84
- package/lib/ui/view.d.ts.map +1 -1
- package/lib/ui/view.js +79 -158
- package/lib/ui/view.js.map +1 -1
- package/lib/work.d.ts +13 -10
- package/lib/work.d.ts.map +1 -1
- package/lib/work.js +30 -8
- package/lib/work.js.map +1 -1
- package/package.json +12 -7
- package/presets/cordis.patch.yml +1 -0
- package/presets/minimal.patch.yml +1 -0
- package/presets/ptc.patch.yml +1 -0
- package/presets/standard.patch.yml +1 -0
- package/themes/deepseek-blue.yaml +38 -51
- package/themes/marine-static.yaml +27 -35
- package/themes/pine-slope.yaml +13 -11
- package/themes/polar-drift.yaml +6 -0
- package/themes/violet-orbit.yaml +14 -18
- package/themes/wine-thicket.yaml +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys-command.d.ts","sourceRoot":"","sources":["../src/keys-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAE5D,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAA4E,CAAA;AAmB5H,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEpD;AAED,
|
|
1
|
+
{"version":3,"file":"keys-command.d.ts","sourceRoot":"","sources":["../src/keys-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAE5D,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAA4E,CAAA;AAmB5H,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEpD;AAED,mHAAmH;AACnH,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,SAAS,EAAE,CAyBhF"}
|
package/lib/model-list.d.ts
CHANGED
|
@@ -1,31 +1,4 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
/**
|
|
3
|
-
* The directory slice a listing reads.
|
|
4
|
-
*
|
|
5
|
-
* Structural rather than the catalog's own type so formatting stays free of the
|
|
6
|
-
* llm service; the order and the entries are exactly what the picker reads. A
|
|
7
|
-
* name is optional here because an adapter may advertise a route without one,
|
|
8
|
-
* while the id is always the value a request would name.
|
|
9
|
-
*/
|
|
10
|
-
export interface ModelListCatalog {
|
|
11
|
-
providers(): readonly {
|
|
12
|
-
readonly id: string;
|
|
13
|
-
readonly name: string;
|
|
14
|
-
}[];
|
|
15
|
-
models(provider: string): Promise<readonly {
|
|
16
|
-
readonly id: string;
|
|
17
|
-
readonly name?: string;
|
|
18
|
-
}[]>;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Format one line per reachable route, in the picker's own order.
|
|
22
|
-
*
|
|
23
|
-
* The order — registered providers in turn, then each provider's models in the
|
|
24
|
-
* order its adapter answered — is read from the catalog and never re-sorted, so
|
|
25
|
-
* any disagreement with the picker is a catalog disagreement, never a
|
|
26
|
-
* formatting one.
|
|
27
|
-
*/
|
|
28
|
-
export declare function modelListLines(catalog: ModelListCatalog): Promise<string[]>;
|
|
29
2
|
/**
|
|
30
3
|
* Print the model directory to stdout and exit, without touching the terminal.
|
|
31
4
|
*
|
package/lib/model-list.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-list.d.ts","sourceRoot":"","sources":["../src/model-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"model-list.d.ts","sourceRoot":"","sources":["../src/model-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AA0DlD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB5F"}
|
package/lib/model-list.js
CHANGED
|
@@ -28,7 +28,7 @@ const CATALOG_GAP_MESSAGES = {
|
|
|
28
28
|
* any disagreement with the picker is a catalog disagreement, never a
|
|
29
29
|
* formatting one.
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
async function modelListLines(catalog) {
|
|
32
32
|
const lines = [];
|
|
33
33
|
for (const provider of catalog.providers()) {
|
|
34
34
|
for (const model of await catalog.models(provider.id)) {
|
package/lib/model-list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-list.js","sourceRoot":"","sources":["../src/model-list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAwB,MAAM,kBAAkB,CAAA;AAElG;;;;;GAKG;AACH,MAAM,eAAe,GAAG,IAAI,CAAA;AAE5B,kFAAkF;AAClF,MAAM,cAAc,GAAG,iCAAiC,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAoC;IAC5D,cAAc,EAAE,GAAG,uBAAuB,CAAC,cAAc,8BAA8B;IACvF,4BAA4B,EAAE,GAAG,uBAAuB,CAAC,4BAA4B,gCAAgC;UACjH,oDAAoD;CACzD,CAAA;AAeD;;;;;;;GAOG;AACH,
|
|
1
|
+
{"version":3,"file":"model-list.js","sourceRoot":"","sources":["../src/model-list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAwB,MAAM,kBAAkB,CAAA;AAElG;;;;;GAKG;AACH,MAAM,eAAe,GAAG,IAAI,CAAA;AAE5B,kFAAkF;AAClF,MAAM,cAAc,GAAG,iCAAiC,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAoC;IAC5D,cAAc,EAAE,GAAG,uBAAuB,CAAC,cAAc,8BAA8B;IACvF,4BAA4B,EAAE,GAAG,uBAAuB,CAAC,4BAA4B,gCAAgC;UACjH,oDAAoD;CACzD,CAAA;AAeD;;;;;;;GAOG;AACH,KAAK,UAAU,cAAc,CAAC,OAAyB;IACrD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACtD,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,GAAG,eAAe,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;QACrF,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAY,EAAE,IAA4B;IAC3E,MAAM,IAAI,GAAG,CAAC,OAAe,EAAQ,EAAE;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,cAAc,GAAG,OAAO,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,CAAC,CAAC,CAAA;IACT,CAAC,CAAA;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IACrC,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;QACvC,OAAM;IACR,CAAC;IACD,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACxF,OAAM;IACR,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,2CAA2C,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7C,IAAI,CAAC,CAAC,CAAC,CAAA;AACT,CAAC"}
|
package/lib/moshi.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DriverStatus } from './herdr/state.ts';
|
|
2
|
+
/** Surface facts exclude transcript, tool arguments, and approval authority. */
|
|
3
|
+
export interface MoshiReporter {
|
|
4
|
+
session(id: string, status: DriverStatus): void;
|
|
5
|
+
driver(status: DriverStatus): void;
|
|
6
|
+
background(running: boolean): void;
|
|
7
|
+
block(key: string): void;
|
|
8
|
+
unblock(key: string): void;
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
11
|
+
/** Best-effort notifications must never hold the terminal or become an agent dependency. */
|
|
12
|
+
export declare function createMoshiReporter(): MoshiReporter | undefined;
|
|
13
|
+
//# sourceMappingURL=moshi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moshi.d.ts","sourceRoot":"","sources":["../src/moshi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAcpD,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC/C,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAClC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAClC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,IAAI,IAAI,CAAA;CAChB;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,IAAI,aAAa,GAAG,SAAS,CA8G/D"}
|
package/lib/moshi.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/** A dedicated token is explicit consent; generic Moshi pairing credentials are never read. */
|
|
2
|
+
const TOKEN_ENV = 'DSH_TUI_MOSHI_TOKEN';
|
|
3
|
+
const WEBHOOK = 'https://api.getmoshi.app/api/webhook';
|
|
4
|
+
// Bound each request so a stalled endpoint cannot retain the single delivery slot indefinitely.
|
|
5
|
+
const REQUEST_TIMEOUT_MS = 3_000;
|
|
6
|
+
const NOTICES = {
|
|
7
|
+
complete: { title: 'DSH finished', message: 'The current session is ready for input.' },
|
|
8
|
+
attention: { title: 'DSH needs attention', message: 'Return to the terminal to continue.' },
|
|
9
|
+
};
|
|
10
|
+
/** Best-effort notifications must never hold the terminal or become an agent dependency. */
|
|
11
|
+
export function createMoshiReporter() {
|
|
12
|
+
const token = process.env[TOKEN_ENV]?.trim();
|
|
13
|
+
if (!token)
|
|
14
|
+
return undefined;
|
|
15
|
+
let session;
|
|
16
|
+
let driverRunning = false;
|
|
17
|
+
let backgroundRunning = false;
|
|
18
|
+
let workPending = false;
|
|
19
|
+
let disposed = false;
|
|
20
|
+
let sending = false;
|
|
21
|
+
let activeRequest;
|
|
22
|
+
const blocked = new Set();
|
|
23
|
+
// Two fixed notice kinds bound memory while a slow endpoint is unavailable.
|
|
24
|
+
const pending = new Set();
|
|
25
|
+
const flush = () => {
|
|
26
|
+
if (disposed || session === undefined || sending)
|
|
27
|
+
return;
|
|
28
|
+
const notice = pending.values().next().value;
|
|
29
|
+
if (notice === undefined)
|
|
30
|
+
return;
|
|
31
|
+
pending.delete(notice);
|
|
32
|
+
sending = true;
|
|
33
|
+
void deliver(notice);
|
|
34
|
+
};
|
|
35
|
+
const deliver = async (notice) => {
|
|
36
|
+
const controller = new AbortController();
|
|
37
|
+
activeRequest = controller;
|
|
38
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
39
|
+
timeout.unref();
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch(WEBHOOK, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: { 'Content-Type': 'application/json' },
|
|
44
|
+
// A redirect must not forward the notification credential elsewhere.
|
|
45
|
+
redirect: 'error',
|
|
46
|
+
signal: controller.signal,
|
|
47
|
+
body: JSON.stringify({ token, ...NOTICES[notice] }),
|
|
48
|
+
});
|
|
49
|
+
await response.body?.cancel();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Errors may contain credentials; neither terminal output nor session logs may receive them.
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
clearTimeout(timeout);
|
|
56
|
+
if (activeRequest === controller)
|
|
57
|
+
activeRequest = undefined;
|
|
58
|
+
sending = false;
|
|
59
|
+
flush();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const enqueue = (notice) => {
|
|
63
|
+
if (disposed || session === undefined)
|
|
64
|
+
return;
|
|
65
|
+
pending.add(notice);
|
|
66
|
+
flush();
|
|
67
|
+
};
|
|
68
|
+
// Completion means observed work settled without blockers, not task success or a repeated idle event.
|
|
69
|
+
const settle = () => {
|
|
70
|
+
if (disposed || session === undefined)
|
|
71
|
+
return;
|
|
72
|
+
if (driverRunning || backgroundRunning) {
|
|
73
|
+
// A resumed run makes an unsent completion obsolete.
|
|
74
|
+
pending.delete('complete');
|
|
75
|
+
workPending = true;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (blocked.size !== 0 || !workPending)
|
|
79
|
+
return;
|
|
80
|
+
workPending = false;
|
|
81
|
+
enqueue('complete');
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
// New session facts invalidate queued notices and outstanding delivery for the previous session.
|
|
85
|
+
session(id, status) {
|
|
86
|
+
if (disposed)
|
|
87
|
+
return;
|
|
88
|
+
pending.clear();
|
|
89
|
+
activeRequest?.abort();
|
|
90
|
+
session = id;
|
|
91
|
+
blocked.clear();
|
|
92
|
+
backgroundRunning = false;
|
|
93
|
+
driverRunning = status === 'running';
|
|
94
|
+
workPending = driverRunning;
|
|
95
|
+
},
|
|
96
|
+
driver(status) {
|
|
97
|
+
driverRunning = status === 'running';
|
|
98
|
+
settle();
|
|
99
|
+
},
|
|
100
|
+
background(running) {
|
|
101
|
+
backgroundRunning = running;
|
|
102
|
+
settle();
|
|
103
|
+
},
|
|
104
|
+
// Several gates may block one episode; only the first needs an attention notice.
|
|
105
|
+
block(key) {
|
|
106
|
+
if (disposed || session === undefined || blocked.has(key))
|
|
107
|
+
return;
|
|
108
|
+
const first = blocked.size === 0;
|
|
109
|
+
blocked.add(key);
|
|
110
|
+
pending.delete('complete');
|
|
111
|
+
if (first)
|
|
112
|
+
enqueue('attention');
|
|
113
|
+
},
|
|
114
|
+
unblock(key) {
|
|
115
|
+
if (!blocked.delete(key))
|
|
116
|
+
return;
|
|
117
|
+
if (blocked.size === 0)
|
|
118
|
+
pending.delete('attention');
|
|
119
|
+
settle();
|
|
120
|
+
},
|
|
121
|
+
dispose() {
|
|
122
|
+
disposed = true;
|
|
123
|
+
session = undefined;
|
|
124
|
+
pending.clear();
|
|
125
|
+
blocked.clear();
|
|
126
|
+
activeRequest?.abort();
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=moshi.js.map
|
package/lib/moshi.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moshi.js","sourceRoot":"","sources":["../src/moshi.ts"],"names":[],"mappings":"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"}
|
package/lib/spacing.d.ts
CHANGED
|
@@ -15,13 +15,6 @@ export interface Spacing {
|
|
|
15
15
|
/** Blank rows where a step of a turn opens, so a thought and the calls it made read as one group. */
|
|
16
16
|
readonly steps: number;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* The widest gap or edge the reader may ask for.
|
|
20
|
-
*
|
|
21
|
-
* Past a few rows the break stops reading as air between two things and starts
|
|
22
|
-
* reading as a hole the reader has to scroll past on every message.
|
|
23
|
-
*/
|
|
24
|
-
export declare const MAX_SPACING = 3;
|
|
25
18
|
/**
|
|
26
19
|
* The shipped spacing: one column at the edges and one row at a break.
|
|
27
20
|
*
|
package/lib/spacing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spacing.d.ts","sourceRoot":"","sources":["../src/spacing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,OAAO;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,qGAAqG;IACrG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;
|
|
1
|
+
{"version":3,"file":"spacing.d.ts","sourceRoot":"","sources":["../src/spacing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,OAAO;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,qGAAqG;IACrG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAUD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,OAA+C,CAAA;AAa7E;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAWlD"}
|
package/lib/spacing.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Past a few rows the break stops reading as air between two things and starts
|
|
13
13
|
* reading as a hole the reader has to scroll past on every message.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
const MAX_SPACING = 3;
|
|
16
16
|
/**
|
|
17
17
|
* The shipped spacing: one column at the edges and one row at a break.
|
|
18
18
|
*
|
package/lib/spacing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spacing.js","sourceRoot":"","sources":["../src/spacing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH;;;;;GAKG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"spacing.js","sourceRoot":"","sources":["../src/spacing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,CAAA;AAErB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;AAE7E,iGAAiG;AACjG,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;AAErF,wCAAwC;AACxC,SAAS,KAAK,CAAC,KAAc,EAAE,KAAa;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;QAClG,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,KAAK,GAAG,oCAAoC,GAAG,WAAW,CAAC,CAAA;IAC1F,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,eAAe,CAAA;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACzH,MAAM,KAAK,GAAG,GAA8B,CAAA;IAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1H,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC;QAChG,QAAQ,EAAE,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC;QACrG,KAAK,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;KACvF,CAAA;AACH,CAAC"}
|
package/lib/startup.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export declare const name = "tui-startup";
|
|
|
3
3
|
/** The launcher owns the arguments; this row only reads its own snapshot. */
|
|
4
4
|
export declare const inject: string[];
|
|
5
5
|
export { PROFILE_NAME } from './identity.ts';
|
|
6
|
-
/**
|
|
6
|
+
/** Align a configured `main` agent with the TUI session; exact-id lookup leaves other agents unchanged. */
|
|
7
7
|
export declare const MAIN_AGENT_ID = "main";
|
|
8
8
|
/** Context key of the parsed launch service consumed by the tui row. */
|
|
9
9
|
export declare const TUI_STARTUP_SERVICE = "tuiStartup";
|
package/lib/startup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,MAAM,UAAkB,CAAA;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,
|
|
1
|
+
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,MAAM,UAAkB,CAAA;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,2GAA2G;AAC3G,eAAO,MAAM,aAAa,SAAS,CAAA;AAEnC,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,eAAe,CAAA;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AA0DlD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAoGxC"}
|
package/lib/startup.js
CHANGED
|
@@ -9,7 +9,7 @@ export const name = 'tui-startup';
|
|
|
9
9
|
/** The launcher owns the arguments; this row only reads its own snapshot. */
|
|
10
10
|
export const inject = ['cmdlineArgs'];
|
|
11
11
|
export { PROFILE_NAME } from "./identity.js";
|
|
12
|
-
/**
|
|
12
|
+
/** Align a configured `main` agent with the TUI session; exact-id lookup leaves other agents unchanged. */
|
|
13
13
|
export const MAIN_AGENT_ID = 'main';
|
|
14
14
|
/** Context key of the parsed launch service consumed by the tui row. */
|
|
15
15
|
export const TUI_STARTUP_SERVICE = 'tuiStartup';
|
|
@@ -39,6 +39,7 @@ function launchOf(program, mode, session, options) {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
catch (error) {
|
|
42
|
+
// Argument mistakes need usage diagnostics; unexpected failures must remain startup failures.
|
|
42
43
|
if (error instanceof LaunchUsageError) {
|
|
43
44
|
program.error(`dsh --profile tui: ${error.message}`);
|
|
44
45
|
return undefined;
|
|
@@ -80,6 +81,8 @@ export function apply(ctx) {
|
|
|
80
81
|
.option('--preset <preset>', 'agent preset (mode) the new session runs')
|
|
81
82
|
.option('--no-color', 'disable ANSI styling')
|
|
82
83
|
.option('--no-bell', 'do not ring the terminal bell when a long turn finishes');
|
|
84
|
+
// Installation must also work without a TTY: use launcher exit without publishing
|
|
85
|
+
// tuiStartup, whose consumers would mount the interactive surface.
|
|
83
86
|
program.command('install-skills')
|
|
84
87
|
.description('install or update the bundled skills in ~/.agents/skills/')
|
|
85
88
|
.option('--update', 'replace an existing skill without asking')
|
|
@@ -97,6 +100,8 @@ export function apply(ctx) {
|
|
|
97
100
|
}
|
|
98
101
|
exit(0);
|
|
99
102
|
};
|
|
103
|
+
// Replacement discards local skill edits, so require --update or affirmative
|
|
104
|
+
// consent. Both streams must be interactive for the prompt; refusal is the default.
|
|
100
105
|
if (options.update === true) {
|
|
101
106
|
try {
|
|
102
107
|
install(true);
|
|
@@ -154,6 +159,9 @@ export function apply(ctx) {
|
|
|
154
159
|
const launch = launchOf(program, mode, session, options);
|
|
155
160
|
if (launch === undefined)
|
|
156
161
|
return;
|
|
162
|
+
// Keep an optional configured main agent aligned with the surface's launch identity.
|
|
163
|
+
// The initial recovery hint must name that same session; it cannot follow later forks
|
|
164
|
+
// or switches. Terminal shutdown builds its hint from the active session instead.
|
|
157
165
|
ctx.provide(CONFIGURED_AGENT_IDENTITIES_KEY, { [MAIN_AGENT_ID]: launch.identity });
|
|
158
166
|
ctx.provide(TUI_STARTUP_SERVICE, launch.startup);
|
|
159
167
|
ctx.provide('tuiGoodbyeMessage', resumeHint(launch.identity.id, PROFILE_NAME));
|
package/lib/startup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,+BAA+B,EAA8B,MAAM,6BAA6B,CAAA;AAEzG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC3G,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAEnF,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAA;AAEjC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,CAAA;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,
|
|
1
|
+
{"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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"}
|
package/lib/stash/lock.d.ts
CHANGED
|
@@ -23,13 +23,7 @@ export interface StashMutationResult<Result> {
|
|
|
23
23
|
readonly didPersist: boolean;
|
|
24
24
|
readonly result: Result;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
readonly pid: number;
|
|
28
|
-
readonly host: string;
|
|
29
|
-
readonly token: string;
|
|
30
|
-
readonly createdAt: string;
|
|
31
|
-
}
|
|
32
|
-
/** Take the file lock for a read that must not observe a half-written file. */
|
|
26
|
+
/** Serialize reads that may quarantine the bank with mutations, so recovery cannot race a writer. */
|
|
33
27
|
export declare function withStashFileLock<Result>(filePath: string, operation: () => Promise<Result>): Promise<Result>;
|
|
34
28
|
/**
|
|
35
29
|
* Take the lock for a mutation, and classify an unlock failure as committed.
|
|
@@ -39,34 +33,4 @@ export declare function withStashFileLock<Result>(filePath: string, operation: (
|
|
|
39
33
|
* failure.
|
|
40
34
|
*/
|
|
41
35
|
export declare function withStashMutationLock<Result>(filePath: string, operation: () => Promise<StashMutationResult<Result>>): Promise<Result>;
|
|
42
|
-
/**
|
|
43
|
-
* The claim a reclaimer takes, named after the bank whose lock it guards.
|
|
44
|
-
*
|
|
45
|
-
* Exported because it is the path a timeout tells the reader to clear by hand.
|
|
46
|
-
*/
|
|
47
|
-
export declare function reclaimMutexPath(lockDir: string): string;
|
|
48
|
-
/**
|
|
49
|
-
* What a reclaim is allowed to act on: one reading of the lock, with the
|
|
50
|
-
* identity of the directory it was read from.
|
|
51
|
-
*
|
|
52
|
-
* The owner bytes alone are not enough, because the directory that held them can
|
|
53
|
-
* be released and replaced between the reading and the removal. A lock is only
|
|
54
|
-
* removed when both the identity and the token still match what was judged.
|
|
55
|
-
*/
|
|
56
|
-
export interface LockObservation {
|
|
57
|
-
readonly owner: LockOwner | undefined;
|
|
58
|
-
readonly device: number;
|
|
59
|
-
readonly inode: number;
|
|
60
|
-
readonly modified: number;
|
|
61
|
-
}
|
|
62
|
-
/** Read a lock and the identity of the directory it was read from, in one pass. */
|
|
63
|
-
export declare function observeLock(lockDir: string): Promise<LockObservation | undefined>;
|
|
64
|
-
/**
|
|
65
|
-
* Remove the lock a judgement was made about, and nothing that replaced it.
|
|
66
|
-
*
|
|
67
|
-
* Exported so the race this exists for can be driven from a test: hold an
|
|
68
|
-
* observation, publish a live lock in its place, and the removal has to refuse.
|
|
69
|
-
*/
|
|
70
|
-
export declare function removeObservedLock(lockDir: string, observed: LockObservation): Promise<boolean>;
|
|
71
|
-
export {};
|
|
72
36
|
//# sourceMappingURL=lock.d.ts.map
|
package/lib/stash/lock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/stash/lock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/stash/lock.ts"],"names":[],"mappings":"AAmDA,uFAAuF;AACvF,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG,cAAc,CAAA;AAEjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;GAMG;AACH,qBAAa,mBAAmB,CAAC,MAAM,GAAG,OAAO,CAAE,SAAQ,KAAK;IAC9D,QAAQ,CAAC,SAAS,QAAO;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,cAAc,EAAE,YAAY,GAAG,SAAS,CAAA;gBAErC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,YAAY;CAYjF;AAED,MAAM,WAAW,mBAAmB,CAAC,MAAM;IACzC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AASD,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7G;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAChD,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
package/lib/stash/lock.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Two `dsh --profile tui` runs can share a working directory, so every read that
|
|
4
4
|
// feeds a write and every write itself happens under an exclusive directory
|
|
5
|
-
// lock
|
|
5
|
+
// lock to coordinate access and reduce lost updates from read-modify-write races.
|
|
6
6
|
// Ownership is recorded in the lock so a lock left by a crashed process is
|
|
7
7
|
// reclaimed rather than wedging the bank forever.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
9
|
+
// Release moves the directory aside before checking ownership to avoid deleting
|
|
10
|
+
// through the acquisition path. Reclaimers use a separate claim and recheck the
|
|
11
|
+
// observed identity to reject visible replacements. That claim serializes only
|
|
12
|
+
// reclaimers; the final check and pathname removal are not atomic with release
|
|
13
|
+
// or acquisition, so they cannot guarantee a successor is untouched.
|
|
14
14
|
import { createHash } from 'node:crypto';
|
|
15
15
|
import { link, mkdir, rename, rm } from 'node:fs/promises';
|
|
16
16
|
import { hostname } from 'node:os';
|
|
@@ -18,21 +18,23 @@ import path from 'node:path';
|
|
|
18
18
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
19
19
|
import { assertPrivateDirectory, ensurePrivateDirectory, hasErrorCode, PRIVATE_DIR_MODE, readPrivateTextFile, removePrivateDirectory, writePrivateFileExclusive, } from "./private-fs.js";
|
|
20
20
|
import { createNewId } from "./schema.js";
|
|
21
|
+
// Space contention polls to limit filesystem work while still noticing a released lock.
|
|
21
22
|
const LOCK_RETRY_MS = 25;
|
|
23
|
+
// Bound contention waits for stash commands; filesystem operations can outlast this deadline.
|
|
22
24
|
const LOCK_TIMEOUT_MS = 2000;
|
|
25
|
+
// Allow incomplete owner publication before recovery, not a lease on a validated live owner.
|
|
23
26
|
const LOCK_STALE_MS = 30_000;
|
|
24
27
|
const LOCK_OWNER_FILE = 'owner.json';
|
|
25
28
|
const LOCK_TAKEOVER_SUFFIX = '.taken';
|
|
26
29
|
/**
|
|
27
30
|
* The name reclaimers link their claim file onto, so exactly one of them wins.
|
|
28
31
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* a digest rather than the key itself, because a key at the sanitizer's limit
|
|
33
|
-
* plus a suffix and a token is longer than the longest name a filesystem accepts.
|
|
32
|
+
* Bank-derived claim names avoid one shared recovery claim for all working
|
|
33
|
+
* directories in storage. A digest leaves room for suffixes and tokens even
|
|
34
|
+
* when the bank key reaches the sanitizer's limit.
|
|
34
35
|
*/
|
|
35
36
|
const RECLAIM_PREFIX = '.claim-';
|
|
37
|
+
// Truncation leaves room for claim tokens in filenames, at the cost of possible cross-bank collisions.
|
|
36
38
|
const RECLAIM_DIGEST_LENGTH = 16;
|
|
37
39
|
const LOCK_CHANGED_MESSAGE = 'stash lock changed before release';
|
|
38
40
|
/**
|
|
@@ -58,7 +60,7 @@ export class StashCommittedError extends Error {
|
|
|
58
60
|
this.releaseFailure = releaseFailure;
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
/**
|
|
63
|
+
/** Serialize reads that may quarantine the bank with mutations, so recovery cannot race a writer. */
|
|
62
64
|
export function withStashFileLock(filePath, operation) {
|
|
63
65
|
return withStashLock(filePath, operation, false);
|
|
64
66
|
}
|
|
@@ -107,10 +109,9 @@ async function withStashLock(filePath, operation, mutation) {
|
|
|
107
109
|
if (mutation && isPersistedMutation(result)) {
|
|
108
110
|
throw new StashCommittedError(result.result, { phase: 'lock-release', error: releaseError });
|
|
109
111
|
}
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
// path of a bank that was quarantined while it was being read.
|
|
112
|
+
// Preserve the completed read, including any quarantine path, rather than
|
|
113
|
+
// discard its result over cleanup. A leftover lock can still block writers:
|
|
114
|
+
// reclamation refuses an owner whose local PID remains alive.
|
|
114
115
|
if (mutation)
|
|
115
116
|
throw releaseError;
|
|
116
117
|
}
|
|
@@ -172,9 +173,9 @@ function lockTimeout(lockDir) {
|
|
|
172
173
|
/**
|
|
173
174
|
* The claim a reclaimer takes, named after the bank whose lock it guards.
|
|
174
175
|
*
|
|
175
|
-
*
|
|
176
|
+
* The timeout names this path so the reader can identify the reclaimer blocking recovery.
|
|
176
177
|
*/
|
|
177
|
-
|
|
178
|
+
function reclaimMutexPath(lockDir) {
|
|
178
179
|
const digest = createHash('sha256').update(path.basename(lockDir), 'utf8').digest('hex');
|
|
179
180
|
return path.join(path.dirname(lockDir), `${RECLAIM_PREFIX}${digest.slice(0, RECLAIM_DIGEST_LENGTH)}`);
|
|
180
181
|
}
|
|
@@ -254,10 +255,9 @@ async function takeLockDirectory(lockDir) {
|
|
|
254
255
|
/**
|
|
255
256
|
* Put a lock back that turned out to belong to someone else.
|
|
256
257
|
*
|
|
257
|
-
* A
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* costs a second writer in the bank.
|
|
258
|
+
* A mismatched token does not authorize deleting the displaced directory. If
|
|
259
|
+
* restoration fails, preserve it and report the failure rather than destroy
|
|
260
|
+
* another owner's record. This cannot exclude a successor at the original path.
|
|
261
261
|
*/
|
|
262
262
|
async function putBackLockDirectory(taken, lockDir) {
|
|
263
263
|
try {
|
|
@@ -281,7 +281,7 @@ function processIsAlive(pid) {
|
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
/** Read a lock and the identity of the directory it was read from, in one pass. */
|
|
284
|
-
|
|
284
|
+
async function observeLock(lockDir) {
|
|
285
285
|
let stats;
|
|
286
286
|
try {
|
|
287
287
|
stats = await assertPrivateDirectory(lockDir, 'stash lock');
|
|
@@ -297,17 +297,15 @@ export async function observeLock(lockDir) {
|
|
|
297
297
|
/**
|
|
298
298
|
* Reclaim a lock whose owner is gone.
|
|
299
299
|
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* otherwise leave its successor's live lock to be deleted, and both writers
|
|
305
|
-
* would then run at once.
|
|
300
|
+
* The claim serializes reclaimers so they cannot independently judge and remove
|
|
301
|
+
* the same lock. Rechecking identity and token rejects replacements visible
|
|
302
|
+
* before deletion, but acquisition and release do not take this claim: it cannot
|
|
303
|
+
* exclude a replacement between the final check and pathname removal.
|
|
306
304
|
*
|
|
307
305
|
* A reclaimer killed inside that section leaves the claim file behind, and every
|
|
308
306
|
* later reclaim fails closed at the timeout instead of guessing. That message
|
|
309
|
-
* names the file
|
|
310
|
-
*
|
|
307
|
+
* names the file so an operator can locate the obstruction. Manual cleanup must
|
|
308
|
+
* account for active reclaimers; deleting their claim would break coordination.
|
|
311
309
|
*/
|
|
312
310
|
async function reclaimAbandonedLock(lockDir) {
|
|
313
311
|
const mutex = reclaimMutexPath(lockDir);
|
|
@@ -321,17 +319,19 @@ async function reclaimAbandonedLock(lockDir) {
|
|
|
321
319
|
return await removeObservedLock(lockDir, observed);
|
|
322
320
|
}
|
|
323
321
|
finally {
|
|
322
|
+
// Best-effort cleanup preserves the reclaim outcome. A leftover mutex still
|
|
323
|
+
// blocks later reclamation and requires the manual recovery described above.
|
|
324
324
|
await rm(claim, { force: true }).catch(() => undefined);
|
|
325
325
|
await rm(mutex, { force: true }).catch(() => undefined);
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
328
|
/**
|
|
329
|
-
*
|
|
329
|
+
* Reject a replacement visible when rechecking the abandoned-lock observation.
|
|
330
330
|
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
331
|
+
* Identity and token checks reduce stale-observation deletion; they cannot
|
|
332
|
+
* exclude replacement after the check because removal still uses the pathname.
|
|
333
333
|
*/
|
|
334
|
-
|
|
334
|
+
async function removeObservedLock(lockDir, observed) {
|
|
335
335
|
const current = await observeLock(lockDir);
|
|
336
336
|
if (current === undefined)
|
|
337
337
|
return false;
|
|
@@ -344,6 +344,10 @@ export async function removeObservedLock(lockDir, observed) {
|
|
|
344
344
|
}
|
|
345
345
|
/** Whether one observation of a lock shows an owner that can no longer hold it. */
|
|
346
346
|
function isAbandonedLock(observed) {
|
|
347
|
+
// Missing or malformed ownership cannot support a PID check. Directory age
|
|
348
|
+
// gives a newly created lock time to publish its owner; it is a grace period,
|
|
349
|
+
// not proof that publication cannot be delayed beyond it.
|
|
350
|
+
// A local PID probe cannot establish whether an owner on another host exited.
|
|
347
351
|
if (observed.owner === undefined)
|
|
348
352
|
return Date.now() - observed.modified > LOCK_STALE_MS;
|
|
349
353
|
if (observed.owner.host !== hostname())
|
|
@@ -365,6 +369,8 @@ async function claimReclaim(mutex) {
|
|
|
365
369
|
return claim;
|
|
366
370
|
}
|
|
367
371
|
catch (error) {
|
|
372
|
+
// Preserve the link outcome: EEXIST means another reclaimer holds the claim.
|
|
373
|
+
// Cleanup failure may leave this contender's private file behind.
|
|
368
374
|
await rm(claim, { force: true }).catch(() => undefined);
|
|
369
375
|
if (hasErrorCode(error, 'EEXIST'))
|
|
370
376
|
return undefined;
|