@crouton-kit/crouter 0.3.83 → 0.3.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/clients/attach/__tests__/attach-keybindings.test.js +14 -1
  2. package/dist/clients/attach/__tests__/crtr-output-render.test.js +5 -4
  3. package/dist/clients/attach/attach-cmd.d.ts +1 -1
  4. package/dist/clients/attach/attach-cmd.js +491 -491
  5. package/dist/commands/human/prompts.js +12 -6
  6. package/dist/commands/human.js +4 -2
  7. package/dist/commands/node.js +2 -1
  8. package/dist/commands/sys/__tests__/setup-front-door.test.js +8 -21
  9. package/dist/commands/sys/setup-core.d.ts +5 -17
  10. package/dist/commands/sys/setup-core.js +12 -36
  11. package/dist/commands/sys/setup.js +6 -4
  12. package/dist/core/__tests__/boot.test.js +141 -6
  13. package/dist/core/__tests__/pid-identity-match.test.js +63 -1
  14. package/dist/core/__tests__/tmux-surface.test.js +180 -2
  15. package/dist/core/canvas/boot.d.ts +44 -0
  16. package/dist/core/canvas/boot.js +35 -2
  17. package/dist/core/canvas/canvas.d.ts +40 -0
  18. package/dist/core/canvas/canvas.js +65 -1
  19. package/dist/core/canvas/pid.d.ts +43 -0
  20. package/dist/core/canvas/pid.js +57 -11
  21. package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +1 -0
  22. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +38 -0
  23. package/dist/core/keybindings/__tests__/resolve.test.js +1 -0
  24. package/dist/core/keybindings/catalog.d.ts +2 -2
  25. package/dist/core/keybindings/catalog.js +1 -0
  26. package/dist/core/keybindings/inbox.d.ts +21 -0
  27. package/dist/core/keybindings/inbox.js +35 -0
  28. package/dist/core/keybindings/index.d.ts +1 -0
  29. package/dist/core/keybindings/index.js +1 -0
  30. package/dist/core/preview-registry.js +7 -6
  31. package/dist/core/runtime/spawn.js +2 -10
  32. package/dist/core/runtime/tmux-chrome.d.ts +1 -1
  33. package/dist/core/runtime/tmux-chrome.js +1 -1
  34. package/dist/core/runtime/tmux.d.ts +1 -0
  35. package/dist/core/runtime/tmux.js +55 -1
  36. package/dist/daemon/crtrd.js +29 -5
  37. package/package.json +2 -2
@@ -7,8 +7,8 @@ type BrowseAction = 'quit' | 'down' | 'up' | 'first' | 'last' | 'expand-or-child
7
7
  type ProfileMenuAction = 'up' | 'down' | 'select' | 'accept-default' | 'abort' | `slot.${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` | 'create' | 'search-existing' | 'use-root' | 'set-default' | 'add-directory' | 'unpin';
8
8
  type SetupAction = 'cancel' | 'tab-next' | 'tab-previous' | 'open' | 'list-down' | 'list-up' | 'toggle' | 'details' | 'advance';
9
9
  type SetupKeybindingAction = 'edit' | 'commit-edit' | 'cancel-edit' | 'unbind' | 'reset-row' | 'reset-all' | 'save' | 'discard' | 'page-up' | 'page-down' | 'filter' | 'filter-delete' | 'filter-clear';
