@11agents/cli 0.1.23 → 0.1.25
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 +52 -0
- package/bin/11agents.js +12 -0
- package/mobile-runtime/README.md +19 -0
- package/mobile-runtime/configs/platforms/xiaohongshu_d01.json +73 -0
- package/mobile-runtime/configs/platforms/xiaohongshu_d02.json +70 -0
- package/mobile-runtime/configs/platforms/xiaohongshu_d03.json +73 -0
- package/mobile-runtime/configs/publish_policy.json +40 -0
- package/mobile-runtime/data-templates/README.md +4 -0
- package/mobile-runtime/data-templates/accounts.example.csv +6 -0
- package/mobile-runtime/data-templates/devices.example.csv +2 -0
- package/mobile-runtime/data-templates/publish_records.example.jsonl +2 -0
- package/mobile-runtime/data-templates/tasks.example.jsonl +5 -0
- package/mobile-runtime/data-templates/video_metrics.example.jsonl +1 -0
- package/mobile-runtime/python/pyproject.toml +34 -0
- package/mobile-runtime/python/src/device_control/__init__.py +5 -0
- package/mobile-runtime/python/src/device_control/adapters/__init__.py +31 -0
- package/mobile-runtime/python/src/device_control/adapters/base.py +43 -0
- package/mobile-runtime/python/src/device_control/adapters/facebook.py +30 -0
- package/mobile-runtime/python/src/device_control/adapters/instagram.py +25 -0
- package/mobile-runtime/python/src/device_control/adapters/reddit.py +29 -0
- package/mobile-runtime/python/src/device_control/adapters/tiktok.py +25 -0
- package/mobile-runtime/python/src/device_control/adapters/x.py +29 -0
- package/mobile-runtime/python/src/device_control/adapters/xiaohongshu.py +26 -0
- package/mobile-runtime/python/src/device_control/adb.py +161 -0
- package/mobile-runtime/python/src/device_control/appium_client.py +131 -0
- package/mobile-runtime/python/src/device_control/appium_manager.py +403 -0
- package/mobile-runtime/python/src/device_control/cli.py +1608 -0
- package/mobile-runtime/python/src/device_control/entrypoints.py +60 -0
- package/mobile-runtime/python/src/device_control/locks.py +162 -0
- package/mobile-runtime/python/src/device_control/metrics/__init__.py +33 -0
- package/mobile-runtime/python/src/device_control/metrics/collectors.py +320 -0
- package/mobile-runtime/python/src/device_control/metrics/tiktok_account_adb.py +367 -0
- package/mobile-runtime/python/src/device_control/metrics/tiktok_video_adb.py +714 -0
- package/mobile-runtime/python/src/device_control/models.py +439 -0
- package/mobile-runtime/python/src/device_control/publish_policy.py +173 -0
- package/mobile-runtime/python/src/device_control/publishers/__init__.py +24 -0
- package/mobile-runtime/python/src/device_control/publishers/facebook_adb.py +494 -0
- package/mobile-runtime/python/src/device_control/publishers/instagram_adb.py +663 -0
- package/mobile-runtime/python/src/device_control/publishers/reddit_adb.py +595 -0
- package/mobile-runtime/python/src/device_control/publishers/tiktok_adb.py +477 -0
- package/mobile-runtime/python/src/device_control/publishers/tiktok_appium.py +259 -0
- package/mobile-runtime/python/src/device_control/publishers/ui_helpers.py +372 -0
- package/mobile-runtime/python/src/device_control/publishers/x_adb.py +636 -0
- package/mobile-runtime/python/src/device_control/publishers/xiaohongshu_adb.py +1143 -0
- package/mobile-runtime/python/src/device_control/store.py +137 -0
- package/mobile-runtime/scripts/appium_smoke.py +71 -0
- package/mobile-runtime/skills/android-collect-tiktok-metrics/SKILL.md +60 -0
- package/mobile-runtime/skills/android-collect-tiktok-metrics/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-group-control-cli/SKILL.md +76 -0
- package/mobile-runtime/skills/android-group-control-cli/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-group-control-cli/references/command-reference.md +122 -0
- package/mobile-runtime/skills/android-publish-facebook/SKILL.md +41 -0
- package/mobile-runtime/skills/android-publish-facebook/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-publish-instagram/SKILL.md +45 -0
- package/mobile-runtime/skills/android-publish-instagram/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-publish-reddit/SKILL.md +41 -0
- package/mobile-runtime/skills/android-publish-reddit/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-publish-tiktok/SKILL.md +43 -0
- package/mobile-runtime/skills/android-publish-tiktok/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-publish-x/SKILL.md +40 -0
- package/mobile-runtime/skills/android-publish-x/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/android-publish-xiaohongshu/SKILL.md +50 -0
- package/mobile-runtime/skills/android-publish-xiaohongshu/agents/openai.yaml +4 -0
- package/mobile-runtime/skills/mobile-publish-data-collection/SKILL.md +49 -0
- package/mobile-runtime/skills/mobile-publish-device-health/SKILL.md +47 -0
- package/mobile-runtime/skills/mobile-publish-execution/SKILL.md +57 -0
- package/mobile-runtime/skills/mobile-publish-records/SKILL.md +29 -0
- package/package.json +4 -1
- package/scripts/mobile-postinstall.js +26 -0
- package/src/commands/mobile.js +695 -0
- package/src/commands/runtime.js +63 -28
package/src/commands/runtime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
2
|
import { createHash } from 'node:crypto'
|
|
3
|
-
import {
|
|
3
|
+
import { createWriteStream, readFileSync } from 'node:fs'
|
|
4
4
|
import { appendFile, mkdir, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises'
|
|
5
5
|
import os from 'node:os'
|
|
6
6
|
import { dirname, resolve } from 'node:path'
|
|
@@ -180,6 +180,15 @@ async function runWithRuntimeHeartbeat(operation, registration, flags, deps, hea
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
function createChunkLogger(filePath) {
|
|
184
|
+
if (!filePath) return null
|
|
185
|
+
const stream = createWriteStream(filePath, { flags: 'a' })
|
|
186
|
+
return {
|
|
187
|
+
write: chunk => { stream.write(chunk) },
|
|
188
|
+
close: () => new Promise(resolve => stream.end(resolve)),
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
183
192
|
async function runWithDaemonRetry(label, operation, deps, retryState) {
|
|
184
193
|
while (true) {
|
|
185
194
|
try {
|
|
@@ -722,9 +731,10 @@ function projectDirForTask(task, flags = {}, deps) {
|
|
|
722
731
|
return buildRuntimeProjectDir(projectSlugForTask(task, flags), { homeDir: deps.homeDir })
|
|
723
732
|
}
|
|
724
733
|
|
|
725
|
-
async function projectSyncToken(project, flags = {}, deps = {}) {
|
|
734
|
+
async function projectSyncToken(project, flags = {}, deps = {}, workspaceToken = '') {
|
|
726
735
|
return resolveProjectToken(project, {
|
|
727
736
|
homeDir: deps.homeDir,
|
|
737
|
+
token: workspaceToken || '',
|
|
728
738
|
fallbackToken: flags.token,
|
|
729
739
|
})
|
|
730
740
|
}
|
|
@@ -935,7 +945,7 @@ async function syncDatabaseIfNeeded({ task, workdir, config, flags, deps }) {
|
|
|
935
945
|
if (!spec.syncRequired && localRevision === spec.cloudRevision) return { synced: false, cloud_revision: localRevision }
|
|
936
946
|
|
|
937
947
|
const project = projectSlugForTask(task)
|
|
938
|
-
const token = await projectSyncToken(projectTokenCandidatesForTask(task, flags), flags, deps)
|
|
948
|
+
const token = await projectSyncToken(projectTokenCandidatesForTask(task, flags), flags, deps, task.workspace?.swarm_token)
|
|
939
949
|
const syncConfig = { ...config, token }
|
|
940
950
|
const result = await deps.requestJson(`/api/projects/${project}/database/sync`, {
|
|
941
951
|
method: 'POST',
|
|
@@ -994,7 +1004,7 @@ async function prepareRuntimeTask(task, flags, deps, config) {
|
|
|
994
1004
|
|
|
995
1005
|
// Resolve and inject the project token so hosted MCP calls spawned by the
|
|
996
1006
|
// runtime agent can authenticate without needing credentials on disk.
|
|
997
|
-
const projectToken = await projectSyncToken(projectTokenCandidatesForTask(task, flags), flags, deps)
|
|
1007
|
+
const projectToken = await projectSyncToken(projectTokenCandidatesForTask(task, flags), flags, deps, task.workspace?.swarm_token)
|
|
998
1008
|
const env = {
|
|
999
1009
|
...process.env,
|
|
1000
1010
|
...agentEnvironment(task),
|
|
@@ -1134,8 +1144,13 @@ async function runCodex({ task, prompt, flags = {}, deps }) {
|
|
|
1134
1144
|
const taskEnv = task.execution_context?.env || process.env
|
|
1135
1145
|
const stdoutLogPath = runDir ? path.join(runDir, 'stdout.log') : ''
|
|
1136
1146
|
if (stdoutLogPath) await writeRunFile(runDir, 'stdout.log', '')
|
|
1137
|
-
|
|
1138
|
-
let result
|
|
1147
|
+
let stdoutLogger = createChunkLogger(stdoutLogPath)
|
|
1148
|
+
let result
|
|
1149
|
+
try {
|
|
1150
|
+
result = await deps.runProcess(codexBin, args, { input: `/goal ${prompt}`, cwd: workdir, env: taskEnv, onStdoutChunk: stdoutLogger?.write })
|
|
1151
|
+
} finally {
|
|
1152
|
+
await stdoutLogger?.close()
|
|
1153
|
+
}
|
|
1139
1154
|
|
|
1140
1155
|
// When --codex-sandbox is set but bwrap is unavailable in the container (missing CAP_NET_ADMIN),
|
|
1141
1156
|
// fall back to --yolo exec which runs commands directly without bwrap.
|
|
@@ -1147,7 +1162,12 @@ async function runCodex({ task, prompt, flags = {}, deps }) {
|
|
|
1147
1162
|
deps.log(JSON.stringify({ warning: 'bwrap unavailable in this environment, retrying without sandbox', fallback_command: fallbackLine }))
|
|
1148
1163
|
await updateRunMeta(runDir, { bwrap_fallback: true, fallback_command_line: fallbackLine })
|
|
1149
1164
|
if (stdoutLogPath) await writeRunFile(runDir, 'stdout.log', '')
|
|
1150
|
-
|
|
1165
|
+
stdoutLogger = createChunkLogger(stdoutLogPath)
|
|
1166
|
+
try {
|
|
1167
|
+
result = await deps.runProcess(codexBin, fallbackArgs, { input: `/goal ${prompt}`, cwd: workdir, env: taskEnv, onStdoutChunk: stdoutLogger?.write })
|
|
1168
|
+
} finally {
|
|
1169
|
+
await stdoutLogger?.close()
|
|
1170
|
+
}
|
|
1151
1171
|
}
|
|
1152
1172
|
}
|
|
1153
1173
|
const rawStdout = String(result.stdout || '')
|
|
@@ -1232,13 +1252,18 @@ async function runClaude({ task, prompt, flags = {}, deps }) {
|
|
|
1232
1252
|
|
|
1233
1253
|
const stdoutLogPath = runDir ? path.join(runDir, 'stdout.log') : ''
|
|
1234
1254
|
if (stdoutLogPath) await writeRunFile(runDir, 'stdout.log', '')
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1255
|
+
const stdoutLogger = createChunkLogger(stdoutLogPath)
|
|
1256
|
+
let result
|
|
1257
|
+
try {
|
|
1258
|
+
result = await deps.runProcess(claudeBin, args, {
|
|
1259
|
+
input: prompt,
|
|
1260
|
+
cwd: workdir,
|
|
1261
|
+
env: task.execution_context?.env || process.env,
|
|
1262
|
+
onStdoutChunk: stdoutLogger?.write,
|
|
1263
|
+
})
|
|
1264
|
+
} finally {
|
|
1265
|
+
await stdoutLogger?.close()
|
|
1266
|
+
}
|
|
1242
1267
|
|
|
1243
1268
|
const rawStdout = String(result.stdout || '')
|
|
1244
1269
|
const output = rawStdout.trim()
|
|
@@ -1339,24 +1364,32 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
|
|
|
1339
1364
|
},
|
|
1340
1365
|
}
|
|
1341
1366
|
|
|
1342
|
-
deps.log(JSON.stringify({
|
|
1367
|
+
deps.log(JSON.stringify({
|
|
1368
|
+
claimed: runtimeTask.id,
|
|
1369
|
+
task_id: runtimeTask.id,
|
|
1370
|
+
task_title: String(runtimeTask.issue?.title || runtimeTask.title || ''),
|
|
1371
|
+
project_slug: String(runtimeTask.workspace?.slug || runtimeTask.workspace_slug || ''),
|
|
1372
|
+
runtime_id: runtime.id,
|
|
1373
|
+
}, null, 2))
|
|
1343
1374
|
await writeCurrentClaim(deps, runtimeTask, machineKey)
|
|
1344
1375
|
let completion = null
|
|
1345
1376
|
let executionContext = null
|
|
1346
1377
|
if (runtimeTask.workspace?.slug) {
|
|
1347
|
-
const token = await projectSyncToken(projectTokenCandidatesForTask(runtimeTask, flags), flags, deps)
|
|
1378
|
+
const token = await projectSyncToken(projectTokenCandidatesForTask(runtimeTask, flags), flags, deps, runtimeTask.workspace?.swarm_token)
|
|
1348
1379
|
const syncConfig = { ...config, token }
|
|
1349
1380
|
try {
|
|
1350
1381
|
await runWithTaskRetry('sync knowledge base', () => (
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1382
|
+
runWithRuntimeHeartbeat(() => (
|
|
1383
|
+
deps.syncKnowledge({
|
|
1384
|
+
project: runtimeTask.workspace.slug,
|
|
1385
|
+
mode: 'pull',
|
|
1386
|
+
server: flags.server,
|
|
1387
|
+
token,
|
|
1388
|
+
}, {
|
|
1389
|
+
requestJson: (apiPath, options = {}) => deps.requestJson(apiPath, { ...options, config: syncConfig }),
|
|
1390
|
+
log: () => {},
|
|
1391
|
+
})
|
|
1392
|
+
), registration, flags, deps, heartbeatIntervalMs)
|
|
1360
1393
|
), deps)
|
|
1361
1394
|
} catch (error) {
|
|
1362
1395
|
completion = {
|
|
@@ -1405,7 +1438,7 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
|
|
|
1405
1438
|
if (executionContext && runtimeTask.workspace?.slug) {
|
|
1406
1439
|
const isDeepOrganize = Boolean(knowledgeDeepOrganizeSpec(runtimeTask))
|
|
1407
1440
|
const syncBack = isDeepOrganize ? deps.mcpKnowledgeSync : deps.syncKnowledge
|
|
1408
|
-
const token = await projectSyncToken(projectTokenCandidatesForTask(runtimeTask, flags), flags, deps)
|
|
1441
|
+
const token = await projectSyncToken(projectTokenCandidatesForTask(runtimeTask, flags), flags, deps, runtimeTask.workspace?.swarm_token)
|
|
1409
1442
|
const syncConfig = { ...config, token }
|
|
1410
1443
|
const pushKnowledge = () => syncBack({
|
|
1411
1444
|
project: runtimeTask.workspace.slug,
|
|
@@ -1418,7 +1451,7 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
|
|
|
1418
1451
|
})
|
|
1419
1452
|
if (isDeepOrganize) {
|
|
1420
1453
|
try {
|
|
1421
|
-
await pushKnowledge
|
|
1454
|
+
await runWithRuntimeHeartbeat(pushKnowledge, registration, flags, deps, heartbeatIntervalMs)
|
|
1422
1455
|
} catch (error) {
|
|
1423
1456
|
const message = `Knowledge sync push failed before task completion: ${errorMessage(error)}. If a knowledge_snapshot is included in completion, the platform will write it directly.`
|
|
1424
1457
|
completion = {
|
|
@@ -1429,7 +1462,9 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
|
|
|
1429
1462
|
}
|
|
1430
1463
|
} else {
|
|
1431
1464
|
try {
|
|
1432
|
-
await runWithTaskRetry('sync knowledge base back to cloud',
|
|
1465
|
+
await runWithTaskRetry('sync knowledge base back to cloud', () => (
|
|
1466
|
+
runWithRuntimeHeartbeat(pushKnowledge, registration, flags, deps, heartbeatIntervalMs)
|
|
1467
|
+
), deps)
|
|
1433
1468
|
} catch (error) {
|
|
1434
1469
|
const message = `Knowledge sync push failed before task completion: ${errorMessage(error)}`
|
|
1435
1470
|
completion = {
|