deliver.mjs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/env node
  2. /**
  3. * deliver.mjs — 成果交付上报(AgentDeliverable 表)
  4. *
  5. * 交付即报纪律:任务节点有明确交付物+链接 → 立即上报
  6. * (每章/每版/每次部署/每轮大修各一条;漏报即补)。
  7. * 幂等:同 agentId+taskId+deliverableType 覆盖更新而非新增。
  8. * Date 坑:deliveredAt 一律经 wrapDate() 包装为 {"__type":"Date","iso":...}
  9. * —— 裸字符串写 Parse 报 schema 111(见 SKILL.md 坑章节)。
  10. *
  11. * 用法:
  12. * node deliver.mjs --agent <agentId> --task <taskId> --title <标题> --url <交付链接> \
  13. * [--type report|code|courseware|data] [--project <项目>] [--summary <一句话>] \
  14. * [--delivered-at "2026-09-12T08:00:00.000Z"]
  15. */
  16. import {
  17. resolveCredentials, failNoCredentials, wrapDate, upsertObject,
  18. } from './parse-client.mjs';
  19. const TABLE = 'AgentDeliverable';
  20. const VALID_TYPES = ['report', 'code', 'courseware', 'data'];
  21. function parseArgs(argv) {
  22. const args = {};
  23. for (let i = 0; i < argv.length; i += 2) {
  24. const key = (argv[i] || '').replace(/^--/, '');
  25. args[key] = argv[i + 1];
  26. }
  27. return args;
  28. }
  29. const args = parseArgs(process.argv.slice(2));
  30. const missing = ['agent', 'task', 'title', 'url'].filter((k) => !args[k]);
  31. if (missing.length > 0) {
  32. console.error(`[task-progress] 缺必填参数: --${missing.join(' --')}`);
  33. console.error('用法: node deliver.mjs --agent <agentId> --task <taskId> --title <标题> --url <交付链接> [--type report|code|courseware|data] [--project <项目>] [--summary <一句话>] [--delivered-at ISO日期]');
  34. process.exit(1);
  35. }
  36. if (args.type && !VALID_TYPES.includes(args.type)) {
  37. console.error(`[task-progress] --type 必须是 ${VALID_TYPES.join('|')} 之一`);
  38. process.exit(1);
  39. }
  40. const cred = resolveCredentials();
  41. if (!cred) failNoCredentials();
  42. // Date __type 包装(schema 111 坑的防线)
  43. let deliveredAt;
  44. try {
  45. deliveredAt = wrapDate(args.deliveredAt || new Date().toISOString());
  46. } catch (e) {
  47. console.error(`[task-progress] --delivered-at ${e.message}`);
  48. process.exit(1);
  49. }
  50. const where = {
  51. agentId: args.agent,
  52. taskId: args.task,
  53. deliverableType: args.type || 'report',
  54. };
  55. const data = {
  56. agentId: args.agent,
  57. taskId: args.task,
  58. title: args.title,
  59. url: args.url,
  60. deliveredAt,
  61. };
  62. if (args.type) data.deliverableType = args.type;
  63. if (args.project) data.project = args.project;
  64. if (args.summary) data.summary = args.summary;
  65. const r = await upsertObject(TABLE, cred, where, data);
  66. console.log(JSON.stringify({
  67. ok: true,
  68. op: 'deliver',
  69. agentId: args.agent,
  70. taskId: args.task,
  71. title: args.title,
  72. url: args.url,
  73. objectId: r.objectId,
  74. created: r.created,
  75. deliveredAt,
  76. }));