提交

298 次代码提交

作者 SHA1 备注 提交日期
tjb-tech 35fb12d5da release: publish 0.1.7 v0.1.7 2026-04-18 14:45:36 +00:00
tjb-tech 738da98b34 fix(terminal): support multiline input and reduce flashing 2026-04-17 11:42:01 +00:00
tjb-tech 04f8747ab6 fix(install): register commands in ~/.local/bin 2026-04-17 11:42:01 +00:00
Junghwan 91c0e32035 fix(sandbox): fail closed for unsupported Docker domain policies (#152)
The Docker backend currently turns any non-empty allowed_domains list into
unrestricted bridge networking even though no per-domain enforcement exists.
Keep Docker networking disabled and emit a warning until the backend can
actually honor domain policies.

Constraint: Preserve a small, reviewable fix instead of designing a full Docker egress filter
Rejected: Keep bridge networking with docs-only clarification | leaves silently overbroad behavior in place
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If Docker domain policies are re-enabled later, add true enforcement before widening network access
Tested: PYTHONPATH=src pytest -q tests/test_sandbox/test_docker_backend.py tests/test_sandbox/test_adapter.py
Tested: PYTHONPATH=src ruff check src tests
Not-tested: Full pytest suite in this environment (collection fails because optional pyperclip dependency is missing)
Related: #150
2026-04-17 18:55:25 +08:00
Junghwan 3b395500a2 fix(personalization): stop replaying exported env var values (#151)
Personalization currently captures full `export NAME=value` payloads and
re-injects them through local rules into future system prompts. Narrow the
environment-variable extraction to the variable name so the feature can still
remember environment hints without persisting secret material.

Constraint: Keep personalization's environment-hint workflow intact
Rejected: Remove env_var extraction entirely | larger behavior change than needed for a first fix
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not persist raw env var values without a separate sensitivity model and tests
Tested: PYTHONPATH=src pytest -q tests/test_personalization/test_extractor.py tests/test_prompts/test_claudemd.py
Tested: PYTHONPATH=src ruff check src tests
Not-tested: Full pytest suite in this environment (collection fails because optional pyperclip dependency is missing)
Related: #149
2026-04-17 18:06:12 +08:00
Hinotobi 59017e0988 fix(plugin): address code execution via untrusted plugin activation (#156)
* [security] fix(plugin): require explicit trust for project plugins

* test: clarify project plugin secure-default behavior
2026-04-17 18:00:13 +08:00
Hinotobi 3186851c47 fix(ohmo): isolate shared-chat sessions by sender (#159) 2026-04-17 17:45:19 +08:00
yulin c881c7deed fix(agent): Explore and claude-code-guide no longer hard-code model=haiku (#154)
Both built-in agents previously set model="haiku", which caused
subprocess spawning to fail for users running any non-Anthropic provider
(OpenAI, Bedrock, custom base URLs, etc.) because the literal string
"haiku" is not a valid model on those APIs.

Changes:
- Explore and claude-code-guide now use model="inherit", consistent
  with the existing Plan and verification built-in agents.
- build_inherited_cli_flags now skips the --model flag when the value
  is "inherit", so the subprocess inherits the parent model via the
  OPENHARNESS_MODEL env var that build_inherited_env_vars already
  forwards. Previously "inherit" was passed verbatim as a model name,
  which would have also broken Plan and verification agents.

Tests added:
- build_inherited_cli_flags: model="inherit" and model=None produce no
  --model flag; a real model name is included as expected.
- Builtin agent definitions: Explore and claude-code-guide must not
  reference Anthropic-only model aliases; Plan, verification, Explore,
  and claude-code-guide must all use None or "inherit".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 17:05:25 +08:00
tjb-tech 78160047f0 fix(dashboard): rename to OpenHarness, simplify kanban to 4 columns, richer pipeline animation
- Replace "OpenHarness-new" with "OpenHarness" in hero title
- Shorten description to "Kanban for OpenHarness self-evolution"
- Group 13 status columns into 4 vibe-kanban style: To Do, In Progress,
  In Review, Done — each card still shows its original status badge
- Redesign PipelineAnimation: orbital layout with 5 color-coded stage
  nodes, central hub, background grid, ambient particles, dual traveling
  packets, spoke data pulses, and scan line — fills the space properly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 13:24:23 +00:00
tjb-tech 992cac66d0 fix(test): align autopilot dashboard assertion 2026-04-16 13:16:32 +00:00
tjb-tech dea9ee8386 feat(dashboard): redesign autopilot kanban with React + dark cyberpunk theme
Replace the inline HTML template with a Vite + React + TypeScript app
in autopilot-dashboard/. The new design follows the AnyFS dark theme
aesthetic with animated SVG hero background (data streams, constellation
nodes, binary rain, scanline), pipeline visualization, glass cards with
status-colored glow effects, and JetBrains Mono typography throughout.

- autopilot-dashboard/: new Vite+React project, builds to docs/autopilot/
- HeroBackground.tsx: multi-layer SMIL SVG animation
- PipelineAnimation.tsx: QUEUE→PREP→RUN→CHECK→MERGE traveling glow
- CI workflow updated to build React app before deploying to Pages
- Python _render_dashboard_html simplified to a minimal fallback page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 13:13:35 +00:00
tjb-tech 2a91f66a3c fix(ci): auto-enable pages for autopilot dashboard 2026-04-16 12:53:45 +00:00
tjb-tech 67617e6eb5 fix(ohmo): restore runtime system prompt after startup 2026-04-16 12:52:11 +00:00
Octopus c0d3de2f95 feat(provider): add MiniMax as a first-class provider (#140)
- Add built-in `minimax` profile to `default_provider_profiles()` with
  `MiniMax-M2.7` as default model and `https://api.minimax.io/v1` base URL
- Add `minimax_api_key` / `MINIMAX_API_KEY` auth source support to
  `auth_source_provider_name()`, `default_auth_source_for_provider()`,
  and `resolve_auth()` env-var lookup
- Add MiniMax to `_KNOWN_PROVIDERS`, `_AUTH_SOURCES`, `_PROFILE_BY_PROVIDER`,
  and auth-status check in `AuthManager`
- Add `minimax` and `minimax_api_key` to CLI provider/auth-source label maps
  and `oh auth login` provider list; update default model for
  `minimax-anthropic` interactive flow from `minimax-m1` to `MiniMax-M2.7`
- Add `MiniMax-M2.7` / `MiniMax-M2.7-highspeed` model suggestions to the
  React UI model picker
- Add unit tests for MiniMax profile, auth-source mapping, env-var resolution,
  and profile materialisation

Co-authored-by: octo-patch <octo-patch@github.com>
2026-04-16 14:38:07 +08:00
Tao Zhang 944ccf9b22 fix(settings): preserve profile base_url/model under env overrides (#139)
ANTHROPIC_BASE_URL and ANTHROPIC_MODEL were applied unconditionally after
profile materialization, replacing explicit profile settings like Ollama's
base_url with unrelated endpoints. Now OPENHARNESS_* env vars always
override, while ANTHROPIC_*/OPENAI_* vars only apply when the active
profile doesn't explicitly configure the corresponding field.

Also adds Ollama setup instructions to README.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 14:35:25 +08:00
yu de9f9c05ca fix(agent): honor spawn overrides and harden task cleanup (#148) 2026-04-16 14:33:46 +08:00
yay2008 9caf7004a6 fix(runtime): resolve profile base_url and support openai_compat format (#146) 2026-04-15 20:33:31 +08:00
Hinotobi fab40c6eab fix(ohmo): secure default remote channel allowlists (#147) 2026-04-15 20:31:46 +08:00
José Maia 4090728163 fix(installer): detect installed launcher instead of hard-coding openh (#145)
The Windows PowerShell installer (scripts/install.ps1) hard-coded openh.exe
as the expected binary and printed "Launch (PowerShell): openh" in the
final instructions. The `openh` console-script alias was added in ce84a6a,
which landed after the v0.1.6 tag — so `pip install openharness-ai`
(the default install path) fetches a wheel whose entry_points.txt only
declares `oh`, `ohmo`, and `openharness`. openh.exe is never created, and
users follow the install banner straight into a "not recognized" error
(issue #144).

Instead of requiring a new PyPI release before the installer becomes
correct, detect which launcher the wheel actually produced and guide the
user to it. Preference order: openh (no shell collisions) -> openharness
(no collisions, always present) -> oh (collides with PowerShell's
Out-Host alias unless invoked as oh.exe).

Verification now succeeds against whichever launcher exists, and the
final "Next steps" block recommends the matching command along with the
relevant Out-Host caveat.

Co-authored-by: José Maia <glitch-ux@users.noreply.github.com>
2026-04-15 14:52:53 +08:00
tjb-tech d38796518a Merge branch 'pr-141' into integrate-pr141
# Conflicts:
#	CHANGELOG.md
#	frontend/terminal/src/App.tsx
#	frontend/terminal/src/components/ConversationView.tsx
#	frontend/terminal/src/components/ToolCallDisplay.tsx
#	frontend/terminal/src/hooks/useBackendSession.ts
2026-04-14 12:07:30 +00:00
siaochuan 7d2a0104ba feat(tui): add codex output style to reduce streaming flicker 2026-04-14 19:18:20 +08:00
tjb-tech 0c84d85630 fix(bash): surface clearer install workflow guidance 2026-04-14 08:59:09 +00:00
tjb-tech ce84a6a1a2 fix(session): sanitize empty assistant messages and add windows alias 2026-04-14 08:51:33 +00:00
José Maia a2dea036e0 fix(engine): keep parallel tool turns alive when one tool raises (#138)
`asyncio.gather` was called without `return_exceptions=True`, so a single
escaping exception from one parallel tool propagated out of the gather,
abandoned its sibling coroutines, and left the assistant turn with one or
more `tool_use` blocks that never received a matching `tool_result`. The
Anthropic Messages API rejects the next request on the session with a 400
in that state, so any unhandled tool exception during a multi-tool turn
effectively bricks the session.

Pass `return_exceptions=True` and synthesize an `is_error=True`
`ToolResultBlock` for each raised exception, matched to the originating
`tool_use_id`. The exception is logged via `log.exception` so the failure
is still observable.

Co-authored-by: José Maia <glitch-ux@users.noreply.github.com>
2026-04-14 16:39:42 +08:00
yulin f8e83c8409 fix(tools): update todo items in place instead of duplicating (#135)
* fix(tools): todo_write updates existing items in-place instead of duplicating

When an agent marks a todo item done by calling todo_write with
checked=True, the tool previously always appended a new [x] line,
leaving the original [ ] line intact. This produced duplicate entries.

The tool now performs an upsert:
- If the item exists as [ ], replace it with [x] in-place.
- If it is already in the target state, return a no-op result.
- Otherwise, append as before.

Adds test_todo_write_upsert to cover the new behaviour.

Co-authored-by: Copilot

* fix(tools): simplify todo_write tool description for LLM clarity

Co-authored-by: Copilot

---------

Co-authored-by: JiangYulin <yulin@JiangYulindeMacBook-Pro.local>
2026-04-14 00:04:24 +08:00
benben951 e537ba9867 chore(installer): add native Windows PowerShell installer (#118) 2026-04-13 20:28:42 +08:00
yulin ed0b5f02ab fix(tui): write trailing newline on exit so shell prompt starts on a fresh line (#133)
* fix(tui): write newline on exit so shell prompt starts on fresh line

Ink hides the cursor during rendering and restores it on exit, but does
not emit a trailing newline.  When the TUI process ends, the terminal
cursor sits at the end of the last rendered line, causing the shell
prompt to appear directly concatenated with the TUI output.

Rename restoreCursor → restoreTerminal and append '\n' alongside the
cursor-show escape sequence so the parent shell always receives the
prompt on a clean new line.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(tui): add regression guard for exit newline; update changelog

- Add tests/test_ui/test_tui_exit_sequence.py with two tests:
  * test_tui_exit_handler_writes_newline: asserts the cleanup write
    includes the trailing \n alongside \x1B[?25h
  * test_tui_exit_handler_registered_for_all_signals: asserts cleanup
    is registered for 'exit', SIGINT, and SIGTERM
- Add entry to CHANGELOG.md [Unreleased] Fixed section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(tests): update ohmo cli test inputs for allow_remote_admin_commands prompt

Commit dd1d235 added a new 'Allow explicitly listed administrative slash
commands from remote channels?' confirmation step to the gateway config
wizard, but the four interactive test cases in test_ohmo/test_cli.py were
not updated to provide an answer for it. This caused stdin to be exhausted
and click to emit Abort(), making all four tests fail with exit_code=1.

Add 'n' as the answer for allow_remote_admin_commands in each affected
test, and move the existing 'restart gateway' answer after it in
test_ohmo_config_interactive_can_restart_gateway.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-13 18:49:47 +08:00
tjb-tech 46a618bae8 test(ohmo): update interactive prompts for remote admin settings 2026-04-13 08:52:04 +00:00
tjb-tech 1ffc4a44fd fix(memory): preserve slug fallback in secure path resolution 2026-04-13 08:25:57 +00:00
hehe1111 45fb335db0 fix(feishu): reply in group threads instead of creating new topics (#125)
The Feishu channel did not support replying inside group topic threads.
Every bot response created a new top-level message, making conversations
in topic-enabled groups fragmented.

Three changes:

1. feishu.py: include thread_id/root_id in inbound metadata so that
   router.py can create per-topic session keys for group chats.

2. feishu.py: add reply_in_thread support to _send_message_sync using
   the lark-oapi ReplyMessageRequest with .reply_in_thread(True).

3. bridge.py: forward inbound message_id to OutboundMessage metadata
   so the Feishu channel can use it for thread replies.
2026-04-13 16:25:28 +08:00
Hinotobi dd1d235450 fix: harden gateway slash command security (#127)
* fix: harden gateway slash command security

* fix: add secure remote admin opt-in for gateway commands
2026-04-13 16:24:20 +08:00
tjb-tech 63ce793cba fix(tui): batch backend updates to reduce flicker 2026-04-13 07:31:24 +00:00
tjb-tech 1f5087c819 feat(subagents): improve discovery and reduce tui rerenders 2026-04-13 07:23:17 +00:00
tjb-tech 7f25a84d8e fix(ci): remove flaky fake subprocess cleanup assertion 2026-04-13 06:13:24 +00:00
tjb-tech 71c62c46a9 fix(ci): relax fake subprocess timeout assertions 2026-04-13 06:11:49 +00:00
tjb-tech cdb7256e6b fix(ci): make bash timeout tests robust across runners 2026-04-13 06:10:21 +00:00
tjb-tech 7f22107170 fix(ci): normalize bash timeout output under pty 2026-04-13 05:48:58 +00:00
tjb-tech 9f97283320 fix(bash): surface partial output for interactive timeouts 2026-04-13 05:34:05 +00:00
José Maia 4857439e50 fix(persistence): atomic writes and locks for shared state (#128)
Files under ~/.openharness/ — credentials, settings, session snapshots,
cron registry, memory index — were written with `Path.write_text()` in
truncating mode. A crash, SIGKILL, power loss, or out-of-disk error
during the write leaves a truncated file on disk; concurrent writers
clobber each other's updates; and the credentials file spent a brief
window at the default umask mode (commonly 0o644) before chmod-to-0600
ran.

Introduce `openharness.utils.fs.atomic_write_text` / `atomic_write_bytes`
which write to a same-directory temp file, fsync, apply the target mode
while the file is still private, and `os.replace` into place. Thread
them through all persistence writers. For read-modify-write on shared
files (credentials, settings, cron, memory index), pair atomic writes
with the existing `exclusive_file_lock` primitive so two `oh` processes
no longer race.

The generic lock helper moves from `openharness.swarm.lockfile` to
`openharness.utils.file_lock`. `swarm.lockfile` is retained as a thin
re-export so existing callers keep working.

Co-authored-by: José Maia <glitch-ux@users.noreply.github.com>
2026-04-13 12:40:24 +08:00
tjb-tech 39ffc199a8 fix(config): resolve compact thresholds and base URL regressions 2026-04-12 15:33:43 +00:00
tjb-tech a6c63fdab9 fix(sandbox): bypass srt wrapping for docker backend 2026-04-12 06:23:12 +00:00
José Maia 508937c996 feat(sandbox): add Docker sandbox backend (#121)
The existing srt/bubblewrap sandbox only wraps shell commands — file I/O
tools bypass it entirely via direct Python calls. This adds Docker as a
second sandbox backend that provides container-level isolation for tool
execution while keeping the engine and API keys on the host.

- Add DockerSandboxSettings with image, resource limits, and env config
- Add backend field to SandboxSettings ("srt" or "docker")
- Implement DockerSandboxSession: long-running container per session
- Route shell, glob, and grep subprocess calls through docker exec
- Add path validation for file tools when Docker sandbox is active
- Auto-build default sandbox image (python:3.11-slim + ripgrep + git)
- Network isolation: --network=none by default, bridge when domains allowed
- Lifecycle integration: container starts/stops with the session
- atexit safety net for cleanup on unexpected exit
- 34 unit tests, 19 E2E tests (require Docker daemon)

Co-authored-by: José Maia <glitch-ux@users.noreply.github.com>
2026-04-12 14:22:37 +08:00
DDY 242e3d90dd fix(auth): support Claude subscription auth lookup on macOS (#123)
* fix claude auth lookup on macos

* fix claude keychain auth status display
2026-04-12 14:22:30 +08:00
tjb-tech 327c6ed2ff fix(ui,openai): reduce TUI flicker and make timeout configurable 2026-04-11 14:31:19 +00:00
tjb-tech bd4df81f63 Merge pull request #92 from 13ernkastel/codex/harden-path-rules-and-web-guards 2026-04-11 13:49:52 +00:00
tjb-tech e3bf45020c Merge pull request #96 from fengjie926/fix/skill-loader-yaml-frontmatter 2026-04-11 13:27:21 +00:00
tjb-tech a21011001a Merge remote-tracking branch 'origin/main' into fix/skill-loader-yaml-frontmatter
# Conflicts:
#	CHANGELOG.md
2026-04-11 13:27:00 +00:00
tjb-tech 76b2b48e5f Merge pull request #110 from yl-jiang/fix/grep-limit-overrun 2026-04-11 13:26:21 +00:00
tjb-tech 33d0f0db7e Merge remote-tracking branch 'origin/main' into fix/grep-limit-overrun
# Conflicts:
#	CHANGELOG.md
#	src/openharness/tools/grep_tool.py
2026-04-11 13:25:54 +00:00
Jiabin Tang 9b75800fde Merge pull request #65 from siaochuan/feat/session-personalization
feat(personalization): auto-extract local environment rules from session history
2026-04-11 21:14:40 +08:00