@larktask/aamp-feishu-task-agent 0.1.0-dev.173 → 0.1.1-dev.2
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/README.md +114 -18
- package/bin/agent-metadata.mjs +54 -0
- package/bin/feishu-task-agent-controller.mjs +1903 -340
- package/bin/runtime-concurrency.mjs +71 -0
- package/bin/runtime-network.mjs +13 -0
- package/bin/runtime-package-executable.mjs +254 -0
- package/bin/traecode-readiness.mjs +173 -0
- package/bootstrap/aamp-feishu-task-agent-bootstrap.sh +1433 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# aamp-feishu-task-agent
|
|
2
2
|
|
|
3
|
-
One-click manager for binding local Codex/Cursor agents to
|
|
4
|
-
Bots and running the corresponding Task bridges.
|
|
3
|
+
One-click manager for binding local Codex/Cursor/Trae/WorkBuddy agents to
|
|
4
|
+
user-owned Feishu Bots and running the corresponding Task bridges.
|
|
5
5
|
|
|
6
6
|
## Install and bind
|
|
7
7
|
|
|
@@ -26,11 +26,82 @@ The package installs the short command `feishu-task-agent`. Running that short
|
|
|
26
26
|
command without arguments shows help. Running the standalone Bootstrap without
|
|
27
27
|
arguments is equivalent to `install`.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
The supported canonical agent names are `codex`, `cursor`, `coco`, `traex`,
|
|
30
|
+
`traecli`, `workbuddy`, `workbuddy_ai`, and `aime`.
|
|
31
|
+
`--agent codex|cursor|coco|traex|traecli|workbuddy|workbuddy_ai|aime` fixes the Agent
|
|
32
|
+
for every new binding in that command instead of prompting.
|
|
33
|
+
Selection menus, saved bindings, and startup output display these canonical
|
|
34
|
+
`agent_type` values verbatim. The removed `trae` value is not accepted as a
|
|
35
|
+
command-line alias or stored binding type; affected bindings must be created
|
|
36
|
+
again with `coco`.
|
|
31
37
|
The Task Agent flow only supports the Online environment. Environment-switch
|
|
32
38
|
arguments are not supported.
|
|
33
39
|
|
|
40
|
+
The Trae-family choice uses this order:
|
|
41
|
+
|
|
42
|
+
1. `traex` → Trae CLI Next(内部版)
|
|
43
|
+
2. `coco` → Trae CLI(内部版) and the existing Next upgrade prompt
|
|
44
|
+
3. only when `coco` is absent, `traecli` → TraeCode CLI
|
|
45
|
+
|
|
46
|
+
For the internal Trae CLI flow, accepting the upgrade prompt runs the Trae CLI
|
|
47
|
+
Next installer and continues with `traex`. A new pending `coco` binding is
|
|
48
|
+
normalized and saved as `traex`, so subsequent startup output uses `traex`.
|
|
49
|
+
Declining the upgrade cancels the current binding or startup without
|
|
50
|
+
invoking legacy `login`, `login status`, or ACP commands, and leaves saved
|
|
51
|
+
bindings unchanged. Native ACP startup is exactly `traex acp serve`; the
|
|
52
|
+
generated command intentionally omits `--yolo` and never adds a bypass or
|
|
53
|
+
approval flag.
|
|
54
|
+
|
|
55
|
+
TraeCode CLI is stored as `agent_type: traecli` and starts native ACP with
|
|
56
|
+
`traecli acp serve`. If that command is unavailable, the launcher asks before
|
|
57
|
+
running `traecli update`, then checks ACP again. It runs
|
|
58
|
+
`traecli doctor --json` without entering the TUI; model errors ask you to open
|
|
59
|
+
TraeCode CLI and use `/model`. The launcher never runs a TraeCode login/status
|
|
60
|
+
command and never falls back to CLI Bridge.
|
|
61
|
+
|
|
62
|
+
A saved `traecli` binding remains TraeCode CLI even after `traex` is installed.
|
|
63
|
+
Ready `coco` bindings keep their stored identity and mailbox, while runtime
|
|
64
|
+
startup output displays the resolved raw type `traex` or `traecli` that will
|
|
65
|
+
actually be used.
|
|
66
|
+
|
|
67
|
+
`workbuddy` is detected only from the standard macOS WorkBuddy.app installation:
|
|
68
|
+
`/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy`.
|
|
69
|
+
The launcher uses the app-bundled `codebuddy --acp` command.
|
|
70
|
+
It does not run a WorkBuddy login command. Open WorkBuddy and complete login
|
|
71
|
+
before starting a binding. Startup verifies login by creating and immediately
|
|
72
|
+
closing a temporary ACP session without sending a model prompt. Nonstandard
|
|
73
|
+
paths and non-macOS installations are not auto-detected.
|
|
74
|
+
|
|
75
|
+
`workbuddy_ai` is the international WorkBuddy AI application. It is detected
|
|
76
|
+
only at
|
|
77
|
+
`/Applications/WorkBuddy AI.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy`.
|
|
78
|
+
Its persisted and displayed Agent type remains the literal `workbuddy_ai`.
|
|
79
|
+
When both WorkBuddy applications are installed, `workbuddy` and
|
|
80
|
+
`workbuddy_ai` are offered independently. The Task Agent does not run a login
|
|
81
|
+
command for either product; complete login in the selected desktop app.
|
|
82
|
+
|
|
83
|
+
`aime` is the ByteDance-internal remote AIME Agent. It is offered only when a
|
|
84
|
+
short `ping aime.bytedance.net` probe succeeds; an explicit `--agent aime`
|
|
85
|
+
selection uses the same gate before any AIME install or login. The launcher
|
|
86
|
+
installs the exact AIME version pinned by the bootstrap as
|
|
87
|
+
`@tengchengwei/aime-acp@<version>` from `https://bnpm.byted.org` into
|
|
88
|
+
the shared `$HOME/.aamp/npm-global` prefix, removes the obsolete unscoped
|
|
89
|
+
`aime-acp` package when present, then runs the scoped package's absolute
|
|
90
|
+
`dist/bin.js` entry with `--site cn`.
|
|
91
|
+
Readiness is authoritative only after `auth status`/`auth login` and
|
|
92
|
+
`doctor --site cn --json` succeed; ping is only the one-click visibility gate.
|
|
93
|
+
The generated bridge config rejects attachments and limits AIME task dispatch
|
|
94
|
+
to one task at a time because AIME is remote and does not use the local
|
|
95
|
+
workspace. All other Agents default to local execution; AIME is explicitly
|
|
96
|
+
configured as remote. It reads requested Feishu/Lark data with its own
|
|
97
|
+
remote-native capabilities and identity, without a local `lark-cli` profile or
|
|
98
|
+
user OAuth. The local Feishu Bridge still uses Bot App credentials and is the
|
|
99
|
+
only writer of the current Task's comment, status, and delivery. Remote
|
|
100
|
+
attachments and local file delivery are unsupported; use text or HTTP(S) links.
|
|
101
|
+
`aamp-feishu-task-bridge` is deprecated and is not an AIME implementation
|
|
102
|
+
target. AIME `auth`/`doctor` success proves adapter readiness only, not access
|
|
103
|
+
to a particular Feishu group.
|
|
104
|
+
|
|
34
105
|
## Commands
|
|
35
106
|
|
|
36
107
|
```bash
|
|
@@ -43,16 +114,22 @@ feishu-task-agent update
|
|
|
43
114
|
feishu-task-agent help
|
|
44
115
|
```
|
|
45
116
|
|
|
46
|
-
- `install`
|
|
47
|
-
|
|
117
|
+
- `install` preserves saved pairs and atomically saves each accepted pair as
|
|
118
|
+
pending before it starts any Bridge. If the Bot App ID is already bound,
|
|
119
|
+
replacement requires explicit confirmation. A startup failure leaves the
|
|
120
|
+
pending pair available for a later `start` retry; successful Bridge processes
|
|
121
|
+
remain running.
|
|
48
122
|
- `start` multi-selects saved pairs. Selecting `全部` takes precedence over any
|
|
49
123
|
other selection. If no pair is configured, the terminal prints the full
|
|
50
|
-
install command.
|
|
124
|
+
install command. Its final summary retains the successful/planned count and
|
|
125
|
+
lists the concrete successful, failed, and cancelled pairs.
|
|
51
126
|
- `list` prints saved Agent-Bot pairs and never prints App Secrets.
|
|
52
|
-
- `add`
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
127
|
+
- `add` uses the same confirmed atomic add/replace behavior and saves each pair
|
|
128
|
+
as pending. It does not acquire an Agent lease, perform ACP pairing, or start
|
|
129
|
+
any Bridge. When another Task Agent is already running, its Bridges are not
|
|
130
|
+
hot-switched or stopped; the saved configuration is used by the next `start`.
|
|
131
|
+
The first subsequent `start` completes pairing, creates runtime configuration,
|
|
132
|
+
and keeps the selected Bridges running.
|
|
56
133
|
- `remove` multi-selects pairs, with a `全部` option. It only removes saved
|
|
57
134
|
pairing records; Bridges that are already running are not stopped.
|
|
58
135
|
- `update` refreshes the installed short command and package.
|
|
@@ -63,7 +140,8 @@ and Enter to confirm the selection.
|
|
|
63
140
|
|
|
64
141
|
Bridge startup is serial. A failure is printed and recorded, then the next pair
|
|
65
142
|
is attempted. The command exits as a startup failure only when every selected
|
|
66
|
-
pair fails.
|
|
143
|
+
pair fails. User-cancelled Coco selections are reported separately and
|
|
144
|
+
are not recorded as system failures. Within one command invocation, all Bots for the same Agent/AAMP
|
|
67
145
|
host reuse one ACP Bridge process. Independent invocations do not attach to an
|
|
68
146
|
existing process; an Agent lease prevents competing runtimes from being
|
|
69
147
|
started for the same Agent identity.
|
|
@@ -107,12 +185,30 @@ version. They remain visible to `list` and can be deleted with `remove`, but
|
|
|
107
185
|
`start` skips them with an explicit error and continues with the next binding.
|
|
108
186
|
|
|
109
187
|
If a saved `lark-cli` profile is missing, `start` recreates it from the stored
|
|
110
|
-
App ID/App Secret
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
188
|
+
App ID/App Secret. User OAuth is optional by default and never blocks Task/IM
|
|
189
|
+
Bridge startup. The embedded version-2 scope manifest configures only the Task
|
|
190
|
+
and IM application capabilities used by this package; it does not expand
|
|
191
|
+
Base, Calendar, Mail, Minutes, VC, Wiki, or other user domains. Existing bot
|
|
192
|
+
profiles are rewritten with `domains: ["task"]` when they are saved again.
|
|
193
|
+
|
|
194
|
+
`FEISHU_USER_AUTH_MODE` controls the local user capability policy:
|
|
195
|
+
|
|
196
|
+
- `optional` (default) reuses an existing valid token, records unavailable
|
|
197
|
+
optional capabilities, and continues without opening a browser.
|
|
198
|
+
- `required` requests the fixed Task user scope set once and fails only when
|
|
199
|
+
those explicit scopes remain missing. The command never passes `--domain`.
|
|
200
|
+
- `disabled` skips user capability checks and runs Task-only.
|
|
201
|
+
|
|
202
|
+
Granted and missing user scopes are recorded without credentials under
|
|
203
|
+
`~/.aamp/feishu-bridge/auth-capabilities/<profile>.json`. Legacy
|
|
204
|
+
`FEISHU_USER_AUTH_EXCLUDES` values are intersected with the current explicit
|
|
205
|
+
request, so stale or tenant-invisible scope names cannot create a new failure.
|
|
206
|
+
|
|
207
|
+
If the persisted Agent or Feishu Bridge mailbox identity is missing or has
|
|
208
|
+
changed, startup rejects that pair and asks the user to bind it again instead
|
|
209
|
+
of reporting a false success. The same Online `LARKSUITE_CLI_CONFIG_DIR` is
|
|
210
|
+
passed to Feishu Bridge, Agent Bridge, and the local Codex/Cursor/Trae process
|
|
211
|
+
so task execution resolves the exact profile created during binding.
|
|
116
212
|
|
|
117
213
|
## Local logs and diagnostics
|
|
118
214
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { realpathSync } from 'node:fs'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
|
|
4
|
+
export const TASK_AGENT_METADATA = Object.freeze({
|
|
5
|
+
codex: Object.freeze({ executionLocation: 'local' }),
|
|
6
|
+
cursor: Object.freeze({ executionLocation: 'local' }),
|
|
7
|
+
coco: Object.freeze({ executionLocation: 'local' }),
|
|
8
|
+
traex: Object.freeze({ executionLocation: 'local' }),
|
|
9
|
+
traecli: Object.freeze({ executionLocation: 'local' }),
|
|
10
|
+
workbuddy: Object.freeze({ executionLocation: 'local' }),
|
|
11
|
+
workbuddy_ai: Object.freeze({ executionLocation: 'local' }),
|
|
12
|
+
aime: Object.freeze({
|
|
13
|
+
executionLocation: 'remote',
|
|
14
|
+
attachmentPolicy: 'reject',
|
|
15
|
+
taskDispatchConcurrency: 1,
|
|
16
|
+
}),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export const TASK_AGENT_TYPES = Object.freeze(Object.keys(TASK_AGENT_METADATA))
|
|
20
|
+
|
|
21
|
+
export function resolveTaskAgentMetadata(agentType) {
|
|
22
|
+
const normalized = String(agentType ?? '').trim()
|
|
23
|
+
const metadata = TASK_AGENT_METADATA[normalized]
|
|
24
|
+
if (!metadata) throw new Error(`Unknown Task Agent type: ${normalized || '(empty)'}`)
|
|
25
|
+
return { ...metadata }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isMainModule() {
|
|
29
|
+
if (!process.argv[1]) return false
|
|
30
|
+
try {
|
|
31
|
+
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))
|
|
32
|
+
} catch {
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isMainModule()) {
|
|
38
|
+
if (process.argv[2] !== '--json' || !process.argv[3] || process.argv[4]) {
|
|
39
|
+
console.error('Usage: node agent-metadata.mjs --json <agent-type>')
|
|
40
|
+
process.exitCode = 2
|
|
41
|
+
} else {
|
|
42
|
+
try {
|
|
43
|
+
const agentType = process.argv[3].trim()
|
|
44
|
+
process.stdout.write(`${JSON.stringify({
|
|
45
|
+
schemaVersion: 1,
|
|
46
|
+
agentType,
|
|
47
|
+
...resolveTaskAgentMetadata(agentType),
|
|
48
|
+
})}\n`)
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
51
|
+
process.exitCode = 1
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|