@yufengtadian/freedom-cli 1.13.1 → 1.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +40 -0
  2. package/README.md +119 -15
  3. package/lib/agents.js +448 -0
  4. package/lib/build.js +189 -45
  5. package/lib/cli.js +258 -9
  6. package/lib/config.js +20 -1
  7. package/lib/desktop.js +133 -0
  8. package/lib/dev.js +149 -0
  9. package/lib/mcp.js +217 -0
  10. package/lib/release.js +90 -0
  11. package/lib/security.js +113 -54
  12. package/lib/shell.js +170 -63
  13. package/lib/toolchain.js +339 -0
  14. package/lib/tui.js +37 -1
  15. package/lib/utils.js +51 -0
  16. package/lib/verify.js +48 -12
  17. package/lib/webkit.js +45 -0
  18. package/package.json +3 -2
  19. package/shell/darwin-arm64/freedom-shell +0 -0
  20. package/shell/linux-x64/freedom-shell +0 -0
  21. package/shell/win-x64/freedom-shell.exe +0 -0
  22. package/skill/freedom/SKILL.md +159 -0
  23. package/templates/desktop/app.html +559 -0
  24. package/templates/desktop/backend/desktop.mjs +327 -0
  25. package/templates/desktop/freedom.config.js +32 -0
  26. package/templates/desktop/icon.ico +0 -0
  27. package/templates/go/go.mod +3 -0
  28. package/templates/go/pkg/freedom/anti_debug_linux.go +69 -0
  29. package/templates/go/pkg/freedom/anti_debug_other.go +5 -3
  30. package/templates/go/pkg/freedom/anti_debug_windows.go +238 -11
  31. package/templates/go/pkg/freedom/assets/freedom.js +3 -0
  32. package/templates/go/pkg/freedom/assets_embed.go +1 -0
  33. package/templates/go/pkg/freedom/backend_proc.go +5 -5
  34. package/templates/go/pkg/freedom/events_windows.go +5 -5
  35. package/templates/go/pkg/freedom/freedom.go +64 -10
  36. package/templates/go/pkg/freedom/msgwindow_windows.go +8 -8
  37. package/templates/go/pkg/freedom/resources.go +119 -14
  38. package/templates/go/pkg/freedom/securetemp.go +61 -0
  39. package/templates/go/pkg/freedom/securetemp_other.go +20 -0
  40. package/templates/go/pkg/freedom/securetemp_windows.go +25 -0
  41. package/templates/go/pkg/freedom/security.go +293 -64
  42. package/templates/go/pkg/freedom/shutdown.go +55 -0
  43. package/templates/go/pkg/freedom/shutdown_windows.go +47 -0
  44. package/templates/go/pkg/freedom/store.go +11 -3
  45. package/templates/go/pkg/freedom/syscap_windows.go +33 -33
  46. package/templates/go/pkg/freedom/sysint_windows.go +2 -2
  47. package/templates/go/pkg/freedom/tray_windows.go +18 -18
  48. package/templates/go/pkg/freedom/updater.go +3 -3
  49. package/templates/go/pkg/freedom/window_other.go +7 -1
  50. package/templates/go/pkg/freedom/window_windows.go +185 -17
  51. package/templates/go/third_party/webview_go/CHANGELOG.md +15 -0
  52. package/templates/go/third_party/webview_go/FREEDOM-PATCH.md +32 -0
  53. package/templates/go/third_party/webview_go/LICENSE +22 -0
  54. package/templates/go/third_party/webview_go/README.md +50 -0
  55. package/templates/go/third_party/webview_go/glue.c +36 -0
  56. package/templates/go/third_party/webview_go/go.mod +3 -0
  57. package/templates/go/third_party/webview_go/go.sum +0 -0
  58. package/templates/go/third_party/webview_go/libs/mswebview2/LICENSE +27 -0
  59. package/templates/go/third_party/webview_go/libs/mswebview2/include/WebView2.h +23568 -0
  60. package/templates/go/third_party/webview_go/libs/mswebview2/include/vendor.go +2 -0
  61. package/templates/go/third_party/webview_go/libs/mswebview2/vendor.go +2 -0
  62. package/templates/go/third_party/webview_go/libs/mswebview2/version.txt +1 -0
  63. package/templates/go/third_party/webview_go/libs/webview/LICENSE +22 -0
  64. package/templates/go/third_party/webview_go/libs/webview/include/vendor.go +2 -0
  65. package/templates/go/third_party/webview_go/libs/webview/include/webview.h +3598 -0
  66. package/templates/go/third_party/webview_go/libs/webview/vendor.go +2 -0
  67. package/templates/go/third_party/webview_go/libs/webview/version.txt +1 -0
  68. package/templates/go/third_party/webview_go/webkit2_40.go +21 -0
  69. package/templates/go/third_party/webview_go/webkit2_41.go +8 -0
  70. package/templates/go/third_party/webview_go/webview.cc +1 -0
  71. package/templates/go/third_party/webview_go/webview.go +332 -0
  72. package/templates/installer/app.nsi +43 -0
  73. package/templates/project/freedom.config.js +14 -0
  74. package/templates/project/freedom.d.ts +77 -0
  75. package/templates/project-minimal/freedom.config.js +14 -0
  76. package/templates/project-minimal/freedom.d.ts +77 -0
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: freedom
3
+ description: 用 Freedom(Go 通用 WebView 桌面壳 + freedom CLI)把任意前端与任意语言后端打包成 Windows/macOS/Linux 桌面应用。当任务涉及 freedom.config.js、freedom build/verify/dev、单文件前端内嵌、NDJSON stdio 后端协议、freedom.invoke / freedom.sys / resources/config.json、FRDM1 资源加密、应用自更新清单(keygen/manifest)或桌面壳选型/排障时使用。
4
+ ---
5
+
6
+ # Freedom 桌面壳使用指南
7
+
8
+ Freedom = 预编译通用壳(Go + 系统 WebView)+ 外部 `resources/` 资源层 + `freedom` CLI。
9
+ 前端构建成**单文件 HTML** 后由壳在内存加载(`SetHtml`),后端可以是**任意语言的子进程**,
10
+ 经 NDJSON over stdio 通信。打包不需要 Go / Rust / Node 工具链在目标机器上存在。
11
+
12
+ ## 1. 最小项目形态
13
+
14
+ ```
15
+ my-app/
16
+ ├─ package.json # 必须 "type":"module"(freedom.config.js 用 ESM 书写)
17
+ ├─ freedom.config.js # 唯一配置入口
18
+ ├─ index.html src/ # 前端(vite + vite-plugin-singlefile 产单文件)
19
+ └─ backend/ # 可选:进程后端脚本,构建时整体拷进 resources/backend/
20
+ ```
21
+
22
+ `freedom init <目录> [--template full|minimal]` 生成骨架;`freedom build` 打包;
23
+ `freedom verify` 校验产物(CI 用退出码)。
24
+
25
+ ### freedom.config.js 可用键
26
+
27
+ | 键 | 含义 |
28
+ |----|------|
29
+ | `name` `title` | 产物文件名 / 窗口标题 |
30
+ | `width` `height` `minWidth` `minHeight` `center` `debug` | 窗口几何与调试 |
31
+ | `titlebar` | `frameless`(默认,前端自绘按钮)/ `native` |
32
+ | `icon` | Win `.ico` / mac `.icns`,构建期注入 |
33
+ | `outDir` | 产物目录,默认 `dist` |
34
+ | `security` | `none` / `basic` / `high`(high = resources 加密为 `app.bin` + `.integrity`) |
35
+ | `backend` | `{ command:'node', args:['backend/x.mjs'] }`;缺省为内嵌 Go 后端模式 |
36
+ | `backendDir` | 后端目录名,默认 `backend` |
37
+ | `staticHtml` | **跳过 npm/vite**,直接内嵌指定单文件 HTML(自举与纯静态页用,零网络) |
38
+ | `url` | 壳改为 `Navigate(url)`(http/https 白名单)——`freedom dev` 热更走这条 |
39
+ | `singleInstance` | `true` 时以 `CreateMutexW` 为权威锁做单实例 |
40
+ | `updater` | `{ manifestURL, publicKey, requireSignature }` 应用自更新 |
41
+
42
+ CLI 侧可用 `freedom config set <key> <value>` 修改;改完必须重新 `freedom build` 生效。
43
+
44
+ ## 2. 前端 SDK(壳自动注入,无需 import)
45
+
46
+ ```js
47
+ // 调用后端方法(内嵌 Go 绑定名 或 进程后端 method 名),参数按 JSON 数组透传
48
+ const sum = await freedom.invoke('Add', 1, 2);
49
+
50
+ freedom.on('tick', (data) => ...) // 订阅后端 Emit 的事件,返回 unlisten
51
+ freedom.once('ready', cb) // 一次性
52
+ freedom.off('tick', cb); freedom.emit(event, data)
53
+
54
+ freedom.window.minimize() / maximize() / setSize(w,h) / setTitle(t) / setAlwaysOnTop(true)
55
+ freedom.window.close(true) // force 跳过关闭拦截
56
+ freedom.window.create({title,url,html,width,height}) / list() / focusWindow(id) / closeWindow(id)
57
+
58
+ // 系统能力:任意能力名走同一个桥
59
+ freedom.sys('os.info', {}); freedom.sys('clipboard.read', {})
60
+ freedom.clipboard.readText() / writeText(t)
61
+ freedom.shell.open(target) // 白名单:仅 http(s)/mailto 与显式放行项
62
+ freedom.notification.show(title, body)
63
+ freedom.shortcut.register('id','Ctrl+Alt+K')
64
+ freedom.autostart.enable({name}) / isEnabled()
65
+ freedom.protocol.register('myapp')
66
+ freedom.path('data'|'config'|'cache'|'temp', name)
67
+ freedom.store.set(k,v) / get(k) / load() / keys()
68
+ freedom.process.id() / exit(0) / restart()
69
+ freedom.update.check() / install() / pending() / onAvailable(cb)
70
+ freedom.taskbar.setProgress(0.4) / setState('error') / setOverlay(dataURL)
71
+ freedom.dialog.message({title,message,buttons})
72
+ freedom.tray.create({icon: dataURL, tooltip}) / setMenu([...])
73
+ freedom.isDesktop // 是否在壳内(浏览器打开为 false)
74
+ ```
75
+
76
+ `window.go.backend.call(...)` 是 Wails 迁移别名。判断"未在桌面壳内"应给出浏览器降级,
77
+ 而不是让 Promise 直接炸页面。
78
+
79
+ ## 3. 进程后端协议(NDJSON over stdio)
80
+
81
+ 换行分隔 JSON,UTF-8,**stdout 只能写协议帧**(日志请写 stderr 或文件)。
82
+
83
+ ```jsonc
84
+ // 壳 → 后端(请求)
85
+ {"id":1,"method":"Add","params":[1,2]}
86
+ // 后端 → 壳(响应:error 为空串表示成功)
87
+ {"id":1,"result":3,"error":""}
88
+ // 后端 → 壳(主动推送,触发前端 freedom.on)
89
+ {"event":"tick","data":{"count":1}}
90
+ ```
91
+
92
+ 后端进程工作目录 = `resources/`,环境变量注入 `FREEDOM_BACKEND=1`、`FREEDOM_IPC=stdio`。
93
+ 最小 Node 实现(零依赖):
94
+
95
+ ```js
96
+ import readline from 'node:readline';
97
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
98
+ rl.on('close', () => process.exit(0)); // 壳关闭 stdin 即优雅退出,别等超时
99
+ rl.on('line', (line) => {
100
+ const r = JSON.parse(line);
101
+ const [a, b] = r.params ?? [];
102
+ process.stdout.write(JSON.stringify({ id: r.id, result: a + b, error: '' }) + '\n');
103
+ });
104
+ ```
105
+
106
+ Go / Python / Rust 同构实现见 `examples/multiproc/backends/`。Rust 侧零依赖单文件、
107
+ `rustc -O` 直编,不走 cargo。
108
+
109
+ ## 4. CLI 命令
110
+
111
+ ```
112
+ freedom # 选择显示方式:终端 TUI / Freedom Desktop
113
+ freedom tui | desktop # 直达对应显示(desktop 会按需自动重打包再拉起)
114
+ freedom init [dir] [--template full|minimal] [--force]
115
+ freedom build [--platform win|mac|linux|all] [--security none|basic|high] [--installer] [--no-cache]
116
+ freedom verify [--platform <p>] # 产物完整性校验,非零退出码 = 有问题
117
+ freedom dev [--port <n>|--url <u>|--command <cmd>] # HMR 联调壳窗口,改码免重打包
118
+ freedom dmg [--platform darwin-arm64] # macOS 上产出 .dmg(hdiutil)
119
+ freedom config [get <k>|set <k> <v>]
120
+ freedom titlebar <native|frameless> | icon <path> | security <mode>
121
+ freedom shell list|download <plat>|build <plat>
122
+ freedom keygen # 生成自更新 ed25519 密钥对(私钥只在发布方)
123
+ freedom manifest --artifact <产物> --url <下载地址> [--version x] [--notes y]
124
+ freedom agents # Agent 集成支持矩阵(本机足迹判定「是否安装」,未安装不写入)
125
+ freedom skill install --agent all [--dry-run] [--force]
126
+ freedom mcp install --agent <key> [--config <path> --format json|toml|toml-aot|yaml] [--force]
127
+ freedom mcp serve # stdio MCP 服务(一般由 agent 拉起,不手敲)
128
+ freedom update | version | tutorial | help
129
+ ```
130
+
131
+ 自动化/脚本环境请设 `FREEDOM_AUTO_UPDATE=0`,否则 npm 相关命令可能触发自动升级。
132
+
133
+ ## 5. 产物与发布
134
+
135
+ - 单平台:`dist/<name>[.exe]` + `dist/resources/{index.html,config.json,backend/}`;多平台落 `dist/<plat>/`。
136
+ - macOS:`--platform mac` 直接产出 `<name>.app.zip`(解压即用);Linux 同理为目录形态。
137
+ - `--installer`:便携 zip 恒产出;Windows 且有 `makensis` 时额外编译 `setup.exe`,否则产出已填充的 `.nsi`。
138
+ - `--security high`:resources 整体加密为 `app.bin`(PBKDF2-HMAC-SHA256 按 exe 名派生密钥 +
139
+ AES-256-CTR + Encrypt-then-MAC)+ `.integrity` 清单;磁盘无明文,校验失败壳拒绝运行。
140
+ 参数与 Go 侧 `security.go` 跨语言同步,**改一侧必须改另一侧**。
141
+ - 自更新:`freedom keygen` → 公钥写进 `updater.publicKey` → 发版用 `freedom manifest` 签
142
+ `latest.json` → 壳内 `freedom.update.check()`。清单签名串固定为
143
+ `freedom-update-v1\n{version}\n{url}\n{sha256小写}`。
144
+
145
+ ## 6. 坑清单(都真实踩过)
146
+
147
+ 1. **前端必须单文件**:壳只读一个 `index.html`,资源请内联(vite-plugin-singlefile)。
148
+ 2. **stdout 污染**:进程后端往 stdout 打日志 = 协议解析失败。日志走 stderr。
149
+ 3. **后端不退出**:stdin EOF 时必须 `process.exit(0)` / 等价处理,否则每次关窗都等满超时被强杀。
150
+ 4. **Bind 回调是异步的**:`freedom.invoke` 的 handler 跑在 worker goroutine,可并发、完成序不保证;
151
+ 壳内置的 `__freedom_window/sys/tray` 桥仍跑在 UI 消息泵内,其中涉及子进程/文件 IO 需自行异步化。
152
+ 5. **平台面不对齐**:Windows 独有能力(taskbar 进度、原生对话框、托盘)在 Linux 会明确报
153
+ not supported,macOS 部分能力仍在路上——UI 要先 `freedom.sys('os.info')` 判平台再摆按钮。
154
+ 6. **PowerShell 脚本**:含中文必须存带 BOM 的 UTF-8,`param()` 必须是首条可执行语句;
155
+ 原生命令失败要显式查 `$LASTEXITCODE`。
156
+ 7. **Windows 打 zip**:必须用 `%SystemRoot%\System32\tar.exe`(bsdtar)。Git Bash 的 GNU tar
157
+ 会抢 PATH,且不认 `-a`、把 `D:\` 当远程主机。
158
+ 8. **能力模型**:`Config.Capabilities{Allow,Deny}`(`path.Match`)在 sys/tray/window 派发前判定,
159
+ 拒绝零副作用;默认全开。