@windypro-rourou/dsh-logcat 0.2.2 → 0.2.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 (3) hide show
  1. package/README.md +7 -1
  2. package/lib/index.js +109 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -13,7 +13,13 @@ DSH Web GUI 的安卓实机调试面板(类似 Android Studio 的 Logcat 视
13
13
  - 关键词过滤、暂停/继续(暂停时缓冲,恢复自动回放)、清空、复制、导出 .txt
14
14
  - 窗口化渲染 + 自动滚动(滚动手动上翻时自动停用)
15
15
  - 未授权设备提示「请在手机上点击允许 USB 调试」
16
- - **Agent 工具**:`logcat_recent`(读取某设备最近 N 条日志,支持级别/关键词过滤)。
16
+ - **Agent 工具**:
17
+ - `logcat_devices`:列出已连接设备(serial / model / state),判断能否实机调试。
18
+ - `adb_exec`:在指定设备执行 `adb shell` 命令(安装 APK、启动 Activity、查进程、截图、dump UI 等),
19
+ 破坏性操作(卸载 / 重启 / 清数据)需先确认。
20
+ - `logcat_recent`:读取某设备最近 N 条日志,支持级别 / 关键词过滤。
21
+ - **实机调试工作流**:构建安卓应用时,agent 的通告会动态列出当前已连接设备(serial + 型号),
22
+ 可先向用户确认后用 `adb_exec` 安装 / 启动、`logcat_recent` 查看崩溃日志,闭环真机调试。
17
23
  - **附加能力**:`POST /api/dsh-logcat/exec` 可对设备执行 `adb shell` 命令(UI 后续版本可扩展)。
18
24
 
19
25
  ## 安装
package/lib/index.js CHANGED
@@ -36,7 +36,19 @@ const SECTION_ORDER = 152
36
36
 
37
37
  /** Model-facing announcement: plugin presence, capabilities, and limits. */
38
38
  export const LOGCAT_GUIDANCE =
39
- '本机已安装 dsh-logcat 插件(DSH Web GUI 的安卓实机调试面板):侧边栏「Logcat」入口;自动探测本机 adb(ANDROID_HOME / 默认 SDK 路径),对处于调试模式的已连接设备自动附加 logcat 流(threadtime 格式,每设备保留最近 2000 行环形缓冲);Web 面板支持设备切换、级别/关键词过滤、暂停/清空/导出;agent 可用 logcat_recent 工具读取最近日志。限制:需设备开启 USB 调试并授权本机;logcat 输出可能含敏感信息;执行 adb 命令消耗真实设备资源,先确认再操作。用户提到「Logcat / 安卓日志 / 实机调试 / adb 日志」时即指本插件,请据此协作。'
39
+ '本机已安装 dsh-logcat 插件(DSH Web GUI 的安卓实机调试面板):侧边栏「Logcat」入口;自动探测本机 adb,对已连接的调试设备自动附加 logcat 流(threadtime,每设备 2000 行环形缓冲);Web 面板支持设备切换、级别/关键词过滤、暂停/清空/导出;agent 工具:logcat_devices(列出已连接设备)、adb_exec(在设备上执行 adb shell:安装/启动/查看日志/截图等)、logcat_recent(读取最近日志)。构建安卓应用时若检测到已连接设备,可先向用户确认后用 adb_exec / logcat_recent 直接实机调试。限制:需设备开启 USB 调试并授权本机;logcat 输出可能含敏感信息;adb 命令消耗真实设备资源,破坏性操作(卸载/重启/清数据)先确认再执行。用户提到「Logcat / 安卓日志 / 实机调试 / adb 日志」时即指本插件,请据此协作。'
40
+
41
+ /** Dynamic model-facing announcement: base guidance plus currently attached devices. */
42
+ function logcatGuidance(engine) {
43
+ return () => {
44
+ const devices = engine.deviceList()
45
+ const live = devices.filter((d) => d.state === 'device')
46
+ const deviceLine = live.length > 0
47
+ ? `当前已连接安卓设备:${live.map((d) => `${d.serial}${d.model !== '' ? `(${d.model})` : ''}`).join('、')}(已授权,可实机调试:安装 APK / 启动应用 / logcat / 截图等)。`
48
+ : '当前无已连接的安卓设备(插上设备并开启 USB 调试后会自动识别)。'
49
+ return `${LOGCAT_GUIDANCE}\n${deviceLine}`
50
+ }
51
+ }
40
52
 
41
53
  /** ---------------------------------------------------------------- adb */
42
54
 
@@ -514,6 +526,96 @@ function logcatRecentTool(engine) {
514
526
  })
515
527
  }
516
528
 
