Skip to content

feat(code): add project hooks workspace trust - #5105

Merged
Johannes du Plessis (johannes117) merged 4 commits into
mainfrom
johannes/code/hooks-v2-project-trust
Jul 29, 2026
Merged

feat(code): add project hooks workspace trust#5105
Johannes du Plessis (johannes117) merged 4 commits into
mainfrom
johannes/code/hooks-v2-project-trust

Conversation

@johannes117

@johannes117 Johannes du Plessis (johannes117) commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Supersedes #5044 (auto-closed when #4997 squash-merged; GitHub seals force-pushed closed PRs).

Project-level hooks now require an explicit workspace trust decision before their commands run. Interactive users can allow once, remember the workspace, or skip project hooks; headless runs remain opt-in through --trust-project-hooks.


This closes the execution gap that left interactive project hooks permanently disabled while preserving fail-closed behavior. Trust is keyed to the canonical repository root, saved atomically, and enforced again at runtime if a snapshot is ever constructed inconsistently. config path and the threat model now expose the relevant project, user, and trust locations.

Re-anchored onto main after #5104 squash-merged, so the PR diff contains only this branch's commits.

Review Guide

  1. hooks/trust.py — store, keys, atomic write, trust APIs
  2. hooks/loading.py — project source ingest vs skip
  3. hooks/runtime.py — fail-closed runtime guard
  4. main.py--trust-project-hooks + interactive prompt
  5. Skim: app.py, client/commands/config.py, THREAT_MODEL.md
  6. Tests: test_trust.py, then config/app/main touches
Test plan
  • Full hooks suite passes on the rebuilt stack tip. test_trust.py keeps one case per regressable behavior: canonical persistence, fail-closed corrupt-store handling, project-source provenance, the runtime trust guard, the three prompt outcomes, prompt suppression on persisted trust, and Textual wiring.

Stack generated by Git Town

@github-actions github-actions Bot added dcode Related to `deepagents-code` feature New feature/enhancement or request for one internal User is a member of the `langchain-ai` GitHub organization size: XL 1000+ LOC labels Jul 27, 2026

@open-swe open-swe Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open SWE Review found 2 potential issues.

Open in WebView Open SWE trace

Comment thread libs/code/deepagents_code/app.py Outdated
Comment thread libs/code/deepagents_code/hooks/trust.py Outdated
@github-actions github-actions Bot added size: L 500-999 LOC and removed size: XL 1000+ LOC labels Jul 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopping on a meeting, submitting this feedback for now before I inevitably forget

Comment thread libs/code/deepagents_code/app.py Outdated
Comment thread libs/code/deepagents_code/app.py Outdated
Comment thread libs/code/deepagents_code/main.py Outdated
Comment thread libs/code/deepagents_code/main.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall pretty good! I think there are a couple things that would be worth taking a look at (I think mostly surfaced in the last review submission) but generally very good!

Comment thread libs/code/deepagents_code/hooks/trust.py
Comment thread libs/code/deepagents_code/hooks/runtime.py
@johannes117
Johannes du Plessis (johannes117) force-pushed the johannes/code/hooks-v2-project-trust branch from 231925f to 26ce3c7 Compare July 28, 2026 22:35
@github-actions github-actions Bot added size: XL 1000+ LOC and removed size: L 500-999 LOC labels Jul 28, 2026

@open-swe open-swe Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open SWE Review found 1 potential issue.

Open in WebView Open SWE trace