10
- export type BindingId = `crtr.tmux.menu.${TmuxMenuAction}` | `crtr.tmux.menu.issue.${'idea' | 'bug'}` | `crtr.tmux.node.${'next' | 'previous'}` | `crtr.tmux.view.${'next' | 'previous'}` | `crtr.attach.${'detach' | 'clear-or-detach' | 'graph.toggle' | 'model-ladder.next' | 'model-ladder.previous'}` | 'crtr.mode.cycle' | `crtr.graph.${GraphAction}` | `crtr.graph.confirm.${'accept' | 'cancel'}` | `crtr.view.host.${'force-quit' | 'editor.backspace'}` | `crtr.view.canvas.${'down' | 'up' | 'refresh' | 'quit'}` | `crtr.view.chat.${'submit' | 'contextual-cancel' | 'reconnect' | 'request-control' | 'release-control' | 'quit'}` | `crtr.view.git-pr.${'down' | 'up' | 'refresh' | 'quit'}` | `crtr.view.inbox.${InboxAction}` | `crtr.view.linkedin.${LinkedinAction}` | `crtr.view.prompt-review.${'down' | 'up' | 'compare-previous' | 'compare-next' | 'toggle-mode' | 'expand' | 'export' | 'refresh' | 'quit'}` | `crtr.view.settings.${'down' | 'up' | 'cell-previous' | 'cell-next' | 'refresh' | 'quit' | 'edit-or-submit' | 'cancel-edit'}` | `crtr.view.workspace-sidebar.${'down' | 'up' | 'open' | 'refresh' | 'quit'}` | `crtr.view-picker.${'down' | 'up' | 'run' | 'quit'}` | `crtr.browse.${BrowseAction}` | `crtr.browse.search.${'cancel' | 'commit' | 'delete' | 'quit'}` | `crtr.profile.menu.${ProfileMenuAction}` | `crtr.profile.search.${'up' | 'down' | 'pick' | 'back' | 'delete' | 'abort'}` | `crtr.setup.${SetupAction}` | `crtr.setup.confirm.${'accept' | 'back'}` | `crtr.setup.keybindings.${SetupKeybindingAction}`;
11
- export declare const BINDING_CATALOG: readonly [BindingDefinition<"crtr.tmux.menu.open">, BindingDefinition<"crtr.tmux.menu.promote">, BindingDefinition<"crtr.tmux.menu.resume">, BindingDefinition<"crtr.tmux.menu.demote">, BindingDefinition<"crtr.tmux.menu.detach">, BindingDefinition<"crtr.tmux.menu.close-subtree">, BindingDefinition<"crtr.tmux.menu.context">, BindingDefinition<"crtr.tmux.menu.providers">, BindingDefinition<"crtr.tmux.menu.graph">, BindingDefinition<"crtr.tmux.menu.focus-manager">, BindingDefinition<"crtr.tmux.menu.issues">, BindingDefinition<"crtr.tmux.menu.issue.idea">, BindingDefinition<"crtr.tmux.menu.issue.bug">, BindingDefinition<"crtr.tmux.node.next">, BindingDefinition<"crtr.tmux.node.previous">, BindingDefinition<"crtr.tmux.view.next">, BindingDefinition<"crtr.tmux.view.previous">, BindingDefinition<"crtr.attach.detach">, BindingDefinition<"crtr.attach.clear-or-detach">, BindingDefinition<"crtr.attach.graph.toggle">, BindingDefinition<"crtr.attach.model-ladder.next">, BindingDefinition<"crtr.attach.model-ladder.previous">, BindingDefinition<"crtr.mode.cycle">, BindingDefinition<"crtr.graph.down">, BindingDefinition<"crtr.graph.up">, BindingDefinition<"crtr.graph.first">, BindingDefinition<"crtr.graph.last">, BindingDefinition<"crtr.graph.collapse-or-manager">, BindingDefinition<"crtr.graph.expand-or-child">, BindingDefinition<"crtr.graph.focus">, BindingDefinition<"crtr.graph.focus-manager">, BindingDefinition<"crtr.graph.close-subtree">, BindingDefinition<"crtr.graph.dismiss">, BindingDefinition<"crtr.graph.confirm.accept">, BindingDefinition<"crtr.graph.confirm.cancel">, BindingDefinition<"crtr.view.host.force-quit">, BindingDefinition<"crtr.view.host.editor.backspace">, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<"crtr.view.chat.submit">, BindingDefinition<"crtr.view.chat.contextual-cancel">, BindingDefinition<"crtr.view.chat.reconnect">, BindingDefinition<"crtr.view.chat.request-control">, BindingDefinition<"crtr.view.chat.release-control">, BindingDefinition<"crtr.view.chat.quit">, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, ...(BindingDefinition<BindingId> | BindingDefinition<"crtr.view.prompt-review.down"> | BindingDefinition<"crtr.view.prompt-review.up"> | BindingDefinition<"crtr.view.prompt-review.compare-previous"> | BindingDefinition<"crtr.view.prompt-review.compare-next"> | BindingDefinition<"crtr.view.prompt-review.toggle-mode"> | BindingDefinition<"crtr.view.prompt-review.expand"> | BindingDefinition<"crtr.view.prompt-review.export"> | BindingDefinition<"crtr.view.prompt-review.refresh"> | BindingDefinition<"crtr.view.prompt-review.quit"> | BindingDefinition<"crtr.view.settings.down"> | BindingDefinition<"crtr.view.settings.up"> | BindingDefinition<"crtr.view.settings.cell-previous"> | BindingDefinition<"crtr.view.settings.cell-next"> | BindingDefinition<"crtr.view.settings.refresh"> | BindingDefinition<"crtr.view.settings.quit"> | BindingDefinition<"crtr.view.settings.edit-or-submit"> | BindingDefinition<"crtr.view.settings.cancel-edit"> | BindingDefinition<"crtr.view.workspace-sidebar.down"> | BindingDefinition<"crtr.view.workspace-sidebar.up"> | BindingDefinition<"crtr.view.workspace-sidebar.open"> | BindingDefinition<"crtr.view.workspace-sidebar.refresh"> | BindingDefinition<"crtr.view.workspace-sidebar.quit"> | BindingDefinition<"crtr.view-picker.down"> | BindingDefinition<"crtr.view-picker.up"> | BindingDefinition<"crtr.view-picker.run"> | BindingDefinition<"crtr.view-picker.quit"> | BindingDefinition<"crtr.browse.quit"> | BindingDefinition<"crtr.browse.down"> | BindingDefinition<"crtr.browse.up"> | BindingDefinition<"crtr.browse.first"> | BindingDefinition<"crtr.browse.last"> | BindingDefinition<"crtr.browse.expand-or-child"> | BindingDefinition<"crtr.browse.collapse-or-parent"> | BindingDefinition<"crtr.browse.toggle-fold"> | BindingDefinition<"crtr.browse.tab-next"> | BindingDefinition<"crtr.browse.tab-previous"> | BindingDefinition<"crtr.browse.tab.2" | "crtr.browse.tab.1" | "crtr.browse.tab.3" | "crtr.browse.tab.4" | "crtr.browse.tab.5"> | BindingDefinition<"crtr.browse.close-subtree"> | BindingDefinition<"crtr.browse.confirm-close"> | BindingDefinition<"crtr.browse.sort"> | BindingDefinition<"crtr.browse.scope"> | BindingDefinition<"crtr.browse.residents"> | BindingDefinition<"crtr.browse.preview"> | BindingDefinition<"crtr.browse.search"> | BindingDefinition<"crtr.browse.revive-now"> | BindingDefinition<"crtr.browse.focus"> | BindingDefinition<"crtr.browse.search.cancel"> | BindingDefinition<"crtr.browse.search.commit"> | BindingDefinition<"crtr.browse.search.delete"> | BindingDefinition<"crtr.browse.search.quit"> | BindingDefinition<"crtr.profile.menu.up"> | BindingDefinition<"crtr.profile.menu.down"> | BindingDefinition<"crtr.profile.menu.select"> | BindingDefinition<"crtr.profile.menu.accept-default"> | BindingDefinition<"crtr.profile.menu.abort"> | BindingDefinition<"crtr.profile.menu.slot.2" | "crtr.profile.menu.slot.1" | "crtr.profile.menu.slot.3" | "crtr.profile.menu.slot.4" | "crtr.profile.menu.slot.5" | "crtr.profile.menu.slot.8" | "crtr.profile.menu.slot.6" | "crtr.profile.menu.slot.7" | "crtr.profile.menu.slot.9">)[], BindingDefinition<"crtr.profile.menu.create">, BindingDefinition<"crtr.profile.menu.search-existing">, BindingDefinition<"crtr.profile.menu.use-root">, BindingDefinition<"crtr.profile.menu.set-default">, BindingDefinition<"crtr.profile.menu.add-directory">, BindingDefinition<"crtr.profile.menu.unpin">, BindingDefinition<"crtr.profile.search.up">, BindingDefinition<"crtr.profile.search.down">, BindingDefinition<"crtr.profile.search.pick">, BindingDefinition<"crtr.profile.search.back">, BindingDefinition<"crtr.profile.search.delete">, BindingDefinition<"crtr.profile.search.abort">, BindingDefinition<"crtr.setup.cancel">, BindingDefinition<"crtr.setup.tab-next">, BindingDefinition<"crtr.setup.tab-previous">, BindingDefinition<"crtr.setup.open">, BindingDefinition<"crtr.setup.list-down">, BindingDefinition<"crtr.setup.list-up">, BindingDefinition<"crtr.setup.toggle">, BindingDefinition<"crtr.setup.details">, BindingDefinition<"crtr.setup.advance">, BindingDefinition<"crtr.setup.confirm.accept">, BindingDefinition<"crtr.setup.confirm.back">, BindingDefinition<"crtr.setup.keybindings.edit">, BindingDefinition<"crtr.setup.keybindings.commit-edit">, BindingDefinition<"crtr.setup.keybindings.cancel-edit">, BindingDefinition<"crtr.setup.keybindings.unbind">, BindingDefinition<"crtr.setup.keybindings.reset-row">, BindingDefinition<"crtr.setup.keybindings.reset-all">, BindingDefinition<"crtr.setup.keybindings.save">, BindingDefinition<"crtr.setup.keybindings.discard">, BindingDefinition<"crtr.setup.keybindings.page-up">, BindingDefinition<"crtr.setup.keybindings.page-down">, BindingDefinition<"crtr.setup.keybindings.filter">, BindingDefinition<"crtr.setup.keybindings.filter-delete">, BindingDefinition<"crtr.setup.keybindings.filter-clear">];
10
+ export type BindingId = `crtr.tmux.menu.${TmuxMenuAction}` | `crtr.tmux.menu.issue.${'idea' | 'bug'}` | `crtr.tmux.node.${'next' | 'previous'}` | `crtr.tmux.view.${'next' | 'previous'}` | 'crtr.tmux.inbox.toggle' | `crtr.attach.${'detach' | 'clear-or-detach' | 'graph.toggle' | 'model-ladder.next' | 'model-ladder.previous'}` | 'crtr.mode.cycle' | `crtr.graph.${GraphAction}` | `crtr.graph.confirm.${'accept' | 'cancel'}` | `crtr.view.host.${'force-quit' | 'editor.backspace'}` | `crtr.view.canvas.${'down' | 'up' | 'refresh' | 'quit'}` | `crtr.view.chat.${'submit' | 'contextual-cancel' | 'reconnect' | 'request-control' | 'release-control' | 'quit'}` | `crtr.view.git-pr.${'down' | 'up' | 'refresh' | 'quit'}` | `crtr.view.inbox.${InboxAction}` | `crtr.view.linkedin.${LinkedinAction}` | `crtr.view.prompt-review.${'down' | 'up' | 'compare-previous' | 'compare-next' | 'toggle-mode' | 'expand' | 'export' | 'refresh' | 'quit'}` | `crtr.view.settings.${'down' | 'up' | 'cell-previous' | 'cell-next' | 'refresh' | 'quit' | 'edit-or-submit' | 'cancel-edit'}` | `crtr.view.workspace-sidebar.${'down' | 'up' | 'open' | 'refresh' | 'quit'}` | `crtr.view-picker.${'down' | 'up' | 'run' | 'quit'}` | `crtr.browse.${BrowseAction}` | `crtr.browse.search.${'cancel' | 'commit' | 'delete' | 'quit'}` | `crtr.profile.menu.${ProfileMenuAction}` | `crtr.profile.search.${'up' | 'down' | 'pick' | 'back' | 'delete' | 'abort'}` | `crtr.setup.${SetupAction}` | `crtr.setup.confirm.${'accept' | 'back'}` | `crtr.setup.keybindings.${SetupKeybindingAction}`;
11
+ export declare const BINDING_CATALOG: readonly [BindingDefinition<"crtr.tmux.menu.open">, BindingDefinition<"crtr.tmux.menu.promote">, BindingDefinition<"crtr.tmux.menu.resume">, BindingDefinition<"crtr.tmux.menu.demote">, BindingDefinition<"crtr.tmux.menu.detach">, BindingDefinition<"crtr.tmux.menu.close-subtree">, BindingDefinition<"crtr.tmux.menu.context">, BindingDefinition<"crtr.tmux.menu.providers">, BindingDefinition<"crtr.tmux.menu.graph">, BindingDefinition<"crtr.tmux.menu.focus-manager">, BindingDefinition<"crtr.tmux.menu.issues">, BindingDefinition<"crtr.tmux.menu.issue.idea">, BindingDefinition<"crtr.tmux.menu.issue.bug">, BindingDefinition<"crtr.tmux.node.next">, BindingDefinition<"crtr.tmux.node.previous">, BindingDefinition<"crtr.tmux.inbox.toggle">, BindingDefinition<"crtr.tmux.view.next">, BindingDefinition<"crtr.tmux.view.previous">, BindingDefinition<"crtr.attach.detach">, BindingDefinition<"crtr.attach.clear-or-detach">, BindingDefinition<"crtr.attach.graph.toggle">, BindingDefinition<"crtr.attach.model-ladder.next">, BindingDefinition<"crtr.attach.model-ladder.previous">, BindingDefinition<"crtr.mode.cycle">, BindingDefinition<"crtr.graph.down">, BindingDefinition<"crtr.graph.up">, BindingDefinition<"crtr.graph.first">, BindingDefinition<"crtr.graph.last">, BindingDefinition<"crtr.graph.collapse-or-manager">, BindingDefinition<"crtr.graph.expand-or-child">, BindingDefinition<"crtr.graph.focus">, BindingDefinition<"crtr.graph.focus-manager">, BindingDefinition<"crtr.graph.close-subtree">, BindingDefinition<"crtr.graph.dismiss">, BindingDefinition<"crtr.graph.confirm.accept">, BindingDefinition<"crtr.graph.confirm.cancel">, BindingDefinition<"crtr.view.host.force-quit">, BindingDefinition<"crtr.view.host.editor.backspace">, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<"crtr.view.chat.submit">, BindingDefinition<"crtr.view.chat.contextual-cancel">, BindingDefinition<"crtr.view.chat.reconnect">, BindingDefinition<"crtr.view.chat.request-control">, BindingDefinition<"crtr.view.chat.release-control">, BindingDefinition<"crtr.view.chat.quit">, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, BindingDefinition<BindingId>, ...(BindingDefinition<BindingId> | BindingDefinition<"crtr.view.prompt-review.down"> | BindingDefinition<"crtr.view.prompt-review.up"> | BindingDefinition<"crtr.view.prompt-review.compare-previous"> | BindingDefinition<"crtr.view.prompt-review.compare-next"> | BindingDefinition<"crtr.view.prompt-review.toggle-mode"> | BindingDefinition<"crtr.view.prompt-review.expand"> | BindingDefinition<"crtr.view.prompt-review.export"> | BindingDefinition<"crtr.view.prompt-review.refresh"> | BindingDefinition<"crtr.view.prompt-review.quit"> | BindingDefinition<"crtr.view.settings.down"> | BindingDefinition<"crtr.view.settings.up"> | BindingDefinition<"crtr.view.settings.cell-previous"> | BindingDefinition<"crtr.view.settings.cell-next"> | BindingDefinition<"crtr.view.settings.refresh"> | BindingDefinition<"crtr.view.settings.quit"> | BindingDefinition<"crtr.view.settings.edit-or-submit"> | BindingDefinition<"crtr.view.settings.cancel-edit"> | BindingDefinition<"crtr.view.workspace-sidebar.down"> | BindingDefinition<"crtr.view.workspace-sidebar.up"> | BindingDefinition<"crtr.view.workspace-sidebar.open"> | BindingDefinition<"crtr.view.workspace-sidebar.refresh"> | BindingDefinition<"crtr.view.workspace-sidebar.quit"> | BindingDefinition<"crtr.view-picker.down"> | BindingDefinition<"crtr.view-picker.up"> | BindingDefinition<"crtr.view-picker.run"> | BindingDefinition<"crtr.view-picker.quit"> | BindingDefinition<"crtr.browse.quit"> | BindingDefinition<"crtr.browse.down"> | BindingDefinition<"crtr.browse.up"> | BindingDefinition<"crtr.browse.first"> | BindingDefinition<"crtr.browse.last"> | BindingDefinition<"crtr.browse.expand-or-child"> | BindingDefinition<"crtr.browse.collapse-or-parent"> | BindingDefinition<"crtr.browse.toggle-fold"> | BindingDefinition<"crtr.browse.tab-next"> | BindingDefinition<"crtr.browse.tab-previous"> | BindingDefinition<"crtr.browse.tab.2" | "crtr.browse.tab.1" | "crtr.browse.tab.3" | "crtr.browse.tab.4" | "crtr.browse.tab.5"> | BindingDefinition<"crtr.browse.close-subtree"> | BindingDefinition<"crtr.browse.confirm-close"> | BindingDefinition<"crtr.browse.sort"> | BindingDefinition<"crtr.browse.scope"> | BindingDefinition<"crtr.browse.residents"> | BindingDefinition<"crtr.browse.preview"> | BindingDefinition<"crtr.browse.search"> | BindingDefinition<"crtr.browse.revive-now"> | BindingDefinition<"crtr.browse.focus"> | BindingDefinition<"crtr.browse.search.cancel"> | BindingDefinition<"crtr.browse.search.commit"> | BindingDefinition<"crtr.browse.search.delete"> | BindingDefinition<"crtr.browse.search.quit"> | BindingDefinition<"crtr.profile.menu.up"> | BindingDefinition<"crtr.profile.menu.down"> | BindingDefinition<"crtr.profile.menu.select"> | BindingDefinition<"crtr.profile.menu.accept-default"> | BindingDefinition<"crtr.profile.menu.abort"> | BindingDefinition<"crtr.profile.menu.slot.2" | "crtr.profile.menu.slot.1" | "crtr.profile.menu.slot.3" | "crtr.profile.menu.slot.4" | "crtr.profile.menu.slot.5" | "crtr.profile.menu.slot.8" | "crtr.profile.menu.slot.6" | "crtr.profile.menu.slot.7" | "crtr.profile.menu.slot.9">)[], BindingDefinition<"crtr.profile.menu.create">, BindingDefinition<"crtr.profile.menu.search-existing">, BindingDefinition<"crtr.profile.menu.use-root">, BindingDefinition<"crtr.profile.menu.set-default">, BindingDefinition<"crtr.profile.menu.add-directory">, BindingDefinition<"crtr.profile.menu.unpin">, BindingDefinition<"crtr.profile.search.up">, BindingDefinition<"crtr.profile.search.down">, BindingDefinition<"crtr.profile.search.pick">, BindingDefinition<"crtr.profile.search.back">, BindingDefinition<"crtr.profile.search.delete">, BindingDefinition<"crtr.profile.search.abort">, BindingDefinition<"crtr.setup.cancel">, BindingDefinition<"crtr.setup.tab-next">, BindingDefinition<"crtr.setup.tab-previous">, BindingDefinition<"crtr.setup.open">, BindingDefinition<"crtr.setup.list-down">, BindingDefinition<"crtr.setup.list-up">, BindingDefinition<"crtr.setup.toggle">, BindingDefinition<"crtr.setup.details">, BindingDefinition<"crtr.setup.advance">, BindingDefinition<"crtr.setup.confirm.accept">, BindingDefinition<"crtr.setup.confirm.back">, BindingDefinition<"crtr.setup.keybindings.edit">, BindingDefinition<"crtr.setup.keybindings.commit-edit">, BindingDefinition<"crtr.setup.keybindings.cancel-edit">, BindingDefinition<"crtr.setup.keybindings.unbind">, BindingDefinition<"crtr.setup.keybindings.reset-row">, BindingDefinition<"crtr.setup.keybindings.reset-all">, BindingDefinition<"crtr.setup.keybindings.save">, BindingDefinition<"crtr.setup.keybindings.discard">, BindingDefinition<"crtr.setup.keybindings.page-up">, BindingDefinition<"crtr.setup.keybindings.page-down">, BindingDefinition<"crtr.setup.keybindings.filter">, BindingDefinition<"crtr.setup.keybindings.filter-delete">, BindingDefinition<"crtr.setup.keybindings.filter-clear">];
12
12
  export declare const BINDING_IDS: ReadonlySet<string>;
