[WIP]feat(miniapp): add built-in bitfun-loopx console MiniApp (replaces #2382) - #2836
Open
xielixing wants to merge 35 commits into
Open
[WIP]feat(miniapp): add built-in bitfun-loopx console MiniApp (replaces #2382)#2836xielixing wants to merge 35 commits into
xielixing wants to merge 35 commits into
Conversation
Replaces GCWing#2382, which was closed when main was replaced with the 1.0.0 codebase; this branch is based on the new main and reapplies the built-in LoopX console MiniApp for OpenBitFun. Highlights: - Built-in MiniApp assets (product-domains/src/miniapp/builtin/assets/bitfun-loopx) registered via BUILTIN_APPS with the content-hash seed policy; private app.loopx.* bridge is injected only for the verified built-in identity (builtin-bitfun-loopx). - LoopX contracts (types/ports/policy/bridge) in product-domains; pinned sidecar CLI adapter + GitHub intake + worktree service behind the new services-integrations 'miniapp-loopx' feature. - Core LoopX controller, agent adapter, store, subscriber, tool activity in assembly/core (custom-agent-runner path per the LoopX cooperative runner contract); desktop Tauri surface (7 commands) with Product Operation Registry rows (Unsupported / ControllerLocal / REFUSED). - Bundled loopx sidecar build pipeline: scripts/build-loopx.mjs (pinned v0.5.1 @ 1bb42f4c) wired into desktop-tauri-build.mjs and dev.cjs, Python 3.13 in the packaging CI, THIRD_PARTY_NOTICES obligations. - Web UI: LoopxAPI/loopxBridgeProtocol, bridge + flow-chat wiring, locales. - Dropped the closed-PR installer-lockfile commit: the 1.0.0 repo pins generated installer lockfiles out of git (OpenBitFun-Installer policy). Verified: cargo check -p openbitfun-product-domains --features miniapp; cargo check -p openbitfun-services-integrations with miniapp-runtime,miniapp-loopx,web-tools; cargo check -p openbitfun-core --features product-full; cargo check -p openbitfun-desktop; cargo test -p openbitfun-product-domains remote_surface (19/19); pnpm run capabilities:generate; pnpm --dir src/web-ui run gen:types; pnpm run type-check:web; node --test scripts/desktop-tauri-build.test.mjs.
Author
3 tasks
…fy approval copy - loopx_cli.rs: decode sidecar stdout/stderr/payload as strict UTF-8 first, then GBK (the PyInstaller bundle ignores PYTHONUTF8 and always emits the ANSI code page, so lossy UTF-8 decode turned Chinese gate messages into U+FFFD mojibake); keep PYTHONUTF8/PYTHONIOENCODING for the managed-source Python entrypoint; add encoding_rs behind the miniapp-loopx feature - ui.js/index.html: open the raw request by default; rewrite approve/reject/recommendation copy to name the concrete boundary (writes/commits, builds, installs, real-run validation) and why approval is needed; stop duplicating the request text in the decision card
Bundle of adapter-level fixes driven by a live A/B against the loopx 0.5.1 + codex reference run (same three fixture issues on both hosts): - CLI adapter: inject --runtime-root <worktree>/.loopx/runtime on every loopx invocation; bootstrap passes --state-file into .loopx/goals and (after bootstrap) patches the registry common_runtime_root to the project-local runtime plus re-points legacy state_file away from .codex paths, so the worktree stays fully .loopx-namespaced and never touches the shared ~/.codex/loopx global registry. - Turn instruction: append the pinned CLI reference and the verbatim pinned workflow-skill documents (loopx-project + loopx-self-repair SKILL.md) on the FIRST turn of each agent session only (codex-style session-start skill load; later turns carry a short pointer so prompt cache and per-turn cost stay low). Closing-ceremony note carries the exact required no_followup flag set and vision contract requirements. - shell_analysis: accept powershell/pwsh/cmd dialects with hard input limits so the complete-shell guard stops failing closed on every Windows ExecCommand (whoami included). - MiniApp UI: preserve the technical-receipt <details> open state across re-renders (was collapsing on every snapshot attach); suite-level pause_all/resume_all allowed by the web-ui bridge guard. - build-loopx: bundle loopx skills via --add-data so the frozen sidecar ships the workflow-skill data (verified workflow-skills --install). - AGENTS.md: record the codex-comparison methodology and the root-cause facts (runtime root localization, required closure flags, dialect guard) for future maintainers.
- Seed the pinned LoopX reference (CLI help reference + verbatim official workflow-skill documents) into .loopx/pinned-loopx-reference.md when the workspace connects; the turn instruction now only carries a short pointer (read once per session, reuse from context) instead of pasting ~130KB into every instruction - mirrors how a LoopX codex-style host loads its workflow skills, and keeps per-turn prompts cache-friendly. - Slim LOOPX_CLOSING_CEREMONY_NOTE to host facts only: follow the reference document for schemas/flags; typed refusal -> apply the named parameter once, blocker after two ordered attempts; runtime stays project-local. The previous hand-written flag listing duplicated the docs and the 'minimal evidence' guidance caused repository_context=not_provided drift, so both were removed.
… terminal UX
Three live A/B runs against the loopx 0.5.1 + codex reference (same three
fixture issues) drove this batch; every fix cites its observed failure.
Execution parity (issue 1 went 16.7min -> 9.8min, faster than codex):
- Re-entry instructions now carry copy-ready settlement commands mirroring
the pinned v0.5.1 canonical templates (effect_program.py writeback,
autonomous_replan_obligation.py replan ACK with accountable
delivery-outcome): the outer-controller envelope only ships a bare
template, and agents re-derived flags from help text into 42 typed
refusals ("turn-scoped refresh-state requires an accountable
--delivery-outcome"; surface_only is not accountable).
- The replan ACK guidance embeds the exact goal_vision_replan_contract_v0
packet shape with enforced budgets - the agent's own blocker todo asked
the host to document this schema.
- Agent sessions now continue across turns of one goal (codex exec resume
parity): settlement keeps the session for Queued/WaitingForUser turns,
discards it on terminal/failure, and stale ids fall back to fresh
sessions. Continued turns get an "already loaded" reference pointer
(read policy has a single source: exactly one Read directive on the
first turn, zero afterwards).
- agent-onboard pack is fetched after register-agent so it carries the
registered agent id; monitor-recheck clock skew clamps at zero.
Owner-gated publishes (A9):
- Environment boundary now forbids git push / gh pr create / gh issue
comment / gh pr merge unless the turn contract explicitly carries the
approval, mirroring loopx requires_user_gate_before_external_write; a
todo's text ("open a PR") is a plan description, not an authorization.
Verified: 0 push/PR executions in the follow-up run (previously a PR
was opened without approval).
Truthful projections (A7/A8):
- A user wait without a typed user_gate (e.g. the owner review/merge
queue entry recorded after a PR) now projects as an owner-action
summary and parks the task as waiting instead of failing the whole
inspection and marking finished work recovery_required.
- The replan-lineage salvage accepts every typed envelope the pinned CLI
still prints under that contract error (live settlement previously
failed on an open blocker todo) and projects RunNow/Complete/Wait from
the envelope shape.
Terminal UX:
- Completed goals render a plain-language outcome note (GitHub activity
does not restart a finished goal) instead of the agent's control-plane
next-step wording; verdict badges show the concrete reason (wont-fix
rationale, missing info) instead of a repeated static note; the
rejected-options block is gone; an empty issue body no longer renders
as an endless "loading" placeholder.
- Agents must keep control-plane vocabulary out of human-facing summary
fields, and a terminal-rejected quota spend is not a blocker (the goal
is simply closed); completed tasks no longer render a blockers card.
- GitHub data must go through the gh CLI (direct WebFetch gets 403).
LoopX knowledge stays pinned: all embedded shapes (delivery outcomes,
vision contract, closeout flags) cite the pinned v0.5.1 validation code
by file and are regenerated when LOOPX_PINNED_VERSION moves. See the
bitfun-loopx AGENTS.md for the full run evidence and methodology.
LoopX v1.0.x moved the control-plane core (coordination state, turn envelopes, vision checkpoints) to a managed TypeScript effect runtime the Python sidecar starts on demand via `node --experimental-strip-types`. Verified live against a clean v1.0.1 checkout: bootstrap fails closed with "LoopX Effect runtime requires Node.js 22.6.0 or newer" when Node is absent, so the upgrade ships a Node dependency surface instead of bundling Node (installer size). Runtime compatibility (each verified against the v1.0.1 source and the rebuilt frozen sidecar, full chain bootstrap -> register-agent -> todo -> turn plan -> guard -> refresh-state -> spend -> complete -> history): - Every BitFun argv builder stays compatible; register-agent's new shape (no --project, global-registry write behind --execute) is exactly what BitFun already passes. - All schemas BitFun parses are unchanged (turn_plan/envelope v0, workflow plan packet v0, settlement identity v0+v1, vision contract v0, progress observation v0, command reference v0). - The turn-scoped refresh-state refusal was reworded but stays semantically equal (outcome_progress still qualifies); lineage error text, vision budgets, terminal-no-followup semantics, envelope budget all identical. - Skills content: only loopx-self-repair and loopx-pr-review changed; pinned resources regenerated wholesale from v1.0.1 (CLI help reference recaptured across all eight commands). Changes: - Pin constants -> 1.0.1 / v1.0.1 / 7f2a020b (adapter, contracts, tests). - build-loopx.mjs: stage the control-plane .ts/.json runtime sources as PyInstaller data (subset staging keeps .py modules out of the data area where loose sources could shadow frozen modules); compliance files now follow what the checkout carries (v1.0.1 dropped TRADEMARKS.md). - Handshake now probes Node (>= 22.6, matching loopx's own floor) and returns it as LoopxNodeRuntimeFact on the manifest; the environment surface gains a core "Node.js" fact that blocks with an install hint when missing. Hermetic tests disable the probe via config. - build_turn recognizes the guard's typed `turn_envelope_skipped` degradation (upstream #3687) and fails loudly with the skip reason instead of a generic missing-signature error.
Update the codex comparison baselines and reproduction manual in the bitfun-loopx AGENTS.md with data from the 2026-09-08 v1.0.1 codex run: - v1.0.1 baseline: issue #2 real fix 7m37s / 204K tokens / 58 execs, exact README +2 lines, stopped at owner gate, zero external writes. BitFun same issue 9.1 min - gap is ~1.5 min from per-turn host scheduling (inspect -> build -> settle), not agent execution. - Corrected methodology: exec injection is not the official codex path (official goes TUI + skill discovery + heartbeat loop) but remains valid as comparison data since the guided packet structure drives the complete issue-fix loop. - Documented sandbox pitfall: `--sandbox workspace-write` fails on Windows with `CreateProcessAsUserW failed: 5`; use `danger-full-access` with explicit operator safety boundaries. - Documented v1.0.1 requirements for the lab: Node.js >= 22.6 on PATH (TS control plane), .cmd suffix needed for codex exec on Windows. - Issue #1 no-op comparison incomplete (codex exec hung after register-agent for 17 min); noted for rerun.
Full v1.0.1 codex comparison run (deepseek-v4-flash, exec injection, danger-full-access sandbox): - #1 no-op: 7m00s / 202K tokens / 135 execs, terminal_no_followup, zero changes - #2 real fix: 7m37s / 204K tokens / 58 execs, exact README +2 lines, stopped at owner gate, zero external writes - #3 acknowledgment: 10m37s / 234K tokens / 114 execs, triage_only/no_followup, zero changes All three closed cleanly with GitHub untouched. BitFun same-day numbers: 9.8 / 9.1 / 10.5 min - total gap ~4 min across the suite, attributable to per-turn host scheduling (inspect -> build -> settle 30-60s each), not agent execution differences.
The 9.8/9.1/10.5 min BitFun numbers in the comparison table came from the v0.5.1 + codex-parity-fix run, not from the v1.0.1 upgrade. The v1.0.1 BitFun verification has not run yet; correct the table until real v1.0.1 numbers are collected.
Four root causes verified against the pinned CLI with live goals; each fix removes the patches that were compensating for it. 1. Settlement binding must follow the loopx receipt authority chain (live 2026-09-09: issue-2's turn-2 writeback AND quota spend were correctly recorded todo-bound on the server, but the host expected the autonomous_replan effect id and settled every such turn as NoDurableProgress). `planned_settlement_binding` now mirrors `quota_rollout_settlement_binding`: the typed `writeback.replan_settlement_contract` wins, then the selected todo, and only a todo-less frontier settles through the obligation. The writeback command flavor follows the SEMANTIC obligation instead (todo_bound_writeback: the obligation shapes the flags while the settlement records through the todo). 2. Continuation inspections probe the live quota decision (`quota should-run --turn-envelope`, no turn identity) instead of `turn plan` - codex/pi host parity. `turn plan` has an 8192-byte envelope-budget gate that degrades to contract_error and strands the goal (live: 9078-byte envelope); the quota decision keeps projecting should_run/selected todo past it. The probe never mints a heartbeat receipt. `envelope_over_budget` stays informational. 3. Two-phase action selection (live: the frontier held two eligible candidates, the guard refused a settlement identity and withheld the writeback commands). build_turn now binds the envelope's recommended todo via a `--todo-id` re-run carrying the SAME turn identity, then re-reads the bound contract. Verified as a three- step protocol against the pinned binary. 4. User-gated frontier parking (live: issue-3 reached an owner-decision frontier; the envelope projected should_run=true through the agent_with_user_gate fallback with no agent work item, and the strict no-binding check failed the task into recovery). The controller now parks such frontiers as WaitingForUser via the extracted `waiting_user_frontier` helper instead of driving a model turn that cannot settle; the UI already surfaces the gate. Removed with the root causes: the turn-plan over-budget degradation and replan-lineage salvage machinery, the legacy receipt path, the v0.5.1 monitor compat cadence and the always-empty scheduler_hint_ms readers, the host-side registry JSON surgery (bootstrap localizes common_runtime_root natively from the injected --runtime-root), and the hardcoded v0.5.1 install copy in the MiniApp UI (now filled from the environment fact). Also: managed-source dir derives from LOOPX_PINNED_VERSION_TAG, the MiniApp thin-client tests are fixed (8/8; the 8cf71c7 approval-copy rewrite never updated them), and the branch's loopx_contracts test target compiles again. Verified live: issue-3 on the fixed build settled 4/4 turns cleanly in ~9.2 min (codex baseline 10.6 min), reaching the owner gate without a single NoDurableProgress.
# Conflicts: # docs/interactive-capabilities/README.md # docs/interactive-capabilities/technical/tauri-command-map.json # scripts/check-core-boundaries.test.mjs # scripts/core-boundaries/cargo-dependency-boundaries.mjs # scripts/core-boundaries/explicit-test-topology.mjs # scripts/core-boundaries/rules/feature-rules.mjs # scripts/desktop-tauri-build.mjs # scripts/dev.cjs # src/crates/assembly/core/src/service/config/types.rs # src/crates/assembly/core/src/service/session_projection_store.rs # src/crates/contracts/product-domains/Cargo.toml # src/crates/contracts/product-domains/src/generated/remote-surface-registry.json # src/crates/contracts/product-domains/src/remote_surface/table.rs # src/crates/services/services-integrations/Cargo.toml # src/web-ui/src/infrastructure/api/generated/remoteSurface.ts
…sume_all The LoopX controller dispatches both actions (miniapp/loopx/controller.rs pause_all/resume_all) and loopxBridgeProtocol.ts already lists them, but the LoopxActionKind union omitted them, so tsc failed with TS2769 and blocked build:web.
- config-contracts: tolerate a legacy blank custom_headers string as absent (Option<HashMap> with serde(default) rejected it as a type error, so the branch's own deserializes_empty_string_custom_headers_as_absent test failed). - services-integrations: route the LoopX GitHub client through the crate-level provider-initializing reqwest_client_builder and keep reqwest::Client fully qualified, per the integration-module TLS rule. - core boundaries: tools-miniapp now declares miniapp-loopx, the MiniApp runtime capability it already composes.
Owner
|
beta旗舰暂不进行大特性合入,稳定性为主,后续阶段再评估 |
…ree-issue run Live experiment (2026-09-10, deepseek-flash official, issues #1-#3) exposed three agent-side closing failures. Fixes follow the host-fallback principle: mechanical steps are compensated host-side, semantic inputs are pre-resolved by the host, prompt text alone is never the last line of defense. 1. Missing quota spend receipt (issue #2 turn 4: writeback validated, spend skipped, task stranded in recovery with settlement_unverified). `verify_turn_settlement` now compensates the spend host-side using the exact command shape the turn instruction projected (same turn identity, binding flags, --source heartbeat): spend is idempotent bookkeeping, not a semantic claim. A terminal-closed accounting is treated as success; a real compensation failure still degrades loudly to RetryRequired. The spend instruction is also marked MANDATORY second step. 2. Vision terminal packet reworded durable fields (issue #1 turn 2: fresh text hit the unsatisfiable outcome=replan vs no_followup pair, burned the turn to NoDurableProgress). Turn instruction now embeds the recorded vision fields (queried via the CLI's own status projection) and demands character-level comparison before submit; work clause adds the turn-scoped settlement binding rule (a successor todo created mid-turn is selectable only by the NEXT turn's guard). 3. Final-response truncation decapitated the loopx_summary_v1 fence (issue closeout rendered as raw `\"rejected\": ...` fragments). Both bounds (subscriber append_bounded_text, controller bounded_agent_summary) now keep the TAIL where the fenced JSON contract lives. Also: - loopx_workspace reset retries the root rename with bounded backoff, and the LoopX agent cancel now waits for the turn to fully drain (the turn-id fast path returned after 1.5s while child processes still held handles, so stopping a task failed the reset with os error 5). - New local AGENTS.md/AGENTS-CN.md for the LoopX host subsystem documenting the settlement contract, the host-fallback principle, and the failure mode -> defense table.
… to the agent Two root causes behind the wasted turns observed in the 2026-09-10 control runs (BitFun and a codex comparison on the same model): 1. Capability-level contracts that the official workflow skills never document (candidate-evidence receipts, resolution outcome enums, the implementation-admission decision rule) had no local source at all. The agent probed --help, guessed argv shapes and, on the codex side, unpacked the frozen PyInstaller binary and read the executable bytes for a three-value enum. The pinned CLI can describe that contract itself: `bootstrap-command-pack --capability-route issue-fix` embeds it under `goal_start_contract.selected_capability_route`. The host now fetches that read-only preview during goal creation and seeds it as `.loopx/capability-contracts.json`, keeping the contract version-bound to the pinned sidecar instead of a hand-written copy that drifts. 2. The onboarding pack advertised only `shell` while every other CLI call in the turn advertised the five capabilities the Agent host actually reports, so the agent saw two contradictory capability surfaces in one turn. Both preview fetches now share one helper that appends the goal context's capability list, with the previous `shell` fallback only when the host reports none. Also: process_error_json uses the payload parsed when the process error was built instead of re-parsing the captured stdout tail (that field was written but never read); stale comments and docs describing a `turn plan` salvage path that no longer exists are corrected; and the documentation that claimed the host may repair a missing quota spend, that settlement is a fair rotation boundary, or that last_agent_summary never takes part in any recovery decision now matches the shipped behavior. Verification: no build run (repo rule: compile only on request). Interacting crates are services-integrations (adapter) and assembly/core (instruction pointer + environment boundary note).
# Conflicts: # src/crates/contracts/product-domains/src/generated/remote-surface-registry.json # src/web-ui/src/infrastructure/api/generated/remoteSurface.ts
…ee-issue runs Root-cause fixes from the 2026-09-11 live observation series on xielixing/dynamic-workflows-lab, all structural (no error-string matching, no case carve-outs): 1. Settlement decisions follow one rule: the authoritative Goal projection outranks receipts. NoDurableProgress from a completed turn now inspects the projection like RetryRequired, and a projection that reports a user gate, terminal completion, or goal failure skips the receipt-driven compensation turn entirely. An exhausted compensation episode parks for interactive recovery instead of requeueing into a re-drive loop. 2. Recovery reasons are distinct per failure mode (settlement_no_progress vs settlement_receipt_missing vs execution_failure) so the console copy can describe what actually happened instead of one misleading label. 3. The terminal close order is taught in the replan writeback guidance: settle the todo lifecycle (todo complete --no-follow-up) before the coverage-backed terminal refresh-state, verified live (issue #1 closed in one corrective turn once the order was known). 4. An approved gate whose frontier went empty gets its promised action materialized as a durable successor todo (new add_todo port), so approval always drives the promised work instead of parking plan-exhausted (live: approve -> PR GCWing#6 created in 19s). 5. A blocked publication todo (the agent's own encoding of 'publishing needs the owner') is projected as the publish approval card when the plan runs dry (new list_todos / unblock_todo ports); approve re-opens the todo, reject remembers the decline so it never resurfaces. 6. Owner-action waits survive reconciliation, the waiting task can resume (backend accepts WaitingForUser, card carries the button labeled as continuation, not recovery), answered gates are never resurrected from history, and the resume/continue feedback is honest about what the action does. 7. Console presentation: approval cards carry the decision context (who asked for what, what the agent did, what happens next) quoted from the structured summary; GitHub references (PRs, issues, commits) link out from the narrative sections; rejected alternatives render from structured data instead of the truncated raw output. Verified: 23/23 focused controller unit tests pass including the new decision-rule, materialization, blocked-publication, and reconciliation guards; the fixed binary ran three full live batches (zero NoDurableProgress losses after the fixes, batch time down from 36 to 19 minutes).
- Confirm the exact owner decision when an approval or rejection is applied; keep the decision notice aligned with the requested action. - Continue controller reset when workspace cleanup is blocked, with background retries, and report cleanup as deferred instead of failing the reset. - Preserve full model output in the console, render completed text output as Markdown, collapse loopx_summary_v1 receipts, and compact raw tool-activity rows behind expanders. - Strengthen CLI quota compensation argument shaping and add regression coverage for the gate notice.
- Treat untyped CLI read gates as read-only when the envelope message names public issue/comment content, so reading body/comments never parks the task for owner approval; typed publish/merge/comment write gates remain interactive. - Hide the lower decision card when a live typed approval panel is already rendered, removing the duplicated request UI. - Add regression coverage for typed and untyped read-gate detection.
…facing copy Owner-reported defects collected across the live monitoring runs. All of them were recorded as "not changing code" at the time; this commit closes them. Event stream - reuse log rows by block key and patch them in place instead of rebuilding the <li> on every chunk, which had dropped :hover and shifted the scroll position - anchor the reader's position when follow-mode is off so new output stops pushing the row being read off screen - one-line disclosures with a type icon and a rotating chevron instead of the native <details> triangles - render markdown while text is still streaming, add table support, and treat a standalone **bold** line as a section heading Task rail - reuse task buttons by id so a click is no longer lost to a full rebuild - show GitHub labels and let a long title use two lines - stop stripping [Bug] while leaving its separator behind - report the verdict for a settled task instead of a bare "completed" Issue panel - strip the loopx_summary_v1 fence from the live brief - keep the full decision text reachable behind an expander instead of a silent 110-char cut - only absolute http(s) targets become links; a local file reference renders as a non-clickable file chip Host - run `gh auth token` with CREATE_NO_WINDOW so hydrating a task stops flashing a console window The thin-client source contract asserted the previous renderTasks shape, so it now asserts keyed reuse instead.
Follow-up to the UI batch: the remaining owner-reported items lived in the host contract rather than in the MiniApp. Summary contract (agent prompt) - wont_fix_reason gains evaluation_pending. An issue that is a genuine request still being evaluated, or with no actionable scope, was forced into by_design, so the card told the owner "works as designed" for a feature request nobody had decided against. - new background / actual_findings / why_no_fix fields, so the middle of the story (what the issue wanted, what was actually found, why nothing changed) is reported instead of the card jumping from a verdict badge to a conclusion. - next_step must now be written for the repository owner and in the language of the issue discussion, instead of an internal plan sentence in English. Issue panel - render the three new sections. - the description panel is a bounded plain-text excerpt with the markdown stripped and long bodies cut with an ellipsis; it now says so and links to the issue instead of reading as a broken renderer. A full-markdown channel would need a new snapshot field and is not part of this commit. Intake - repository candidates were requested with sort=updated, so a recently commented old issue outranked newer ones and the list did not match the GitHub issue list the owner was reading. Request created-desc now, matching GitHub's default.
…visible
MiniApp (builtin bitfun-loopx):
- Approval receipts are localized and concrete: panel/banner state what will
happen (branch, commit, "opens a pull request, no auto-merge"); the applied
notice reuses a presentation cached before submit, and the host's English
"[P1] ..." gate text is never echoed back. Priority tags are stripped anywhere
in the string, not only at the start.
- Approve/reject now answer the task the panel is actually showing
(displayedTask) instead of selectedTask(); the old code silently returned when
no rail row had been clicked, so the button looked dead. Both buttons enter a
submitting state immediately (disabled + spinner) and recover in finally.
- Queued labels name the same-repo task holding the lane ("waiting for GCWing#2704 to
finish") and remember "approved, waiting to run", so a task stops flipping
between queued and approved as events scroll out of the window. The rail orders
the repository lane by creation time instead of fine-grained state, which stops
rows from jumping on every turn settlement.
- The issue header keeps a persistent "PR #N" link and a one-time notice
announces "Pull request created: #N" (clickable) as soon as the published
artifact appears - detected from a standalone PR URL plus a matching PR-number
mention, skipping reuse/merge routes and deduplicated across restarts.
- Evidence/artifacts are classified in Chinese (source issue, reproduction
evidence, validation, implementation scope, design basis, review packet) and
rendered under the conclusion as "supporting evidence"; artifact paths no
longer carry the "English original" tag.
- Removed the generic approval boilerplate: push-only, external validation and
unknown external actions get concrete templates. Tool rows use the
deepseek-harness icon set (filled paths) instead of hand-drawn glyphs. Notice
tones are a faint tint plus a 2px semantic bar instead of a saturated bar.
LoopX host:
- Project toolId into tool-activity details so the fallback timeline can merge
running/completed rows on a stable key.
Providers:
- Add deepseek-flash to the DeepSeek catalog policy.
xielixing
force-pushed
the
builtin/loopx-miniapp
branch
from
September 14, 2026 03:18
d00f597 to
12acc11
Compare
added 2 commits
September 14, 2026 15:37
…sions in the console UI - Move the status badge onto its own row under the task meta with semantic tinted pills (running pulse, waiting warning, failed error, completed success, queued info); the old full-width right-aligned pill left a large empty background band (owner screenshot feedback). - Track the PR-lifecycle monitoring stage explicitly: queued monitor waits now read '监控 PR #N' instead of '排队中', with the next scheduled check in the badge tooltip, so a cadence wait no longer looks like a queue stall. - Separate cards from the rail by elevation (elevated surface + subtle border, Linear-style) instead of colored backgrounds that read as error states; per-issue identity is a small stable-hue dot in the meta line, restricted to the cyan-blue-purple range away from state semantics. - Disambiguate the meta time label per state: completed reads 'finished X ago', recovery-required reads 'awaiting recovery for X', running reads 'last output X ago'. - Tint streamed model text blocks in the live console so settlement summaries stand out from thinking/tool telemetry, and pin a highlighted terminal-conclusion card (verdict-toned, markdown-rendered, idempotently updated) at the end of the run timeline once a task completes, so both log views carry the final outcome.
…timeline rendering - Require every published PR description to end with a searchable tooling attribution block: the exact locale-stable marker 'Powered by OpenBitFun', a repository link, and the task branch name in backticks. Adoption then stays countable through GitHub search across all future contributions. The requirement is recorded in the pinned issue-fix workflow contract (stage 10) and the pinned reference next to the Related Issue block rules, with a canonical example block agents must keep byte-stable and never drop during semantic-preference rewrites. - Fix the timeline terminal-conclusion card never appearing: the row was pushed onto the source list after the rendered slice was taken, so it could never enter the render list. Push before the slice. - Align tool-row icons with their labels: switch the milestone tool row from baseline to center alignment and normalize the icon to a 12px muted glyph instead of a 14px accent one, so the icons stop reading as jarring.
added 10 commits
September 14, 2026 15:57
The detail pane always displays a task (explicit selection, else the followed running/actionable task), but the rail only highlighted explicit selections, so follow mode showed issue content with no focused card in the rail. Highlight the displayed task instead: explicit selection still wins, otherwise the follow target carries the focus ring.
Replace the floating conclusion card (own margin, border, and radius) with a turn-output text row: same full-bleed padding, separators, and markdown body as the streamed log entries, with only a tinted background and left edge to mark it, so the conclusion reads as the last entry of one continuous log instead of a second, disconnected surface (owner feedback).
- Add winget-backed one-click installs for the required environment tools (Node.js, Git, GitHub CLI) as first-class remediation actions, mirroring the existing InstallLoopx pipeline: idempotent by clientRequestId, single-flight, marks the affected fact checking while running, and re-checks the whole environment when the install resolves. - Classify install failures into actionable guidance instead of raw exit codes: the 15-minute deadline turns stalled downloads into a slow-or- blocked-network message that names the system-proxy path (winget honors the system proxy), and winget-absent machines fall back to manual install links. Installs run through the same windowless process runner as the pinned CLI, inheriting the non-interactive child-process policy. - Split the GitHub auth remediation by root cause: gh CLI missing maps to a one-click CLI install, gh present but unauthenticated maps to sign-in guidance, and the probe now carries cli_available so legacy persisted probes degrade to the softer guidance. - Environment panel layout: single-column card stack instead of two columns, which left a large blank area under the optional group once the Python fallback item stopped rendering; per-fact action buttons render inline next to the status. - Hide the Python fallback fact entirely while the bundled/System runtime is selected: it is build-time-relevant only and rendered as a permanent unknown before.
Every scope listed in the intake preview is a hard prerequisite of the
autonomous issue-fix loop — the host already rejects partial grants — so
offering per-scope checkboxes invited users to start a task with defective
permissions that could never work.
- Render the scopes as a read-only required-capability disclosure (high-risk
scopes keep their warning styling); the create button becomes the consent
action ('同意并开始修复'), and cancel declines everything.
- grantedScopes now always equal the disclosed scope set; the partial-grant
warning and the create-button gate are gone.
- Update the intake runtime test to the consent semantics (no permission
checkboxes; grantedScopes equal the disclosed set).
- Fix the task-rail ordering test fixture: the queued fixture inherited the
same createdAt as the running task, so the documented creation-order
tie-break could not place running first; give the queued task a realistic
later creation time. This also unmasked a stale assertion in the same test
(decision card duplicating the gate request text) which is left for the
owner to settle separately.
…t, and trim the intake header - Intake preview: the workspace fact now shows the actual save location — the workspace probe reports the deterministic per-repository workspace directory (root + repository hash), so a clone-required preview reads 'path(将克隆并创建 Worktree)' instead of a vague promise, with the full text on hover. - Image capability states its consequence: supported reads 'can read image/screenshot attachments (video not supported)'; unsupported says plainly that screenshot-heavy issues may not be fully recognized and suggests adding text descriptions. - Remove the '已连接/Connected' sub-label under the LoopX wordmark: the environment chip and the failure banner already carry connection state, and a permanent green status line is noise (owner feedback). - Hide the native datalist picker arrow on the intake input: the history dropdown opens on focus/typing and the arrow itself was a dead control (owner feedback). The background-attach behavior the old connection-label observer covered is now asserted directly.
The previous attempt nested the rule inside .intake-form input, which this stylesheet does not use; the arrow kept rendering.
…auth as a core fact - The environment panel read core.node_runtime off a camelCase snapshot (nodeRuntime), so the Node card rendered a permanent '未知/未知' regardless of the probe result while every other fact resolved. Read nodeRuntime. - Move the GitHub auth fact from the optional group into core: every external write of the issue-fix loop (candidate evidence, PR creation, lifecycle monitoring) goes through gh, so an unauthenticated machine is a degraded environment, not an enhanced one. derive_environment_status now gates on it like the other core facts; the optional group only holds the Python fallback and its section hides when empty. - Intake preview labels follow: the 增强能力 group disappears when it has nothing to show.
The intake form let the browser draw its own '请填写此字段。' validation bubble on empty submits — an unstylable black-bordered overlay that read as alien to the panel. The form is now novalidate; an empty submit shows the panel's own warning notice, briefly highlights the field, and focuses the input.
…etails - The datalist-arrow fix had split the .intake-form input rule, leaving border: 0/outline: 0/background orphaned outside any selector — the input drew its own native focus outline inside the form frame, which read as a second black border (owner screenshot). Restore the full reset with the picker-indicator rule alongside it. - Environment fact details are authored in English on the host; the zh UI now maps the stable, known sentence shapes (Node control-plane runtime, writable workspace root, configured agent model, authenticated/unauthen- ticated GitHub access with rate-limit counts, gh-missing/not-authenticated states) to Chinese, keeping unrecognized text verbatim rather than mistranslating it.
…to-latest - Add an end-of-log cap as the last entry of the log flow: a muted-surface strip (same family as the main background) with centered '已到最新' and the last-output age, so the reader can tell at a glance whether they are looking at the newest state instead of a truncated row (owner feedback). - The scroll-to-latest button now reflects the real scroll position: it is hidden while the view is at the bottom (previously expanding a row paused follow mode and pinned the button forever, even at the bottom), and reappears only when new content actually sits below the viewport.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces #2382 (closed when
mainwas replaced with the 1.0.0 codebase). This PR reapplies the built-in bitfun-loopx console MiniApp on the newmainand links back to #2382 for review context.内置 MiniApp bitfun-loopx(品牌统一为 bitfun-loopx,
src/crates/contracts/product-domains/src/miniapp/builtin/assets/bitfun-loopx/即权威源码,不依赖任何外部仓库快照):粘贴 GitHub Issue 链接,由 OpenBitFun 宿主 Agent 驱动本机 loopx 持续修复,心跳调度、人工审批、中途插话。Ported from #2382 (adapted to the 1.0.0 codebase)
product-domains/src/miniapp/builtin/assets/bitfun-loopx/; registered inBUILTIN_APPS(builtin.rs) with the content-hash seed policy of the 1.0.0 codebase;private_bridge_extensionexposesapp.loopx.*only to the verified built-in identity (builtin-bitfun-loopx).product-domains/src/miniapp/loopx/{types,ports,policy,bridge}.rs— typed DTOs, narrow ports, pure lifecycle policy (cargo test -p openbitfun-product-domains --features miniappcovered byloopx_contracts).services-integrations/src/miniapp/loopx_{cli,github,workspace}.rsbehind the newminiapp-loopxfeature — pinned sidecar selection + typed CLI argv/JSON translation + durable readback, GitHub intake adapter, Git/worktree service.core/src/miniapp/loopx/{controller,agent_adapter,store,subscriber,tool_activity}.rs— host driver, batch/queue, fair rotation, recovery and state projection; custom-agent-runner path per the LoopX mainstream cooperative runner contract.miniapp_loopx_api.rs(7 Tauri commands, registered inlib.rs, declared in the Product Operation Registry withUnsupported/ControllerLocalstances), bundled loopx sidecar resolution (BITFUN_RESOURCE_DIR),worker_host.jspolicy/environment handling.scripts/build-loopx.mjs(pinned loopx v0.5.1 @ 1bb42f4c, PyInstaller onefile) invoked byscripts/desktop-tauri-build.mjs(prepareBundledLoopx+injectLoopxResource,--no-bundleskip) andscripts/dev.cjs(ensureLoopxSidecar); CI (desktop-package.yml / nightly-artifacts.yml) installs Python 3.13; THIRD_PARTY_NOTICES.md carries the LoopX MIT/NOTICE/TRADEMARKS obligations;resources/loopx/is gitignored (generated artifact).LoopxAPI.ts,loopxBridgeProtocol.ts, MiniApp scene/bridge updates, FlowChat/event wiring, locales (zh-CN/zh-TW/en-US).AGENTS.md/README.mdupdated to OpenBitFun naming; desktop AGENTS.md reconciled with the registry-driven peer/workspace policy.Deviations / notes
BitFun-Installerlockfile commit from feat(miniapp): add builtin bitfun-loopx console MiniApp #2382 is dropped: the 1.0.0 repo pins generated installer lockfiles out of git (.gitignore,OpenBitFun-Installer).remote_surface/table.rs(Product Operation Registry) instead of the removed hand-written tables; loopx commands areUnsupportedon remote workspaces,ControllerLocalunder Peer Device Mode (contracts to be negotiated across peers), CLI peer host refuses before dispatch.cargo check -p openbitfun-product-domains --features miniapp,cargo check -p openbitfun-services-integrations --no-default-features --features miniapp-runtime,miniapp-loopx, plus the desktop/core compile chain (see checklist).Fixes # (none; replaces the closed #2382)
Type and Areas
Type: Feature
Areas: contracts/product-domains (builtin MiniApp assets, loopx contracts), services-integrations (loopx CLI/GitHub/workspace adapters), assembly/core (LoopX controller), Desktop (Tauri commands, sidecar bundling), Web UI, scripts/CI, docs, THIRD_PARTY_NOTICES
Motivation / Impact
loopx (huangruiteng/loopx) is a control plane CLI for long-running Agent tasks: goals, todos, gates, quotas are all recorded, but it has no scheduler or executor. bitfun-loopx adds both: a heartbeat alarm and the OpenBitFun host Agent as the hand. Marketplace installs are limited by the
marketStrictruntime tier and cannot run the repair loop; the built-in version is not.The bundled sidecar means users need neither Python, git, nor network access to use loopx; the MIT redistribution obligations ship alongside the binary (LICENSE / NOTICE / LICENSE-MIT / TRADEMARKS / manifest.json in
resources/loopx/, plus THIRD_PARTY_NOTICES.md).Verification
cargo check -p openbitfun-product-domains --features miniapp— passes (loopx_contracts + builtin_miniapp covered)cargo check -p openbitfun-services-integrations --no-default-features --features miniapp-runtime,miniapp-loopx— passesnode --test scripts/desktop-tauri-build.test.mjs— 17/17node scripts/check-core-boundaries.test.mjs— loopx feature-ownership rules included (see the env-artifact note during migration)Checklist