529
+ /** The logcat_devices agent tool: list attached adb devices for on-device debugging. */
530
+ function logcatDevicesTool(engine) {
531
+ return defineTool({
532
+ name: 'logcat_devices',
533
+ description: 'List currently attached Android devices (serial, model, state) for on-device debugging. ' +
534
+ 'Triggers: check adb devices, see which phones are connected, decide whether to debug a build on a real device.',
535
+ parameters: {},
536
+ output: {
537
+ schema: {
538
+ type: 'object',
539
+ additionalProperties: false,
540
+ properties: {
541
+ devices: {
542
+ type: 'array',
543
+ required: true,
544
+ items: {
545
+ type: 'object',
546
+ additionalProperties: false,
547
+ properties: {
548
+ serial: { type: 'string', required: true },
549
+ model: { type: 'string', required: true },
550
+ state: { type: 'string', required: true },
551
+ },
552
+ },
553
+ },
554
+ },
555
+ },
556
+ render: (_args, value) => {
557
+ const devices = value?.devices ?? []
558
+ if (devices.length === 0) return [{ type: 'text', text: '(no devices attached)' }]
559
+ const lines = devices.map((d) => `${d.state.padEnd(11)} ${(d.model || '?').padEnd(22)} ${d.serial}`)
560
+ return [{ type: 'text', text: lines.join('\n') }]
561
+ },
562
+ },
563
+ async execute() {
564
+ return { devices: engine.deviceList().map(({ serial, model, state }) => ({ serial, model, state })) }
565
+ },
566
+ })
567
+ }
568
+
569
+ /** The adb_exec agent tool: run one adb shell command on a device. */
570
+ function adbExecTool(engine) {
571
+ return defineTool({
572
+ name: 'adb_exec',
573
+ description: 'Run one adb shell command on an attached Android device — e.g. install an APK (pm install -r <path>), ' +
574
+ 'start an activity (am start -n pkg/.Activity), list processes, take a screenshot (screencap -p /sdcard/x.png), ' +
575
+ 'or dump UI (uiautomator dump). NOTE: executes real commands on the user\'s device and consumes device resources — ' +
576
+ 'confirm intent before destructive actions (uninstall, reboot, clear data, factory reset).',
577
+ parameters: {
578
+ serial: { type: 'string', description: 'Device serial from logcat_devices (optional; defaults to the first attached device).' },
579
+ command: { type: 'string', description: 'The shell command to run without the "adb shell" prefix, e.g. "pm list packages | grep com.example" or "am start -n com.example/.MainActivity".' },
580
+ timeoutMs: { type: 'integer', description: 'Command timeout in ms (default 15000, max 120000).' },
581
+ },
582
+ output: {
583
+ schema: {
584
+ type: 'object',
585
+ additionalProperties: false,
586
+ properties: {
587
+ ok: { type: 'boolean', required: true },
588
+ code: { type: 'integer' },
589
+ stdout: { type: 'string', required: true },
590
+ stderr: { type: 'string', required: true },
591
+ },
592
+ },
593
+ render: (_args, value) => {
594
+ const out = value?.stdout ?? ''
595
+ const err = value?.stderr ?? ''
596
+ const parts = []
597
+ if (out !== '') parts.push(out.trimEnd())
598
+ if (err !== '') parts.push('stderr: ' + err.trimEnd())
599
+ if (parts.length === 0) parts.push(`(exit ${value?.code ?? '?'}, no output)`)
600
+ return [{ type: 'text', text: parts.join('\n') }]
601
+ },
602
+ },
603
+ async execute(args) {
604
+ const devices = engine.deviceList()
605
+ const serial = typeof args.serial === 'string' && args.serial !== ''
606
+ ? args.serial
607
+ : devices.find((d) => d.state === 'device')?.serial ?? ''
608
+ const command = typeof args.command === 'string' ? args.command.trim() : ''
609
+ if (engine.adb === null) return { ok: false, code: null, stdout: '', stderr: 'adb not found on this host' }
610
+ if (serial === '') return { ok: false, code: null, stdout: '', stderr: 'no attached device; connect and authorize one first' }
611
+ if (command === '') return { ok: false, code: null, stdout: '', stderr: 'command is required' }
612
+ const timeoutMs = Math.min(Math.max(Number(args.timeoutMs ?? 15000) || 15000, 1000), 120000)
613
+ const result = await runAdbFull(engine.adb, ['-s', serial, 'shell', command], timeoutMs)
614
+ return { ok: result.ok, code: result.code, stdout: result.stdout, stderr: result.stderr }
615
+ },
616
+ })
617
+ }
618
+
517
619
  /** ------------------------------------------------------------------ */
518
620
 
519
621
  /** Mount the adb engine, routes, tool, and announcement. */
@@ -565,7 +667,7 @@ export function apply(ctx, config) {
565
667
  disposeSection = ctx.systemPrompt.section({
566
668
  name: 'plugin:dsh-logcat',
567
669
  order: SECTION_ORDER,
568
- text: LOGCAT_GUIDANCE,
670
+ text: logcatGuidance(engine),
569
671
  })
570
672
  }
571
673
  disposeRoutes = ctx.effect(() => {
@@ -577,7 +679,11 @@ export function apply(ctx, config) {
577
679
  }
578
680
  }, 'dsh-logcat: routes')
579
681
  disposeTools = ctx.effect(() => {
580
- const disposers = [logcatRecentTool(engine)].map((tool) => ctx.tools.register(tool))
682
+ const disposers = [
683
+ logcatRecentTool(engine),
684
+ logcatDevicesTool(engine),
685
+ adbExecTool(engine),
686
+ ].map((tool) => ctx.tools.register(tool))
581
687
  return () => { for (const dispose of disposers) dispose() }
582
688
  }, 'dsh-logcat: tools')
583
689
  initOnce()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@windypro-rourou/dsh-logcat",
3
3
  "description": "Android Logcat viewer for the dsh web GUI: auto-connects to any adb device in debug mode, live logcat stream with level/keyword filters, pause/clear/export, plus agent tools (logcat_recent). Hot-pluggable — mounted via ~/.dsh/cordis.patch.yml + a profile node_modules copy, no dsh source changes.",
4
- "version": "0.2.2",
4
+ "version": "0.2.3",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.22.0",
7
7
  "engines": {