news 2026/9/19 11:29:40

Wails v3 的 AI Agent 协作规范与 Streams 运行时架构深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Wails v3 的 AI Agent 协作规范与 Streams 运行时架构深度解析

Wails v3 的 AI Agent 协作规范与 Streams 运行时架构深度解析

【免费下载链接】wailsCreate beautiful applications using Go项目地址: https://gitcode.com/gh_mirrors/wa/wails

本篇指南围绕仓库根目录下的 AGENTS.md 展开,系统解读该 Wails v3 项目为 AI Agent(含 GitHub Copilot、Claude 等编码助手)制定的工程协作规范:从 GitHub Issue 驱动的任务流转、history/临时文档治理、coderabbit质量门禁,到前端运行时双构建产物的机制,再到 Streams 传输层内部文档的源码级解读。读完你将掌握在 Wails 仓库中正确发起协作任务、构建运行时、接入 Streams 以及安全收尾会话的完整流程,并能在v3代码库中精准定位每项规范背后的实现证据。

1. 这份 AGENTS.md 是什么

AGENTS.md是 Wails 仓库专门写给AI 编码代理(而非人类贡献者)的“行为契约”。它解决的核心矛盾是:当 AI 以半自主方式参与 Issue 管理、代码生成、文档整理和 Git 提交时,如何保证工作流可追踪、可审计、不破坏项目既有约定。

从内容结构看,它由四大部分组成:

  1. GitHub Issue 工作流:确立 GitHub Issues/PR 为唯一权威追踪器;
  2. AI 生成规划文档的治理:约定临时文档统一放入history/目录;
  3. 前端运行时双构建产物:澄清@wailsio/runtime两种输出物及其消费方,避免“只重建一半”的经典错误;
  4. 会话收尾(Landing the Plane):规定结束工作会话时的强制步骤。

以下各节将逐项拆解,并补充仓库中的源码、配置与测试证据。该文档本身不包含可执行代码示例,因此本文会将其规范与v3/目录下的实际实现对应起来,帮助读者把“规则”映射到“代码”。

2. Issue 驱动的协作工作流

2.1 权威追踪器原则

AGENTS.md 首先强调一条硬性约定:

GitHub Issues 与 Pull Requests 是本项目唯一的权威追踪器,禁止在本地平行维护一套 Issue 数据库或 Markdown 任务清单。

这意味着 AI 代理不得在仓库内新建TASKS.mdTODO.md之类的文件来替代 Issue 系统。该约定与仓库中的自动化配置相互印证——.github/workflows/labeler.yml 负责自动打标签、.github/workflows/stale-issues.yml 负责清理陈年 Issue、.github/workflows/redirect-enhancement-issues.yml 负责 issue 重定向,全部围绕 GitHub Issues 生态运转。

2.2 建议的代理工作流

文档给出五步工作流,可直接作为 Agent 的 checklist 使用:

  1. 先搜索后创建:在新建 Issue/PR 前,先检索现有条目,避免重复(仓库中 .github/workflows/pr-master.yml 等 PR 检查流水线会进一步保证合入质量);
  2. 工作与 Issue/PR 建立关联:实现代码必须链接到对应 Issue 或 PR;
  3. 新发现的可行动工作:以 GitHub Issue 形式登记,附上复现细节、影响范围、验收标准三要素;
  4. 用标签/里程碑/交叉引用表达语义:优先级用 labels,发布范围用 milestones,依赖关系用 cross-references;
  5. 关闭 Issue 的唯一条件:工作已完成且验证通过;否则必须写明延期或不再适用的原因。

2.3 强制规则

  • 不得重复已存在的 Issue;
  • 当 Issue 范围或复现步骤变化时,及时更新描述;
  • AI 生成的规划文档存放在history/,而非仓库根目录;
  • 提交前必须执行coderabbit --plain,提前暴露问题(详见第 4 节);
  • 所有提交必须使用taliesin-ai身份;
  • 在用户明确手动确认之前,绝不 push

3. AI 规划文档的存放治理(history/ 目录)

