Codify the box-only #4 customizations into Git so the AWS deployment
(which deploys from this repo) actually applies them — previously only
the retired sh-openswe box had them.
- prompt.py: branch names feature|bug|hotfix/<kebab> (optional <KEY->);
imperative PR titles with no conventional-commit type: prefix; PR body
Summary/Validation/Tests/Notes; handbook commit format. Rewrite the
collaboration template from an attribution MANDATE to a PROHIBITION —
no Co-authored-by bot trailer, no "Made by [Open SWE]" footer, no
agent/AI notes on any artifact.
- github_comments.py: add @seahaven-openswe (the deployed App slug) to
the mention triggers.
- authorship.py: remove the now-unused attribution helpers
(build_pr_attribution_footer, add_bot_coauthor_trailer,
add_pr_collaboration_note, PR_ATTRIBUTION_*). Keep OPEN_SWE_BOT_* —
server.py still uses them for the sandbox git identity.
- Flip the attribution unit tests to assert the no-attribution behavior;
drop tests for the removed helpers.
Commits stay authored as the triggering user for now — flipping
authorship to the bot account depends on the Vercel preview-deploy
constraint and is deferred to #11.
Refs: #4#11
Claude-Session: https://claude.ai/code/session_01DMhLf4G5V8MStJQyAW95hi
* fix(prompt): allow agent to pause and ask before adding a dependency
Brace's review on #1577 noted that the agent can in fact pause to ask
mid-task: post a Slack message (or PR-description note) and end the
turn without a tool call, then resume when the user replies. Reword
the DEPENDENCY_SECTION guidance so it tells the agent to use that
mechanism instead of claiming it cannot pause.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Update agent/prompt.py
Co-authored-by: open-swe[bot] <215916821+open-swe[bot]@users.noreply.github.com>
* fix(prompt): restore dependency pause guidance assertion
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: open-swe[bot] <215916821+open-swe[bot]@users.noreply.github.com>
The "Made by Open SWE" PR footer linked to the generic dashboard
homepage. Point it at the dashboard thread that generated the PR
(/agents/<thread_id>), falling back to the homepage when no thread
id is available.
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
The Co-authored-by trailer and bot git identity used
open-swe@users.noreply.github.com, which resolves to the separate
open-swe *user* account rather than the open-swe[bot] GitHub App.
Switch OPEN_SWE_BOT_EMAIL to the bot's noreply address
(215916821+open-swe[bot]@users.noreply.github.com) so co-author credit
and the fallback author identity point at the bot.
Drive the prompt trailer and sandbox git config from the constant
instead of hardcoding the address.
Replace the double-attribution PR body footer (_Opened collaboratively by
{user} and open-swe._) with a single Cursor-style footer linking to the
project. Since PRs are now opened as the triggering user, the user no longer
needs to be named in the footer. The commit Co-authored-by trailer is kept.
Legacy footers are migrated on PR updates.
* feat: open Slack-triggered PRs as the triggering user
Route the Slack per-user GitHub token through the dashboard OAuth store
(the backend the self-service link prompt populates) and block runs that
lack a valid user token, prompting the user to (re-)link. Per-user OAuth
now wins over bot-token-only mode for mapped Slack/dashboard users.
Flip commit/PR authorship across all sources: the triggering user is the
commit author (via repo-local git identity using their resolvable GitHub
noreply email) and open-swe[bot] is the Co-authored-by collaborator.
* fix: address PR review — shell-escape commit identity, fix token cache impersonation
- Shell-escape the triggering user's name/email with shlex.quote before
embedding them in the repo-setup `git config` command, so a name like
O'Connor (or a crafted one) can't break or inject into the command.
- Stop consulting the shared thread-metadata token cache in
_resolve_dashboard_user_token. Slack thread ids are shared across the
conversation, so a cached token from a prior triggering user could be
returned for the current github_login. Always resolve by login from the
dashboard OAuth store instead.
* feat: dashboard self-service user mapping + UI cleanup
- Add session-scoped GET/PUT /dashboard/api/my-mapping so users can set their
own work email / Slack member ID (keyed by their GitHub login, source=self).
- Slack account-link prompt now redirects to Profile Settings after auth.
- Rename "My Settings" -> "Profile Settings" and "Cloud Agents" -> "Open SWE
Agent"; remove the Integrations tab/section (folded out, low value for now)
and redirect /integrations to Profile Settings.
- Add a "User mapping" section to Profile Settings (work email used by Slack
and Linear, optional Slack member ID).
- Make dashboard auth cookies scheme-aware: Secure;SameSite=None over HTTPS,
non-Secure;SameSite=Lax over http://localhost so local login works.
* feat: self-service Slack account linking via Sign in with Slack (OIDC)
Replace the spoofable manual work-email/Slack-ID form with a verified
"Sign in with Slack" flow so a logged-in GitHub user can only ever link
their own Slack identity.
- New agent/dashboard/slack_oauth.py: OIDC authorize URL, code exchange,
userInfo identity parse, optional workspace gate, configured check.
- routes.py: session-gated GET /slack/login and /slack/callback that upsert
the mapping from Slack-verified user_id + email (source=slack_oauth).
Remove the spoofable PUT /my-mapping; expose slack_oauth_enabled on /me.
- UI: drop the editable inputs; add a Connect Slack button + status to the
User mapping section.
Admin-managed mappings are unaffected and still resolve at trigger time.
* fix: include GitHub username in collaboration footer
Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com>
* fix: clarify legacy footer replacement
Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com>
---------
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com>
* Replace hardcoded GitHub-email map with Store-backed user mapping
Move the static GITHUB_USER_EMAIL_MAP to a Store-backed bidirectional
mapping (GitHub login <-> work email <-> optional Slack ID) with an
in-process cache, self-service onboarding, and admin management.
- agent/dashboard/user_mappings.py: Store CRUD + login/email/slack-id
indexes, sync cache readers for hot paths, async fallthrough, and a
bulk_import that preserves existing richer records.
- Migrate all read sites (auth.py, agent_overrides.py, authorship.py,
github_comments.py, webapp.py x2) off the dict.
- Unmapped Slack tags now run on the GitHub App installation token
(use_installation_token_fallback) and get an ephemeral "link your
GitHub account" prompt carrying the Slack id + email via a signed
account-link token threaded through the OAuth state.
- OAuth callback completes a self-service (org-gated) mapping from that
token, falling back to the verified GitHub email.
- Admin CRUD endpoints + one-time legacy import; dashboard UI section.
- Legacy dict retained only as the import payload (no longer read).
Tests: mapping store, account-link round-trip + completion, mapped vs
unmapped Slack flows; existing trust-gate tests updated to prime cache.
* Address review: cold-cache email resolution + stale alias de-indexing
- agent_overrides: add resolve_login_from_email_async that falls through to
the Store on a cold cache; use it at the async repo-resolution call sites
(Slack repo config, Linear comment, owner-metadata) so a mapped user still
resolves to their GitHub login + dashboard default_repo on a fresh worker.
- user_mappings.upsert_mapping: de-index the existing login before re-indexing
so a changed email/Slack id no longer leaves stale aliases resolving to the
login in-process.
- Tests for both fixes; update Slack repo-config test to patch the async resolver.
* fix: preserve pushed commit history
Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com>
* refactor: consolidate no-force-push prompt guidance
Collapse the repeated force-push rule into a single IMPORTANT block,
drop the confusing rebase-onto-origin step, and stop mandating a
no-op trailer-only commit for already-pushed work.
---------
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
* feat: tell agent its source code lives at langchain-ai/open-swe
* fix: scope self-reference to only when user talks to the agent about itself
---------
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com>
The gh-cli migration removed agent/middleware/open_pr.py and
agent/tools/commit_and_open_pr.py — the only callers of
add_user_coauthor_trailer / add_pr_collaboration_note. Since then the
agent has been driving commits and PRs entirely via gh, with no
attribution back to the Slack/Linear/GitHub user who triggered the run.
Resolve the triggering user's identity in get_agent (reusing the
existing authorship helpers) and inject a Collaborative Attribution
section into the system prompt with the exact trailer and PR-body note
to use. The section is only rendered when an identity is resolvable, so
runs without a known triggering user are unchanged.
* feat: add GitHub PR comment trigger and reply support
* refactor: improve readability of GitHub integration
* linting
* fix: resolve github token from thread metadata and improve PR trigger flow
* fix: fall back to OAuth for GitHub webhook when no token in thread metadata
* give me commit message github integeration working without a breaking
* auth.py refactor
* fix: validate cached GitHub token before use to handle expiry
* liniting
* ci unitest formatting
* feat: post PR comments as GitHub App bot instead of user OAuth token
* resolved comments
* slack resolveed comments
* Refactor docstring and comments in get_slack_repo_config
Removed unnecessary comments and cleaned up docstring formatting.
* cr
* cr
* cr
* cr
---------
Co-authored-by: bracesproul <braceasproul@gmail.com>