@borgee/agents-host 0.2.44 → 0.2.62

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 (65) hide show
  1. package/README.md +24 -27
  2. package/dist/agents-host.d.ts +27 -5
  3. package/dist/agents-host.js +266 -201
  4. package/dist/chat/chat-control-plane.d.ts +3 -0
  5. package/dist/chat/sdk-chat-control-plane.d.ts +4 -3
  6. package/dist/chat/sdk-chat-control-plane.js +3 -0
  7. package/dist/cli.js +1 -5
  8. package/dist/compatibility-gates.d.ts +4 -0
  9. package/dist/compatibility-gates.js +20 -1
  10. package/dist/config.d.ts +2 -0
  11. package/dist/config.js +21 -0
  12. package/dist/context/claude-file-brief.d.ts +2 -0
  13. package/dist/context/claude-file-brief.js +83 -0
  14. package/dist/context/compaction.d.ts +20 -0
  15. package/dist/context/compaction.js +59 -0
  16. package/dist/context/injection.d.ts +58 -7
  17. package/dist/context/injection.js +370 -36
  18. package/dist/context/main-session-delegation.d.ts +1 -1
  19. package/dist/context/projection-strategy.d.ts +24 -0
  20. package/dist/context/projection-strategy.js +90 -0
  21. package/dist/context/prompt.d.ts +16 -1
  22. package/dist/context/prompt.js +464 -26
  23. package/dist/context/resolved-workspace.d.ts +3 -0
  24. package/dist/context/resolved-workspace.js +106 -0
  25. package/dist/context/skill-manual.d.ts +1 -0
  26. package/dist/context/skill-manual.js +4 -1
  27. package/dist/context/turn-preparation.d.ts +8 -2
  28. package/dist/context/turn-preparation.js +64 -14
  29. package/dist/gateway/localhost-gateway.js +4 -5
  30. package/dist/local-config.js +11 -1
  31. package/dist/managed-daemon.js +127 -9
  32. package/dist/plugin-sdk.js +264 -364
  33. package/dist/plugin-sdk.js.map +4 -4
  34. package/dist/policy/copilot-permission.d.ts +1 -0
  35. package/dist/policy/copilot-permission.js +18 -0
  36. package/dist/policy/gateway-authorization.js +2 -2
  37. package/dist/progress-to-activity.d.ts +16 -0
  38. package/dist/progress-to-activity.js +24 -0
  39. package/dist/projection-strategy-values.d.ts +4 -0
  40. package/dist/projection-strategy-values.js +28 -0
  41. package/dist/providers/acp-progress-collector.d.ts +44 -0
  42. package/dist/providers/acp-progress-collector.js +130 -0
  43. package/dist/providers/awaiting-user.d.ts +2 -3
  44. package/dist/providers/awaiting-user.js +5 -7
  45. package/dist/providers/claude/activity-metadata.d.ts +14 -0
  46. package/dist/providers/claude/activity-metadata.js +81 -0
  47. package/dist/providers/claude/cli-client.d.ts +2 -3
  48. package/dist/providers/claude/cli-client.js +220 -120
  49. package/dist/providers/codex/cli-client.d.ts +2 -0
  50. package/dist/providers/codex/cli-client.js +28 -104
  51. package/dist/providers/codex/project-doc.js +12 -11
  52. package/dist/providers/copilot/cli-client.d.ts +1 -1
  53. package/dist/providers/copilot/cli-client.js +12 -86
  54. package/dist/providers/create-provider.d.ts +2 -0
  55. package/dist/providers/create-provider.js +22 -4
  56. package/dist/state-paths.d.ts +1 -1
  57. package/dist/state-paths.js +3 -3
  58. package/dist/task-thread-resolution.d.ts +3 -2
  59. package/dist/types.d.ts +143 -6
  60. package/package.json +2 -2
  61. package/skills/borgee-agent/SKILL.md +12 -4
  62. package/skills/borgee-agent/references/errors.md +2 -2
  63. package/skills/borgee-agent/references/task-properties.md +6 -2
  64. package/dist/durable-cursor-store.d.ts +0 -5
  65. package/dist/durable-cursor-store.js +0 -7
