Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
de3d95f
feat(peer): attribute ping_peer deliveries with trusted provenance
heavygee Aug 9, 2026
979800d
feat(web): show peer delivery sender as @session mention chip
heavygee Aug 9, 2026
3c948eb
fix(peer): bind provenance to CLI path; surface source to agents
heavygee Aug 9, 2026
f094e2b
fix(peer): require session capability for attributed delivery; annota…
heavygee Aug 9, 2026
4d70bb5
fix(peer): stabilize user-row aui selectors; recover capability on re…
heavygee Aug 9, 2026
8c53c0e
fix(peer): gate capability mint on session tag; fail closed on race
heavygee Aug 9, 2026
5f83c77
fix(peer): drop shared credential store; parent-broker CLI attribution
heavygee Aug 9, 2026
842d3b7
fix(peer): close pass2e-alt B1/M1-M4 provenance residuals
heavygee Aug 9, 2026
81d64b7
fix(peer): drain resume mint fd before any await (pass2f B1)
heavygee Aug 9, 2026
6afccf3
fix(peer): hub one-shot resume mint; no tag in child (pass2g B1)
heavygee Aug 9, 2026
45f257d
fix(peer): bind resume mint to spawn nonce + PID inject (pass2h B1)
heavygee Aug 9, 2026
d20bd6e
fix(peer): run inject tests under Vitest; fix resume mint comment (pa…
heavygee Aug 9, 2026
f70c36c
fix(peer): bind machine RPC to machineTag; fix peercred/RPC/inject races
heavygee Aug 9, 2026
2037afb
fix(cli): tolerate sockets without timeout() in rpc-register retry
heavygee Aug 9, 2026
4734537
fix(peer): close legacy machine tag bind; restore session RPC
heavygee Aug 9, 2026
8b446da
test(hub): expect machine tag arg on lazy session create
heavygee Aug 9, 2026
2d4df36
fix(peer): mint resume capability only on exact machineId
heavygee Aug 9, 2026
69aabe2
fix(peer): fail soft on inject bind; persist re-enrolled machineId
heavygee Aug 9, 2026
737f6dc
fix(peer): keep lazy re-enroll machineId; catch broker disconnects
heavygee Aug 9, 2026
8f44a2b
fix(peer): require session/machine possession for identity RPC
heavygee Aug 9, 2026
7987fa3
fix(peer): block peer slash control; mint terminal resume RPC proof
heavygee Aug 9, 2026
6d108ed
fix(peer): drop machineTag session-capability mint; gate Codex peer s…
heavygee Aug 9, 2026
f151c7f
fix(peer): bind machine RPC to memory-only runner lease
heavygee Aug 9, 2026
19c4d63
fix(peer): bind runner proof hash; strip forged peer meta; resume ali…
heavygee Aug 9, 2026
8299bbb
fix(peer): keep runnerProof memory-only; refuse null-hash first-claim
heavygee Aug 9, 2026
fee59f8
fix(peer): hand off runnerProof on restart; await broker listen
heavygee Aug 10, 2026
1909b6b
fix(peer): socket-handoff runnerProof; fail-closed direct resume
heavygee Aug 10, 2026
21e4f49
fix(peer): close bot Majors on inject, proof, and resume
heavygee Aug 10, 2026
f42063e
fix(peer): type prepareLocalResumeInject mock return
heavygee Aug 10, 2026
16362df
fix(peer): peercred local-resume grant; source-proof migrate
heavygee Aug 10, 2026
cf563f5
fix(peer): clear direct-resume capability between tests
heavygee Aug 10, 2026
eb5f890
fix(peer): refuse same-UID proof store and open local grants
heavygee Aug 10, 2026
130dc8b
fix(peer): re-enroll machine on cold-start proof loss
heavygee Aug 10, 2026
4f5aa8e
fix(peer): restore terminal resume; Windows broker; await readiness
heavygee Aug 10, 2026
618d28e
fix(peer): cold-restart reenroll grant, Windows PPID, lazy broker await
heavygee Aug 10, 2026
21d9e47
fix(peer): refresh reenroll grants; fix migrate race and Win handles
heavygee Aug 10, 2026
48acc5c
test(store): expect schema v25 after reenroll grants table
heavygee Aug 10, 2026
993a8f1
fix(peer): crash-safe reenroll grants and terminal local resume
heavygee Aug 10, 2026
bd1e25c
fix(peer): scope local-resume mint; harden cold recovery
heavygee Aug 10, 2026
21932f1
fix(peer): serialize grant refresh; atomic migrate+consume
heavygee Aug 10, 2026
1fae0aa
fix(peer): operator exe check; pending grant write; migrate replay
heavygee Aug 10, 2026
6e5ec7e
fix(peer): resume cmdline proof; durable pending grant; strict replay
heavygee Aug 10, 2026
6e28965
fix(peer): tracked-only unix mint; consumed-grant replay; dir fsync
heavygee Aug 10, 2026
faaa9c2
fix(peer): kill HTTP resume mint; durable replay; unattributed fallback
heavygee Aug 10, 2026
f65418e
fix(store): renumber peer schema steps after work-graph v23
heavygee Aug 10, 2026
a7d1dd3
fix(peer): drop file reenroll grants for same-UID isolation
heavygee Aug 10, 2026
a81b70b
fix(peer): refuse cold machine rotation without secure remap
heavygee Aug 10, 2026
76af8f4
fix(peer): offline proof rebind keeps machineId for cold start
heavygee Aug 10, 2026
07e775c
fix(peer): drop tag offline rebind; restore cold machine rotate
heavygee Aug 10, 2026
4f65f30
fix(peer): cold proof rebind keeps machineId for Cursor resume
heavygee Aug 10, 2026
785c4fe
fix(web): show unverified peer chips with claimed @name and ⚠
heavygee Aug 10, 2026
905c7e5
fix(web): only strip From: stamps on unverified peer rows
heavygee Aug 10, 2026
db46b4e
fix(web): hide unavailable history actions and reorder message action…
techotaku39 Aug 11, 2026
2548eaf
fix(cli): raise flaky claudeRemote first-test timeout to 15s under CI…
swear01 Aug 11, 2026
24e0c76
feat(cursor): bump hub thinking on ACP harness wake (#1487)
heavygee Aug 11, 2026
d147ae0
fix(web): rename storageUsagePie helper to storageUsageSlices to avoi…
swear01 Aug 11, 2026
a062119
feat(web): native/deep-link ingest for /share (GET url, text, title) …
heavygee Aug 11, 2026
5d8cd9b
fix(web): exclude path-only husks from @ session mentions (#1507)
heavygee Aug 11, 2026
450deae
fix(cli): win32 peer-cap inject without named-pipe client PID
heavygee Aug 11, 2026
8b500f6
merge(upstream): main into feat/a2a-p05-peer-provenance
heavygee Aug 11, 2026
134e741
fix(cli): drop duplicate claudeRemote it() timeout after main merge
heavygee Aug 11, 2026
6a9bbaf
fix(hub): gate machine-alive and state updates on runner proof bind
heavygee Aug 11, 2026
0d12035
feat(web): searchable session picker on Android share target (#986)
heavygee Aug 11, 2026
ee52ede
fix(cli): win32 peer-broker auth when named-pipe PID is unavailable
heavygee Aug 11, 2026
1cd4d11
feat(hub,cli,web): fleet runner version governance (skew, self-upgrad…
heavygee Aug 11, 2026
c2aa4bf
fix(web): align generated share watermark to bottom right (#1513)
techotaku39 Aug 11, 2026
173da49
fix(web): remove duplicate queued composer gap (#1505)
techotaku39 Aug 11, 2026
eb7a762
fix(web): clarify session list status hints (#1504)
techotaku39 Aug 11, 2026
e6b9fd6
feat(pi): queue mid-turn messages by default; steer only via explicit…
swear01 Aug 11, 2026
d396e9d
feat(voice): curate dictation credential presets to ElevenLabs, OpenA…
swear01 Aug 11, 2026
0ea80c9
merge(upstream): main into feat/a2a-p05-peer-provenance
heavygee Aug 11, 2026
11964b4
fix(a2a): stamp causing inbound on work_ad notify ingest (#1510)
heavygee Aug 11, 2026
c5d2a76
fix(hub): do not fake-archive in-flight CLIs without KillSession
heavygee Aug 12, 2026
119e258
fix(hub): treat archive liveness as heartbeat, not room join
heavygee Aug 12, 2026
291e7bc
fix(test): stop runner integration suite from leaking detached proces…
swear01 Aug 12, 2026
c1ceb83
fix(web): fail-closed scheme-less markdown file links (#1519)
heavygee Aug 12, 2026
7c4b3ab
fix(cursor): stop session-list spinner flicker from ACP state_update …
heavygee Aug 12, 2026
c69a88a
fix(cursor): close ACP list-models race and false exit 143 window (#1…
heavygee Aug 12, 2026
51ae260
feat(web): settings for AGENT_NOTIFY_SUMMARY chat display (default hi…
heavygee Aug 12, 2026
b9d1abe
fix(web): restore scroll chaining from reasoning panel to chat viewpo…
swear01 Aug 12, 2026
fea4221
Release version 0.27.3
tiann Aug 12, 2026
08abd05
feat(doctor): add cross-machine provenance audit subcommand
heavygee Aug 12, 2026
0e55c5a
merge(upstream): main into feat/a2a-p05-peer-provenance
heavygee Aug 12, 2026
e819571
fix(web): add showSessionSummaryInChat to chat context test mocks
heavygee Aug 12, 2026
df1a56e
fix(cursor): exclusive agent spawn lease for list-models vs ACP (#1529)
heavygee Aug 12, 2026
febbf8f
fix(web): improve session search UI (#1545)
techotaku39 Aug 13, 2026
a77a025
feat(doctor): audit unverified peer messages in provenance scan
heavygee Aug 13, 2026
d6ad992
merge(upstream): main into feat/a2a-p05-peer-provenance
heavygee Aug 13, 2026
ac04304
fix(web): dedupe showSessionSummaryInChat in markdown-a test mock
heavygee Aug 13, 2026
7701e51
fix(#1473): address Codex review threads on provenance hardening
heavygee Aug 13, 2026
885d234
fix(cli): fail closed when active resume lacks capability
heavygee Aug 13, 2026
1d55a4b
fix(cli): always hand off active sessions before local resume
heavygee Aug 13, 2026
ad72229
feat(sessions): add on-demand AI title suggestions (#1577)
techotaku39 Aug 15, 2026
e0354b0
fix(web): align new-session and settings controls (#1578)
techotaku39 Aug 15, 2026
e314522
fix(web): lower context warning thresholds (#1576)
techotaku39 Aug 15, 2026
7be4bab
fix(web): shorten Codex sync label and size action menu to content (#…
techotaku39 Aug 15, 2026
effc505
fix(mcp): clarify display_image user-output semantics (#1568)
techotaku39 Aug 15, 2026
235d6dd
fix(web): clarify displayed media labels (#1565)
techotaku39 Aug 15, 2026
a794be0
fix(web): recover silently-dead SSE connections quickly, stop banner …
swear01 Aug 15, 2026
b2ae6b9
fix(web): keep share actions visible during generation (#1550)
techotaku39 Aug 15, 2026
f803967
fix(web): stabilize autocomplete dropdown layout (#1547)
techotaku39 Aug 15, 2026
44703d0
fix(web): localize Fork and Rewind labels in Simplified Chinese (#1546)
techotaku39 Aug 15, 2026
e83dbdd
fix(web): add clear action to collapsed session search (#1544)
techotaku39 Aug 15, 2026
0e60697
fix(web): prevent Rewind crashes when message history resets (#1530)
techotaku39 Aug 15, 2026
386ee41
fix(web): hide chat viewport focus outline after Home/End (#1495)
techotaku39 Aug 15, 2026
c35b320
fix(web): normalize Windows file search query separators (#1490)
techotaku39 Aug 15, 2026
339607b
fix(web): keep single tildes literal in markdown (#1471)
Kryptonzy Aug 15, 2026
901f17d
feat(pi): support Pi slash commands from HAPI web (compact/session/mo…
swear01 Aug 15, 2026
5d2580f
merge(upstream): main into feat/a2a-p05-peer-provenance
heavygee Aug 15, 2026
97ecb2b
fix(web): drop stale merge leftovers after upstream/main
heavygee Aug 15, 2026
bcfee3b
fix(pi): do not execute peer /compact as a receiver command
heavygee Aug 15, 2026
1f2fbcb
fix(web): map codex-enveloped compact-summary to the chat block (#1582)
swear01 Aug 16, 2026
7248322
fix(web): restore Ctrl+A select-all on the chat page (#1595)
swear01 Aug 16, 2026
3050425
feat(web): keep quiet active sessions in the pinned top section — Run…
swear01 Aug 16, 2026
767e40a
fix(web): preserve current Fork action while reading history (#1573)
techotaku39 Aug 16, 2026
e32334f
fix(web): prioritize latest tail on session re-entry (#1560)
techotaku39 Aug 16, 2026
5c81ed6
fix(runner) preserve native instructions (#1557)
0xshawn Aug 16, 2026
daa10ea
fix(hub): retry Cursor legacy SQLite cleanup on Windows (#1561)
techotaku39 Aug 16, 2026
ec19699
fix(web): preserve session sidebar scroll during navigation (#1552)
techotaku39 Aug 16, 2026
44aff5a
fix(codex): cache codex model list to avoid spawning app-server per r…
swear01 Aug 16, 2026
bf6bae1
fix(pi): settle autonomous agent lifecycles instead of swallowing the…
KorenKrita Aug 16, 2026
8dc4a50
fix(web): prevent replaying historical assistant output (#1572)
techotaku39 Aug 16, 2026
7909c46
feat(search): support wildcard patterns across search fields (#1571)
techotaku39 Aug 16, 2026
ca6a6f0
fix(cursor): retry transient ACP connection errors (#1541)
swear01 Aug 16, 2026
79ffe9a
feat(web): composer model/effort value buttons and first-class permis…
swear01 Aug 16, 2026
a6feb6e
feat: unified agent configuration descriptors (session config consoli…
swear01 Aug 16, 2026
6c6f4b4
feat(agy): replace fragile PTY/TUI wrapper with headless print-mode t…
swear01 Aug 16, 2026
76e00f0
feat(hub): add background-only ServerChan fallback (#1608)
techotaku39 Aug 16, 2026
d644d4f
feat(cli): follow conversation language in status prompt (#1584)
techotaku39 Aug 16, 2026
b3c42f8
merge(upstream): main into feat/a2a-p05-peer-provenance
heavygee Aug 16, 2026
068dc65
fix(cli): strip terminal controls from doctor provenance output
heavygee Aug 16, 2026
41eb1f1
fix(cli): finish doctor TTY sanitize and move peer name off the From …
heavygee Aug 16, 2026
167eaee
fix(cli): settle peer-cap inject receives on EOF and silence
heavygee Aug 16, 2026
1b47c69
fix(hub): treat machineId as hub-owned; allow untagged migrate source
heavygee Aug 16, 2026
0bfbee7
fix(hub): unbreak migrate-sessions test typecheck
heavygee Aug 16, 2026
22e4bf7
fix(hub): reject untagged migrate-sessions sources
heavygee Aug 16, 2026
85cf1bc
fix(cli): soft-fail untagged migrate after legacy re-enroll
heavygee Aug 16, 2026
9c9c36d
fix(cli): keep peer Claude prompts free of \$skill expansion
heavygee Aug 16, 2026
e7275bb
fix(peer): fail-closed Windows peercred; drop dead reenroll grants
heavygee Aug 16, 2026
865bb2f
fix(cli): redact resume mint nonce in spawn logs; fail-closed inject …
heavygee Aug 16, 2026
4132339
fix(peer): fail-closed active resume and gate session-alive heartbeats
heavygee Aug 16, 2026
96c27a3
fix(peer): reject tag-only proof rebind; fail-closed all unattributed…
heavygee Aug 16, 2026
8f071f7
fix(peer): require source proof on migrate; refuse host-fallback resu…
heavygee Aug 16, 2026
da03bd5
docs(cli): clarify local-resume grant is descendant-only
heavygee Aug 16, 2026
c098754
fix(peer): runner-side terminal resume; offline-only cold proof rebind
heavygee Aug 17, 2026
eb63b00
fix(peer): durable runnerProof; await resume inject; local mint resume
heavygee Aug 17, 2026
e377fd9
fix(peer): keep runnerProof memory-only; fail-closed terminal resume
heavygee Aug 17, 2026
ba61bda
docs(peer): clarify memory-only runnerProof in hub comments
heavygee Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 14 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ jobs:
- run: bun install
- run: bun typecheck
- run: bunx playwright install --with-deps chromium
- run: bun run test:e2e -- terminal-wrap-fidelity.spec.ts
- name: Create integration test env
run: |
{
echo "HAPI_HOME=~/.hapi-dev-test"
echo "HAPI_API_URL=http://localhost:3006"
echo "CLI_API_TOKEN=${CLI_API_TOKEN:-dev-test-token}"
echo "HAPI_DAEMON_HTTP_TIMEOUT=60000"
echo "HAPI_DAEMON_HEARTBEAT_INTERVAL=30000"
} > cli/.env.integration-test
- run: bun run test:e2e -- terminal-wrap-fidelity.spec.ts composer-copy.spec.ts
- run: bun run test

# Serial runner-integration suite: starts real detached runner/session
# process trees against an isolated temp hub, so it runs in its own job
# (never in the parallel unit-test path). See cli/vitest.integration.config.ts.
integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14
- run: bun install
- run: bun run test:cli:integration
22 changes: 11 additions & 11 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ hapi resume
hapi resume <session-id>
```

`hapi resume` lists resumable sessions for the current machine. `hapi resume <session-id>` hands off an active remote session and opens the same HAPI session in the local terminal.
`hapi resume` lists resumable sessions for the current machine. `hapi resume <session-id>` hands off an active remote session and opens the same HAPI session in the local terminal when inject env or a peercred grant from a tracked session tree is available; otherwise resume from the web UI (same-UID provenance fails closed for unrelated shells).

### Authentication

Expand Down
14 changes: 8 additions & 6 deletions cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@twsxtd/hapi",
"version": "0.27.2",
"version": "0.27.3",
"description": "App for agentic coding - access coding agent anywhere",
"author": "Kirill Dubovitskiy & weishu",
"license": "AGPL-3.0-only",
Expand All @@ -26,11 +26,11 @@
}
},
"optionalDependencies": {
"@twsxtd/hapi-darwin-arm64": "0.27.2",
"@twsxtd/hapi-darwin-x64": "0.27.2",
"@twsxtd/hapi-linux-arm64": "0.27.2",
"@twsxtd/hapi-linux-x64": "0.27.2",
"@twsxtd/hapi-win32-x64": "0.27.2"
"@twsxtd/hapi-darwin-arm64": "0.27.3",
"@twsxtd/hapi-darwin-x64": "0.27.3",
"@twsxtd/hapi-linux-arm64": "0.27.3",
"@twsxtd/hapi-linux-x64": "0.27.3",
"@twsxtd/hapi-win32-x64": "0.27.3"
},
"scripts": {
"postinstall": "node -e \"try{require('fs').chmodSync(require('path').join(__dirname,'bin','hapi.cjs'),0o755)}catch(e){}\"",
Expand All @@ -44,6 +44,8 @@
"tools:unpack": "bun run scripts/unpack-tools.ts",
"update-homebrew-formula": "bun run scripts/update-homebrew-formula.ts",
"test": "bun run tools:unpack && vitest run",
"test:integration": "bun run tools:unpack && vitest run --config vitest.integration.config.ts",
"test:integration:stress": "bun run tools:unpack && HAPI_RUN_STRESS_TESTS=true vitest run --config vitest.integration.config.ts",
"test:win": "vitest run",
"dev": "bun src/index.ts",
"dev:local-server": "bun --env-file .env.dev-local-server src/index.ts",
Expand Down
11 changes: 7 additions & 4 deletions cli/src/agent/backends/acp/AcpSdkBackend.initialize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ const transportState = vi.hoisted(() => ({
calls: [] as Array<{ method: string; params?: unknown }>
}));

vi.mock('./AcpStdioTransport', () => ({
AcpStdioTransport: class {
constructor(_options: unknown) {}
vi.mock('./AcpStdioTransport', () => {
class MockAcpStdioTransport {
static async create(_options: unknown) {
return new MockAcpStdioTransport();
}
onNotification = vi.fn();
onStderrError = vi.fn();
registerRequestHandler = vi.fn();
Expand All @@ -19,7 +21,8 @@ vi.mock('./AcpStdioTransport', () => ({
});
close = vi.fn(async () => {});
}
}));
return { AcpStdioTransport: MockAcpStdioTransport };
});

import { AcpSdkBackend } from './AcpSdkBackend';

Expand Down
127 changes: 127 additions & 0 deletions cli/src/agent/backends/acp/AcpSdkBackend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1412,4 +1412,131 @@ describe('AcpSdkBackend', () => {
{ type: 'turn_complete', stopReason: 'end_turn' }
]);
});

it('notifies agent-activity listener for sustained running + idle, not content/usage noise (#1470/#1502)', () => {
vi.useFakeTimers();
const backend = new AcpSdkBackend({ command: 'agent' });
const activity: boolean[] = [];
backend.setAgentActivityListener((thinking) => {
activity.push(thinking);
});

const backendInternal = backend as unknown as {
handleSessionUpdate: (params: unknown) => void;
};

backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: {
sessionUpdate: ACP_SESSION_UPDATE_TYPES.agentMessageChunk,
content: { type: 'text', text: 'resumed' }
}
});
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: {
sessionUpdate: ACP_SESSION_UPDATE_TYPES.toolCallUpdate,
toolCallId: 'tc-bg',
status: 'in_progress'
}
});
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'usage_update', used: 1_000, size: 200_000 }
});
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: {
sessionUpdate: ACP_SESSION_UPDATE_TYPES.sessionInfoUpdate,
title: 'noise'
}
});
// Chatter: running then idle before debounce → no true bump (idle may clear)
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'state_update', state: 'running' }
});
vi.advanceTimersByTime(200);
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'state_update', state: 'idle' }
});
expect(activity.filter((v) => v === true)).toEqual([]);

// Sustained running commits after debounce
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'state_update', state: 'running' }
});
vi.advanceTimersByTime(750);
expect(activity.filter((v) => v === true)).toEqual([true]);
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'state_update', state: 'idle' }
});
expect(activity.at(-1)).toBe(false);
vi.useRealTimers();
});

it('ignores idle clears while a HAPI prompt turn is still draining', () => {
const backend = new AcpSdkBackend({ command: 'agent' });
const activity: boolean[] = [];
backend.setAgentActivityListener((thinking) => {
activity.push(thinking);
});
const backendInternal = backend as unknown as {
handleSessionUpdate: (params: unknown) => void;
isProcessingMessage: boolean;
};
backendInternal.isProcessingMessage = true;
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'state_update', state: 'idle' }
});
expect(activity).toEqual([]);
backendInternal.isProcessingMessage = false;
backendInternal.handleSessionUpdate({
sessionId: 'session-1',
update: { sessionUpdate: 'state_update', state: 'idle' }
});
expect(activity).toEqual([false]);
});

it('notifies agent-activity listener when a permission request arrives (#1470)', async () => {
const backend = new AcpSdkBackend({ command: 'agent' });
const activity: boolean[] = [];
backend.setAgentActivityListener((thinking) => {
activity.push(thinking);
});
backend.onPermissionRequest(() => {
// leave pending; we only care that activity fired first
});

const backendInternal = backend as unknown as {
handlePermissionRequest: (params: unknown, requestId: string) => Promise<unknown>;
};

const pending = backendInternal.handlePermissionRequest({
sessionId: 'session-1',
toolCall: {
toolCallId: 'tc-1',
title: 'Shell',
kind: 'execute',
status: 'pending'
},
options: [{ optionId: 'allow-once', name: 'Allow once', kind: 'allow_once' }]
}, 'req-1');

expect(activity).toEqual([true]);
// Cancel so the promise does not hang the suite.
await backend.respondToPermission('session-1', {
id: 'tc-1',
sessionId: 'session-1',
toolCallId: 'tc-1',
title: 'Shell',
kind: 'execute',
options: []
}, { outcome: 'cancelled' });
await pending;
});
});
Loading
Loading