Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
feafd4b
refactor: decouple agent, tool, and web layers
M09Ic Jul 18, 2026
47fa41a
feat: switch to AOP event protocol + unify chat with cyber-ui viewer
M09Ic Jul 18, 2026
4653912
feat(agent): expose webproto stdio execution
M09Ic Jul 19, 2026
a321e03
refactor(agent): unify harness on webproto stdio
M09Ic Jul 19, 2026
6ad465f
refactor(harness): keep AOP data typed
M09Ic Jul 19, 2026
d9a7fc7
feat(aop): make AOP the single agent transport
M09Ic Jul 19, 2026
807f088
test(aop): remove versioned envelope fixtures
M09Ic Jul 19, 2026
b12c81c
fix(web): auto-start local agent and restore chat UI
M09Ic Jul 19, 2026
9dedd4d
fix(web): restore structured scanner results
M09Ic Jul 19, 2026
bd3eaca
feat(web): group asset table by SCO type
M09Ic Jul 19, 2026
b71b9e6
fix(web): replace replayed AOP session history
M09Ic Jul 19, 2026
5a8e7d9
build: use local libcstx during integration
M09Ic Jul 19, 2026
e6651a5
refactor(aop): unify transport identity and execution paths
M09Ic Jul 20, 2026
f8f6d2d
build(aop): pin IOA and cyber-ui protocol updates
M09Ic Jul 20, 2026
7b487a9
build: keep local module replaces out of CI
M09Ic Jul 20, 2026
4239248
build: align go.mod with linux tidy
M09Ic Jul 20, 2026
82d2251
build: add linux yaml module checksums
M09Ic Jul 20, 2026
9c88c98
fix: close native runner CI gaps
M09Ic Jul 20, 2026
2e9690a
build: drop superseded pty checksums
M09Ic Jul 20, 2026
9626944
build: restore portable libcstx profile
M09Ic Jul 20, 2026
2390f1c
fix(build): package frontend and generate CLI help
M09Ic Jul 20, 2026
9f099e7
refactor(pty): use canonical frames across transports
M09Ic Jul 20, 2026
b96d020
refactor(commands): unify execution with PTY sessions
M09Ic Jul 20, 2026
d1c26a1
refactor(stdio): accept plain request and stream raw AOP
M09Ic Jul 21, 2026
44b1f3a
refactor(runner): drop cairnrunner, expose tool-only node via webagent
M09Ic Jul 21, 2026
fed2aec
test(webagent): cover tool node wire interop with cairn bridge dialect
M09Ic Jul 21, 2026
8046a1f
feat(aop): execute runner tools over canonical events
M09Ic Jul 21, 2026
b1f0ae8
feat(commands): accept per-call timeout in bash tool
M09Ic Jul 21, 2026
45fc21b
refactor(aop): adopt AOP as the single agent semantics carrier
M09Ic Jul 21, 2026
02ad0a7
feat(web): add live IOA console coverage
M09Ic Jul 21, 2026
85ea7ee
fix(webagent): persist scanner assets from chat nodes
M09Ic Jul 21, 2026
f5c70a2
fix(scan): emit composite results to asset pipeline
M09Ic Jul 21, 2026
7b6a7ae
refactor(agent): drop SteerUserMessage, queue TUI input at run boundary
M09Ic Jul 21, 2026
e517401
refactor(web): converge chat tasks on the root session.end event
M09Ic Jul 21, 2026
1b2aa07
test(agent,runner,web): lock AOP encoder, input, stdio, and replay se…
M09Ic Jul 21, 2026
cbe3528
build(frontend): exclude test files from hub tsconfig, bump cyber-ui
M09Ic Jul 21, 2026
cbeb5c1
feat(frontend): align chat timeline and IOA references
M09Ic Jul 22, 2026
0d6bc40
fix(ci): restore portable module and embed inputs
M09Ic Jul 22, 2026
9427ff6
fix(ci): preserve generated template dependencies
M09Ic Jul 22, 2026
fbb1abb
feat: load prompt content from existing files
M09Ic Jul 22, 2026
30e8ac6
feat(agent): AOP schema codegen, runtime-owned sessions, converged ex…
M09Ic Jul 22, 2026
8d8c96a
ci: stop publishing agent binaries
M09Ic Jul 22, 2026
d36efcc
feat(agent): converge agent execution on AOP tool.call sessions
M09Ic Jul 23, 2026
70c081c
feat(web): converge hub dispatch and errors on AOP, single LLM profil…
M09Ic Jul 23, 2026
aadbd67
feat(frontend): subscribe to converged AOP events, localize hub errors
M09Ic Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
**
!go.mod
!go.sum
!cmd/
!cmd/runner/
!cmd/runner/**
!core/
!core/**
!pkg/
!pkg/**
!skills/
!skills/**
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,22 @@ jobs:
go-version-file: go.mod
cache: true

- name: Set up Node.js
if: matrix.id == 'full'
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: web/frontend/package-lock.json

- name: Build embedded frontend
if: matrix.id == 'full'
run: |
npm --prefix web/frontend ci
npm --prefix web/frontend run build
test -s web/static/index.html
test -n "$(find web/static/assets -type f -size +0c -print -quit)"

- name: Generate embedded resources
if: matrix.generate
run: go generate ./core/resources
Expand Down
30 changes: 20 additions & 10 deletions .github/workflows/go-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ concurrency:
cancel-in-progress: false

# ---------------------------------------------------------------------------
# Three parallel build jobs (standard / full / agent) → one release job
# Two parallel build jobs (standard / full) → one release job
# ---------------------------------------------------------------------------

jobs:
Expand Down Expand Up @@ -93,20 +93,14 @@ jobs:
profile: standard
main: ./cmd/aiscan
binary: aiscan
tags: "forceposix emptytemplates noembed osusergo netgo"
tags: "forceposix emptytemplates noembed osusergo netgo cstx_native"
generate: true
- id: aiscan-full
profile: full
main: ./cmd/aiscan
binary: aiscan-full
tags: "forceposix emptytemplates noembed osusergo netgo full sqlite"
tags: "forceposix emptytemplates noembed osusergo netgo full cstx_native katana_slim"
generate: true
- id: aiscan-agent
profile: agent
main: ./cmd/agent
binary: aiscan-agent
tags: "forceposix emptytemplates noembed osusergo netgo"
generate: false

env:
GORELEASER_CURRENT_TAG: ${{ needs.prepare.outputs.tag }}
Expand All @@ -126,6 +120,22 @@ jobs:
go-version-file: go.mod
cache: true

- name: Set up Node.js
if: matrix.profile == 'full'
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: web/frontend/package-lock.json

- name: Build embedded frontend
if: matrix.profile == 'full'
run: |
npm --prefix web/frontend ci
npm --prefix web/frontend run build
test -s web/static/index.html
test -n "$(find web/static/assets -type f -size +0c -print -quit)"

- name: Generate embedded resources
if: matrix.generate
run: go generate ./core/resources
Expand Down Expand Up @@ -194,7 +204,7 @@ jobs:
tmpdir=$(mktemp -d)
cp "$f" "${tmpdir}/${inner_name}"
cp README.md "${tmpdir}/" 2>/dev/null || true
if [[ "$BINARY" != "aiscan-agent" ]] && [ -d docs ]; then
if [ -d docs ]; then
cp -r docs "${tmpdir}/" 2>/dev/null || true
fi
(cd "$tmpdir" && zip -r - .) > "$zipfile"
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ jobs:
go-version-file: go.mod
cache: true

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: web/frontend/package-lock.json

- name: Install upx
run: sudo apt install upx -y
continue-on-error: true
Expand All @@ -65,6 +72,11 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GOPATH: "/home/runner/go"

- name: Verify embedded frontend was built
run: |
test -s web/static/index.html
test -n "$(find web/static/assets -type f -size +0c -print -quit)"

- name: Publish release (remove draft)
run: gh release edit "$TAG" --draft=false --prerelease
env:
Expand Down
42 changes: 2 additions & 40 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,36 +71,6 @@ builds:
gcflags:
- all=-trimpath={{.Env.GOPATH}}

- id: aiscan-agent
main: ./cmd/agent
binary: "{{ .ProjectName }}-agent"
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
ignore:
- goos: windows
goarch: arm64
flags:
- -trimpath
tags:
- forceposix
- emptytemplates
- noembed
- osusergo
- netgo
ldflags:
- -s -w -X github.com/chainreactors/aiscan/core/config.Version={{.Version}}
asmflags:
- all=-trimpath={{.Env.GOPATH}}
gcflags:
- all=-trimpath={{.Env.GOPATH}}

upx:
- enabled: true
goos: [linux, windows]
Expand All @@ -109,7 +79,7 @@ upx:

archives:
- id: aiscan
builds: [aiscan]
ids: [aiscan]
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
formats:
- zip
Expand All @@ -118,22 +88,14 @@ archives:
- src: docs/*

- id: aiscan-full
builds: [aiscan-full]
ids: [aiscan-full]
name_template: "{{ .ProjectName }}-full_{{ .Os }}_{{ .Arch }}"
formats:
- zip
files:
- src: README.md
- src: docs/*

- id: aiscan-agent
builds: [aiscan-agent]
name_template: "{{ .ProjectName }}-agent_{{ .Os }}_{{ .Arch }}"
formats:
- zip
files:
- src: README.md

checksum:
name_template: "{{ .ProjectName }}_checksums.txt"

Expand Down
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ STANDARD_BIN ?= $(BIN_DIR)/aiscan$(EXE)
AGENT_BIN ?= $(BIN_DIR)/aiscan-agent$(EXE)
FULL_BIN ?= $(BIN_DIR)/aiscan-full$(EXE)

# Keep the local feature tiers aligned with the release workflow.
# Standard/full match release artifacts; agent remains a developer build target.
STANDARD_TAGS := forceposix emptytemplates noembed osusergo netgo cstx_native $(RE2_TAGS)
AGENT_TAGS := forceposix emptytemplates noembed osusergo netgo
FULL_TAGS := forceposix emptytemplates noembed osusergo netgo full sqlite cstx_native katana_slim $(RE2_TAGS)
FULL_TAGS := forceposix emptytemplates noembed osusergo netgo full cstx_native katana_slim $(RE2_TAGS)
BUILD_FLAGS := -trimpath -buildvcs=false

.PHONY: help prepare frontend standard agent full web-build web-run web all clean
.PHONY: help prepare frontend aop-gen standard agent full web-build web-run web all clean

help:
@echo "AIScan build targets (aligned with release editions):"
@echo "AIScan build targets:"
@echo " make / make standard Build the standard AIScan edition"
@echo " make agent Build the lightweight agent edition"
@echo " make agent Build the developer-only lightweight agent runtime"
@echo " make full Build frontend, then build the full edition"
@echo " make web Build the full edition and start the Web UI"
@echo " make frontend Build only web/frontend into web/static"
Expand All @@ -46,6 +46,9 @@ help:
prepare:
mkdir -p "$(BIN_DIR)"

aop-gen:
$(GO) generate ./pkg/aop/...

frontend:
$(NPM) --prefix "$(WEB_DIR)" run build

Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ From [GitHub Releases](https://github.com/chainreactors/aiscan/releases/latest):
| --- | --- |
| **aiscan** | Standard — scan/agent/gogo/spray/zombie/neutron/proton/arsenal |
| **aiscan-full** | Full — adds playwright browser, passive recon, katana crawler |
| **aiscan-agent** | Lightweight agent runtime, ideal for remote worker deployment |

| OS | Arch | Standard | Full | Agent |
| --- | --- | --- | --- | --- |
| Linux | amd64 / arm64 | `aiscan_linux_amd64` | `aiscan-full_linux_amd64` | `aiscan-agent_linux_amd64` |
| macOS | Intel / Apple Silicon | `aiscan_darwin_amd64` | `aiscan-full_darwin_arm64` | `aiscan-agent_darwin_arm64` |
| Windows | amd64 | `aiscan_windows_amd64.exe` | `aiscan-full_windows_amd64.exe` | `aiscan-agent_windows_amd64.exe` |
| OS | Arch | Standard | Full |
| --- | --- | --- | --- |
| Linux | amd64 / arm64 | `aiscan_linux_amd64` | `aiscan-full_linux_amd64` |
| macOS | Intel / Apple Silicon | `aiscan_darwin_amd64` | `aiscan-full_darwin_arm64` |
| Windows | amd64 | `aiscan_windows_amd64.exe` | `aiscan-full_windows_amd64.exe` |

```bash
# Linux
Expand All @@ -72,14 +71,17 @@ git clone https://github.com/chainreactors/aiscan.git && cd aiscan

go build -o aiscan ./cmd/aiscan # standard
go build -tags full -o aiscan-full ./cmd/aiscan # full (playwright/katana/passive)
go build -o aiscan-agent ./cmd/agent # developer-only lightweight agent runtime
```

The Makefile mirrors the three release editions. The full target builds the
frontend first so the latest `web/static` assets are embedded into the binary:
GitHub Releases publish only the standard and full editions. The lightweight
agent runtime remains available for developers to build from source. The full
target builds the frontend first so the latest `web/static` assets are embedded
into the binary:

```bash
make # standard edition
make agent # lightweight agent edition
make agent # developer-only lightweight agent runtime
make full # frontend + full edition
make web WEB_ADDR=127.0.0.1:18081 WEB_TOKEN=local-dev # full build + Web UI
```
Expand Down
19 changes: 10 additions & 9 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ aiscan agent --base-url "https://api.deepseek.com" --api-key "sk-..." --model de
| --- | --- |
| **aiscan** | 标准版 — scan/agent/gogo/spray/zombie/neutron/proton/arsenal |
| **aiscan-full** | 完整版 — 额外包含 playwright 浏览器、passive recon、katana 爬虫 |
| **aiscan-agent** | 轻量 agent 版 — 仅 agent 运行时,适合部署为远程 worker |

| 系统 | 架构 | 标准版 | 完整版 | Agent 版 |
| --- | --- | --- | --- | --- |
| Linux | amd64 / arm64 | `aiscan_linux_amd64` | `aiscan-full_linux_amd64` | `aiscan-agent_linux_amd64` |
| macOS | Intel / Apple Silicon | `aiscan_darwin_amd64` | `aiscan-full_darwin_arm64` | `aiscan-agent_darwin_arm64` |
| Windows | amd64 | `aiscan_windows_amd64.exe` | `aiscan-full_windows_amd64.exe` | `aiscan-agent_windows_amd64.exe` |
| 系统 | 架构 | 标准版 | 完整版 |
| --- | --- | --- | --- |
| Linux | amd64 / arm64 | `aiscan_linux_amd64` | `aiscan-full_linux_amd64` |
| macOS | Intel / Apple Silicon | `aiscan_darwin_amd64` | `aiscan-full_darwin_arm64` |
| Windows | amd64 | `aiscan_windows_amd64.exe` | `aiscan-full_windows_amd64.exe` |

```bash
# Linux
Expand All @@ -72,14 +71,16 @@ git clone https://github.com/chainreactors/aiscan.git && cd aiscan

go build -o aiscan ./cmd/aiscan # 标准版
go build -tags full -o aiscan-full ./cmd/aiscan # 完整版(含 playwright/katana/passive)
go build -o aiscan-agent ./cmd/agent # 仅供开发者使用的轻量 agent 运行时
```

Makefile 对应 Release 的三种功能层级。`make full` 会先构建前端,再将最新的
`web/static` 嵌入 full 二进制:
GitHub Releases 只发布标准版和完整版。轻量 agent 运行时仍保留给开发者从
源码自行编译。`make full` 会先构建前端,再将最新的 `web/static` 嵌入 full
二进制:

```bash
make # Standard 默认版
make agent # Agent 轻量版
make agent # 仅供开发者使用的轻量 agent 运行时
make full # 前端 + Full 完整版
make web WEB_ADDR=127.0.0.1:18081 WEB_TOKEN=local-dev # Full 构建并启动 Web UI
```
Expand Down
31 changes: 16 additions & 15 deletions cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"

cfg "github.com/chainreactors/aiscan/core/config"
"github.com/chainreactors/aiscan/core/runner"
transportpkg "github.com/chainreactors/aiscan/core/transport"
"github.com/chainreactors/aiscan/pkg/telemetry"
"github.com/chainreactors/aiscan/pkg/webagent"
goflags "github.com/jessevdk/go-flags"
)

Expand Down Expand Up @@ -62,28 +62,29 @@ Examples:
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(option.Timeout)*time.Second)
defer cancel()

var interruptMu sync.RWMutex
var interruptFn func() bool
sigChan := make(chan os.Signal, 2)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
defer signal.Stop(sigChan)
go func() {
for {
<-sigChan
if interruptFn != nil && interruptFn() {
for sig := range sigChan {
interruptMu.RLock()
fn := interruptFn
interruptMu.RUnlock()
if sig == os.Interrupt && fn != nil && fn() {
continue
}
fmt.Fprintf(os.Stderr, "\nPress Ctrl+C again to exit\n")
<-sigChan
os.Exit(1)
cancel()
return
}
}()

if option.WebURL != "" {
err = webagent.Run(ctx, &option, logger)
} else {
err = runner.RunAgentMode(ctx, &option, logger, func(fn func() bool) {
interruptFn = fn
})
}
err = transportpkg.Run(ctx, &option, logger, os.Stdin, os.Stdout, func(fn func() bool) {
interruptMu.Lock()
interruptFn = fn
interruptMu.Unlock()
})
if err != nil {
logger.Errorf("agent failed: %s", err)
os.Exit(1)
Expand Down
Loading
Loading