openclawmp 0.1.3 → 0.1.5

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.
@@ -2,124 +2,156 @@
2
2
  // commands/issue.js — Create / list issues on an asset
3
3
  // ============================================================================
4
4
 
5
- 'use strict';
5
+ "use strict";
6
6
 
7
- const api = require('../api.js');
8
- const auth = require('../auth.js');
9
- const { ok, info, err, c, detail } = require('../ui.js');
7
+ const api = require("../api.js");
8
+ const auth = require("../auth.js");
9
+ const { ok, info, err, c, detail } = require("../ui.js");
10
10
 
11
11
  /**
12
12
  * Format a timestamp to a readable date string
13
13
  */
14
14
  function fmtDate(ts) {
15
- if (!ts) return '?';
16
- const d = new Date(ts);
17
- if (isNaN(d.getTime())) return String(ts);
18
- return d.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
15
+ if (!ts) return "?";
16
+ const d = new Date(ts);
17
+ if (isNaN(d.getTime())) return String(ts);
18
+ return d.toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
19
19
  }
20
20
 
21
21
  /**
22
22
  * Render issue status with color
23
23
  */
24
24
  function renderStatus(status) {
25
- switch (status) {
26
- case 'open': return c('green', '● open');
27
- case 'closed': return c('red', 'closed');
28
- default: return c('dim', status || 'open');
29
- }
25
+ switch (status) {
26
+ case "open":
27
+ return c("green", "open");
28
+ case "closed":
29
+ return c("red", "● closed");
30
+ default:
31
+ return c("dim", status || "open");
32
+ }
30
33
  }
31
34
 
32
35
  /**
33
36
  * openclawmp issue <assetRef> <title> [--body "..."] [--labels "bug,help"] [--as-agent]
34
37
  */
35
38
  async function runIssue(args, flags) {
36
- if (args.length < 2) {
37
- err('Usage: openclawmp issue <assetRef> <title> [--body "..."] [--labels "bug,help"] [--as-agent]');
38
- console.log(' Example: openclawmp issue trigger/@xiaoyue/pdf-watcher "安装后无法启动" --body "详细描述..."');
39
- process.exit(1);
40
- }
41
-
42
- if (!auth.isAuthenticated()) {
43
- err('Authentication required. Run: openclawmp login');
44
- process.exit(1);
45
- }
46
-
47
- const asset = await api.resolveAssetRef(args[0]);
48
- const title = args.slice(1).join(' ');
49
- const displayName = asset.displayName || asset.name || args[0];
50
-
51
- const body = {
52
- title,
53
- authorType: flags['as-agent'] ? 'agent' : 'user',
54
- };
55
-
56
- if (flags.body) {
57
- body.bodyText = flags.body;
58
- }
59
-
60
- if (flags.labels) {
61
- body.labels = flags.labels.split(',').map(l => l.trim()).filter(Boolean);
62
- }
63
-
64
- const { status, data } = await api.post(`/api/assets/${asset.id}/issues`, body);
65
-
66
- if (status >= 200 && status < 300) {
67
- const issue = data.issue || data;
68
- const issueNum = issue.number || issue.id || '?';
69
-
70
- console.log('');
71
- ok(`Issue #${issueNum} 已创建于 ${c('bold', displayName)}`);
72
- detail('标题', title);
39
+ if (args.length < 2) {
40
+ err(
41
+ 'Usage: openclawmp issue <assetRef> <title> [--body "..."] [--labels "bug,help"] [--as-agent]',
42
+ );
43
+ console.log(
44
+ ' Example: openclawmp issue trigger/@xiaoyue/pdf-watcher "安装后无法启动" --body "详细描述..."',
45
+ );
46
+ process.exit(1);
47
+ }
48
+
49
+ if (!auth.isAuthenticated()) {
50
+ err("Authentication required. Run: openclawmp login");
51
+ process.exit(1);
52
+ }
53
+
54
+ const asset = await api.resolveAssetRef(args[0]);
55
+ const title = args.slice(1).join(" ");
56
+ const displayName = asset.displayName || asset.name || args[0];
57
+
58
+ const body = {
59
+ title,
60
+ authorType: flags["as-agent"] ? "agent" : "user",
61
+ };
62
+
73
63
  if (flags.body) {
74
- detail('描述', flags.body.length > 60 ? flags.body.slice(0, 60) + '...' : flags.body);
64
+ body.bodyText = flags.body;
75
65
  }
66
+
76
67
  if (flags.labels) {
77
- detail('标签', flags.labels);
68
+ body.labels = flags.labels
69
+ .split(",")
70
+ .map((l) => l.trim())
71
+ .filter(Boolean);
72
+ }
73
+
74
+ const { status, data } = await api.post(
75
+ `/api/assets/${asset.id}/issues`,
76
+ body,
77
+ );
78
+
79
+ if (status >= 200 && status < 300) {
80
+ const issue = data.issue || data;
81
+ const issueNum = issue.number || issue.id || "?";
82
+
83
+ console.log("");
84
+ ok(
85
+ `Issue #${issueNum} 正在审核 ${c("bold", displayName)},审核后自动创建`,
86
+ );
87
+ detail("标题", title);
88
+ if (flags.body) {
89
+ detail(
90
+ "描述",
91
+ flags.body.length > 60
92
+ ? flags.body.slice(0, 60) + "..."
93
+ : flags.body,
94
+ );
95
+ }
96
+ if (flags.labels) {
97
+ detail("标签", flags.labels);
98
+ }
99
+ console.log("");
100
+ } else {
101
+ err(
102
+ `创建 Issue 失败 (${status}): ${data.error || data.message || JSON.stringify(data)}`,
103
+ );
104
+ process.exit(1);
78
105
  }
79
- console.log('');
80
- } else {
81
- err(`创建 Issue 失败 (${status}): ${data.error || data.message || JSON.stringify(data)}`);
82
- process.exit(1);
83
- }
84
106
  }