Comment thread libs/code/deepagents_code/client/non_interactive.py Outdated
Comment thread libs/code/deepagents_code/hooks/trust.py Fixed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Base automatically changed from johannes/code/dcd-71-client-lifecycle to main July 29, 2026 15:29
Alexander Olsen (aolsenjazz) added a commit that referenced this pull request Jul 29, 2026
Supersedes #5010 (auto-closed when #4997 squash-merged; GitHub seals
force-pushed closed PRs).
Related:
[DCD-71](https://linear.app/langchain/issue/DCD-71/hooks-v2-integrate-client-owned-lifecycle-events)

dcode now runs client-owned Hooks v2 lifecycle events consistently in
interactive and headless sessions, including hook-driven approval
decisions before permission prompts are shown.

---

- Invokes `SessionStart` and `SessionEnd` at startup, resume, clear,
compact, switch, and exit boundaries.
- Applies `PermissionRequest` allow, deny, ask, interrupt, notice,
terminal, and stop effects before client approval resolution.
- Routes supported dcode notifications through one typed service with
explicit wire mappings while avoiding migrated legacy duplicates.
- Preserves session-start context for the next model turn and adds
TUI/headless decision-parity coverage.
- Ignores generated local transcript state through `.gitignore`.

This branch was re-anchored onto `main` after #4997 squash-merged; the
diff is identical to the approved #5010 head (`f4e8ee672`), minus a
stale resurrection of `todo_list_prompt.md` that #5098 deleted on main.

## Review Guide

1. `hooks/client_lifecycle.py` — `ClientHookService`, context,
permission outcomes
2. `app.py` — SessionStart/End boundaries + service wiring
3. `tui/textual_adapter.py`, `client/non_interactive.py` — interactive
vs headless parity
4. Skim: `transcript.py`, `server_middleware.py` (PermissionRequest),
`runtime.py` / `projection.py`
5. Tests: `test_client_lifecycle.py`, then adapter / non-interactive /
server-lifecycle deltas

<details>
<summary>Test plan</summary>

- 266 hooks unit tests pass on the rebuilt tip
- 412 non-interactive / Textual adapter / status widget tests pass

</details>


<!-- branch-stack-start -->

-------------------------
- main
- **feat(code): integrate Hooks v2 client lifecycle events**
:point_left:
    - #5105
      - #5045

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://github.com/git-town/git-town)</sup>

<!-- branch-stack-end -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added deepagents Related to the `deepagents` SDK / agent harness dependencies Pull requests that update a dependency file evals Evaluation suite and Harbor integration github_actions PR touching `.github` labels Jul 29, 2026
Project-level hooks now require an explicit workspace trust decision before
their commands run. Interactive users can allow once, remember the workspace,
or skip project hooks; headless runs remain opt-in through
--trust-project-hooks.

Re-anchored onto the rebuilt dcd-71 branch after #4997 squash-merged;
carries the full PR #5044 delta.
The trust suite covered store internals (thread-lock gating, concurrent
writers, symlink/worktree aliasing, partially invalid payloads) and
repeated the same trusted/untrusted runtime assertions across several
cases. Keep one test per behavior that can actually regress: canonical
persistence with restrictive permissions, fail-closed handling of a
corrupt store, project-source provenance in the runtime, the runtime
trust guard, the three interactive prompt outcomes, prompt suppression
for persisted trust, and the Textual wiring. The `test_app` mock-shape
tweak is no longer needed, so it is dropped as well.

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Addresses automated review feedback on the project hook trust plumbing.

- `WorkspaceTrust.explicit_only` ignores the persisted store, so a workspace
  remembered during an interactive session no longer opts a later `dcode -n`
  invocation into executing that repository's hooks. Headless runs stay
  explicit-opt-in, as their docstrings already promised.
- `_load_store` now catches `UnicodeDecodeError` where decoding actually
  happens — during the read. A non-UTF-8 `hooks_trust.json` previously escaped
  the unreadable-store handler and crashed startup with a traceback instead of
  failing closed.
- `WorkspaceTrust.allows` no longer restates the working directory in its
  warning; the raised exception already carries it, and CodeQL flagged the
  interpolation under py/clear-text-logging-sensitive-data.
@johannes117
Johannes du Plessis (johannes117) force-pushed the johannes/code/hooks-v2-project-trust branch 2 times, most recently from 37ba40e to 4b05a0a Compare July 29, 2026 17:14
@johannes117
Johannes du Plessis (johannes117) merged commit 9b2185b into main Jul 29, 2026
55 checks passed
@johannes117
Johannes du Plessis (johannes117) deleted the johannes/code/hooks-v2-project-trust branch July 29, 2026 17:22
Johannes du Plessis (johannes117) added a commit that referenced this pull request Jul 29, 2026
Hook execution now reports progress, warnings, notices, and permission
decisions consistently in the TUI and non-interactive client. Configured
`statusMessage` values appear while handlers run, and server-owned hook
output is no longer confined to logs.

---

A shared `HookFeedback` presenter keeps event ownership out of the UI
layer while preserving ordered engine reduction. It deduplicates visible
diagnostics, tracks concurrent handler statuses without clearing a
still-running hook, emits validated terminal sequences once, and
attributes hook-owned allow/deny decisions in both clients.

Re-anchored onto `main` after #5105 squash-merged. Call sites keep the
parent `WorkspaceTrust` API and layer `HookFeedback` on top.

## Review Guide

1. `hooks/feedback.py` — `HookFeedback` presenter (progress / notices /
decisions)
2. `hooks/engine.py` — handler progress reporting
3. `hooks/client_lifecycle.py`, `hooks/client.py` — feedback attachment
vs log-only
4. `client/non_interactive.py`, `app.py`, `tui/widgets/status.py` —
UI/status sinks
5. Skim: `HOOKS.md`, tiny adapter/runtime/threat-model edits
6. Tests: `test_feedback.py`, then engine / client-lifecycle / status

<details>
<summary>Test plan</summary>

- Added focused presenter, concurrent progress, `statusMessage`,
server-notice, and permission-attribution coverage.
- Targeted feedback / engine / lifecycle / trust / status suite passed
on the prior stack tip; CI re-runs on this re-anchor.

</details>

<!-- branch-stack-start -->

-------------------------
- main
  - **feat(code): surface Hooks v2 runtime feedback** 👈

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://www.git-town.com)</sup>

<!-- branch-stack-end -->
Marcelo5444 pushed a commit to Marcelo5444/deepagents that referenced this pull request Jul 30, 2026
…5104)