package/README.md CHANGED
@@ -27,7 +27,7 @@ Borgee channel message
27
27
  - local-config multi-agent startup
28
28
  - one isolated `AgentsHost` per effective agent key
29
29
  - per-channel conversation memory via each provider's native session mechanism
30
- - one draft progress message per turn when a provider emits public progress
30
+ - one message per turn, posted once the turn ends, with what the agent is doing reported on the ephemeral activity rail meanwhile
31
31
  - hot reload for host config and agent file add / update / remove
32
32
 
33
33
  **Out of scope:**
@@ -479,38 +479,35 @@ successfully applied snapshot running.
479
479
  Each Borgee channel is mapped 1:1 to a provider-native session while it stays
480
480
  active:
481
481
 
482
- - **Claude**: one persistent `@agentclientprotocol/claude-agent-acp` subprocess
483
- is shared by a single `AgentsHost`, with one ACP session per Borgee channel.
484
- Same-channel turns are serialized; different channels keep isolated ACP
485
- sessions. Ordinary threads keep the shared runtime workspace cwd, while
486
- eligible `task_assignment` threads switch the real ACP session cwd to that
487
- same hidden local task-scoped workspace. The host persists the
488
- channel→ACP-session map in its state root, restores same-host continuity with
489
- ACP `session/resume` when available, retries stale restores with a fresh
490
- session immediately, and injects the per-channel local context paths through
491
- Claude ACP `_meta.systemPrompt.append`.
482
+ - **Claude**: one persistent `@agentclientprotocol/claude-agent-acp` subprocess is shared by a single `AgentsHost`, with one ACP session per Borgee channel. Same-channel turns are serialized; different channels keep isolated ACP sessions. The real ACP session cwd now comes from the resolved channel workspace `~/.borgee/channels/<encoded-channel-id>/workspace`. Task threads only switch execution onto an explicit existing `execution.local_directory`; otherwise they stay discussion-only on `~/.borgee/channels/<encoded-thread-id>/scratch/workspace`, and ACP permission requests are denied so filesystem and shell tools stay unavailable. The host persists the channel→ACP-session map in its state root, restores same-host continuity with ACP `session/resume` when available, retries stale restores with a fresh session immediately, and injects the per-channel local context paths through Claude ACP `_meta.systemPrompt.append`.
492
483
  - **Codex**: one persistent `@agentclientprotocol/codex-acp` subprocess is
493
484
  shared by a single `AgentsHost`, with one ACP session per Borgee channel. When
494
485
  the current turn has a materialized channel context payload, Codex refreshes a
495
486
  same-directory `AGENTS.md` project document inside a provider-visible
496
487
  per-channel projection directory and exposes that directory to Codex through
497
- ACP `additionalDirectories`. Ordinary threads keep the shared runtime
498
- workspace as the ACP session cwd, while eligible `task_assignment` threads
499
- switch the real ACP session cwd to a hidden local task workspace under
500
- `<startup-workspace>/.borgee-task-workspaces/<thread>/<task>/`; that local
501
- writable workspace is explicitly not a claim that the target repository is
502
- already checked out there. The host persists the channel→ACP-session map in
503
- its state root and attempts ACP `session/resume` first when the adapter
504
- advertises it, otherwise `session/load`.
488
+ ACP `additionalDirectories`. The real ACP session cwd now comes from the
489
+ resolved channel workspace `~/.borgee/channels/<encoded-channel-id>/workspace`.
490
+ Task threads only switch execution onto an explicit existing
491
+ `execution.local_directory`; otherwise they stay discussion-only on
492
+ `~/.borgee/channels/<encoded-thread-id>/scratch/workspace`, and ACP
493
+ permission requests are denied so filesystem and shell tools stay
494
+ unavailable. The host persists the
495
+ channel→ACP-session map in its state root and attempts ACP `session/resume`
496
+ first when the adapter advertises it, otherwise `session/load`.
505
497
  - **Copilot**: one persistent `copilot --acp` subprocess is shared by a single
