Files
dingtalk-workspace-cli/skills/mono/scripts/minutes_recent_summary.py
修雨 5ce7cb61b0 feat(skill): dws skill setup with mono/multi modes (#332)
新增 `dws skill setup` 交互式安装命令,支持单产品(mono)和多产品(multi,标记为试验版)两种 skill 布局,并与开源 dws v1.0.30 命令对齐。

主要变更:
- 骨架:skills/ 拆为 skills/mono/ 和 skills/multi/(29 个产品 skill),git rename 保留历史
- 命令:新增 `skill setup` cobra 子命令,支持 --mode、--target、--source、--yes,huh 交互
  - multi 模式支持 -s/--skill、-x/--exclude 按产品选择
  - 覆盖全部 14 个 agent home 目录(与 install.sh 一致)
- 发布:install.sh / install.ps1 / post-goreleaser.sh 改读 skills/mono;dws-skills.zip 同时包含 mono 和 multi 内容;~/.dws 本地缓存
- 内容对齐:删除 8 个仅内部使用的产品 skill、dingtalk-a2a;修正 mono/multi 共 15+ 处命令引用以匹配 OSS dws v1.0.30;chat skill 从 dws-wukong 回移更新
- 漂移清理:物理删除 skill 文档中 OSS 未暴露的命令,true-fail 命令转为 caveat;--help diff 100% 覆盖审计
- 测试:新增 Layer A 静态命令调度验证 + Layer B 端到端 mock 调度验证
- 同步 main:drive 9 个命令同步到 mono/multi skill
2026-05-26 09:17:37 +08:00

119 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""
获取最近 N 条听记的 AI 摘要并合并输出
用法:
python minutes_recent_summary.py # 最近 5 条
python minutes_recent_summary.py --max 10 # 最近 10 条
python minutes_recent_summary.py --output summary.md
python minutes_recent_summary.py --dry-run
"""
import sys
import json
import subprocess
import argparse
from pathlib import Path
from typing import List, Any, Optional
_scripts_dir = Path(__file__).resolve().parent
if str(_scripts_dir) not in sys.path:
sys.path.insert(0, str(_scripts_dir))
from minutes_list_parse import uuid_title_pairs_from_payload
def run_dws(
args: List[str], dry_run: bool = False,
) -> Optional[Any]:
cmd = ['dws'] + args
if dry_run:
print(f"[dry-run] {' '.join(cmd)}")
return None
try:
result = subprocess.run(
cmd, capture_output=True, text=True, timeout=60
)
if result.returncode != 0:
print(f"错误:{result.stderr.strip()}", file=sys.stderr)
return None
return json.loads(result.stdout)
except (subprocess.TimeoutExpired, json.JSONDecodeError,
FileNotFoundError) as e:
print(f"错误:{e}", file=sys.stderr)
return None
def main():
parser = argparse.ArgumentParser(
description='获取最近听记的 AI 摘要'
)
parser.add_argument(
'--max', type=int, default=5, help='获取条数 (默认 5)'
)
parser.add_argument(
'--output', default='', help='输出到 Markdown 文件'
)
parser.add_argument('--dry-run', action='store_true')
args = parser.parse_args()
print('🎙️ 获取听记列表...')
list_data = run_dws([
'minutes', 'list', 'mine',
'--max', str(args.max),
'--format', 'json',
], dry_run=args.dry_run)
if args.dry_run:
run_dws([
'minutes', 'get', 'summary',
'--id', '<TASK_UUID>', '--format', 'json',
], dry_run=True)
return
if not list_data:
print('未找到听记')
return
pairs = uuid_title_pairs_from_payload(list_data)
if not pairs:
print('暂无听记')
return
output_lines = [f"# 最近 {len(pairs)} 条听记摘要\n"]
for i, (uuid, title) in enumerate(pairs, 1):
print(f" [{i}/{len(pairs)}] 获取摘要: {title}")
summary_data = run_dws([
'minutes', 'get', 'summary',
'--id', uuid, '--format', 'json',
])
summary_text = ''
if summary_data:
if isinstance(summary_data, str):
summary_text = summary_data
elif isinstance(summary_data, dict):
summary_text = (summary_data.get('summary')
or summary_data.get('content')
or json.dumps(summary_data,
ensure_ascii=False))
output_lines.append(f"## {i}. {title}\n")
if summary_text:
output_lines.append(f"{summary_text}\n")
else:
output_lines.append("(暂无摘要)\n")
full_output = '\n'.join(output_lines)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(full_output)
print(f"\n✓ 已输出到 {args.output}")
else:
print('\n' + full_output)
if __name__ == '__main__':
main()