13
13
  export declare const SAFETY_REQUIREMENTS: readonly SafetyRequirement[];
14
14
  export {};
@@ -40,6 +40,7 @@ export const BINDING_CATALOG = Object.freeze([
40
40
  b('crtr.tmux.menu.issue.bug', 'Global tmux', 'Create bug', 'Create a bug issue.', ['b'], 'tmux-menu-selector', ['tmux.menu.issue']),
41
41
  b('crtr.tmux.node.next', 'Global tmux', 'Next node', 'Focus the next canvas node.', ['alt+]'], 'host-global', ['tmux.root']),
42
42
  b('crtr.tmux.node.previous', 'Global tmux', 'Previous node', 'Focus the previous canvas node.', ['alt+['], 'host-global', ['tmux.root']),
43
+ b('crtr.tmux.inbox.toggle', 'Global tmux', 'Toggle inbox', 'Open or close the human inbox popup.', ['alt+i'], 'host-global', ['tmux.root']),
43
44
  b('crtr.tmux.view.next', 'Global tmux', 'Next view', 'Focus the next view.', ['alt+v > ]'], 'tmux-sequence', ['tmux.root']),
44
45
  b('crtr.tmux.view.previous', 'Global tmux', 'Previous view', 'Focus the previous view.', ['alt+v > ['], 'tmux-sequence', ['tmux.root']),
45
46
  b('crtr.attach.detach', 'Attach', 'Detach', 'Detach from the node.', ['ctrl+d'], 'host-global', ATTACH_CONTEXTS),
@@ -0,0 +1,21 @@
1
+ import type { BindingId } from './catalog.js';
2
+ import type { BindingResolution } from './types.js';
3
+ /** The single source of truth for how every pending-interaction surface names
4
+ * the inbox shortcut. Resolves the live `crtr.tmux.inbox.toggle` gestures and
5
+ * returns the formatted label(s) — joined with ' / ' when multiple, matching
6
+ * crouter's `formatBinding` convention — or null when the binding is disabled.
7
+ * Bindings default to the user's resolved config so a bare call reflects
8
+ * current state; callers holding a live snapshot (e.g. the attach viewer) pass
9
+ * it so a `/reload` rebind is honored. */
10
+ export declare function inboxShortcut(bindings?: BindingResolution<BindingId>): string | null;
11
+ /** Closed-inbox footer affordance: "<shortcut> inbox", or the CLI fallback
12
+ * `hl inbox open` when the binding is disabled. */
13
+ export declare function inboxOpenHint(bindings?: BindingResolution<BindingId>): string;
14
+ /** Bare token naming the inbox affordance for a parenthetical — the resolved
15
+ * shortcut (e.g. `Alt+I`), or the backtick-quoted CLI form when disabled. Use
16
+ * where prose reads "the inbox popup (<hint>)". */
17
+ export declare function inboxPopupHint(bindings?: BindingResolution<BindingId>): string;
18
+ /** Imperative clause telling the human how to open the inbox — "press
19
+ * <shortcut> (or run `hl inbox open` at a terminal)", or just the CLI form
20
+ * when the binding is disabled. */
21
+ export declare function inboxOpenInstruction(bindings?: BindingResolution<BindingId>): string;
@@ -0,0 +1,35 @@
1
+ import { formatGesture } from './match.js';
2
+ import { resolveUserKeybindings } from './resolve.js';
3
+ const INBOX_TOGGLE = 'crtr.tmux.inbox.toggle';
4
+ /** The single source of truth for how every pending-interaction surface names
5
+ * the inbox shortcut. Resolves the live `crtr.tmux.inbox.toggle` gestures and
6
+ * returns the formatted label(s) — joined with ' / ' when multiple, matching
7
+ * crouter's `formatBinding` convention — or null when the binding is disabled.
8
+ * Bindings default to the user's resolved config so a bare call reflects
9
+ * current state; callers holding a live snapshot (e.g. the attach viewer) pass
10
+ * it so a `/reload` rebind is honored. */
11
+ export function inboxShortcut(bindings = resolveUserKeybindings()) {
12
+ const gestures = bindings.gestures(INBOX_TOGGLE);
13
+ return gestures.length > 0 ? gestures.map(formatGesture).join(' / ') : null;
14
+ }
15
+ /** Closed-inbox footer affordance: "<shortcut> inbox", or the CLI fallback
16
+ * `hl inbox open` when the binding is disabled. */
17
+ export function inboxOpenHint(bindings) {
18
+ const shortcut = inboxShortcut(bindings);
19
+ return shortcut !== null ? `${shortcut} inbox` : 'hl inbox open';
20
+ }
21
+ /** Bare token naming the inbox affordance for a parenthetical — the resolved
22
+ * shortcut (e.g. `Alt+I`), or the backtick-quoted CLI form when disabled. Use
23
+ * where prose reads "the inbox popup (<hint>)". */
24
+ export function inboxPopupHint(bindings) {
25
+ return inboxShortcut(bindings) ?? '`hl inbox open`';
26
+ }
27
+ /** Imperative clause telling the human how to open the inbox — "press
28
+ * <shortcut> (or run `hl inbox open` at a terminal)", or just the CLI form
29
+ * when the binding is disabled. */
30
+ export function inboxOpenInstruction(bindings) {
31
+ const shortcut = inboxShortcut(bindings);
32
+ return shortcut !== null
33
+ ? `press ${shortcut} (or run \`hl inbox open\` at a terminal)`
34
+ : 'run `hl inbox open` at a terminal';
35
+ }
@@ -1,5 +1,6 @@
1
1
  export { BINDING_CATALOG, BINDING_IDS, SAFETY_REQUIREMENTS, type BindingId, } from './catalog.js';
2
2
  export { GestureSyntaxError, KeybindingValidationError, normalizeGesture, normalizeSparseOverrides, normalizeStroke, resolveKeybindings, resolveUserKeybindings, } from './resolve.js';
3
3
  export { canonicalTerminalStroke, formatBinding, formatGesture, formatStroke, matchesPiTuiInput, matchesTerminalInput, type PiTuiMatcher, type RawTerminalInput, } from './match.js';
4
+ export { inboxOpenHint, inboxOpenInstruction, inboxPopupHint, inboxShortcut, } from './inbox.js';
4
5
  export { KeybindingConcurrentEditError, persistUserKeybindings, type PersistedKeybindings, type PersistKeybindingsOptions, } from './persistence.js';
5
6
  export type { BindingDefinition, BindingInputKind, BindingResolution, BindingSafetyCapability, EffectiveBinding, KeybindingDiagnostic, KeybindingDiagnosticCode, SafetyRequirement, SparseKeybindingOverrides, } from './types.js';
@@ -1,4 +1,5 @@
1
1
  export { BINDING_CATALOG, BINDING_IDS, SAFETY_REQUIREMENTS, } from './catalog.js';
2
2
  export { GestureSyntaxError, KeybindingValidationError, normalizeGesture, normalizeSparseOverrides, normalizeStroke, resolveKeybindings, resolveUserKeybindings, } from './resolve.js';
3
3
  export { canonicalTerminalStroke, formatBinding, formatGesture, formatStroke, matchesPiTuiInput, matchesTerminalInput, } from './match.js';
4
+ export { inboxOpenHint, inboxOpenInstruction, inboxPopupHint, inboxShortcut, } from './inbox.js';
4
5
  export { KeybindingConcurrentEditError, persistUserKeybindings, } from './persistence.js';
@@ -1085,11 +1085,12 @@ const ASK_TEASER_CHARS = 160;
1085
1085
  /** `crtr human ask` (humanAsk.run, src/commands/human/prompts.ts) returns
1086
1086
  * `{job_id, dir, follow_up}` — `job_id` is always short (a node id) so it
1087
1087
  * always bullets; `dir`/`follow_up` cross the prose threshold depending on
1088
- * path length, so the shape is recognized by `job_id` plus the single FIXED
1089
- * QUEUED_FOLLOW_UP road-sign (`Queued for the human`, prompts.ts) appearing
1088
+ * path length, so the shape is recognized by `job_id` plus the stable road-sign
1089
+ * prefix `Queued for the human` (queuedFollowUp, prompts.ts — its inbox-
1090
+ * affordance tail resolves per call, the prefix never varies) appearing
1090
1091
  * anywhere in the text — never by assuming dir/follow_up's bullet vs. prose
1091
- * form. Arrival is now always just durable queue state (no tmux/non-tmux
1092
- * drained-vs-delivered fork), so the card collapses to one posted line. The
1092
+ * form. Arrival is always just durable queue state, so the card collapses to
1093
+ * one posted line. The
1093
1094
  * question text isn't in the output at all (only the bare-question invocation
1094
1095
  * echoes it), so it's recovered from argv: the first non-flag token after
1095
1096
  * `human ask`, skipping `--context-file`'s value — absent for a
@@ -1113,8 +1114,8 @@ function summarizeHumanAsk(text, tokens) {
1113
1114
  }
1114
1115
  /** `crtr human review` (humanReview.run, src/commands/human/prompts.ts)
1115
1116
  * returns `{job_id, dir, output, follow_up}` — same recognition strategy as
1116
- * summarizeHumanAsk (job_id bullet + the single fixed QUEUED_FOLLOW_UP
1117
- * road-sign, `Queued for the human`, which review shares with ask). The
1117
+ * summarizeHumanAsk (job_id bullet + the stable `Queued for the human`
1118
+ * road-sign prefix, which review shares with ask). The
1118
1119
  * reviewed file isn't in the output either, so its basename is recovered
1119
1120
  * from argv (the file positional, skipping `--output`'s value). Returns null
1120
1121
  * when the road-sign is absent. */
@@ -24,7 +24,6 @@ import { appendSituationalContext } from './situational-context.js';
24
24
  import { hasRoadmap, seedRoadmap } from './roadmap.js';
25
25
  import { buildIdentityAssertion, buildWakeBearings } from './bearings.js';
26
26
  import { installTmuxBindings } from './tmux-chrome.js';
27
- import { installInboxBinding } from '@crouton-kit/humanloop';
28
27
  import { getNode, fullName, recordPid } from '../canvas/index.js';
29
28
  import { registerViewerFocus, openViewerWindow, waitForBrokerViewSocket, viewerSplitEnv, windowOfPane, currentTmux, inTmux, focusWindow, } from './placement.js';
30
29
  import { transition } from './lifecycle.js';
@@ -98,19 +97,12 @@ export async function bootRoot(opts) {
98
97
  // mandate (bare `crtr` has none — writeGoal no-ops on empty).
99
98
  if (opts.prompt !== undefined)
100
99
  writeGoal(meta.node_id, opts.prompt);
101
- // Reconcile the crouter-owned tmux bindings on this server.
100
+ // Reconcile the crouter-owned tmux bindings on this server, including the
101
+ // inbox-toggle key (crtr.tmux.inbox.toggle) folded into the same manifest sweep.
102
102
  try {
103
103
  installTmuxBindings();
104
104
  }
105
105
  catch { /* best-effort */ }
106
- // Reconcile humanloop's collision-safe M-i inbox popup binding on the same
107
- // server so the inbox is reachable from any window. Crouter calls humanloop's
108
- // installer — it never authors or parses its own tmux command; the installer
109
- // is idempotent and leaves any pre-existing M-i binding untouched.
110
- try {
111
- installInboxBinding();
112
- }
113
- catch { /* best-effort */ }
114
106
  // This terminal becomes the root's attach VIEWER in the user's CURRENT session,
115
107
  // so its window stays where the user already is. The node row carries NO
116
108
  // presence — a broker node's pane/window/tmux_session stay NULL; the viewer
@@ -1 +1 @@
1
- export { installTmuxBindings, sendKeysEnter, displayMessage, paneCurrentPath, type TmuxInstalledPair, type TmuxInstallDiagnostic, type TmuxInstallResult, } from './tmux.js';
1
+ export { installTmuxBindings, legacyInboxKeyFile, sendKeysEnter, displayMessage, paneCurrentPath, type TmuxInstalledPair, type TmuxInstallDiagnostic, type TmuxInstallResult, } from './tmux.js';
@@ -1,4 +1,4 @@
1
1
  // tmux-chrome.ts — chrome seam (§2.1): stateless keybind/input verbs.
2
2
  // The ONLY non-placement module allowed to import the tmux driver, per the
3
3
  // §5.1 lint. Re-exports the server chrome callers need.
4
- export { installTmuxBindings, sendKeysEnter, displayMessage, paneCurrentPath, } from './tmux.js';
4
+ export { installTmuxBindings, legacyInboxKeyFile, sendKeysEnter, displayMessage, paneCurrentPath, } from './tmux.js';
@@ -218,5 +218,6 @@ export interface TmuxInstallResult {
218
218
  readonly installed: readonly TmuxInstalledPair[];
219
219
  readonly diagnostics: readonly TmuxInstallDiagnostic[];
220
220
  }
221
+ export declare function legacyInboxKeyFile(): string;
221
222
  /** Reconcile the tmux server with one immutable crouter binding snapshot. */
222
223
  export declare function installTmuxBindings(bindings?: BindingResolution<BindingId>): TmuxInstallResult;
@@ -8,9 +8,13 @@
8
8
  // root) or switch-client + select-window (across roots). done/dead nodes close
9
9
  // their window; reviving opens a fresh one.
10
10
  import { spawnSync } from 'node:child_process';
11
+ import { readFileSync, rmSync } from 'node:fs';
12
+ import { homedir } from 'node:os';
13
+ import { join } from 'node:path';
11
14
  import { resolveUserKeybindings, } from '../keybindings/index.js';
12
15
  import { bundledPiCommandForShell } from './pi-cli.js';
13
16
  import { surfaceTmuxStyleArgs } from './surface-bg.js';
17
+ import { inboxToggleTmuxCommand } from '@crouton-kit/humanloop';
14
18
  // ---------------------------------------------------------------------------
15
19
  // Shell quoting + tmux invocation
16
20
  // ---------------------------------------------------------------------------
@@ -428,6 +432,7 @@ const MENU_ACTIONS = {
428
432
  'crtr.tmux.menu.issue.bug': undefined,
429
433
  'crtr.tmux.node.next': undefined,
430
434
  'crtr.tmux.node.previous': undefined,
435
+ 'crtr.tmux.inbox.toggle': undefined,
431
436
  'crtr.tmux.view.next': undefined,
432
437
  'crtr.tmux.view.previous': undefined,
433
438
  };
@@ -546,12 +551,28 @@ function readManifest() {
546
551
  return null;
547
552
  }
548
553
  }
554
+ // Crouter's own pre-manifest root bindings. When a machine had these installed
555
+ // before the ownership manifest existed, the first reconciliation adopts them
556
+ // into the manifest (unbinding the stale copy so it reinstalls cleanly) instead
557
+ // of reporting them foreign. Gated on a fresh manifest — once one exists these
558
+ // keys are already crouter-owned through it.
549
559
  const LEGACY_ROOT_BINDINGS = [
550
560
  { key: 'M-c', markers: ['display-menu', 'promote to orchestrator', 'crtr canvas chord', 'new issue / todo'] },
551
561
  { key: 'M-]', markers: ['run-shell', 'crtr node cycle --dir next', "--pane '#{pane_id}'"] },
552
562
  { key: 'M-[', markers: ['run-shell', 'crtr node cycle --dir prev', "--pane '#{pane_id}'"] },
553
563
  { key: 'M-v', markers: ['switch-client', '-T crtr-view'] },
554
564
  ];
565
+ // The inbox toggle is a crouter-owned root binding, resolved from keybindings.json
566
+ // and installed through the manifest sweep like every sibling. Root bindings
567
+ // matching these markers that are NOT tracked in the manifest are hl-owned
568
+ // strays; reconciliation removes them (and the state file naming their key) so
569
+ // the manifest stays the sole owner of the inbox command.
570
+ const LEGACY_INBOX_MARKERS = ['run-shell', 'hl inbox toggle'];
571
+ const LEGACY_INBOX_DEFAULT_KEY = 'M-i';
572
+ export function legacyInboxKeyFile() {
573
+ const stateHome = process.env['XDG_STATE_HOME'] || join(homedir(), '.local', 'state');
574
+ return join(stateHome, 'humanloop', 'inbox-key');
575
+ }
555
576
  function adoptLegacyBindings() {
556
577
  for (const legacy of LEGACY_ROOT_BINDINGS) {
557
578
  const existing = bindingAt(ROOT_TABLE, legacy.key);
@@ -560,10 +581,42 @@ function adoptLegacyBindings() {
560
581
  }
561
582
  }
562
583
  }
584
+ // Enforce the manifest's sole ownership of the inbox command: any hl-owned
585
+ // inbox binding not tracked in the manifest is unbound, and the humanloop
586
+ // state file is discarded. Runs on every reconciliation regardless of whether
587
+ // a manifest already exists. Checks the default key plus the key the state
588
+ // file records (the file's value only locates a stray binding — it is never
589
+ // imported into crouter config). A key tracked in the manifest is crouter's
590
+ // own and left alone; a foreign non-hl binding never matches the markers and
591
+ // is preserved. Idempotent: with no file and no untracked hl binding, a no-op.
592
+ function removeLegacyInboxBindings(manifestPairs) {
593
+ const owned = new Set(manifestPairs.filter((pair) => pair.table === ROOT_TABLE).map((pair) => pair.key));
594
+ const keys = new Set([LEGACY_INBOX_DEFAULT_KEY]);
595
+ const file = legacyInboxKeyFile();
596
+ try {
597
+ const configured = readFileSync(file, 'utf8').trim();
598
+ if (configured !== '')
599
+ keys.add(configured);
600
+ }
601
+ catch { /* no state file: only the default key can hold a stale binding */ }
602
+ for (const key of keys) {
603
+ if (owned.has(key))
604
+ continue;
605
+ const existing = bindingAt(ROOT_TABLE, key);
606
+ if (existing !== null && LEGACY_INBOX_MARKERS.every((marker) => existing.includes(marker))) {
607
+ tmux(['unbind-key', '-T', ROOT_TABLE, key]);
608
+ }
609
+ }
610
+ try {
611
+ rmSync(file, { force: true });
612
+ }
613
+ catch { /* best-effort */ }
614
+ }
563
615
  function actionCommand(id) {
564
616
  switch (id) {
565
617
  case 'crtr.tmux.node.next': return ['run-shell', `crtr node cycle --dir next --pane '#{pane_id}' >/dev/null 2>&1`];
566
618
  case 'crtr.tmux.node.previous': return ['run-shell', `crtr node cycle --dir prev --pane '#{pane_id}' >/dev/null 2>&1`];
619
+ case 'crtr.tmux.inbox.toggle': return inboxToggleTmuxCommand();
567
620
  case 'crtr.tmux.view.next': return ['run-shell', `crtr surface view cycle --dir next --pane '#{pane_id}' >/dev/null 2>&1`];
568
621
  case 'crtr.tmux.view.previous': return ['run-shell', `crtr surface view cycle --dir prev --pane '#{pane_id}' >/dev/null 2>&1`];
569
622
  default: throw new Error(`no tmux command for ${id}`);
@@ -580,6 +633,7 @@ export function installTmuxBindings(bindings = resolveUserKeybindings()) {
580
633
  }
581
634
  if (!manifest.existed)
582
635
  adoptLegacyBindings();
636
+ removeLegacyInboxBindings(manifest.pairs);
583
637
  for (const pair of manifest.pairs) {
584
638
  const result = tmux(['unbind-key', '-T', pair.table, pair.key]);
585
639
  if (!result.ok && bindingAt(pair.table, pair.key) !== null) {
@@ -606,7 +660,7 @@ export function installTmuxBindings(bindings = resolveUserKeybindings()) {
606
660
  for (const gesture of bindings.gestures('crtr.tmux.menu.open')) {
607
661
  install(ROOT_TABLE, tmuxKey(gesture), menuCommand, 'crtr.tmux.menu.open', gesture);
608
662
  }
609
- for (const id of ['crtr.tmux.node.next', 'crtr.tmux.node.previous']) {
663
+ for (const id of ['crtr.tmux.node.next', 'crtr.tmux.node.previous', 'crtr.tmux.inbox.toggle']) {
610
664
  for (const gesture of bindings.gestures(id))
611
665
  install(ROOT_TABLE, tmuxKey(gesture), actionCommand(id), id, gesture);
612
666
  }
@@ -56,7 +56,7 @@ import { dirname, join } from 'node:path';
56
56
  import { homedir } from 'node:os';
57
57
  import { spawnSync } from 'node:child_process';
58
58
  import { crtrHome, nodeDir, jobDir } from '../core/canvas/paths.js';
59
- import { listNodes, getRow, getNode, dueClockTriggers, consumeTrigger, advanceTrigger, listFocuses, closeFocusRow, pruneToLimit, subscribersOf, } from '../core/canvas/index.js';
59
+ import { listNodes, getRow, getNode, migrateLegacyPidIdentities, dueClockTriggers, consumeTrigger, advanceTrigger, listFocuses, closeFocusRow, pruneToLimit, subscribersOf, } from '../core/canvas/index.js';
60
60
  import { fullName } from '../core/canvas/labels.js';
61
61
  import { transition } from '../core/runtime/lifecycle.js';
62
62
  import { isBusy, busySince } from '../core/runtime/busy.js';
@@ -65,7 +65,7 @@ import { fanDoctrineWake } from '../core/runtime/close.js';
65
65
  import { logger } from '../core/log.js';
66
66
  export { FAULT_QUIET_MS };
67
67
  import { isPidAlive, isRecordedPidAlive, recordedPidLiveness } from '../core/canvas/pid.js';
68
- import { reconcileBootLiveness } from '../core/canvas/boot.js';
68
+ import { reconcileAndMigrateBoot } from '../core/canvas/boot.js';
69
69
  import { listLivePanes, tearDownNode } from '../core/runtime/placement.js';
70
70
  import { reviveNode } from '../core/runtime/revive.js';
71
71
  import { isBrokerLive } from '../core/runtime/model-swap.js';
@@ -1614,9 +1614,33 @@ export function runDaemon(opts = {}) {
1614
1614
  // "leave it, nothing to revive" and never calls reviveNode at all — a
1615
1615
  // pid-reuse collision on the first post-boot tick would silently no-op
1616
1616
  // forever with no revive attempt to even hit reviveNode's own reconcile call.
1617
- const { changed, cleared } = reconcileBootLiveness();
1618
- if (changed) {
1619
- process.stderr.write(`[crtrd] boot change detected cleared ${cleared.length} stale pi_pid(s) recorded before this boot\n`);
1617
+ //
1618
+ // Ordering + gate live in reconcileAndMigrateBoot (canvas/boot.ts) so the
1619
+ // migration-gate regression tests exercise the real composition rather than a
1620
+ // test-side copy of these lines.
1621
+ const { reconcile, migrated } = reconcileAndMigrateBoot(migrateLegacyPidIdentities);
1622
+ if (reconcile.changed) {
1623
+ process.stderr.write(`[crtrd] boot change detected — cleared ${reconcile.cleared.length} stale pi_pid(s) recorded before this boot\n`);
1624
+ }
1625
+ // Then, once, complete the boot-scoped-identity format migration for any
1626
+ // broker that survived an in-place crouter upgrade and still carries a legacy
1627
+ // `lstart#ticks` baseline: re-record it as `<bootId>#<ticks>` if its pid still
1628
+ // names the same live process. `identitiesMatch` only TOLERATES legacy rows;
1629
+ // this is what actually closes the cross-boot ticks-collision exposure for
1630
+ // them, so the legacy compare lane then only engages for genuinely no-boot_id
1631
+ // hosts.
1632
+ //
1633
+ // GATED on PROVEN same-boot provenance: the sweep blesses a legacy row's pid
1634
+ // as a current-boot process (`<currentBootId>#<ticks>`) on a ticks match, so
1635
+ // it is correct ONLY when the recorded pid provably belongs to THIS boot. We
1636
+ // run it solely when reconciliation matched an exact kernel `boot_id` on both
1637
+ // sides (`sameBootProven`) — never on a first-ever/absent/malformed marker or
1638
+ // the wall-clock epoch fallback, where an equal-ticks collision with an
1639
+ // unrelated cross-boot process could otherwise baptize a stranger. (On a
1640
+ // detected boot change the prior-boot pids were just cleared, so there is
1641
+ // nothing left to migrate either.)
1642
+ if (migrated.length > 0) {
1643
+ process.stderr.write(`[crtrd] migrated ${migrated.length} legacy pi_pid identity baseline(s) to boot-scoped format\n`);
1620
1644
  }
1621
1645
  writePidfile();
1622
1646
  log.info(`started (pid ${process.pid}, interval ${interval}ms)`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crouton-kit/crouter",
3
- "version": "0.3.83",
3
+ "version": "0.3.85",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -54,7 +54,7 @@
54
54
  },
55
55
  "license": "MIT",
56
56
  "dependencies": {
57
- "@crouton-kit/humanloop": "^0.3.35",
57
+ "@crouton-kit/humanloop": "^0.3.37",
58
58
  "@earendil-works/pi-agent-core": "0.80.6",
59
59
  "@earendil-works/pi-ai": "0.80.6",
60
60
  "@earendil-works/pi-coding-agent": "0.80.6",