506
498
  `AgentsHost`, with one ACP session per Borgee channel. Same-channel turns are
507
- serialized; different channels keep isolated ACP sessions. Ordinary threads
508
- keep the shared runtime workspace cwd, while eligible `task_assignment`
509
- threads switch the real ACP session cwd to that same hidden local
510
- task-scoped workspace. The host persists the channel→ACP-session map in its
511
- state root and restores same-host continuity with ACP `session/resume` when
512
- available, otherwise `session/load` plus local replay cleanup on runtimes
513
- that advertise only load support.
499
+ serialized; different channels keep isolated ACP sessions. The real ACP
500
+ session cwd now comes from the resolved channel workspace
501
+ `~/.borgee/channels/<encoded-channel-id>/workspace` by default. Task threads
502
+ only switch execution onto an explicit existing `execution.local_directory`;
503
+ otherwise they stay discussion-only on
504
+ `~/.borgee/channels/<encoded-thread-id>/scratch/workspace`, and ACP
505
+ permission requests are denied so filesystem and shell tools stay
506
+ unavailable. The
507
+ host persists the channel→ACP-session map in its state root and restores
508
+ same-host continuity with ACP `session/resume` when available, otherwise
509
+ `session/load` plus local replay cleanup on runtimes that advertise only
510
+ load support.
514
511
 
515
512
  We keep no transcript or history store of our own — only the native session id each provider should try to reopen next time. The transcripts themselves live in each CLI's own on-disk session store: `~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl` for Claude, `~/.codex/sessions/<yyyy>/<mm>/<dd>/rollout-<timestamp>-<threadId>.jsonl` for Codex, and `~/.copilot/session-state/<guid>/` for Copilot. Because those stores are on disk rather than in the adapter process, a session can be reopened later by a *different* process on the same machine — which is what makes conversation memory survive both a host restart and the idle recycle below. Continuity is same-machine and same-`$HOME` only: another machine, or a different home directory, has no session to reopen.
516
513
 
@@ -525,7 +522,7 @@ When a restore does fail, the run does not break: the stale session id is droppe
525
522
  - **A different machine or a different `$HOME`.** The session store is local, so continuity never crosses hosts.