85
107
 
86
108
  /**
87
109
  * openclawmp issues <assetRef>
88
110
  */
89
111
  async function runIssues(args) {
90
- if (args.length === 0) {
91
- err('Usage: openclawmp issues <assetRef>');
92
- console.log(' Example: openclawmp issues trigger/@xiaoyue/pdf-watcher');
93
- process.exit(1);
94
- }
95
-
96
- const asset = await api.resolveAssetRef(args[0]);
97
- const displayName = asset.displayName || asset.name || args[0];
98
-
99
- const result = await api.get(`/api/assets/${asset.id}/issues`);
100
- const issues = result?.data?.issues || result?.issues || [];
101
-
102
- console.log('');
103
- info(`${c('bold', displayName)} 的 Issues(${issues.length} 个)`);
104
- console.log(` ${'─'.repeat(50)}`);
105
-
106
- if (issues.length === 0) {
107
- console.log(` ${c('dim', '暂无 Issues。')}`);
108
- } else {
109
- for (const iss of issues) {
110
- const num = iss.number || iss.id || '?';
111
- const status = renderStatus(iss.status);
112
- const author = iss.author?.name || iss.authorName || iss.authorType || 'anonymous';
113
- const badge = iss.authorType === 'agent' ? c('magenta', ' 🤖') : '';
114
- const time = fmtDate(iss.createdAt || iss.created_at);
115
- const labels = (iss.labels || []).map(l => c('yellow', `[${l}]`)).join(' ');
116
-
117
- console.log('');
118
- console.log(` ${status} ${c('bold', `#${num}`)} ${iss.title} ${labels}`);
119
- console.log(` ${c('dim', `by ${author}${badge} · ${time}`)}`);
112
+ if (args.length === 0) {
113
+ err("Usage: openclawmp issues <assetRef>");
114
+ console.log(
115
+ " Example: openclawmp issues trigger/@xiaoyue/pdf-watcher",
116
+ );
117
+ process.exit(1);
118
+ }
119
+
120
+ const asset = await api.resolveAssetRef(args[0]);
121
+ const displayName = asset.displayName || asset.name || args[0];
122
+
123
+ const result = await api.get(`/api/assets/${asset.id}/issues`);
124
+ const issues = result?.data?.issues || result?.issues || [];
125
+
126
+ console.log("");
127
+ info(`${c("bold", displayName)} 的 Issues(${issues.length} 个)`);
128
+ console.log(` ${"─".repeat(50)}`);
129
+
130
+ if (issues.length === 0) {
131
+ console.log(` ${c("dim", "暂无 Issues。")}`);
132
+ } else {
133
+ for (const iss of issues) {
134
+ const num = iss.number || iss.id || "?";
135
+ const status = renderStatus(iss.status);
136
+ const author =
137
+ iss.author?.name ||
138
+ iss.authorName ||
139
+ iss.authorType ||
140
+ "anonymous";
141
+ const badge = iss.authorType === "agent" ? c("magenta", " 🤖") : "";
142
+ const time = fmtDate(iss.createdAt || iss.created_at);
143
+ const labels = (iss.labels || [])
144
+ .map((l) => c("yellow", `[${l}]`))
145
+ .join(" ");
146
+
147
+ console.log("");
148
+ console.log(
149
+ ` ${status} ${c("bold", `#${num}`)} ${iss.title} ${labels}`,
150
+ );
151
+ console.log(` ${c("dim", `by ${author}${badge} · ${time}`)}`);
152
+ }
120
153
  }
121
- }
122
- console.log('');
154
+ console.log("");
123
155
  }
124
156
 
125
157
  module.exports = { runIssue, runIssues };