Commit Graph
27 Commits
Author SHA1 Message Date
Sycun e8a5392b37 fix: serialize installation updates and recover interrupted adoption and rollback 2026-10-09 10:58:12 +08:00
Sycun 54d8f1187d fix: preserve rollback binaries during ambiguous recovery and YAML settings 2026-10-09 10:27:17 +08:00
Sycun 36e1d9680b fix: a version write keeps the document it lands in and the mode it had
Inserting `version` above a leading `---` put it in a document of its own, so
every setting after the marker parsed as a second document and was silently
ignored: the installation came up on defaults with a config that looked intact.
Both writers - the Go one and upgrade.sh's - now insert after the document
start, and the parse-back check still refuses anything a line rewrite cannot do
safely.

upgrade.sh rewrote config.yaml through a temp file created with the process
umask, so a 0600 config came back 0644 on every package upgrade - the file
holding the API keys became group/world readable. It now creates the temp file
privately and restores the original mode before the atomic replace.

A package upgrade also deleted `.update-build-pending`, because rsync --delete
only keeps what the exclude list names: the installation forgot a compile it
still owed and the next click reported "already up to date". Every one-click
update artifact is on the keep list now, asserted against .gitignore so the
next one cannot be forgotten the same way.
2026-10-08 22:46:29 +08:00
Sycun 9a68a17cec fix: the password-reset entry builds the cmd/server package, not one file
`./run.sh --reset-admin-password` rebuilds the binary whenever it is missing or
older than the sources, through build_go_project_quiet - the one build path left
that compiled the single file `cmd/server/main.go`. A file-based go build only
compiles the file it names, so it dropped every sibling of package main that
this PR added; measured on the parent commit:

    cmd/server/main.go:35:22: undefined: updateCommandIfNeeded

