Skip to content

feat(types): add devin (Cognition CLI) as an agent type - #197

Merged
lodar merged 4 commits into
5dive-ai:mainfrom
A-MO7SEN:add-devin-agent-type
Jul 28, 2026
Merged

feat(types): add devin (Cognition CLI) as an agent type#197
lodar merged 4 commits into
5dive-ai:mainfrom
A-MO7SEN:add-devin-agent-type

Conversation

@A-MO7SEN

Copy link
Copy Markdown
Contributor

Closes #196.

Adds Cognition's devin CLI as a first-class agent type. It has the same shape as claude/codex — an interactive TUI that tmux hosts, subscription OAuth, an official curl installer — so this is registry wiring, no new machinery.

What's included

  • src/header.sh — registry entries: TYPE_BIN (~/.local/bin/devin symlink, grok/opencode convention), TYPE_AUTH (credentials.toml sentinel, verified against devin 3000.2.17), TYPE_INSTALL (official cli.devin.ai installer with an exact -x path guard, not command -v — avoiding the stray-binary short-circuit the codex comment documents), TYPE_PROBE (file-presence; devin -p spins a full session, too slow for a 5s probe), TYPE_CHANNELS=0.
  • src/cmd_auth.shagent auth login devin TTY handoff (hermes pattern).
  • src/cmd_init.sh — wizard menu entry.
  • 5dive-agent-start — launch dispatch (--permission-mode dangerous, parity with claude's --dangerously-skip-permissions), cross-provider UNSET_CREDS hygiene, and per-agent seeding of credentials.toml + config.json from the shared /home/claude login (mtime-newer re-seed, mirrors the codex block). The config.json seed carries shell.setup_complete=true so devin's first-run wizard never blocks the unattended session.
  • READMEs — type-table row (en + zh-CN).
  • Bundle + sha256 rebuilt via ./build.sh.

Deliberately not included

  • No telegram/discord bridge — that's the multi-day part and deserves its own PR. TYPE_CHANNELS=0 keeps the key bound (every reader does a bare ${TYPE_CHANNELS[$type]} under set -u; omission crashes agent types — found this the hard way) while --channels=telegram fails with the proper validation error. The agent is reachable via agent send/ask, the task queue, and sibling agents.
  • No TYPE_API_FILE/TYPE_API_VAR entries — devin is OAuth-only here, same absent-shape as hermes/openclaw.

Testing

  • ./build.sh && bash -n 5dive && bash -n 5dive-agent-start clean; agent types --json lists devin with channels:false.
  • Draft until end-to-end validation completes on a real box (Ubuntu 24.04, devin 3000.2.17): agent install devinauth logincreateagent ask round-trip. Will update with results and flip to ready.

🤖 Generated with Claude Code

@lodar

lodar commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Thanks for this — and for running it on real hardware rather than reasoning about it. We want it.

I've reviewed the substance and it's the right shape: registry entries plus the existing type machinery, no new subsystems. I checked the cli.devin.ai curl installer against precedent before flagging it and it's consistent with five types we already install that way (claude, opencode, hermes, antigravity, grok), so it isn't a new pattern. And --respect-workspace-trust false reads as a security bypass in a commit subject but isn't one — it's devin's own first-boot dialog blocking an unattended tmux session, the same reason we pass --dangerously-skip-permissions to claude. Worth the explicit comment you gave it.

Two things in your diff I want to call out, because they're better than the equivalents in our own code:

  • [devin]=0 for TYPE_CHANNELS with the reason written into the comment, rather than omitting the key. That's the right call and your reasoning is exactly right.
  • Verifying the exact TYPE_BIN path instead of command -v. We hit the identical bug in our own selfcheck verb this morning — a probe resolved command -v 5dive and graded the installed binary instead of the one under test, which only ever failed on a developer box and never in CI.

Both of your findings in #196 are real and are now filed as defects against our code, credited to you:

  • The command -v guard in TYPE_INSTALL — confirmed, and worse than you described: [claude] uses it while the comment two lines below says not to. claude is our primary type and the one every box installs. Three types are on the wrong side of that (claude, antigravity, grok), three are correct (opencode, hermes, pi).
  • The TYPE_CHANNELS crash — confirmed, five bare ${TYPE_CHANNELS[$type]} reads under set -uo pipefail. A contributor adding a type has no way to learn that except by crashing, which is a documentation defect on our side.

One ask, and an apology for the cause. The branch is conflicting because we shipped twelve versions today, so it's nine behind. Could you rebase onto current main? That's our churn, not yours.

Please drop the FIVE_VERSION bump when you do. We changed that convention today, back to what CONTRIBUTING.md already said: don't bump in a PR — the version is assigned at merge. The old way had every open PR reserving a number it couldn't hold, so every merge invalidated the others. One of our own PRs was renumbered five times before we worked out that the rule was generating the work. You'd have hit the same tax.

I'll merge on green rather than sitting on it. If anything in the rebase looks like our mess rather than yours, say so and I'll take it.

@A-MO7SEN
A-MO7SEN force-pushed the add-devin-agent-type branch from a5ac8bb to dc5256b Compare July 26, 2026 12:18
@A-MO7SEN

A-MO7SEN commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto 0.16.10 — your churn didn't actually touch any of my anchor points, so it re-applied clean. One commit now, no version bump.

Two things I hit running it on real hardware since your review: devin blocks on its own workspace-trust prompt on first boot in a fresh workdir, so it now launches with --respect-workspace-trust false (same story as claude's skip-permissions — looks scary in the diff, isn't). And its composer glyph turns out to be , not — added it to the readiness/idle markers so sends stop eating the 45s timeout like your codex case did.

Still draft — I want one clean round-trip on my box before I call it ready. Should be today.

@A-MO7SEN

Copy link
Copy Markdown
Contributor Author

Validated on my box — Ubuntu 24.04, devin 3000.2.17 on a Pro sub. install → auth login → create → send all work. Trust bypass holds (footer shows 'bypass permissions on', boots straight to the composer) and the ❭ marker fix too — sends land instantly now instead of eating the 45s timeout.

One caveat worth knowing: agent ask is flaky with devin's default SWE-1.7 Medium model. It answers — 'pong from devin' is right there in the pane — but it inlined both fence markers on one line once and typo'd the marker id another time, so the strict fence parser returned nothing either way. Not devin-specific plumbing, just a smaller model being loose with format. send + logs works fine, and a tolerant single-line parse in the fence reader would probably fix ask for every weaker model, not just this one.

Ready for review.

@A-MO7SEN
A-MO7SEN marked this pull request as ready for review July 26, 2026 13:02
@A-MO7SEN
A-MO7SEN force-pushed the add-devin-agent-type branch from dc5256b to 6f0247e Compare July 26, 2026 13:03
@A-MO7SEN

Copy link
Copy Markdown
Contributor Author

Rebased again (0.16.11). My side is scripted now, so re-syncing takes me under a minute — if it goes red again before you get to it, just say so and I'll bump it.

lodar added a commit that referenced this pull request Jul 26, 2026
…— a stray binary on PATH suppressed the install forever (DIVE-2075, fixes #196) (#205)

* install: TYPE_INSTALL gates on the exact TYPE_BIN path, not `command -v` — a stray binary on PATH could suppress the install forever (DIVE-2075)

Reported by A-MO7SEN (github #196), filed as a defect in our code while adding
devin in #197, and hit live during `5dive init` on a box carrying an old
npm-global claude.

`command -v claude` answers "is something named claude on PATH". The question
the recipe has to ask is "is the binary I am about to hand to the systemd unit
present" — TYPE_BIN, an exact path. On a box with a stray claude anywhere on
PATH the two answers diverge: the gate is satisfied, the recipe no-ops in 0s,
~/.local/bin/claude is never created, and cmd_install fails with "install
reported success but $bin still missing". Permanently — the gate can never flip,
so retrying `5dive init` or `agent create` cannot recover the box. The codebase
already documented the trap on the line directly below claude's, for codex.

Same primitive as DIVE-2061, shipped the same morning, where `command -v 5dive`
resolved the INSTALLED CLI instead of the bundle under test and graded the wrong
artifact. Two instances in one codebase in one day, found independently inside
and outside the team, so this sweeps every `command -v` rather than the one line
that was reported.

claude, antigravity and grok move to the exact-path gate (opencode, hermes, pi
and codex already had it). antigravity keeps its DIVE-901 post-install
`command -v agy` fallback: there the question genuinely is "where did the
installer put it". grok's gate mattered doubly — a suppressed install left
~/.grok/bin/grok absent, so the symlink branch no-oped too and the recipe still
exited 0 via its trailing `rm -f`.

opencode_catalog and pi_catalog took `command -v` FIRST with TYPE_BIN only as a
fallback, so a stray copy on the caller's PATH (root's, usually) would have us
validate --model against a different binary's catalog than the agent unit runs.
Order reversed; PATH stays as the fallback.

tests/type_install_gate_dimension_unit.sh measures the GATE'S OWN DECISION —
did the install action run — under two environments per type: stray-on-PATH with
TYPE_BIN absent (must install) and TYPE_BIN present (must not). It observes the
guard rather than whether a binary appeared, because observing the binary would
be defeated by the harness's own stubs. Against the pre-fix header it reds with
3 graded failures naming claude, antigravity and grok while the other 5 recipes
stay green; post-fix 8/8 on both environments.

Two findings from the sweep are out of this PR's concern and filed separately:
DIVE-2080 (`proof scorecard` re-resolves `command -v 5dive` and shells `digest`
into the installed bundle, re-opening DIVE-2061 one call deeper) and DIVE-2081
(`--upgrade` reports "upgraded" while 6 of 8 recipes ignore FORCE_INSTALL).

* chore(release): 0.16.12 — TYPE_INSTALL guards keyed off TYPE_BIN (DIVE-2075)

Assigns the release number and CHANGELOG entry at merge time per CONTRIBUTING; the
branch was correctly left unversioned at main's 0.16.11 by its author.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@A-MO7SEN
A-MO7SEN force-pushed the add-devin-agent-type branch from 6f0247e to 2924fb9 Compare July 26, 2026 15:35
@A-MO7SEN
A-MO7SEN force-pushed the add-devin-agent-type branch from 2924fb9 to c988b4b Compare July 26, 2026 22:48
@A-MO7SEN

Copy link
Copy Markdown
Contributor Author

Green again on 0.16.22. Third rebase — no complaints, but you might want to know why it keeps happening: the committed bundle means any PR from outside conflicts within an hour or two of being opened, no matter how small the src change is. Mine touches 5 source lines and 44k lines of generated artifact.

If it helps, I'm happy to strip the bundle from the commit and let you rebuild at merge — then the diff is just src/ and the README, and it stops going red between when you look at it and when you press the button. Say the word and I'll repush that way.

@lodar lodar 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.

Reviewed properly — sorry it took a day. Two things went wrong on our side and neither is about the code: CI never ran because first-time-contributor workflow approval sat unactioned (approved now), and #196 got auto-closed out from under you when an unrelated fix carried a fixes #196 trailer. Reopened with an explanation.

The work itself is good, and specifically good in ways I want to name because they're not the default for a new-type PR:

  • TYPE_INSTALL uses an exact -x path guard rather than command -v. You didn't just report that trap in #196, you avoided it here. Landed as DIVE-2075 in #205.
  • TYPE_CHANNELS=0 explicit rather than omitted, with the DIVE-2076 note cited. That's the ticket you filed, applied to your own code.
  • TYPE_PROBE is file-presence with the reasoning stated (devin -p spins a full session, too slow for a 5s probe). That's the right call and the comment saves the next person from re-deriving it.
  • Version-stamped empirical claims (credentials.toml sentinel, 3000.2.17) rather than claims from docs.

One question, on the only line that carries real risk:

-  grep -qE '❯|›|\? for shortcuts|esc to cancel' <<<"${1:-}"
+  grep -qE '❯|›|❭|\? for shortcuts|esc to cancel' <<<"${1:-}"

(U+276D) and claude's (U+276F) are two codepoints apart and render near-identically in most terminal fonts. The collision-free claim is the load-bearing one here, and it's load-bearing in a direction worth being paranoid about: this predicate decides whether we type into a pane. A false positive means we type into something that isn't a chat input — which is exactly the failure you reported in #214, from the other end. If you have a pane sample from the live box, tests/heartbeat_idle_marker_unit.sh takes real pane fixtures with no tmux; adding devin's would make the claim checkable instead of trusted. That's the one thing I'd ask for before merge.

Everything else reads as ready. The config.json seed carrying shell.setup_complete=true so the first-run wizard can't block an unattended session is the kind of detail that usually gets found in production instead of in the PR.

Needs a rebase on current main — rebuild the bundle with ./build.sh rather than resolving the generated 5dive artifact by hand. That conflict is our merge queue serialising on a committed build output (DIVE-2091), not anything you did.

On the type itself: yes. It fits the registry with no new machinery, and shipping it without a telegram bridge is the right scope — say so in the README row and it's honest.

@lodar

lodar commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Heads-up so you don't chase this: GitHub now shows this as conflicting again. That's the committed 5dive bundle, not your change — every merge to main regenerates a 47k-line build artifact that we track in git, so every landed PR invalidates every other open one. It's our design problem (DIVE-2091) and it is not your job to keep re-resolving it.

Don't rebase just to clear the red. Push whatever you're doing on the review notes, and I'll rebuild the bundle against whatever main looks like at merge time.

@lodar

lodar commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Yes — strip the bundle. Please repush that way.

That's the right answer and you shouldn't have had to ask twice. Your diff being 5 source lines and 44k lines of generated artifact is the whole problem stated in one sentence, and "the PR goes red between when a maintainer looks at it and when they press the button" is a better description of the failure than the one in our own ticket. I've quoted it into DIVE-2091.

To be concrete so you're not guessing at our conventions: drop 5dive and 5dive.sha256 from the commit, leave src/, 5dive-agent-start and the READMEs. bundle-drift will red on your branch — that's expected and I'll own it, and I'll rebuild with ./build.sh at merge. Same offer stands for #213.

Three other things I owe you.

Your PR has been ready since 13:02 yesterday and nobody said so. You marked it ready, you'd validated it on real hardware, and it sat. lodar said "I'll merge on green rather than sitting on it" and then we sat on it. No excuse worth typing.

CI. Workflow approval for outside contributors is a manual tap here, and it wasn't being tapped — several of your pushes have runs stuck at action_required and never executed. I've approved what was queued. Whether we loosen that gate for contributors with a landed PR is a call for lodar, not me, and I've put the question to him rather than quietly changing a security setting.

The agent ask finding in your 13:02 comment is a real bug and I nearly missed it because it was in a validation report rather than an issue. The strict fence parser returning nothing when a weaker model inlines both markers on one line, or typos the marker id, is not devin-specific — every weaker model will do this, and today the failure is silent: ask returns empty and the caller cannot tell "the agent said nothing" from "the agent answered and we couldn't parse it". That's the same fail-silent shape as your #211. Filing it with your tolerant-single-line-parse suggestion, credited to you.

Reviewed the code substantively in my other comment — one question there about the marker, which is the only line I'd want a fixture for before merge.

@lodar

lodar commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Status on the conflicts here, and a split of what's ours vs what needs you.

Ours, and we'll handle it: 5dive.sha256 (and the 5dive bundle). We commit the built artifact, so every merge to main invalidates the checksum on every open PR. No contributor should ever hand-resolve that. I did exactly this rebase on your #213 a few minutes ago — it's mergeable again and needed nothing from you.

Needs a judgement call, and it's genuinely yours or a maintainer's: 5dive-agent-start really does conflict. Since your branch point, you added 37 lines there for devin and main changed 69 in the same file. That's two real edits overlapping, not a generated-file artifact, so resolving it blind would risk dropping one side of your work.

Two options, your pick:

  1. Rebase just that one file yourself — you know what your devin block needs.
  2. Say the word and I'll rebase it and post the resolution as a diff for you to check before it lands.

Worth knowing: lodar picked devin as the theme for v0.17, so this PR is wanted. It's not sitting because anyone deprioritised it.

One caveat I'd rather state than have you discover: I verified the conflict by actually running the cherry-pick, not by trusting a predictor — git merge-tree and git merge-file disagreed about this file and only the real operation settled it.

Registry entries (TYPE_BIN/AUTH/INSTALL/PROBE, explicit TYPE_CHANNELS=0
to declare no-bridge intent per DIVE-2076), `agent auth login devin`
TTY handoff, init wizard entry, README type-table rows, and
5dive-agent-start launch support: --permission-mode dangerous
--respect-workspace-trust false (devin's trust dialog blocks an
unattended session on first boot — verified live), cross-provider
UNSET_CREDS hygiene, and per-agent credential + config seeding from the
shared /home/claude login (config carries shell.setup_complete=true,
suppressing devin's first-run wizard).

Prompt markers verified live against devin 3000.2.17 on Ubuntu 24.04:
composer glyph is ❭ (U+276D), collision-free with claude ❯ / codex › —
added to _agent_pane_input_ready and _hb_idle_marker.

Closes 5dive-ai#196.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lodar
lodar force-pushed the add-devin-agent-type branch from c988b4b to 579ba7f Compare July 27, 2026 10:52
@lodar

lodar commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Rebased and conflict-resolved for you, pushed to the branch. It's mergeable now and CI is approved and running. Your commit and authorship are unchanged.

The conflict turned out to be adjacency, not disagreement — which is the good case, so nothing of yours was dropped. Since you branched, main inserted a block of credential-seed helpers into 5dive-agent-start at almost exactly the point your devin seeding block goes in. Two independent additions landing next to each other, not two edits to the same logic. I kept both, helpers first, since your block and the codex block below it both sit downstream of them.

Verified after resolving: your devin block present, main's helpers present, bash -n clean on both the script and the bundle, and the committed bundle byte-identical to a fresh ./build.sh.

One optional follow-up, and it's a nice loop back to your own report. The helpers that landed in that spot are the fix for your gh#214 — cred_seed_failed writes a breadcrumb the send-side refusal reads back to name the root cause at the moment it bites. Your devin block still uses a bare echo "warn: could not seed ..." >&2, which is the pattern gh#214 showed is invisible to operators. Swapping that one line for cred_seed_failed "..." would give devin the same diagnostic every other type now gets. Entirely up to you — it doesn't block this PR.

Also worth knowing: lodar picked devin as the theme for v0.17, so this is wanted rather than tolerated.

Heads-up on a rough edge that's ours, not yours: force-pushing a rebase resets CI to needs maintainer approval on outside-contributor PRs, so a PR can sit at zero checks looking fine. I approved both of yours by hand. If you ever see no checks at all, that's us, not you — ping and we'll tap it.

…the glyph

lodar asked for a fixture behind the collision-free claim on ❭ (U+276D) vs
claude's ❯ (U+276F). Writing it found a worse problem than the one being
guarded against, so the marker changed rather than just gaining a test.

devin draws ❭ for BOTH the composer AND menu selections — its workspace-trust
dialog is literally '❭ 1 Yes, trust <path>'. So a glyph marker doesn't just
risk confusion with claude's ❯; it reports a TRUST PROMPT as a chat composer,
and the send path then types the next inter-agent message into it. That is the
gh#214 failure shape from the other end, which is exactly the direction the
review said to be paranoid about.

devin now keys off its composer placeholders instead — 'Ask Devin' (idle) and
'Guide Devin' (mid-turn). Both are prose, so no codepoint collision is
possible and no menu row can match.

Fixtures in tests/heartbeat_idle_marker_unit.sh, from live devin 3000.2.17
panes: idle reads idle and input-ready; mid-turn does not read idle; the trust
dialog reads neither; and both cross-checks (devin pane vs claude's marker,
claude pane vs devin's) fail as they should. 31 assertions, all passing.

Also adopted cred_seed_failed in the devin seed block, per the review note —
so a failed devin seed leaves the same breadcrumb every other type now does
(DIVE-2137 / gh#214) instead of a stderr line nobody reads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@A-MO7SEN

Copy link
Copy Markdown
Contributor Author

Fixture added — and you were right to be paranoid about that line, though not for the reason either of us had in mind.

Writing the fixture found that the collision I should have worried about isn't ❭ vs ❯ at all. devin draws ❭ for menu selections too — its workspace-trust dialog is literally ❭ 1 Yes, trust <path>. So the glyph marker doesn't just risk confusion with claude's composer; it reports a trust prompt as a chat input, and the send path then types the next inter-agent message into it. That's gh#214 from the other end, which is the exact direction you pointed at.

So the marker is gone rather than tested. devin keys off its composer placeholders now — Ask Devin idle, Guide Devin mid-turn. Prose, so no codepoint can collide and no menu row can match.

tests/heartbeat_idle_marker_unit.sh has real 3000.2.17 panes: idle reads idle and input-ready, mid-turn doesn't read idle, the trust dialog reads neither, and both cross-checks (devin pane vs claude's marker, claude pane vs devin's) fail as they should. 31 assertions, all green. The old glyph predicate fails the trust-dialog case, which is the point.

Also took the cred_seed_failed suggestion — nice loop back, thanks.

On the bundle: you'd already rebuilt it in your rebase, so I kept it in sync (./build.sh, committed) rather than stripping it and turning bundle-drift red on work you'd just fixed. Say the word if you still want it stripped and I'll repush that way.

Thanks for the rebase and the conflict write-up — 'adjacency, not disagreement' with the verification listed was more than I'd have asked for.

@A-MO7SEN

Copy link
Copy Markdown
Contributor Author

Taking you up on the offer: my push landed zero checks — CI is sitting at needs-approval again. Also gone red on the bundle since main moved, which you said to leave to you, so I have.

lodar added 2 commits July 27, 2026 17:14
…e rather than resolving 5dive.sha256 by hand)

# Conflicts:
#	5dive.sha256
@lodar
lodar merged commit 44249ec into 5dive-ai:main Jul 28, 2026
11 checks passed
lodar added a commit that referenced this pull request Jul 29, 2026
…287)

A seat that inlines the whole fence —

    <5dive-r:ab12> pong from the seat </5dive-r:ab12>

— gets dropped. The extractor requires the opening marker alone on its line
(is_marker rejects anything word-like after it), so the reply is discarded and
the caller sees a bare timeout. It cannot distinguish 'the seat said nothing'
from 'the seat answered and we could not parse it', which is the fail-silent
shape of gh#211 and gh#214.

Measured on devin 3000.2.17 (SWE-1.7), but this is not devin-specific: any
weaker model does it, and the same seat formats correctly on the next attempt,
so it presents as a flaky ask rather than a parser bug.

This does NOT reopen the scraping fallback that DIVE-1901 iteration 2 deleted.
It is strictly a fence match: both unique per-message markers must be present
AND closed on that line, and the inner text must be non-empty. The echoed
instruction can never qualify — its markers are adjacent (<5dive-r:id></5dive-r:id>),
so the inner text is empty. A mid-write frame has no closing marker and cannot
match either. Scanned newest-first so a retry beats an earlier answer.

tests/ask_capture_unit.sh gains three cases: the same-line reply returns, the
echoed instruction still returns nothing, and a half-typed same-line fence
still returns nothing.

Reported in the validation notes on #197; filing the fix rather than leaving
it as a comment.

Co-authored-by: A-MO7SEN <ahmed.mohsen@see.com.co>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent type request: devin (Cognition's Devin CLI)

2 participants