Supersedes langchain-ai#5010 (auto-closed when langchain-ai#4997 squash-merged; GitHub seals
force-pushed closed PRs).
Related:
[DCD-71](https://linear.app/langchain/issue/DCD-71/hooks-v2-integrate-client-owned-lifecycle-events)

dcode now runs client-owned Hooks v2 lifecycle events consistently in
interactive and headless sessions, including hook-driven approval
decisions before permission prompts are shown.

---

- Invokes `SessionStart` and `SessionEnd` at startup, resume, clear,
compact, switch, and exit boundaries.
- Applies `PermissionRequest` allow, deny, ask, interrupt, notice,
terminal, and stop effects before client approval resolution.
- Routes supported dcode notifications through one typed service with
explicit wire mappings while avoiding migrated legacy duplicates.
- Preserves session-start context for the next model turn and adds
TUI/headless decision-parity coverage.
- Ignores generated local transcript state through `.gitignore`.

This branch was re-anchored onto `main` after langchain-ai#4997 squash-merged; the
diff is identical to the approved langchain-ai#5010 head (`f4e8ee672`), minus a
stale resurrection of `todo_list_prompt.md` that langchain-ai#5098 deleted on main.

## Review Guide

1. `hooks/client_lifecycle.py` — `ClientHookService`, context,
permission outcomes
2. `app.py` — SessionStart/End boundaries + service wiring
3. `tui/textual_adapter.py`, `client/non_interactive.py` — interactive
vs headless parity
4. Skim: `transcript.py`, `server_middleware.py` (PermissionRequest),
`runtime.py` / `projection.py`
5. Tests: `test_client_lifecycle.py`, then adapter / non-interactive /
server-lifecycle deltas

<details>
<summary>Test plan</summary>

- 266 hooks unit tests pass on the rebuilt tip
- 412 non-interactive / Textual adapter / status widget tests pass

</details>


<!-- branch-stack-start -->

-------------------------
- main
- **feat(code): integrate Hooks v2 client lifecycle events**
:point_left:
    - langchain-ai#5105
      - langchain-ai#5045

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://github.com/git-town/git-town)</sup>

<!-- branch-stack-end -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Marcelo5444 pushed a commit to Marcelo5444/deepagents that referenced this pull request Jul 30, 2026
Supersedes langchain-ai#5044 (auto-closed when langchain-ai#4997 squash-merged; GitHub seals
force-pushed closed PRs).

Project-level hooks now require an explicit workspace trust decision
before their commands run. Interactive users can allow once, remember
the workspace, or skip project hooks; headless runs remain opt-in
through `--trust-project-hooks`.

---

This closes the execution gap that left interactive project hooks
permanently disabled while preserving fail-closed behavior. Trust is
keyed to the canonical repository root, saved atomically, and enforced
again at runtime if a snapshot is ever constructed inconsistently.
`config path` and the threat model now expose the relevant project,
user, and trust locations.

