Commit Graph
100 Commits
Author SHA1 Message Date
zsbgnw12andGitHub 9444cdb498 fix agent deploy caps
approved
2026-06-08 17:49:35 +08:00
zsbgnw12andGitHub b3d864b29b fix(agent): refresh list status from AM
Refresh non-terminal agent statuses before returning /api/heicode/agents.
2026-06-08 16:22:21 +08:00
efb0016f5c fix(secret): 撤销资源时删除 Key Vault 凭证材料 (#4) (#13)
#4:撤销资源此前只把 DB 状态置 "revoked",真凭证仍留在 Azure Key Vault。
现在 DeleteResource 同时删除 KV 中的 secret(best-effort:DB 撤销已提交,
外部 KV 失败只记日志、不阻塞响应)。

- secret_store.go:新增 deleteSecret / purgeSecret / rotateSecret
  (AKV REST,api-version=7.4,与 putSecret/getJSONSecret 同风格;404 幂等)。
  ※ 该文件受组织权限策略保护、自动化无读写权,本段由 HM owner 手动粘贴,
    审阅者请核对其与本意一致。
- resource.go:DeleteResource 在撤销事务提交后调用 deleteSecret(resource.SecretRef)。

本轮为 #4 最小修复(堵住"撤销后 KV 材料残留"的洞)。后续仍待:
purgeSecret 接入 30/90 天生命周期、轮换流程。

go build ./... 与 go vet 通过。

影响面(组织规则第 10 条):仅 Manager(HM) —— 涉密钥/安全/审计。
不影响 Client / Swarm / AM 契约 / CodeGW / 计费 / 发布链路。

Refs #4

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:26:47 +08:00
zsbgnw12andGitHub 6d360454dd fix(relay): return errors instead of panic for Claude conversion stubs
Replace unimplemented ConvertClaudeRequest panic stubs with explicit not implemented errors across 11 relay adaptors.

Reviewed: narrow relay hardening only; no billing/secrets/Agent-Swarm/product semantic changes.
2026-06-07 19:59:21 +08:00
chenchenandClaude Opus 4.8 f4968b8072 fix(agent): review fixes — deployable-template gating, stopped-status guard, UI consistency
Backend:
- loadAgentTemplate now requires status='active' — a known template_key can no
  longer deploy a template an admin deactivated (matches the client list).
- refreshAgentStatus no longer lets AM's eventually-consistent live status
  resurrect a user-initiated "stopped" agent.
- HeicodeStopAgent persists via field-level Updates (not a stale full-row Save),
  matching refreshAgentStatus discipline.
- Drop dead amStartResult.AccessToken field (AM's token is never used; HM mints
  its own per-agent token).

Frontend:
- deploy-agent statusLabel: add the missing pending/starting → 启动中 branch so a
  just-deployed agent isn't shown as raw English fallback.
- cockpit 最近部署: map template_id → Chinese template name (consistent with the
  deploy/status pages) instead of showing the raw key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 11:06:49 +08:00
chenchenandClaude Opus 4.8 c05b27de6a revert: drop outbound env-key logging; root cause was AM stale prod image
Token IS transmitted by HM (confirmed); the agent didn't enforce it because AM
hadn't deployed the image containing the §5 check to production. So the debug
log is unnecessary — removed. Contract §0.1 updated: token-check is "code-ready,
pending AM prod image", not a HM gap. UI access-token/direct-URL display kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 00:28:53 +08:00
chenchenandClaude Opus 4.8 05de8f50e4 feat(agent): log outbound env keys to AM; show direct URL + access token in 运行状态
- runtime: log the env KEY NAMES (never values) sent to AM on start, so we can
  confirm AGENT_ACCESS_TOKEN is actually transmitted without leaking secrets.
- web/运行状态: detail panel now shows the full direct-connect URL (copyable) and
  the per-agent access token (masked + reveal + copy) with a hint that the client
  sends it as X-Agent-Access-Token. These are what's actually needed to hand the
  agent to a client / test it — previously only the bare hostname was shown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 00:16:28 +08:00
chenchenandClaude Opus 4.8 ed46acd4d3 docs(agent): fix stale runtime comments about token injection
amStartTemplateAgent no longer claims OPENAI_API_KEY is uninjected or that
access_token is left empty for a future V2 path: the handler now mints +
injects both OPENAI_API_KEY and the per-agent AGENT_ACCESS_TOKEN (forwarded
as-is), and HM returns its own access_token to the client.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 22:29:40 +08:00
chenchenandClaude Opus 4.8 e326964362 feat(agent): per-agent client↔agent access token for per-user authorization
HM now mints a random per-agent access token at deploy, injects it into the
agent env (AGENT_ACCESS_TOKEN + HEICODE_AGENT_ID) and returns it to the
deploying client (agent list access_token). Only the owning user receives it,
so only they can drive the agent — closing the gap where any valid sk- could
drive any agent and exfiltrate its mounted resources.

AM authorizes the caller either locally (compare to its env token) or via the
new public POST /api/heicode/agent-access/verify {agent_id, access_token} ->
{valid, user_id} (constant-time compare, no info leak on miss). AM may opt out.

Docs: AM contract §3.1 + client API §6 updated; access_token no longer empty.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 21:58:10 +08:00
chenchenandClaude Opus 4.8 3a2ad36e5d fix(web): show unsupported resources (vm) disabled; Overview uses new-model framing
1) Deploy Sub Agent: stop hiding resource types AM doesn't support yet (vm) —
   show them but disabled with a "暂不支持" badge + tooltip, so users see their
   bindings instead of wondering where the vm went.
