@songsid/agend 2.1.3 → 2.1.4-beta.1
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.
- package/LICENSE +21 -0
- package/README.md +2 -2
- package/README.zh-TW.md +2 -2
- package/dist/backend/opencode.js +2 -4
- package/dist/backend/opencode.js.map +1 -1
- package/dist/cli.js +9 -10
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +0 -9
- package/dist/daemon.js +0 -53
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +0 -2
- package/dist/fleet-manager.js +0 -31
- package/dist/fleet-manager.js.map +1 -1
- package/dist/quickstart.js +4 -2
- package/dist/quickstart.js.map +1 -1
- package/dist/setup-wizard.d.ts +4 -2
- package/dist/setup-wizard.js +2 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/ui/dashboard.html +5 -4
- package/dist/web-api.js +2 -2
- package/dist/web-api.js.map +1 -1
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AgEnD contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -131,7 +131,7 @@ graph LR
|
|
|
131
131
|
- Telegram bot token ([@BotFather](https://t.me/BotFather)) or Discord bot token
|
|
132
132
|
- Groq API key (optional, for voice)
|
|
133
133
|
|
|
134
|
-
> **⚠️** All CLI backends run with `--dangerously-skip-permissions` (or equivalent). See [Security](SECURITY.md).
|
|
134
|
+
> **⚠️** All CLI backends run with `--dangerously-skip-permissions` (or equivalent). See [Security](docs/SECURITY.md).
|
|
135
135
|
|
|
136
136
|
> **WSL (Windows Subsystem for Linux):** Fully supported. The install script auto-detects WSL and avoids using Windows `node.exe` from PATH. If you encounter PATH issues, add to `/etc/wsl.conf`:
|
|
137
137
|
> ```ini
|
|
@@ -145,7 +145,7 @@ graph LR
|
|
|
145
145
|
- [Features](docs/features.md) — detailed feature documentation
|
|
146
146
|
- [CLI Reference](docs/cli.md) — all commands and options
|
|
147
147
|
- [Configuration](docs/configuration.md) — fleet.yaml complete reference
|
|
148
|
-
- [Security](SECURITY.md) — trust model and hardening
|
|
148
|
+
- [Security](docs/SECURITY.md) — trust model and hardening
|
|
149
149
|
- [Development Setup](docs/development.md) — working on AgEnD itself
|
|
150
150
|
|
|
151
151
|
## Discord ClassicBot
|
package/README.zh-TW.md
CHANGED
|
@@ -116,14 +116,14 @@ graph LR
|
|
|
116
116
|
- Telegram bot token([@BotFather](https://t.me/BotFather))或 Discord bot token
|
|
117
117
|
- Groq API key(選用,語音轉文字用)
|
|
118
118
|
|
|
119
|
-
> **⚠️** 所有 CLI 後端都以 `--dangerously-skip-permissions`(或等效參數)執行。詳見 [Security](SECURITY.md)。
|
|
119
|
+
> **⚠️** 所有 CLI 後端都以 `--dangerously-skip-permissions`(或等效參數)執行。詳見 [Security](docs/SECURITY.zh-TW.md)。
|
|
120
120
|
|
|
121
121
|
## 文件
|
|
122
122
|
|
|
123
123
|
- [Features](docs/features.md) — 功能詳細說明
|
|
124
124
|
- [CLI Reference](docs/cli.md) — 所有指令與選項
|
|
125
125
|
- [Configuration](docs/configuration.zh-TW.md) — fleet.yaml 完整設定參考
|
|
126
|
-
- [Security](SECURITY.md) — 信任模型與安全強化
|
|
126
|
+
- [Security](docs/SECURITY.zh-TW.md) — 信任模型與安全強化
|
|
127
127
|
- [開發環境設定](docs/development.md) — 開發 AgEnD 本身
|
|
128
128
|
|
|
129
129
|
## 已知限制
|
package/dist/backend/opencode.js
CHANGED
|
@@ -13,7 +13,8 @@ export class OpenCodeBackend {
|
|
|
13
13
|
buildCommand(config) {
|
|
14
14
|
// Use per-instance config via OPENCODE_CONFIG env (set in writeConfig)
|
|
15
15
|
let cmd = this.binaryPath;
|
|
16
|
-
// Resume
|
|
16
|
+
// Resume only a session explicitly persisted for this instance. OpenCode's
|
|
17
|
+
// --continue is global and can hijack an unrelated session from another cwd.
|
|
17
18
|
if (!config.skipResume) {
|
|
18
19
|
const sessionIdFile = join(this.instanceDir, "session-id");
|
|
19
20
|
if (existsSync(sessionIdFile)) {
|
|
@@ -21,9 +22,6 @@ export class OpenCodeBackend {
|
|
|
21
22
|
if (sid)
|
|
22
23
|
cmd += ` --session ${sid}`;
|
|
23
24
|
}
|
|
24
|
-
else {
|
|
25
|
-
cmd += " --continue";
|
|
26
|
-
}
|
|
27
25
|
}
|
|
28
26
|
if (config.model) {
|
|
29
27
|
const model = validateModel(config.model);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/backend/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAqG,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAElL,MAAM,OAAO,eAAe;IAIN;IAHX,UAAU,GAAG,UAAU,CAAC;IACzB,UAAU,CAAS;IAE3B,YAAoB,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;QACrC,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC;IAED,YAAY,CAAC,MAAwB;QACnC,uEAAuE;QACvE,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;QAE1B
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/backend/opencode.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -598,20 +598,19 @@ const backend = program.command("backend").description("Backend diagnostics");
|
|
|
598
598
|
backend
|
|
599
599
|
.command("doctor")
|
|
600
600
|
.description("Check backend prerequisites and configuration")
|
|
601
|
-
.argument("[backend]", "Backend to check (claude-code, codex,
|
|
601
|
+
.argument("[backend]", "Backend to check (claude-code, codex, opencode, kiro-cli, antigravity, grok, gemini-cli [deprecated])", "claude-code")
|
|
602
602
|
.action(async (backendName) => {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
"opencode": { binary: "opencode", label: "OpenCode", install: "go install github.com/opencode-ai/opencode@latest", auth: "Configure provider API key" },
|
|
608
|
-
"kiro-cli": { binary: "kiro-cli", label: "Kiro CLI", install: "brew install --cask kiro-cli", auth: "kiro-cli login (AWS Builder ID)" },
|
|
609
|
-
};
|
|
610
|
-
const info = backends[backendName];
|
|
603
|
+
// Single source of truth for backend metadata — a hand-copied list here is
|
|
604
|
+
// how the doctor previously drifted (missing antigravity/grok entirely).
|
|
605
|
+
const { BACKENDS } = await import("./setup-wizard.js");
|
|
606
|
+
const info = BACKENDS.find(b => b.id === backendName);
|
|
611
607
|
if (!info) {
|
|
612
|
-
console.error(`Unknown backend: ${backendName}. Available: ${
|
|
608
|
+
console.error(`Unknown backend: ${backendName}. Available: ${BACKENDS.map(b => b.id).join(", ")}`);
|
|
613
609
|
process.exit(1);
|
|
614
610
|
}
|
|
611
|
+
if (info.deprecated) {
|
|
612
|
+
console.warn(`⚠️ ${info.label} is deprecated (stops 2026-06-18). Consider switching to backend: antigravity`);
|
|
613
|
+
}
|
|
615
614
|
let issues = 0;
|
|
616
615
|
const ok = (msg) => console.log(` \x1b[32m✓\x1b[0m ${msg}`);
|
|
617
616
|
const fail = (msg) => { issues++; console.log(` \x1b[31m✗\x1b[0m ${msg}`); };
|