Re-anchored onto `main` after langchain-ai#5104 squash-merged, so the PR diff
contains only this branch's commits.

## Review Guide

1. `hooks/trust.py` — store, keys, atomic write, trust APIs
2. `hooks/loading.py` — project source ingest vs skip
3. `hooks/runtime.py` — fail-closed runtime guard
4. `main.py` — `--trust-project-hooks` + interactive prompt
5. Skim: `app.py`, `client/commands/config.py`, `THREAT_MODEL.md`
6. Tests: `test_trust.py`, then config/app/main touches

<details>
<summary>Test plan</summary>

- Full hooks suite passes on the rebuilt stack tip. `test_trust.py`
keeps one case per regressable behavior: canonical persistence,
fail-closed corrupt-store handling, project-source provenance, the
runtime trust guard, the three prompt outcomes, prompt suppression on
persisted trust, and Textual wiring.

</details>


<!-- branch-stack-start -->

-------------------------
- main
  - **feat(code): add project hooks workspace trust** 👈
    - langchain-ai#5045

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://github.com/git-town/git-town)</sup>

<!-- branch-stack-end -->

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Marcelo5444 pushed a commit to Marcelo5444/deepagents that referenced this pull request Jul 30, 2026
Hook execution now reports progress, warnings, notices, and permission
decisions consistently in the TUI and non-interactive client. Configured
`statusMessage` values appear while handlers run, and server-owned hook
output is no longer confined to logs.

---

A shared `HookFeedback` presenter keeps event ownership out of the UI
layer while preserving ordered engine reduction. It deduplicates visible
diagnostics, tracks concurrent handler statuses without clearing a
still-running hook, emits validated terminal sequences once, and
attributes hook-owned allow/deny decisions in both clients.

Re-anchored onto `main` after langchain-ai#5105 squash-merged. Call sites keep the
parent `WorkspaceTrust` API and layer `HookFeedback` on top.

## Review Guide

1. `hooks/feedback.py` — `HookFeedback` presenter (progress / notices /
decisions)
2. `hooks/engine.py` — handler progress reporting
3. `hooks/client_lifecycle.py`, `hooks/client.py` — feedback attachment
vs log-only
4. `client/non_interactive.py`, `app.py`, `tui/widgets/status.py` —
UI/status sinks
5. Skim: `HOOKS.md`, tiny adapter/runtime/threat-model edits
6. Tests: `test_feedback.py`, then engine / client-lifecycle / status

<details>
<summary>Test plan</summary>

- Added focused presenter, concurrent progress, `statusMessage`,
server-notice, and permission-attribution coverage.
- Targeted feedback / engine / lifecycle / trust / status suite passed
on the prior stack tip; CI re-runs on this re-anchor.

</details>

<!-- branch-stack-start -->

-------------------------
- main
  - **feat(code): surface Hooks v2 runtime feedback** 👈

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://www.git-town.com)</sup>

<!-- branch-stack-end -->
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
> [!CAUTION]
> Merging this PR will automatically publish to **PyPI** and create a
**GitHub release**.