(the symbol lives in cmd/server/update_cli.go), which made the documented
password-reset entry exactly the path that could not build itself. The normal
start path and upgrade.sh already build `./cmd/server`; the quiet path now does
too, and a test scans run.sh, upgrade.sh and scripts/*.sh so a file-based
go build cannot come back unnoticed - it fails on the pre-fix tree with the
command named.
2026-10-08 16:16:14 +08:00
Sycun 9c6928074d fix: a rollback keeps the operator's edits, and a retry really compiles
The review found two failure paths that reported success for work the engine had
not done.

Rollback: it refused only when *non-protected* source files were modified, and
then ran `git reset --hard` to the previous commit - which discards every local
change to tracked files, not just the update's. Edits to roles/skills/tools (the
update itself keeps those via its own stash) and edits made after the update
were silently wiped, while Result said nothing: deployment.md's promise that
"work done afterwards is not swept away" did not hold. Rollback now copies every
protected file that differs right now into `.update-backup/rollback_<ts>/`
before the reset, sets the copies back after it, re-applies hand deletions, and
names what it kept in Result.KeptContent like an update does.

Retry: Apply merges and writes the state file before it builds, so a failed (or
toolchain-less) build leaves HEAD on the new commit with the old binary still in
place. The retry then took the `!snap.UpdateAvailable` no-op branch, aligned the
version and returned err=nil - the job was recorded as succeeded, the page said
"update finished", the CLI printed that source and binary were in place, and the
old executable kept running. The tree now carries a `.update-build-pending`
marker, written the moment the merge lands (and when an adoption commits to its
work tree) and cleared only after the new binary is in place. The no-op branch
reads it: with a toolchain it compiles and reports the build (commits=0,
binaryBuilt=true); without one it keeps refusing exactly like the first attempt,
so "install go and click again" is now a real instruction. The console stops
treating "nothing to pull" as "nothing to do" (the retry button stays live, the
confirm dialog and the done toast say the build is what will happen), and the
CLI's printResult no longer swallows the build-only result.

Both paths are covered by regression tests that fail on the pre-fix tree: two
rollback scenarios driven through real git (edit before and after the update, a
hand deletion), and four retry scenarios driven through a scripted go on PATH
(failed build, state-write failure, an adoption's failed build retried by the
next update, and no toolchain then toolchain).
2026-10-08 16:16:07 +08:00
Sycun 94a18263b9 feat: make the update source one repository address, the official repo by default
The update source used to be three things - a remote name or an address, plus an
optional branch - and unset it followed whatever this directory's remotes and
upstream happened to say. That asked people to understand git topology before
they could update, and the person it was built for could not tell what "follow
the remote this tree tracks" meant. It is now one field: config.yaml update.repo,
an address, empty meaning the official repository
(https://github.com/AIPentest/CyberStrikeAI.git). Point it at a mirror (GitHub is
hard to reach in some places) or at your own fork and that is the whole
configuration.

The branch nothing is any more: an update follows the source repository's own
default branch, resolved from the source itself (ls-remote --symref HEAD), so a
fork whose default is not "main" still works and nobody has to name a branch.
Remote names, the mine/origin/upstream ranking, @{upstream} tracking and the
adopt flow's branch argument are all gone with it.

The console page loses two input fields: the source section is one address, a
hint that empty means the official repository, and a save button; clearing the
address is the way back to the default. The install facts drop the remote name,
the check section shows the source's default branch once the network answer
arrives, and the adopt entry no longer requires saving an address first - the
official default makes connecting a tarball install a zero-configuration action.

The CLI now reads the same update.repo field the page saves (LoadUpdateRepo reads
just that field, without validating the rest of the file - a broken unrelated
section must not block the path that fixes the tree), so the keyboard and the
button cannot update from different repositories. -check-update prints the source
it is about to use.

Tests: the source suite now pins the default (official), the single-address save
(including the empty-string reset), and that the followed branch comes from the
source's own default branch rather than a hardcoded "main"; the console suite
posts the one field and renders the default hint; docs, config.example.yaml and
upgrade.sh describe the one-field story.
2026-10-08 13:46:14 +08:00
Sycun cb8bc6b824 feat: update this installation's own source in one action
An operator running a fork has no honest way to upgrade: upgrade.sh downloads the
Release tarball of one hard-coded third-party repository and rsyncs it over the
tree, so "upgrade" means "overwrite yourself with somebody else's code", and the
safe alternative is to pull by hand and remember the build command.

internal/update drives the remote the directory already tracks: fetch, fast-forward,
go build into .update-staging, atomic rename of the binary (the previous one kept as
cyberstrike-ai.prev), and a .update-state.json so a rollback has a target that is
not guessed at. Refusals are the point - local source edits and a diverged branch
stop with the file names and commit counts in the error rather than being reset to
match, and operator-owned content (roles/skills/tools/agents/data/config.yaml) is put
aside before the merge and restored over it, with what was kept listed in keptContent
instead of quietly dropped.

Consumers: GET/POST /api/system/update* behind update:read / update:apply (mutations
are process-global, so they need a global-scope session); a console page at
#system-update with an apply button that names why it is blocked, a job polled from
the server and a rollback control; the same three actions as -check-update / -update
/ -update-rollback on the binary; OpenAPI entries for all five endpoints. Permission
gating no longer re-enables a control a page disabled for a reason of its own
(data-state-disabled), which every state-disabled, permission-gated button in the
console was subject to. upgrade.sh becomes a thin shell over the same implementation
and only falls back to the tarball path for installs that are not git work trees.

Docs and the zh/EN/RU dictionaries are updated. The package runs 13 tests against
real temporary git repositories; the HTTP layer, RBAC and the console page each
carry their own contract tests.
2026-10-07 12:07:26 +08:00
Ed1s0nZ f7882be546 feat: manage task process lifetimes and preserve turn history 2026-09-16 17:52:58 +08:00
苏尼克andsycpro c563567502 fix: startup banner hardcodes 127.0.0.1 regardless of server.host (#307)
The Web UI startup banner always printed 127.0.0.1, even when
server.host was bound to 0.0.0.0 or a specific interface. This made
users believe the host setting was ignored (the actual listen binding
was correct). Pass the configured host into the banner and expand
wildcard binds to the machine's real addresses so LAN URLs are shown.

Fixes #301

Co-authored-by: sycpro <sycpro@sycprodeMacBook-Pro.local>
2026-09-13 15:27:38 +08:00
Ed1s0nZ 94cdf760af feat: persist diagnostic logs with daily rotation and retention 2026-09-08 14:41:46 +08:00
Ed1s0nZ 6ad9ea2d13 feat: add configurable tool call blocking and monitoring 2026-09-08 09:44:32 +08:00
公明 7b6f56e476 Add files via upload 2026-07-24 16:43:01 +08:00
公明 b62ba3b214 Add files via upload 2026-07-22 10:31:20 +08:00
公明 cb0d61a48d Add files via upload 2026-07-20 10:48:28 +08:00
公明 1cf10981ef Add files via upload 2026-07-11 11:30:50 +08:00
公明 46f891a114 Add files via upload 2026-07-09 19:31:32 +08:00
公明 508de5fad0 Add files via upload 2026-06-18 12:47:24 +08:00
公明 f37d613a0c Add files via upload 2026-05-15 14:09:37 +08:00
公明 d961ba1ec7 Add files via upload 2026-05-15 11:43:33 +08:00
Gilles Ceyssat dca5666b18 fix(mcp-stdio): initialize result storage so query tools work
The stdio MCP entrypoint (cmd/mcp-stdio/main.go) constructed the
security Executor without calling SetResultStorage, leaving it nil.
Any tool that goes through the query path — notably `exec` (the
generic shell tool) and the YAML wrappers that emit large results —
failed with:

    "错误: 结果存储未初始化"  (Error: result storage not initialized)

The full HTTP app at internal/app/app.go:118-147 initializes a
FileResultStorage from cfg.Agent.ResultStorageDir and wires it via
both agent.SetResultStorage and executor.SetResultStorage. The stdio
entrypoint needs the same wiring.

This replicates the storage init block in main.go so stdio-mode tool
execution stops failing on the query path.

Verified: before, `exec` calls returned the "结果存储未初始化" error.
After, `exec nmap -p 22,80,443 127.0.0.1` (bridged through an
external MCP client) returns the full nmap output as expected.
2026-05-12 08:13:13 +04:00
公明 c841809f9e Add files via upload 2026-04-22 10:03:46 +08:00
公明 5b3709b9ad Add files via upload 2026-03-09 22:37:37 +08:00
公明 3043232937 Add files via upload 2026-01-08 22:43:41 +08:00
公明 d8ed2d8cb3 Add files via upload 2025-11-15 17:50:47 +08:00
公明 5a4a1b3269 Add files via upload
增加mcp-stdio
2025-11-13 00:44:37 +08:00
公明 2bba007295 Add files via upload 2025-11-08 20:32:50 +08:00
公明 add33e1cf7 Add files via upload 2025-11-08 18:56:23 +08:00