526
523
  - **A stale Copilot session lock.** The Copilot CLI does not reliably unlink its `inuse.<pid>.lock` on an unclean exit ([github/copilot-cli#3255](https://github.com/github/copilot-cli/issues/3255), still open), so a force-killed process can leave a lock that makes the next restore believe the session is still in use. The idle teardown mitigates this: it gives the CLI a 5-second SIGTERM grace before any SIGKILL — twenty times the grace a fatal teardown uses — precisely so the CLI has time to unlink that lock. This is an internal default, not a knob.
527
524
  - **A very large Copilot transcript.** Long-running channels can hit upstream resume bugs: slow or memory-hungry resume ([#4251](https://github.com/github/copilot-cli/issues/4251)), a session that becomes unloadable once `events.jsonl` outgrows the V8 maximum string length ([#4325](https://github.com/github/copilot-cli/issues/4325)), and a resume-triggered compaction hang ([#4138](https://github.com/github/copilot-cli/issues/4138)). A Copilot resume may also reset the model back to the default ([#4397](https://github.com/github/copilot-cli/issues/4397)).
528
- - **Our own mapping rules, which are stricter than the CLI's.** We only reuse a persisted session id when the session's working directory *and* the set of directories exposed to it still match. So an ordinary channel turn and an eligible `task_assignment` turn which runs in its own task workspace — deliberately do not share a session, and the switch between them starts a fresh one even though the CLI could still load the old session.
525
+ - **Our own mapping rules, which are stricter than the CLI's.** We only reuse a persisted session id when the session's working directory *and* the set of directories exposed to it still match. So if the resolved channel workspace path changes, or if the injected provider-visible directory set changes, the host deliberately drops the old mapping and starts a fresh session even though the CLI could still load it.
529
526
 
530
527
  If you would rather keep the adapter process resident than take any of that, set `PROVIDER_IDLE_SHUTDOWN_MINUTES=0`, raise the window, or roll the behavior back entirely with `AGENTS_HOST_INTERNAL_DISABLED_COMPATIBILITY_GATES=provider-idle-shutdown`.
531
528
 
@@ -27,9 +27,12 @@ export declare class AgentsHost {
27
27
  */
28
28
  private readonly recordedAgentSessionByTask;
29
29
  private readonly attentionSnapshotByChannel;
30
+ private readonly compactionSnapshotByChannel;
31
+ private readonly activeCompactionByChannel;
32
+ private readonly compactionSnapshotLoadedChannels;
33
+ private readonly compactionSnapshotWriteQueueByChannel;
30
34
  private readonly missedCollaborationDiagnosticByChannel;
31
- private readonly progressChannelQueues;
32
- private readonly progressDrafts;
35
+ private readonly channelTurnQueues;
33
36
  private readonly collaborationDrafts;
34
37
  private readonly collaborationChannels;
35
38
  private readonly participantDirectoryByUserId;
@@ -99,7 +102,12 @@ export declare class AgentsHost {
99
102
  private confirmProtocolMessage;
100
103
  private findChannelHistoryMessageById;
101
104
  private resolveAttentionStatePath;
105
+ private resolveCompactionStatePath;
102
106
  private buildDefaultAttentionSnapshot;
107
+ private ensureCompactionSnapshotLoaded;
108
+ private commitCompactionSnapshot;
109
+ private enqueueCompactionSnapshotCommit;
110
+ private noteCompactionProgress;
103
111
  /**
104
112
  * Record which provider session worked this task, as agent.session_id.
105
113
  *
@@ -117,6 +125,7 @@ export declare class AgentsHost {
117
125
  private revalidateAttentionSnapshotForTurn;
118
126
  private getAttentionSnapshotForTurn;
119
127
  private isHumanWakeFiltered;
128
+ private isOrdinaryAgentWakeFiltered;
120
129
  private applyAttentionUpdate;
121
130
  private commitAttentionSnapshot;
122
131
  private resolveTaskThreadCollaborationContractForTurn;
@@ -126,16 +135,29 @@ export declare class AgentsHost {
126
135
  private noteWakeSuppressedAttentionPolicy;
127
136
  private runUngatedTurn;
128
137
  private executeTurn;
138
+ /**
139
+ * Opens this turn's report on the activity rail.
140
+ *
141
+ * The generation is captured here, where the turn's own is, and every report
142
+ * is checked against the channel's current turn before it leaves. That is what
143
+ * keeps a superseded turn from announcing a boundary for a turn that no longer
144
+ * exists — including its ending, which a window opened before it was replaced
145
+ * would otherwise carry out on its behalf.
146
+ *
147
+ * Every turn reports, including the silent and deferred ones that deliver
148
+ * nothing to the channel. The rail writes nothing anywhere, and the question
149
+ * it answers — whether anything is happening in this channel — is worth the
150
+ * same answer for a turn that keeps its reply to itself.
151
+ */
152
+ private beginTurnActivity;
129
153
  private canAcceptTurnOutput;
130
154
  private canAcceptCompletedTurnOutput;
131
155
  private canContinueSharedProtocol;
132
- private enqueueProgressChannelTurn;
133
- private ensureProgressDraft;
156
+ private enqueueChannelTurn;
134
157
  private publishCollaborationDraft;
135
158
  private finalizeCollaborationDraft;
136
159
  private clearCollaborationDraft;
137
160
  private readCollaborationDraft;
138
- private discardDraft;
139
161
  private supersedeActiveTurn;
140
162
  private invalidateChannelTurn;
141
163
  private rememberRecentTurn;