For the full release process, see
[`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md).

---

_Release notes preview: keep this section in sync with the package
`CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`,
not this PR description — keep them aligned anyway so the PR stays an
accurate historical record for reviewers and anyone returning later._

---


##
[0.1.50](deepagents-code==0.1.49...deepagents-code==0.1.50)
(2026-07-30)

### Highlights

- Added project hooks workspace trust and expanded Hooks v2 support with
client and server lifecycle events plus runtime feedback
([#5105](#5105),
[#5104](#5104),
[#4997](#4997),
[#5045](#5045)).
- Added an option to mute the “YOLO is active” toast
([#5103](#5103)).
- Made the splash screen `thread` ID clickable to copy it
([#5173](#5173)).
- Show `ask_user` answers directly on the answered tool row
([#5100](#5100)).
- Show a toast when submitting an empty required `ask_user` answer
([#5095](#5095)).
- Added thread message counts to the Debug Console
([#5117](#5117)).

### Fixes and improvements

- Gated Hooks v2 behind `DEEPAGENTS_CODE_EXPERIMENTAL` and improved hook
resume stability across identity and Command tool results
([#5146](#5146),
[#5176](#5176)).
- Kept server hook state out of task results
([#5164](#5164)).
- Stopped duplicate Auto transcript events during interrupt replay
([#5157](#5157)).
- Kept `/update` and `/install --package` prompts responsive
([#5127](#5127)).
- Refreshed the `/threads` cache after each turn
([#5174](#5174)).
- Anchored toasts above the chat input and added a toast when media is
dropped into a free-text question
([#5101](#5101),
[#5099](#5099)).
- Improved thread status message styling and links
([#5118](#5118)).
- Made resume hints echo the launched command name
([#5119](#5119)).
- Scoped selection copy to the clicked screen
([#5140](#5140)).
- Ignored mouse hits on detached widgets
([#5114](#5114)).

_End release notes preview._

---

> [!NOTE]
> A **New Contributors** section is appended to the GitHub release notes
automatically at publish time (see [Release
Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline),
step 2).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
Supersedes #5010 (auto-closed when #4997 squash-merged; GitHub seals
force-pushed closed PRs).
Related:
[DCD-71](https://linear.app/langchain/issue/DCD-71/hooks-v2-integrate-client-owned-lifecycle-events)

dcode now runs client-owned Hooks v2 lifecycle events consistently in
interactive and headless sessions, including hook-driven approval
decisions before permission prompts are shown.

---

- Invokes `SessionStart` and `SessionEnd` at startup, resume, clear,
compact, switch, and exit boundaries.
- Applies `PermissionRequest` allow, deny, ask, interrupt, notice,
terminal, and stop effects before client approval resolution.
- Routes supported dcode notifications through one typed service with
explicit wire mappings while avoiding migrated legacy duplicates.
- Preserves session-start context for the next model turn and adds
TUI/headless decision-parity coverage.
- Ignores generated local transcript state through `.gitignore`.

This branch was re-anchored onto `main` after #4997 squash-merged; the
diff is identical to the approved #5010 head (`f4e8ee672`), minus a
stale resurrection of `todo_list_prompt.md` that #5098 deleted on main.

1. `hooks/client_lifecycle.py` — `ClientHookService`, context,
permission outcomes
2. `app.py` — SessionStart/End boundaries + service wiring
3. `tui/textual_adapter.py`, `client/non_interactive.py` — interactive
vs headless parity
4. Skim: `transcript.py`, `server_middleware.py` (PermissionRequest),
`runtime.py` / `projection.py`
5. Tests: `test_client_lifecycle.py`, then adapter / non-interactive /
server-lifecycle deltas

<details>
<summary>Test plan</summary>

- 266 hooks unit tests pass on the rebuilt tip
- 412 non-interactive / Textual adapter / status widget tests pass

</details>

<!-- branch-stack-start -->

-------------------------
- main
- **feat(code): integrate Hooks v2 client lifecycle events**
:point_left:
    - #5105
      - #5045

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://github.com/git-town/git-town)</sup>

<!-- branch-stack-end -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
Supersedes #5044 (auto-closed when #4997 squash-merged; GitHub seals
force-pushed closed PRs).

Project-level hooks now require an explicit workspace trust decision
before their commands run. Interactive users can allow once, remember
the workspace, or skip project hooks; headless runs remain opt-in
through `--trust-project-hooks`.

---

This closes the execution gap that left interactive project hooks
permanently disabled while preserving fail-closed behavior. Trust is
keyed to the canonical repository root, saved atomically, and enforced
again at runtime if a snapshot is ever constructed inconsistently.
`config path` and the threat model now expose the relevant project,
user, and trust locations.

Re-anchored onto `main` after #5104 squash-merged, so the PR diff
contains only this branch's commits.

## Review Guide

1. `hooks/trust.py` — store, keys, atomic write, trust APIs
2. `hooks/loading.py` — project source ingest vs skip
3. `hooks/runtime.py` — fail-closed runtime guard
4. `main.py` — `--trust-project-hooks` + interactive prompt
5. Skim: `app.py`, `client/commands/config.py`, `THREAT_MODEL.md`
6. Tests: `test_trust.py`, then config/app/main touches

<details>
<summary>Test plan</summary>

- Full hooks suite passes on the rebuilt stack tip. `test_trust.py`
keeps one case per regressable behavior: canonical persistence,
fail-closed corrupt-store handling, project-source provenance, the
runtime trust guard, the three prompt outcomes, prompt suppression on
persisted trust, and Textual wiring.

</details>


<!-- branch-stack-start -->

-------------------------
- main
  - **feat(code): add project hooks workspace trust** 👈
    - #5045

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://github.com/git-town/git-town)</sup>

<!-- branch-stack-end -->

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
Hook execution now reports progress, warnings, notices, and permission
decisions consistently in the TUI and non-interactive client. Configured
`statusMessage` values appear while handlers run, and server-owned hook
output is no longer confined to logs.

---

A shared `HookFeedback` presenter keeps event ownership out of the UI
layer while preserving ordered engine reduction. It deduplicates visible
diagnostics, tracks concurrent handler statuses without clearing a
still-running hook, emits validated terminal sequences once, and
attributes hook-owned allow/deny decisions in both clients.

Re-anchored onto `main` after #5105 squash-merged. Call sites keep the
parent `WorkspaceTrust` API and layer `HookFeedback` on top.

## Review Guide

1. `hooks/feedback.py` — `HookFeedback` presenter (progress / notices /
decisions)
2. `hooks/engine.py` — handler progress reporting
3. `hooks/client_lifecycle.py`, `hooks/client.py` — feedback attachment
vs log-only
4. `client/non_interactive.py`, `app.py`, `tui/widgets/status.py` —
UI/status sinks
5. Skim: `HOOKS.md`, tiny adapter/runtime/threat-model edits
6. Tests: `test_feedback.py`, then engine / client-lifecycle / status

<details>
<summary>Test plan</summary>

- Added focused presenter, concurrent progress, `statusMessage`,
server-notice, and permission-attribution coverage.
- Targeted feedback / engine / lifecycle / trust / status suite passed
on the prior stack tip; CI re-runs on this re-anchor.

</details>

<!-- branch-stack-start -->

-------------------------
- main
  - **feat(code): surface Hooks v2 runtime feedback** 👈

<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://www.git-town.com)</sup>

<!-- branch-stack-end -->
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
> [!CAUTION]
> Merging this PR will automatically publish to **PyPI** and create a
**GitHub release**.

For the full release process, see
[`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md).