2) Overview (概述/cockpit): replaced the old task-model status cards
   (Running/Completed/Failed/裁决 + "code delivery runs") with template-agent
   semantics — Agent 总数 / 运行中 / 启动中 / 异常, "最近部署 · 我的 Agent",
   all Chinese. Dropped unused t()/useTranslation/PlayCircle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:59:12 +08:00
chenchenandClaude Opus 4.8 c4316f7fcd feat(web): new "运行状态" page (new-model agent status, not old task fields)
Re-add a run-status menu (I shouldn't have removed it) but showing ONLY what the
template-agent model actually has — no old 待确认/sub_agile/子任务流/智能体任务图/
产物/SK快照/合并时间线. New /agent-status page:
- summary counts (total / running / starting / other)
- agent list (template Chinese name, live status badge, subdomain, #resources)
- detail panel: live status (polls /agents/{id}/status from AM), copyable
  subdomain, mounted resources (names from /api/resources), runtime_id, timestamps.
Sidebar item "运行状态" + zh key added; build + tsc clean; route registered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:46:22 +08:00
chenchenandClaude Opus 4.8 d19920d1d0 fix(web): remove old "运行总览" task UI; Overview shows new template agents
The old /deployments (运行总览) + /tasks/$id pages rendered the new template agents
with meaningless old sub-task fields (待确认/sub_agile/子任务流/智能体任务图/产物/
SK快照/合并时间线 — all empty). Removed the whole old-model UI cluster and pointed
the Overview dashboard at the real new endpoint:

- deleted features/agent-console, features/agent-hub, features/tasks and the
  routes /deployments and /tasks/$id.
- cockpit (Overview) now lists deployed template agents from /api/heicode/agents
  (status counts + recent agents), not the old listAgentDeployments.
- removed the "运行总览" sidebar item + dead /deployments links in footer /
  top-nav / sidebar-config.
- routeTree regenerated; frontend build + tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:32:03 +08:00
chenchenandClaude Opus 4.8 436b079c16 feat(agent): inject OPENAI_API_KEY (minted sk-) so the agent can call HM /v1
Deploy now also passes OPENAI_API_KEY (the 3rd of OPENAI_BASE_URL/MODEL_NAME/
OPENAI_API_KEY AM expects). HM mints a hidden, unlimited-quota sk- token for the
user per agent ("sk-"+key, billed to the user), injects it as OPENAI_API_KEY, and
stores the token id on the deployment. The token is revoked on delete and rolled
back if AM start / persist fails (no leaked keys). gateway accepts Bearer
sk-<key> (middleware strips sk-).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:44:17 +08:00
chenchenandClaude Opus 4.8 1d81002c2d fix(agent): default MODEL_NAME=gpt-5.4 for started agents (not template tier)
Preset templates carry a Claude-style frontmatter model (opus/sonnet) which is
NOT a model on the HM gateway. Passing it as MODEL_NAME would make the agent's
model calls fail. Now MODEL_NAME defaults to the gateway model gpt-5.4
(env AGENT_RUNTIME_DEFAULT_MODEL); a non-Claude-tier template model is honored.
Tests + AM contract doc updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:25:21 +08:00
chenchenandClaude Opus 4.8 b33bcf90bd feat(device): desktop client self-logout endpoint
POST /api/devices/logout (UserOrV2DeviceAuth): a device-signed client revokes its
OWN bound token via the signed X-Heicode-Device-Id (cannot touch other devices);
a session/JWT caller may pass {device_id}. Idempotent. The existing DELETE
/api/devices/:id revoke is session-only, so device clients had no self-logout —
this closes that gap. Documented in the client API doc §1.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:15:47 +08:00
chenchenandClaude Opus 4.8 557fb2b829 test(agent): fix status round-trip path assertion to /agents/{id}
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:48:09 +08:00
chenchenandClaude Opus 4.8 f1637c3ecd fix(agent): resilient delete — always remove local record even if AM delete fails
Real test showed AM's DELETE /agents/{id} currently 500s (AM bug), which left the
HM record permanently undeletable. HeicodeDeleteAgent now treats the AM delete as
best-effort: on AM failure it logs + still removes the local record and returns
runtime_cleanup:"failed" so the user can always clear their list. (Stop stays
strict — AM has no /stop endpoint yet, pending their confirmation.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:47:23 +08:00
chenchenandClaude Opus 4.8 27459bb476 fix(agent): align AM lifecycle paths to /agents/{id} (real-test: create works)
Real production test (user account) confirmed HM->AM POST /agents creates a real
agent (returned subdomain + status). But stop/delete still used the old
/api/agent/agents/{id} defaults and 404'd. Aligned status/stop/delete defaults to
the same namespace as create: /agents/{id}, /agents/{id}/stop. AM contract doc
notes these are HM's best guess pending AM's confirmation of the real lifecycle
endpoints (their doc only specified create).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:41:34 +08:00
chenchenandClaude Opus 4.8 074a3cc7e7 feat(agent): align HM to AM's coding_a2a_agent contract
Adapt HM's template-agent integration to AM's actual CODING_A2A API (per their
doc), keeping it isolated in agent_template_runtime.go:

- start payload -> AM's POST /agents { name, template:"coding_a2a_agent",
  framework:"A2A", config:{user_id,...}, env } with the template .md folded into
  env.AGENT_INSTRUCTION_TEXT, template_key -> AGENT_ROLE_NAME, model gateway via
  OPENAI_BASE_URL + MODEL_NAME (OPENAI_API_KEY left to the client per A2A request).
- response parse -> access_info.domain/external_ip -> subdomain, namespace/name
  -> runtime_id; AM issues no access_token (client uses A2A api_key).
- env names aligned to AM: GIT_DEFAULT_BRANCH, POSTGRES_* (was PG_*),
  AZURE_BLOB_ACCOUNT_NAME/CONTAINER/ACCOUNT_KEY (was BLOB_*); source keys aligned
  to the resource-binding form (db_name/username/database_password/access_key).
  Only AM-supported types (git/mysql/postgres/azure-blob); vm/redis/mongo/bucket
  now rejected as unsupported until AM adds them.
- frontend: resources page splits DB into MySQL/PostgreSQL (correct provider),
  drops vm; deploy page hides unsupported resource types.
- docs: AM contract + client doc updated to the real env names, payload, and the
  A2A direct-connect (message/send · message/stream) + api_key auth.
- tests updated for the new env names + AM payload/response shape. All green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:30:33 +08:00
chenchenandClaude Opus 4.8 ac32a2db51 fix(agent): encrypt agent access_token at rest (AES-256-GCM via CryptoSecret)
Closes the last review finding: the AM-issued access_token was stored in plaintext
in agent_deployments. Now sealed with common.SealWithCryptoSecret on write and
unsealed on read — the client still receives the plaintext token (no contract
change), but a DB dump no longer exposes live agent tokens. Legacy/plaintext
values and an unset CryptoSecret degrade gracefully (pass-through). Round-trip test added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 14:35:15 +08:00
chenchenandClaude Opus 4.8 7a48155568 fix(agent): apply review findings (backend data-integrity + frontend error UX)
Two review agents (backend + frontend) audited the template-agent feature. Real
findings fixed (verified the one false-positive — okOrThrow already reads the
top-level success because the response interceptor returns response, not
response.data):

Backend:
- buildAgentEnvFromBindings now filters status='active' so a revoked/disabled
  binding can't still have its KV secret resolved + injected.
- same-type binding env collision (e.g. two git repos -> GIT_REPO_URL) now errors
  instead of silently overwriting.
- refreshAgentStatus uses a field-level Updates (status/updated_at) instead of
  Save(full row) to avoid clobbering a concurrent stop/delete.
- tests added: same-type collision rejected, inactive binding rejected.

Frontend:
- deploy/stop/delete now pass noBusinessError so the global interceptor stops
  double-toasting the raw English backend message; okOrThrow+onError give one
  friendly Chinese error. Extracted okOrThrow/noBusinessError into lib/api.ts.
- resources page revoke + create + KV-secret-write now check success (okOrThrow)
  so a failed unbind / credential write no longer falsely reports success.
- clipboard copy wrapped in try/catch (no false "copied" on failure).
- resources group label shows Chinese resource-type names.

Go + frontend builds/tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 14:24:25 +08:00
chenchenandClaude Opus 4.8 16cca5df1c fix(agent): review fixes — success-check, template name, seed Once, update guard
Full review of the template-agent code surfaced and fixed:
- [frontend, critical] deploy/stop/delete treated HTTP-200-with-success:false as
  success (backend agentError returns 200 per new-api convention) -> a failed
  call wrongly toasted success. Added okOrThrow() that inspects the envelope and
  throws the server (or a friendly Chinese) message so onError fires.
- [frontend] "我的 Agent" showed the raw template key (architect) instead of the
  Chinese name; now resolves name via the templates list.
- [backend] ensureAgentTemplatesSeeded consumed sync.Once even when model.DB was
  nil (would permanently skip seeding) -> DB check moved outside the Once.
- [backend] AdminUpdateAgentTemplate could wipe name_zh/definition with empty
  values -> guard those critical fields.
- [security] warn when starting an agent with secret-bearing env over a non-HTTPS
  AM URL (secrets must not transit the network in clear).

Go + frontend build/tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:59:03 +08:00
chenchenandClaude Opus 4.8 8823bf5e5d feat(web): add "部署 Sub Agent" menu + page (pick resources + template -> deploy)
Customer-facing, plain Chinese (no env/technical jargon). New sidebar item
"部署 Sub Agent" -> /deploy-agent. The page:
- Step 1: pick which bound resources the agent may use (multi-select cards from
  /api/resources).
- Step 2: pick an agent template (cards show Chinese name + description from
  /api/heicode/agent-templates).
- Deploy -> POST /api/heicode/agents {template_id, binding_ids}.
- "我的 Agent" list (/api/heicode/agents) with status, copy-address, stop, delete.

Frontend builds clean (tsc + rsbuild; routeTree regenerated). zh label added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:25:12 +08:00
chenchenandClaude Opus 4.8 4605cf4f62 feat(agent): HM-maintained agent template library (md), sent to AM on deploy
Templates now live in HM (not AM). A template is a Claude-Code style subagent
.md definition; HM passes it to AM at deploy time.

- model AgentTemplate (agent_templates): template_key, name_zh / description_zh
  (Chinese display for the console), model, definition (full .md), source, status.
- 19 presets from oh-my-claudecode (MIT, NOTICE.md attribution) embedded via
  go:embed and idempotently seeded; Chinese name+desc mapping in code.
- GET /api/heicode/agent-templates now reads HM's library (Chinese name/desc),
  not AM. Admin CRUD at /api/agent-templates (AdminAuth).
- deploy loads the chosen template and sends {template_key, agent_definition (md),
  model, env, callback_url} to AM via a generic /api/agent/agents/start; removed
  the AM-template-listing path. AM adapter still isolated (amStartArgs).
- tests: frontmatter parse, seed (19 + 架构顾问), start round-trip asserts
  agent_definition in payload. All green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:05:08 +08:00
chenchenandClaude Opus 4.8 692506c9fc chore(agent): remove dead artifact-revision & cloud-deployment models (phase B)
After phase A removed the old client task layer, AgentArtifactRevision and
AgentCloudDeployment became unreferenced (their only consumers — the deleted
heicode_task_create/project_artifacts/artifact_edits/cloud_deploy — are gone).
Removed the structs + their AutoMigrate entries. Existing tables are left in
place (harmless, no model) and can be dropped later if desired.

Option B teardown: kept the shared platform backend still used by the web
console / runtime callbacks (admin /api/agent/*, approvals, leases, callbacks,
AgentArtifact, sk-snapshots, withDisplayStatus). Build + controller/model/router
tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 23:36:43 +08:00
chenchenandClaude Opus 4.8 3863296f85 chore(agent): remove old client sub-task API (phase A of legacy teardown)
The template-agent model replaces the old sub/swarm task orchestration. Removed
the entire client-facing task surface:
- routes: registerHeicodeTaskRoutes (all /heicode/{sub-agile,swarm}/tasks/*) and
  GET /heicode/deployment-targets.
- controllers deleted: heicode_task_create, heicode_client_routes,
  heicode_project_artifacts, heicode_artifact_edits, heicode_cloud_deploy
  (+ the agent_deliverable_secret_test that covered the deleted markdown-project
  parsing).

Build + controller/router/model tests green. Shared backend (AgentDeployment,
agent_runtime_client helpers, admin /api/agent/*) intentionally kept — trimmed in
the next phase.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 23:29:22 +08:00
chenchenandClaude Opus 4.8 19fd4f3326 refactor(agent): built-in per-type env mapping; fix start timeout, orphan, guards
Replace the user-facing env_map mistake with a built-in env convention keyed by
resource type + provider — users never see/edit env names; they only fill plain
resource fields. Supports git (gitea/github/gitlab), vm, database
(mysql/pg/redis/mongo, with alias normalisation), storage (azure blob / bucket).
Lenient: missing optional fields are skipped; only unsupported type or a KV read
failure errors.

Other issues found in review and fixed:
- start timeout: template-agent start now uses a longer timeout (default 60s,
  AGENT_RUNTIME_START_TIMEOUT_SECONDS) since AM provisions synchronously — 5s
  would time out. amTemplateDo takes a per-call timeout.
- orphan agent: if AM start succeeds but the Manager record fails to persist, the
  orphan is rolled back (best-effort amDeleteTemplateAgent).
- findUserTemplateAgent now guards template_id<>'' so the new endpoints can't
  touch a legacy task deployment.
- binding_ids defaults to [] (not null).
- removed ResourceBinding.EnvMap field entirely.

Tests rewritten for the built-in convention (blob metadata-only, db provider
prefixes incl pg/mg aliases, git provider-agnostic names, ownership, unsupported
type, empty); adapter round-trip + router tests still pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 22:48:29 +08:00
chenchenandClaude Opus 4.8 65a71f6b35 feat(agent): pull live template-agent status from AM (no callback needed)
- amGetAgentStatus: HM pulls a running agent's status from AM on demand
  (is it alive / crashed), isolated in the AM adapter like the rest.
- GET /api/heicode/agents/:id/status + status refresh on GET /:id detail,
  best-effort (keeps last-known status if AM is unreachable; never blocks read).
- tests: httptest-backed round-trip tests for amStartTemplateAgent and
  amGetAgentStatus against a fake AM (validates the full request/parse path);
  router registration still clean. All pass.

Note: no required-resource validation added — HM injects whatever bindings the
user selected into the agent .env (per env_map); AM reads what it needs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 22:04:00 +08:00
chenchenandClaude Opus 4.8 cdbc43baeb feat(agent): template-agent deploy/list/stop API (AM contract isolated)
HM-side logic for the template-agent model, written against a proposed AM
contract that is fully isolated in agent_template_runtime.go — when AM ships its
real API, only the default paths + response field names in that one file change.

- agent_template_runtime.go: AM adapter (list templates, start template agent
  with env, stop/delete) reusing the existing runtime config/url/envelope helpers.
- agent_template_handlers.go: GET /api/heicode/agent-templates; POST /api/heicode/
  agents (resolve bindings -> env, start via AM, persist subdomain+token);
  GET /agents, GET/:id, POST/:id/stop, DELETE/:id. Owner-scoped; env never logged.
- reuses AgentDeployment as the agent record (TemplateID/Subdomain/AccessToken/
  BindingIDsJSON) and buildAgentEnvFromBindings for env assembly.
- routes wired under /api/heicode (UserOrV2DeviceAuth), verified no registration
  panic (router tests pass).
- agent_template_test.go: 7 independent unit tests (env assembly metadata-only,
  ownership, secret-without-ref, unknown-source, empty; path substitution;
  response mapping) — all pass without AM/KV.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 21:55:24 +08:00
chenchenandClaude Opus 4.8 8ecab2c270 feat(controller): env assembly from resource bindings for template agents
buildAgentEnvFromBindings resolves selected resource bindings into a flat env map
for a template agent's .env at start: non-secret values from Metadata, secret
values resolved from Key Vault (getJSONSecret) only here, lazily, never persisted.
AM-independent foundation for the deploy-agent flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 21:43:34 +08:00
chenchenandClaude Opus 4.8 efdc360499 feat(model): add template-agent fields (reuse AgentDeployment + ResourceBinding.EnvMap)
Additive, AutoMigrate-friendly (new columns only, cross-DB safe). Foundation for
the template-agent + direct-connect model:
- AgentDeployment: TemplateID, Subdomain, AccessToken, BindingIDsJSON — reuse the
  existing deployment record as the deployed-agent record instead of a new table.
- ResourceBinding.EnvMap: declares which env vars a binding exposes to a template
  agent at start (non-secret from Metadata; secret resolved from KV only at start).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 21:41:19 +08:00
chenchenandClaude Opus 4.8 0eb754b1e1 refactor(web): Overview usage reuses WalletStatsCard (same as 模型与余额)
The wallet page already renders Current Balance / Total Usage / API Requests
from /api/user/self. Reuse that exact component (WalletStatsCard) on the
Overview instead of a hand-written block — DRY, identical numbers
($160.47 / $39.53 / 521 for the current user).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 11:08:45 +08:00
chenchenandClaude Opus 4.8 42883dac63 fix(web): Overview usage shows the CURRENT user own consumption, not global
The reused LogStatCards aggregates ALL users for admin accounts, so an admin
(root) saw gateway-wide totals (e.g. $628 / 339M tokens / 5218 req) instead of
their own. And per-user windowed quota-dates were empty (0). Replaced with the
user's own lifetime usage from /api/user/self (used_quota = spend, quota =
remaining, request_count), formatted with formatQuota. Real, non-zero, per-user.
(LogStatCards also gained an optional userScope prop for future per-user use.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 11:04:54 +08:00
chenchenandClaude Opus 4.8 448571496d feat(web): add usage & cost (user consumption) to the Overview dashboard
Reuse the existing LogStatCards (requests / quota=cost / tokens=consumption,
all props optional) on the Overview cockpit — no new data/logic, just renders
the current user usage stats under a "Usage & cost" section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 10:40:29 +08:00
chenchenandClaude Opus 4.8 8710de7c20 feat(web): resource binding page in the Manager console (5 types)
Re-adds Resource binding to the Heicode cockpit (/resources). Add bindings for
GitHub / Gitea (type=git + provider), VM (ssh), database, blob; non-secret
fields go to metadata, the credential is written to Azure Key Vault via
POST /api/resources/:id/secret and only the secret_ref is shown (masked).
List + unbind. Backend already supported this; now functional since KV is up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:39:28 +08:00
chenchenandClaude Opus 4.8 ae251cf70e feat(resource): add vm/database/blob binding types; KV now provisioned
Resource binding backend (CRUD + secret-to-KV) is now fully functional after
provisioning the Key Vault. Added vm/database/blob to allowedResourceTypes for
the desktop binding set (gitea/github use type=git + provider). git binding +
KV secret write verified end-to-end (secret lands in heicode-kv).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:31:47 +08:00
chenchenandClaude Opus 4.8 8329a323b0 refactor(web): Overview is now a dashboard, drop the idea-capture hero
Per direction: 概述 should be a 看板, not a "turn an idea into shippable
software" marketing surface.
- Removed the idea-hero (home-hero.tsx: IdeaInput + mcp-fed ContinueTasks/
  TodayFocus/HelperEntries, which were often empty/unreachable).
- Overview now renders the live metrics dashboard (CockpitView, previously
  dead code): Running / Completed / Failed / Pending counts by display_status
  + recent runs, fed by the working listAgentDeployments.
- Dropped the marketing "Quick actions / Control plane online" tier.
- Subtitle: "From an idea to shippable software." -> "Live overview of your
  Agent runs." Added zh translations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:22:44 +08:00
chenchenandClaude Opus 4.8 5d7854d9ac fix(heicode): mode-filter task lists, hard-delete, mode-aware Agent runs page
- /api/heicode/sub-agile/tasks now returns only sub_agile, /swarm only swarm
  (both previously returned every deployment regardless of mode).
- DELETE /tasks/{id} now hard-deletes the record (best-effort runtime stop +
  remove row + in-memory entry) so a deleted task disappears from the list,
  instead of only marking it stopped.
- Admin runs page: renamed Task overview -> Agent runs, cards show the mode
  (Sub Agile / Swarm) chip, added a mode filter; status already uses
  display_status.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 21:11:39 +08:00
chenchenandClaude Opus 4.8 8b28c180c7 refactor(web): remove legacy/non-functional admin console pages, align to current product
The Manager console carried screens built to an early control-plane vision
that no longer matches how the product runs (desktop client drives tasks;
Manager is gateway + status judge). Removed the dead/misleading ones and
aligned task overview to the real status model. Frontend only; no backend
endpoints touched.

Deleted (routes + pages + menu entries):
- Resource binding (/sk-sources): mcp-server /api/resources unwired (301) +
  Azure Key Vault unreachable -> page was inert.
- Audit (/audit): only simulated approvals, empty leases, mcp audit unwired.
- Events / Templates / Agents pages: legacy control-plane (hardcoded mock
  templates), not in the main menu but route-reachable.
- azure-cloud-binding-sheet + create-agent-deployment-sheet (New run).

Task overview (/deployments) kept and fixed:
- status now uses Manager-judged display_status (completed / needs_codegen /
  completed_without_deliverable=fail / running ...) instead of raw phase, so
  success vs failure is legible.
- dropped New run, scope/budget/secret_ref pills, permission-manifest grants
  table, Simulate; kept the task list, per-task audit timeline and artifacts.

Cleaned all menu/nav/dashboard references to the deleted routes (sidebar,
top-nav, footer, cockpit, home-hero, agent-hub, task-card-view) and
regenerated routeTree.gen.ts. tsc -b and rsbuild build both pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 19:39:49 +08:00
chenchenandClaude Opus 4.8 6fd294635f fix(swarm): align Manager swarm-runtime default routes to HeiCode-Swarm standard
Per the HeiCode-Swarm 蜂群对接文档 §3.1, the swarm runtime standard routes are
/api/agent/swarm/* (legacy /api/swarms/* still works but is no longer default).
Swarm-only change; sub-agile (AGENT_RUNTIME_*) defaults and the agent_management
wiring are untouched.

- SWARM_RUNTIME default create/stop/approval -> /api/agent/swarm/deployments[...]
- swarm status: the runtime has no /status subpath, so status is read from the
  deployment detail endpoint GET /api/agent/swarm/deployments/{deployment_id};
  StatusPath/ArtifactContentPath defaults made mode-aware (sub keeps legacy).
- update the swarm HTTP smoke test to assert the standard runtime paths.

Verified reachable: HeiCode-Swarm at 52.139.240.116:8000 returns the standard
POST /api/agent/swarm/deployments (401 needs token, endpoint exists).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:45:00 +08:00
chenchenandClaude Opus 4.8 65ce549fb2 fix(heicode): sub-mode workflow/list gaps from desktop client (A/B/D/F)
Address the desktop client sub-mode gap report:
- B: /tasks list items now carry Manager-judged display_status (were raw
  status, so completed could really be needs_codegen).
- D: list + detail expose top-level mode (sub_agile|swarm) derived from the
  runtime mode, so a task recovered from /list after restart routes to the
  right mode instead of defaulting to sub-agile.
- F: unify mode naming on sub_agile everywhere (capabilities/list/detail/
  workflow); workflow keeps sub_mode for the agile/waterfall cadence.
- A: /workflow gains phases[], per-agent tokens/tools/elapsed_seconds/
  artifact_ids, and top-level metrics + aggregates, filled from runtime
  status diagnostics. Per-agent tokens/tools, artifact source role and phase
  breakdown surface as 0/[] until agent_management reports them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 16:20:38 +08:00
chenchenandClaude Opus 4.8 856c184421 fix(heicode): order accepted-revision lookup by real column created_at_ms
LatestAcceptedRevisionForDeployment ordered by a non-existent column
(created_at), so the query errored and /messages and /execute never picked
up the latest accepted local-edit revision. Found via live VM smoke test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:57:27 +08:00
chenchenandClaude Opus 4.8 2613c5763c fix(heicode): close client gap-analysis P0/P1 items for unified API
Address the desktop client team gap analysis on the unified /api/heicode/*
surface:

- P0-1 GET device auth: no-body V2 signed-GET path (fetch forbids GET body),
  same Ed25519 canonical with empty-body hash; UserOrV2DeviceAuth +
  OptionalV2DeviceAuth dispatch on signature headers. Unit test added.
- P0-2 approval inbox: GET .../tasks/{id}/approvals?status=pending.
- P0-3 project_folder: artifacts list normalizes the primary code deliverable
  to display_artifact_type=project_folder + is_project + manifest/files/
  archive/revisions subpaths.
- P0-4 archive contract: real application/zip + Content-Disposition +
  Content-Length; ARTIFACT_ARCHIVE_NOT_READY (retryable) when no files yet.
- P1-1 file path: GET .../files?path=<url-encoded> (no segment ambiguity).
- P1-2/P1-3 revision: local edits stored as accepted baseline; /messages and
  /execute consume the latest accepted revision (-> applied), return
  active_project_revision.
- P1-4 doc: Swarm same-shape routes stated explicitly.

Doc updated to match. Build + middleware/controller tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:48:03 +08:00
chenchenandClaude Opus 4.8 0f1d3d2009 feat(agent): three-layer status on workflow, error retryable, V2/envelope doc alignment
按桌面客户端 spec 重审后补齐:
- workflow 端点补三层状态(cloud_deployment_status/runtime_execution_status/display_status/
  conversation_id/last_synced_at,§10.2),作为客户端右侧面板状态源。
- agentError 补 error.retryable(§14)。
- 文档:明确 V2 body 加密与模型调用一致(directive)、真实响应 envelope、轮询刷新(无 SSE,
  按 §17.3 兜底)、需求包创建 + messages/execute/delete。

V2 加密链核验:新 /api/heicode/* 全走 UserOrV2DeviceAuth(同模型调用),
heicode-aead-v1/ChaCha20/Ed25519 常量未被改名误伤,中间件测试通过——加密未丢失。

go build ./... + go test 全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 03:37:05 +08:00
chenchenandClaude Opus 4.8 7f3806c510 feat(agent): client requirement-package create + messages/execute/delete (spec §5.1/§8)
补齐桌面客户端对接缺口:之前 POST /tasks 只收 orchestration_plan、且缺 messages/execute/delete,
客户端无法照 spec §8 需求包直接对接。本次:

- POST /api/heicode/{sub-agile,swarm}/tasks 改收需求包 {mode,conversation_id,requirement,model_selection,roles},
  Manager 翻译成 orchestration_plan(per_role/default/primary 模型),仍兼容直传 orchestration_plan。
- POST .../tasks/{id}/messages:持续对话,记录用户消息 + 回当前 display_status。
- POST .../tasks/{id}/execute:确保派发 Runtime + reconcile。
- DELETE .../tasks/{id}:停止任务。
- 重构 createAgentDeploymentFromPlan,供原始 plan 与需求包两条路径复用。
- 更新 docs/integration/heicode-desktop-unified-api.md(创建改需求包 + 新路由)。

go build ./... + go test(controller/router)全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 03:26:57 +08:00
chenchenandClaude Opus 4.8 56eef58b3c feat(agent): project-folder artifacts, local-edit revisions, cloud-deploy control plane
完成统一方案 v0.1 剩余客户端要求(#10/#11/#12)+ 对接文档。

- #10 项目文件夹产物(§12):Manager 解析 runtime 的 markdown 多文件 artifact 成项目文件树,
  新增 .../artifacts/{id}/manifest、/files/{path}、/archive 三接口(按需解析,zip 打包)。
- #11 本地修改 revision 协议(§12.7):新模型 AgentArtifactRevision + 迁移;
  .../local-edits、/local-edits/batch、/revisions;base_revision 冲突检测返回
  ARTIFACT_REVISION_CONFLICT;Manager 持有 accepted 基线,回调 Runtime(审计事件)。
- #12 云部署控制面(§18):新模型 AgentCloudDeployment + 迁移;
  GET /api/heicode/deployment-targets;.../tasks/{id}/deployments(创建/列表);
  生产环境进 waiting_approval;客户端只传 resource_binding_id(禁 inline secret);
  真实云执行留 executor=pending_worker,等 Deploy Worker 接入。
- 文档:新增 docs/integration/heicode-desktop-unified-api.md(取代旧 sub-agile 文档,
  覆盖 capabilities/统一任务路由/display_status/项目文件夹/本地修改/云部署/客户端约束/错误码)。

验证:go build ./... + go test(controller/router/model/middleware)全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:23:02 +08:00
chenchenandClaude Opus 4.8 443f552917 fix(agent): reconcile deployment from runtime status on read
真实生产模拟暴露:runtime 完成极快时,artifact.created/status callback 会与
runtime_swarm_id 映射的异步持久化竞态——callback 先到、按 swarm_id 匹配不到
deployment 而成孤儿,导致 deployment 永远停在 accepted、/artifacts 为空,
尽管 runtime 已 completed 且可直查到。

修复:detail / timeline / workflow / artifacts 读取时,对非终态且有 runtime
映射的 deployment 调 reconcileDeploymentFromRuntime——复用 diagnostics 的
runtime 状态直查,把终态 + 真实 artifact 反写落库,不再单依赖会丢/会竞态的 callback。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:05:43 +08:00
chenchenandClaude Opus 4.8 0fe1d20d67 feat(agent): unify agnet→agent and implement client/runtime unification spec v0.1 core
按桌面客户端统一方案 v0.1 + agent_management Sub Mode Runtime 对接,强制全量统一,不留兼容。

命名统一(强制,无兼容):
- 全仓 agnet/Agnet/AGNET → agent/Agent/AGENT:后端 Go(路由 /api/agent/*、env AGENT_*、
  结构体/函数、19 个文件改名)、前端(agent-console/agent-hub、/api/agent 调用、i18n)、
  DB(表 agent_*、列 agent_id)、compose/.env、文档、脚本。
- DB 加幂等迁移 renameAgnetTablesToAgent():启动时 rename 老 agnet_* 表/列,保住生产数据。

统一方案核心(10 项):
- callback 统一 /api/agent/callbacks/runtime-events(路由/广播URL/函数名)。
- artifact 兜底判定改用 Runtime 权威信号 metadata.synthesized(§7.2)+ 结构化 artifact_type。
- Manager→Runtime 路径对齐 /api/agent/sub-agile/deployments(§2.2),{deployment_id} 回退 swarm_id。
- 状态裁决 display_status:Manager 唯一裁判,completed 无有效产物→needs_codegen/
  completed_without_deliverable(§10.6),接入 detail/timeline/workflow。
- GET /api/heicode/capabilities 能力发现(§6)。
- 模型策略 per_role(role_models)+ 收集 allowed_model_ids(§9)。
- resource_binding_id→secret_ref 服务端解析,客户端不再 inline secret_ref(§17.6)。
- 客户端统一路由层 /api/heicode/sub-agile|swarm/*(task≡deployment,复用控制面)+ workflow 投影。
- 日志分层 user_logs/debug_logs(§13)。

验证:go build ./... + go test(controller/router/model/middleware)全绿;前端 tsc -b + rsbuild build 通过。
待部署:VM .env 的 AGNET_*→AGENT_*;启动迁移自动 rename 表;其他三仓库需同步切到 /api/agent。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 23:45:10 +08:00
chenchenandClaude Opus 4.8 12602ebcd6 fix(agnet): structured deliverable judgment, secret_ref validation, single default model
代码评审(2026-06-01 全链路报告)中 Manager 侧自主可修项:

- P2 交付物判定: runtimeArtifactsAreSummaryOnly 改为优先读结构化字段
  (artifact_type + files_modified 信号),修复 Runtime 新 uri scheme 与
  artifact_type=document 被旧 /artifacts/summary 字符串启发式漏判的回归。
- P6a: Resource CRUD(normalizeResourcePayload)强制 secret_ref 必须 azkv://,
  与 agnet 部署/审批路径一致,堵住直写任意 secret_ref 的旁路。
- P6b: 明文密钥检测从仅按字段名升级为同时扫字符串值(sk-/ghp_/AKIA/JWT/PEM
  等高置信模式),containsPlaintextSecret 与 containsSensitiveGrantField 均覆盖。
- P5 默认模型收敛: 新增单一来源 defaultAgnetModelID()(env AGNET_DEFAULT_MODEL_ID,
  默认生产已验证的 gpt-5.4);移除 draft 构造器两处 agnet-model-<role> 占位回退
  (生产 NewAPI "No available channel" 根因)与角色模板硬编码 claude-* 默认。
- P3 文档: 对接文档状态枚举补 completed 终态、runtime_state 镜像说明与未知值兜底;
  role-templates 示例占位名改为 gpt-5.4。

新增 controller/agnet_deliverable_secret_test.go 覆盖以上行为。
go build ./... 与 go test ./controller/ 全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 17:33:32 +08:00
gongzhiyong 8e56284baa fix: polish manager account pages 2026-05-30 15:37:28 +08:00