AI 在开发过程中往往会生成 PLAN.md、ARCHITECTURE.md、DESIGN.md、CODEBASE_SUMMARY.md、INTEGRATION_PLAN.md、TESTING_GUIDE.md、TECHNICAL_DESIGN.md 等临时规划文档。AGENTS.md 明确建议:

  • 在项目根目录创建history/目录;
  • 所有临时的 AI 规划/设计文档统一放入其中;
  • 仓库根目录保持整洁,只保留永久性项目文件;
  • 仅在被明确要求回顾历史规划时访问history/

文档还给出了可选的.gitignore片段:

# AI planning documents (ephemeral) history/

其收益包括:根目录整洁、临时与永久文档分离、按需排除出版本控制、保留“考古式”的规划历史、降低浏览项目的噪音。仓库中 history/beta-readiness-audit.html 正是这种治理实践的现存示例——它是一份 beta 就绪审计文档,被收纳在history/而非仓库根目录,印证了该规范的实际落地。

4. 提交前的质量门禁:coderabbit 与提交身份

AGENTS.md 规定了一条不可省略的命令:

coderabbit --plain

--plain表示以纯文本(无交互、无花哨输出)方式运行 CodeRabbit 代码审查,在提交前捕获潜在缺陷。CodeRabbit 作为 AI 审查机器人,其价值在于把“过早合入问题代码”的成本前移——这与仓库的 CI 策略互为补充:例如 .github/workflows/semgrep.yml 提供静态安全扫描,.github/workflows/build-and-test-v3.yml 提供构建与测试矩阵,而coderabbit --plain则是开发者/AI 在本地提交前的最后一道人工(机器)审查。

配套的提交身份约定为:

所有提交必须使用taliesin-ai身份;未经用户显式手动确认,绝不 push。

这保证了仓库历史中 AI 提交可被统一识别与回溯。

5. 前端运行时:必须理解的两个构建产物

AGENTS.md 明确指出,v3/internal/runtime/desktop/@wailsio/runtime下的 TypeScript 运行时会产生两个相互独立的产物。只重建其中一个而忽略另一个是常见且极易混淆的错误:

任务产物消费方
task v3:runtime:build:assetsv3/internal/assetserver/bundledassets/runtime.js(另有.debug.jswebview,以/wails/runtime.js路径被资源服务器提供
task v3:runtime:build:packagenpm 包目录下的dist/应用的 frontend,通过node_modules导入

这两个任务在源码中有精确定义:v3/internal/runtime/Taskfile.yaml中的build:assets依赖build:debugbuild:production(两者均用 esbuild 将src/index.ts打包进../assetserver/bundledassets/),而build:package则调用npm run build:code生成 npm 包用的dist/。产物的去向也清晰可见:v3/internal/assetserver/bundledassets/ 目录下确实存在runtime.jsruntime.debug.js两个文件。

5.1 为什么必须两个都重建

  • webview 侧:桌面应用的 HTML/JS 运行时由 Go 侧通过go:embed内嵌的bundledassets/runtime.js提供,webview 加载/wails/runtime.js获得运行时能力;
  • frontend 侧:生成的应用通过 npm 导入@wailsio/runtime包,Vite 等打包器从node_modules解析该包,走的完全是另一条路径。

因此,只要修改了src/下的任何代码(例如stream.ts),两个产物都必须重建并一并提交

5.2 CI 如何强制“产物与源码一致”

AGENTS.md 提到“CI 会校验提交的 bundle 与build:assets输出完全一致”。仓库中的 .github/workflows/verify-runtime-assets.yml 正是这项强制检查的实现:

  • 该 job 运行于每个 PR,且当 PR 未改动v3/internal/assetserver/bundledassetsv3/internal/runtime相关路径时自动跳过;
  • 一旦相关路径有改动,它会对 PR 源码做一次干净的重新构建,然后与提交中的runtime.js/runtime.debug.js逐字节比对;
  • 由于 minified JS 无法靠肉眼审查,该检查将 bundle 视为“内部构建产物”,并要求 PR 必须提交与源码严格匹配的字节。

这意味着 Agent 修改运行时源码后,不能只提交.ts源码而忘记更新 bundle——CI 会直接拒绝。

5.3 用本地 checkout 的运行时测试应用

一个生成的 Wails v3 应用从 npm 导入@wailsio/runtime,因此看不到本 checkout 中对运行时所做的改动。要在真实应用上测试工作树中的运行时改动,AGENTS.md 给出了命令:

task v3:install-runtime -- ./path/to/your-app/frontend

该任务在 v3/Taskfile.yaml 中定义:它首先依赖runtime:build:package重建dist/,然后进入目标 frontend 目录执行npm install "file:..."指向本仓库的运行时包,确保安装的一定是当前源码构建的产物。撤销方式同样简单——在相同目录执行:

npm install @wailsio/runtime@latest

6. 子系统内部文档索引:以 Streams 为例

AGENTS.md 建议:部分子系统为 Agent 准备了专门的内部文档页面,修改对应代码前必须先阅读,因为其中若干设计决策看似随意,实则都是为了规避某个已被测量的 bug。

它给出的示例是Streams

  • 涉及文件:v3/pkg/application/stream*.go(Go 侧)与v3/internal/runtime/desktop/@wailsio/runtime/src/stream.ts(TS 侧);
  • 内部文档:docs/mpress/content/guides/advanced/streams-internals.mpd,覆盖 held-poll 设计、缓冲区常量及其选择方法、会话与连接生命周期、传输层选择,以及未完成事项;
  • 若要把现有 WebSocket 实现迁移到 Streams,遵循 docs/mpress/content/guides/advanced/streams-from-websockets.mpd——一份机械式检查清单,其中标注了“静默失效”的差异点。

这一节的深层含义是:Wails v3 的文档体系已经为 AI 代理做过索引优化——遇到 Streams 相关改动,Agent 应先读内部文档再动手,否则很容易“破坏一个被测量的修复”。

6.1 源码侧的文件分布

AGENTS.md 中列出的 Streams 实现文件均可在仓库中定位:

  • v3/pkg/application/stream.go:公开 API、StreamConnstreamSink、管理器与注册表;
  • v3/pkg/application/stream_session.go:单窗口单次页面加载的会话——出站队列、帧类型、连接表;
  • v3/pkg/application/stream_transport.go:两个 HTTP 端点、二进制分帧、分块重组、运行时 prelude;
  • v3/pkg/application/stream_server.go:-tags server构建下的真实 WebSocket sink;
  • v3/pkg/application/stream_prelude_desktop.go 与 stream_prelude_server.go:在 bundle 服务时选择客户端传输层;
  • v3/internal/runtime/desktop/@wailsio/runtime/src/stream.ts:WebSocket形态的客户端实现;
  • v3/tests/stream-performance/:负载测试工具(-upload-reloads、场景扫描)。

6.2 Streams 的核心设计:非对称传输

内部文档指出,Go→JS 与 JS→Go 使用不同机制,而这种不对称性正是整个设计的核心:

Go webview ── ─────── Send() ─► per-window queue ─────────► GET /wails/stream/poll (held open) └─ one held request per window, carrying frames for every connection Receive() ◄─ per-conn inbox ◄──────── POST /wails/stream/send (one or more frames)
  • Go→JS 是“保持打开的轮询”(held poll):请求一直挂起直到有内容可投递。没有轮询间隔,也没有自适应机制——服务器挂住直到帧出现,投递延迟天然接近 0;任何客户端间隔都只会增加延迟。响应在途期间到达的帧会累积到下一次响应,往返本身即批处理窗口。实测:100/s 时每响应 1.0 帧,5000/s 时仍为 1.0,20000/s 时达到 3.4,且 p99 延迟随速率上升反而下降
  • JS→Go 是普通 POST:发送按连接用 promise 链串行化(并发fetch不保序,而 Go 依赖发送顺序即观察顺序)。Go 在响应之前就把被接受的帧(或批次前缀)追加到连接的 inbox,因此客户端不可能越过 Go 尚未排队的字节。
  • 每窗口只有一个在途 poll,复用所有连接:单队列、单 drainer,顺序正确性由构造保证;同时绕开了 Windows 上 HTTP/1.1 每主机 6 连接的瓶颈(这些是http://wails.localhost上真实的 Chromium 网络请求)。

6.3 为什么做这些特定决策(每个都是一道“疤痕”)

内部文档强调:以下每一条都来自事件传输工作的实测教训,移除任一决策都会重新打开一个已测量的 bug:

  • Go→JS 路径不碰主线程Send在互斥锁下追加后立即返回。事件系统曾在主线程 emit 与 goroutine emit 并发排队时内联执行 eval,导致三个平台上 4.4% 的事件乱序。单队列单 drainer 从构造上杜绝了这一点。
  • 任何规模下都不使用evaluateJavaScript:把 payload 拼接进 eval 源码会保留宿主内存,且存在平台相关的“拐点”(macOS 11.6 GB、WebKitGTK 6.2 GB,均为 100 × 1 MB/s 场景)。Streams 完全不经过 eval,因此恒定字节速率扫描在每个帧大小下都是平坦的。
  • 控制数据走 header,不走路由参数或 query string:WebKitGTK 6.0 可能把自定义 URI scheme 的 POST body 当作 query 参数投递(transport_http.go为此带了一个 fallback),WebView2 则把 body 投递上限限制在约 2 MB。
  • poll 响应是二进制而非 JSON:帧是[]byte;若用 JSON 信封装 base64,每帧多花 33% 开销,还会在 UI 线程上多一次解析。二进制帧格式为:
magic "WS1\0" | flags u8 | count u32 | count × ( connID u32 | kind u8 | len u32 | payload )

kind取值 data / open / close / error。没有序号、没有 ack——WebSocket 本就不回放,断连就丢失在途数据,模拟它比维护一个有界缓冲无法总是满足的游标更简单也更诚实。

  • 挂住请求是安全的:每个 webview 请求本来就有自己的 goroutine。assetserver_webview.go中的dispatchWorkers被固定为 0,且注释明确点名此场景;若开启该池,必须先为请求生命周期设定上界。

6.4 缓冲区常量:编译期常量而非选项

所有常量集中在 v3/pkg/application/stream.go 中。它们是编译期常量,不是配置项——没有Options.Streams,也没有按流设置。修改即改源码:

常量约束对象
streamOutQueueBytes8 MB每窗口等待收集的字节
streamOutQueueDepth256每窗口缓冲的帧数
streamOutQueueBytesGlobal/streamOutQueueDepthGlobal256 MB / 8192整个应用范围的出站数据缓冲
streamInQueueBytesGlobal/streamInQueueDepthGlobal256 MB / 8192整个应用范围等待Receive的入站数据
streamMaxConnections256单会话内的活动连接 + 排队关闭
streamMaxConnectionsGlobal4096整个应用范围的活动连接
streamOutCloseDepthGlobal4096整个应用范围未投递的关闭通知
streamMaxSessionsPerWindow16单窗口可持有的会话数(超限时新代次必须取代旧代次)
streamMaxSessions1024整个应用范围的会话数
streamOutControlDepth/streamOutControlDepthGlobal256 / 4096排队的非关闭控制帧(每会话 / 全应用)
streamMaxChunkSets/streamMaxChunkTotal256 / 4096每会话未完成上传数 / 单次上传的分块数
streamMaxChunkBytesGlobal/streamMaxChunkPartsGlobal128 MB / 4096全应用范围的分块 payload / 分块元数据
streamMaxChunkIDLen64 字节单个客户端提供的 chunk-set 标识符
streamMaxResponseBytes1 MB单个 poll 响应
streamHoldTimeout20 s空 poll 挂起的最长时间
streamSessionTTL60 s无 poll 且无活动连接 ⇒ 会话死亡
streamSessionGrace10 min有活动连接但长时间无 poll ⇒ 会话死亡
streamSessionSweep20 sjanitor 扫描死亡会话的周期
streamMaxFrameBytes64 MB任意方向单帧上限
streamMaxNameLen256 字节单个注册或请求的流名称
streamInQueueDepth/streamInQueueBytes256 / 8 MB已接收但未被Receive取走的帧
如何选择这些值(内部文档的调参指南)
  • streamOutQueueDepth故意不是eventQueueCapacity(64):后者是按“一次 eval 排空一个”的队列测出来的,深度只增加尾部延迟;而 poll 按批排空,深度必须覆盖一个往返的生产量——5000 帧/s、5 ms 往返约 25 帧,256 给突发留了余量且不阻塞生产者。
  • streamOutQueueBytes才是真正重要的上界:256 帧 × 1 MB 就是 256 MB。它是前端停止收集时宿主内存的后盾。
  • 两条交互规则(第二条极易被无意破坏):
    • 深度与字节上限约束的是累积量
    • 空队列始终接受一帧,无论多大。无条件执行字节上限会让“大于上限的帧”根本无法发送——等待条件永远无法成立,Send永久阻塞、TrySend永远报告满。帧大小并非总是调用方能选择的(带[]byte字段的结构体 marshal 成多大就是多大)。
  • streamMaxResponseBytes的存在是因为 Windows:WebView2 响应写入器会先把整个 body 累积在内存中,到Finish才交接,无界响应即无界分配。调高它不会提升 Windows 吞吐——实测 Windows 瓶颈是按字节而非按响应(帧扫描中响应/s 波动 4 倍,而 MB/s 稳定在约 90)。
  • 入站上限是前端等待的原因:桌面上deliver报告满时,端点返回429,客户端用有界退避重试同一帧或未被接受的批次后缀;server 模式下 socket 读泵等待,由 TCP 施加背压。若无此上限,一个迟迟不调Receive的 handler 会让宿主内存无限增长。
  • 控制帧绕过数据上限,但有独立生命周期上限:丢一个数据帧只是变慢,丢一个 open ack 会让前端永远停在CONNECTING,丢一个 close 会让前端认为死连接还活着。因此非关闭控制帧有独立的有界队列;每个被接受的连接还会预留一个 close 槽位。
  • 每会话上限都配套全应用级上限,否则每个被准入的会话/连接都能同时占满自己的本地配额。出站、入站数据共享独立的 256 MiB / 8192 帧预算;活动连接 4096 项预算;未投递的关闭通知另有同尺寸预算。两个预算刻意分离:每个预留恰好由唯一所有者释放(连接的槽位由只运行一次的shutdown释放;关闭帧的槽位由处置该帧的一方释放),避免所有权迁移导致的永久泄漏(早期版本曾因此泄漏)。
  • Go 帧转移所有权、JS 帧快照拷贝:Go 的Send在传输层写入前保留调用方切片,调用成功后不得再修改/复用该存储;JS 的send()返回前复制可变二进制输入,与原生 WebSocket 所有权语义一致。
  • JS 发送遵循 WebSocket 缓冲契约:send()不能阻塞,bufferedAmount包含该 socket 保留的所有字节,是调用方的背压信号;宿主侧队列仍由上述上限独立约束。
  • 分块重组共享宿主内存配额:每会话可组装最大 64 MiB 的单帧,但该配额不能乘以每个准入会话。未完成/可重试的 chunk 集共享 128 MiB 准入 payload 预算(完成时短暂同时保留分块与连续组装帧,仍处于 256 MiB 有效内存天花板内);保留的分块另共享 4096 项元数据配额。
  • poll 重试只针对可恢复失败:网络错误、408请求超时、425早期数据、429背压、5xx服务端错误,使用 250 ms 起步、最高 5 s 的指数退避;其余4xx属于协议或所有权失败,立即关闭页面 Streams;410是退役会话的干净终止信号。关闭最后一个连接会中止在途 poll 或退避定时器。
  • streamSessionTTL必须明显高于streamHoldTimeout,否则会话会在自己的 poll 合法挂起期间被回收。
  • 调参经验:小消息密集负载先撞深度上限,大 payload 先撞字节上限。典型应用无需调整——macOS 上默认值可支撑 634000 帧/s 与 2100 MB/s(该数据来自内部文档的实测记录)。

6.5 会话与连接生命周期

  • 会话(session)= 某窗口的一次页面加载,以客户端生成的 id(类似运行时clientId)为键,由先到的请求惰性创建。当平台无法识别请求窗口(windowID == 0)时,会话 id 仍全局有界,但代次(generation)故意不比较。
  • 三种关闭机制(按感知速度排序):
    1. 新代次会话 poll 取代旧代次:重载会生成新会话 id 并在窗口的sessionStorage中递增代次;同一值镜像到window.name(存储被禁用时仍能跨重载存活),并锚定到performance.timeOrigin(旧引擎回退Date.now())。poll 只退役更低的页面代次;窗口被销毁时旧会话的连接立即关闭。
    2. 窗口销毁:丢弃该窗口的所有会话,类似eventPayloadStore.dropWindow
    3. TTL 回收:兜底一切其他情况(渲染进程崩溃、机器休眠)。
  • 只有前两种机制退役页面代次;TTL 清理只移除空闲会话而不推进“已退役代次水位线”,这样仍加载的页面在最后一个连接关闭后还能再开新流。已经被真正取代的代次仍被封锁,因为新页面的 poll 会在旧会话被移除前推进水位线。
  • Apple WebView 会报告已取消的请求:macOS/iOS 上 WebKit 的stopURLSchemeTask回调会取消匹配的请求上下文,使导航离开后的 poll 立即解除阻塞。Linux/Windows 当前桥接层没有等效的提前中止回调,parked 请求会一直挂到 hold 超时(连接仍会按规则 1 及时关闭;取消在 Linux 上表现为EPIPE,在 Windows 上直到Finish才显现)。

6.6 传输层选择机制

Stream(name)会查询window._wails.streamFactory

  • server 构建:安装一个返回真实WebSocket的工厂;
  • webview 构建:保持未设置,客户端走 poll 传输层。

关键约束是:工厂必须在任何模块体执行之前安装,因为生成的 bindings 会在模块作用域创建流(例如export const Telemetry = Stream("telemetry"))。custom.js无法胜任——它通过loadOptionalScript注入,先做 HEAD 请求再追加<script>标签,落地太晚。正确做法是把工厂前置到运行时 bundle 上(见 v3/pkg/application/stream_prelude_server.go):ES 模块依赖先于导入者求值,因此 prelude 同步先于任何生成模块运行。若新增第三传输层,同样放入 prelude,不要回到custom.js

6.7 尚未完成的事项(内部文档的诚实清单)

事项状态
平台层请求取消Apple 已完成;Linux/Windows 待办
缓冲区常量作为选项未做,仅编译期
类型化流未做(有意为之,帧按决策就是[]byte
流水线(第二个在途 poll)未做,需要 JS 侧有序重组
每连接公平性未做——同窗口连接共享一个队列,洪泛连接会拖慢邻居
JS→Go 帧合并已完成——在途请求后累积的帧以有界批次发送;轻载连接仍每 POST 一帧
Windows 吞吐约 100 MB/s,受WebResourceRequested编组限制;候选修复是共享缓冲区(PostSharedBufferToScript),bindings 已存在于internal/webview2/pkg/webview2/但未接入pkg/edge
wails3 dev/ Vite可用——已验证生成vanilla-js项目,Vite dev server 在/代理,/wails/stream/*在代理前被资源服务器中间件匹配
多窗口负载下未测,虽然会话按构造是窗口作用域的

6.8 Streams 的测试与验证

内部文档给出可直接运行的测试命令:

go test ./pkg/application/ -run TestStream -race # protocol, ordering, backpressure go test -tags server ./pkg/application/ -run TestServerMode pnpm --dir v3/internal/runtime/desktop/@wailsio/runtime test

顺序测试是最关键的一个:八个 goroutine 并发发送,在队列锁下分发计数器,排空顺序必须与被接受顺序完全一致。一旦失败,说明“单 drainer”不变量被破坏。

负载测试工具(v3/tests/stream-performance/):

go run ./tests/stream-performance -duration 20s # full sweep go run ./tests/stream-performance -upload -duration 10s # JS→Go matrix go run ./tests/stream-performance -reloads 6 # connection lifecycle

在 Windows 上,负载测试必须在交互式控制台会话中运行(纯 SSH 调用会在 session 0 中以零长度输出失败),且二进制必须放在 SSH 账号与控制台账号都能读取的位置(C:\Users\<user>被 ACL 限制为属主)。

7. 会话收尾(Landing the Plane):结束工作的强制流程

AGENTS.md 规定了结束工作会话时的强制工作流,任何 Agent 都应严格遵守:

  1. 为剩余工作登记 Issue——所有需要跟进的事项创建为 Issue;
  2. 运行质量门禁(若改了代码)——测试、lint、构建;
  3. 更新 Issue 状态——关闭已完成项,更新进行中项;
  4. 准备远端同步
    git status

    工作树干净且确认要同步时,执行git pull --rebase只有用户明确确认后才git push

  5. 清理——审查 stash,仅移除过时的;清理远端已合并分支;
  6. 验证——所有预期变更在请求时均已存在并已提交;
  7. 交接——为下一会话提供上下文。

三条关键规则贯穿始终:

  • 每次提交使用taliesin-ai身份;
  • 未经用户显式手动确认不 push;
  • 清晰汇报变更状态:未提交 / 本地已提交 / 已推送。

8. 结语:让 AI 代理在 Wails 中“可预期地工作”

从 AGENTS.md 可以提炼出 Wails v3 对 AI 协作的完整治理哲学:

  • 一切可追踪:Issue/PR 是唯一事实源,规划文档归档于history/
  • 一切有门禁:提交前coderabbit --plain,CI 层verify-runtime-assets保证运行时产物与源码逐字节一致;
  • 一切有依据:Streams 内部文档把每个看似随意的决策都回溯到被测量的 bug,形成“改代码前先读文档”的强约束;
  • 一切可回退task v3:install-runtime指向工作树、npm install @wailsio/runtime@latest撤销,双构建产物并提交,收尾流程以“不 push 直到用户确认”为底线。

对于任何想要为 Wails v3 贡献代码(尤其是涉及v3/internal/runtimev3/pkg/application/stream*.go的改动)的开发者或 AI 代理,这套规范既是操作手册,也是理解代码库演进逻辑的入口。遵守它,你的每一次会话都会留下干净、可审计、可交接的痕迹。

【免费下载链接】wailsCreate beautiful applications using Go项目地址: https://gitcode.com/gh_mirrors/wa/wails

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 11:28:13

从0到1自建轻量级Web CRM:PHP+SQLite+Docker实践

就是今年年初的事。我们团队从三个人涨到八个人&#xff0c;客户资料还躺在各个人的微信聊天记录、Excel 表格和邮箱签名里。谁跟进过哪个客户、上次聊到哪、承诺过什么价格&#xff0c;全靠开会时候互相“考古”。我一开始想直接上现成的 SaaS 平台&#xff0c;后来算了一笔账…

作者头像 李华
网站建设 2026/9/19 11:27:33

数字钱包抗量子迁移实战:格密码签名与密钥管理全解析

简介&#xff1a;一份面向区块链安全与后量子密码研究者的二十页PDF技术报告。文档系统梳理量子计算对RSA、ECC等传统密码体制的冲击&#xff0c;聚焦格密码在数字钱包抗量子攻击中的落地方法&#xff0c;涵盖格困难问题&#xff08;SVP/CVP&#xff09;、NTRU算法、数字签名&a…

作者头像 李华
网站建设 2026/9/19 11:23:13

GitHub趋势周刊:AI开发工具本地化实战解析

这一周的 Github 趋势榜信息量很大。awesome-gpt-image-2直接登顶了 star 增长榜首&#xff0c;Archify带着“架构图可核验”的概念冲进视野&#xff0c;Codex CLI的本地化讨论热度不减&#xff0c;和Claude Code的生态把整个榜单下半区占掉了一大半。我刷了两天榜单和 issus&a…

作者头像 李华
网站建设 2026/9/19 11:22:53

软件测试外包协作框架:资产契约化与分层自动化实践

简介&#xff1a;本资源是一份面向互联网企业技术负责人、质量保障团队及外包服务采购人员的《软件测试外包服务解决方案》实务指南&#xff0c;聚焦解决自建测试团队成本高、专业度不足、响应灵活性差等现实痛点。文档系统梳理了外包测试的八大实施阶段——从需求调研、方案制…

作者头像 李华
网站建设 2026/9/19 11:22:39

Java Swing图形绘制工具开发指南

1. 项目概述与核心思路这个Java画图项目实现了一个基础的图形绘制工具&#xff0c;允许用户通过鼠标交互绘制直线、矩形、等腰三角形、任意三角形和多边形等基本几何图形。核心思路是通过Swing组件构建图形用户界面(GUI)&#xff0c;结合事件监听机制实现用户交互。作为Java GU…

作者头像 李华