---

_Release notes preview: keep this section in sync with the package
`CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`,
not this PR description — keep them aligned anyway so the PR stays an
accurate historical record for reviewers and anyone returning later._

---


##
[0.1.50](deepagents-code==0.1.49...deepagents-code==0.1.50)
(2026-07-30)

### Highlights

- Added project hooks workspace trust and expanded Hooks v2 support with
client and server lifecycle events plus runtime feedback
([#5105](#5105),
[#5104](#5104),
[#4997](#4997),
[#5045](#5045)).
- Added an option to mute the “YOLO is active” toast
([#5103](#5103)).
- Made the splash screen `thread` ID clickable to copy it
([#5173](#5173)).
- Show `ask_user` answers directly on the answered tool row
([#5100](#5100)).
- Show a toast when submitting an empty required `ask_user` answer
([#5095](#5095)).
- Added thread message counts to the Debug Console
([#5117](#5117)).

### Fixes and improvements

- Gated Hooks v2 behind `DEEPAGENTS_CODE_EXPERIMENTAL` and improved hook
resume stability across identity and Command tool results
([#5146](#5146),
[#5176](#5176)).
- Kept server hook state out of task results
([#5164](#5164)).
- Stopped duplicate Auto transcript events during interrupt replay
([#5157](#5157)).
- Kept `/update` and `/install --package` prompts responsive
([#5127](#5127)).
- Refreshed the `/threads` cache after each turn
([#5174](#5174)).
- Anchored toasts above the chat input and added a toast when media is
dropped into a free-text question
([#5101](#5101),
[#5099](#5099)).
- Improved thread status message styling and links
([#5118](#5118)).
- Made resume hints echo the launched command name
([#5119](#5119)).
- Scoped selection copy to the clicked screen
([#5140](#5140)).
- Ignored mouse hits on detached widgets
([#5114](#5114)).

_End release notes preview._

---

> [!NOTE]
> A **New Contributors** section is appended to the GitHub release notes
automatically at publish time (see [Release
Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline),
step 2).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dcode Related to `deepagents-code` deepagents Related to the `deepagents` SDK / agent harness dependencies Pull requests that update a dependency file evals Evaluation suite and Harbor integration feature New feature/enhancement or request for one github_actions PR touching `.github` internal User is a member of the `langchain-ai` GitHub organization size: XL 1000+ LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants