huly-mcp-selfhost 3.4.0 → 3.5.0

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 (222) hide show
  1. package/.env.example +3 -0
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +54 -16
  4. package/dist/guides/workflow.md +1 -0
  5. package/dist/index.js +105034 -55
  6. package/dist/setup.js +4 -0
  7. package/package.json +12 -11
  8. package/dist/connection.d.ts +0 -100
  9. package/dist/connection.js +0 -344
  10. package/dist/connection.js.map +0 -1
  11. package/dist/env.d.ts +0 -1
  12. package/dist/env.js +0 -17
  13. package/dist/env.js.map +0 -1
  14. package/dist/guard.d.ts +0 -39
  15. package/dist/guard.js +0 -165
  16. package/dist/guard.js.map +0 -1
  17. package/dist/http.d.ts +0 -22
  18. package/dist/http.js +0 -213
  19. package/dist/http.js.map +0 -1
  20. package/dist/index.d.ts +0 -2
  21. package/dist/index.js.map +0 -1
  22. package/dist/junit-cli.d.ts +0 -8
  23. package/dist/junit-cli.js +0 -106
  24. package/dist/junit-cli.js.map +0 -1
  25. package/dist/registry.d.ts +0 -18
  26. package/dist/registry.js +0 -321
  27. package/dist/registry.js.map +0 -1
  28. package/dist/resources.d.ts +0 -19
  29. package/dist/resources.js +0 -255
  30. package/dist/resources.js.map +0 -1
  31. package/dist/schemas.d.ts +0 -1583
  32. package/dist/schemas.js +0 -1097
  33. package/dist/schemas.js.map +0 -1
  34. package/dist/server.d.ts +0 -29
  35. package/dist/server.js +0 -215
  36. package/dist/server.js.map +0 -1
  37. package/dist/tools/activity.d.ts +0 -10
  38. package/dist/tools/activity.js +0 -62
  39. package/dist/tools/activity.js.map +0 -1
  40. package/dist/tools/agent.d.ts +0 -156
  41. package/dist/tools/agent.js +0 -523
  42. package/dist/tools/agent.js.map +0 -1
  43. package/dist/tools/attachments.d.ts +0 -31
  44. package/dist/tools/attachments.js +0 -61
  45. package/dist/tools/attachments.js.map +0 -1
  46. package/dist/tools/calendar.d.ts +0 -49
  47. package/dist/tools/calendar.js +0 -116
  48. package/dist/tools/calendar.js.map +0 -1
  49. package/dist/tools/cards.d.ts +0 -87
  50. package/dist/tools/cards.js +0 -246
  51. package/dist/tools/cards.js.map +0 -1
  52. package/dist/tools/channels.d.ts +0 -118
  53. package/dist/tools/channels.js +0 -211
  54. package/dist/tools/channels.js.map +0 -1
  55. package/dist/tools/comments.d.ts +0 -42
  56. package/dist/tools/comments.js +0 -77
  57. package/dist/tools/comments.js.map +0 -1
  58. package/dist/tools/components.d.ts +0 -45
  59. package/dist/tools/components.js +0 -107
  60. package/dist/tools/components.js.map +0 -1
  61. package/dist/tools/contacts.d.ts +0 -69
  62. package/dist/tools/contacts.js +0 -130
  63. package/dist/tools/contacts.js.map +0 -1
  64. package/dist/tools/crm.d.ts +0 -61
  65. package/dist/tools/crm.js +0 -117
  66. package/dist/tools/crm.js.map +0 -1
  67. package/dist/tools/diagnostics.d.ts +0 -17
  68. package/dist/tools/diagnostics.js +0 -133
  69. package/dist/tools/diagnostics.js.map +0 -1
  70. package/dist/tools/documents.d.ts +0 -100
  71. package/dist/tools/documents.js +0 -294
  72. package/dist/tools/documents.js.map +0 -1
  73. package/dist/tools/drive.d.ts +0 -107
  74. package/dist/tools/drive.js +0 -277
  75. package/dist/tools/drive.js.map +0 -1
  76. package/dist/tools/fields.d.ts +0 -33
  77. package/dist/tools/fields.js +0 -124
  78. package/dist/tools/fields.js.map +0 -1
  79. package/dist/tools/generic.d.ts +0 -72
  80. package/dist/tools/generic.js +0 -242
  81. package/dist/tools/generic.js.map +0 -1
  82. package/dist/tools/github.d.ts +0 -21
  83. package/dist/tools/github.js +0 -80
  84. package/dist/tools/github.js.map +0 -1
  85. package/dist/tools/hr.d.ts +0 -97
  86. package/dist/tools/hr.js +0 -150
  87. package/dist/tools/hr.js.map +0 -1
  88. package/dist/tools/inbox.d.ts +0 -39
  89. package/dist/tools/inbox.js +0 -139
  90. package/dist/tools/inbox.js.map +0 -1
  91. package/dist/tools/inventory.d.ts +0 -61
  92. package/dist/tools/inventory.js +0 -103
  93. package/dist/tools/inventory.js.map +0 -1
  94. package/dist/tools/issues.d.ts +0 -114
  95. package/dist/tools/issues.js +0 -484
  96. package/dist/tools/issues.js.map +0 -1
  97. package/dist/tools/labels.d.ts +0 -87
  98. package/dist/tools/labels.js +0 -232
  99. package/dist/tools/labels.js.map +0 -1
  100. package/dist/tools/log-time.d.ts +0 -25
  101. package/dist/tools/log-time.js +0 -95
  102. package/dist/tools/log-time.js.map +0 -1
  103. package/dist/tools/meetings.d.ts +0 -30
  104. package/dist/tools/meetings.js +0 -78
  105. package/dist/tools/meetings.js.map +0 -1
  106. package/dist/tools/members.d.ts +0 -8
  107. package/dist/tools/members.js +0 -33
  108. package/dist/tools/members.js.map +0 -1
  109. package/dist/tools/message-templates.d.ts +0 -54
  110. package/dist/tools/message-templates.js +0 -88
  111. package/dist/tools/message-templates.js.map +0 -1
  112. package/dist/tools/milestones.d.ts +0 -56
  113. package/dist/tools/milestones.js +0 -172
  114. package/dist/tools/milestones.js.map +0 -1
  115. package/dist/tools/organizations.d.ts +0 -37
  116. package/dist/tools/organizations.js +0 -88
  117. package/dist/tools/organizations.js.map +0 -1
  118. package/dist/tools/overview.d.ts +0 -55
  119. package/dist/tools/overview.js +0 -395
  120. package/dist/tools/overview.js.map +0 -1
  121. package/dist/tools/planner.d.ts +0 -60
  122. package/dist/tools/planner.js +0 -145
  123. package/dist/tools/planner.js.map +0 -1
  124. package/dist/tools/process.d.ts +0 -50
  125. package/dist/tools/process.js +0 -137
  126. package/dist/tools/process.js.map +0 -1
  127. package/dist/tools/products.d.ts +0 -17
  128. package/dist/tools/products.js +0 -45
  129. package/dist/tools/products.js.map +0 -1
  130. package/dist/tools/projects.d.ts +0 -41
  131. package/dist/tools/projects.js +0 -93
  132. package/dist/tools/projects.js.map +0 -1
  133. package/dist/tools/qms.d.ts +0 -57
  134. package/dist/tools/qms.js +0 -171
  135. package/dist/tools/qms.js.map +0 -1
  136. package/dist/tools/recruiting.d.ts +0 -112
  137. package/dist/tools/recruiting.js +0 -203
  138. package/dist/tools/recruiting.js.map +0 -1
  139. package/dist/tools/relations.d.ts +0 -72
  140. package/dist/tools/relations.js +0 -192
  141. package/dist/tools/relations.js.map +0 -1
  142. package/dist/tools/search.d.ts +0 -23
  143. package/dist/tools/search.js +0 -60
  144. package/dist/tools/search.js.map +0 -1
  145. package/dist/tools/sharing.d.ts +0 -62
  146. package/dist/tools/sharing.js +0 -149
  147. package/dist/tools/sharing.js.map +0 -1
  148. package/dist/tools/statuses.d.ts +0 -19
  149. package/dist/tools/statuses.js +0 -93
  150. package/dist/tools/statuses.js.map +0 -1
  151. package/dist/tools/surveys.d.ts +0 -22
  152. package/dist/tools/surveys.js +0 -53
  153. package/dist/tools/surveys.js.map +0 -1
  154. package/dist/tools/templates.d.ts +0 -95
  155. package/dist/tools/templates.js +0 -260
  156. package/dist/tools/templates.js.map +0 -1
  157. package/dist/tools/test-automation.d.ts +0 -81
  158. package/dist/tools/test-automation.js +0 -225
  159. package/dist/tools/test-automation.js.map +0 -1
  160. package/dist/tools/testing.d.ts +0 -234
  161. package/dist/tools/testing.js +0 -401
  162. package/dist/tools/testing.js.map +0 -1
  163. package/dist/tools/workspace-admin.d.ts +0 -55
  164. package/dist/tools/workspace-admin.js +0 -117
  165. package/dist/tools/workspace-admin.js.map +0 -1
  166. package/dist/tools/workspaces.d.ts +0 -6
  167. package/dist/tools/workspaces.js +0 -19
  168. package/dist/tools/workspaces.js.map +0 -1
  169. package/dist/utils/attributes.d.ts +0 -37
  170. package/dist/utils/attributes.js +0 -188
  171. package/dist/utils/attributes.js.map +0 -1
  172. package/dist/utils/classes.d.ts +0 -51
  173. package/dist/utils/classes.js +0 -73
  174. package/dist/utils/classes.js.map +0 -1
  175. package/dist/utils/content.d.ts +0 -11
  176. package/dist/utils/content.js +0 -86
  177. package/dist/utils/content.js.map +0 -1
  178. package/dist/utils/errors.d.ts +0 -11
  179. package/dist/utils/errors.js +0 -24
  180. package/dist/utils/errors.js.map +0 -1
  181. package/dist/utils/files.d.ts +0 -5
  182. package/dist/utils/files.js +0 -50
  183. package/dist/utils/files.js.map +0 -1
  184. package/dist/utils/format.d.ts +0 -8
  185. package/dist/utils/format.js +0 -57
  186. package/dist/utils/format.js.map +0 -1
  187. package/dist/utils/junit.d.ts +0 -13
  188. package/dist/utils/junit.js +0 -81
  189. package/dist/utils/junit.js.map +0 -1
  190. package/dist/utils/markdown.d.ts +0 -14
  191. package/dist/utils/markdown.js +0 -149
  192. package/dist/utils/markdown.js.map +0 -1
  193. package/dist/utils/meeting.d.ts +0 -13
  194. package/dist/utils/meeting.js +0 -118
  195. package/dist/utils/meeting.js.map +0 -1
  196. package/dist/utils/people.d.ts +0 -25
  197. package/dist/utils/people.js +0 -80
  198. package/dist/utils/people.js.map +0 -1
  199. package/dist/utils/redact.d.ts +0 -3
  200. package/dist/utils/redact.js +0 -26
  201. package/dist/utils/redact.js.map +0 -1
  202. package/dist/utils/resolve.d.ts +0 -17
  203. package/dist/utils/resolve.js +0 -54
  204. package/dist/utils/resolve.js.map +0 -1
  205. package/dist/utils/spec.d.ts +0 -10
  206. package/dist/utils/spec.js +0 -90
  207. package/dist/utils/spec.js.map +0 -1
  208. package/dist/utils/storage.d.ts +0 -7
  209. package/dist/utils/storage.js +0 -86
  210. package/dist/utils/storage.js.map +0 -1
  211. package/dist/utils/tasks.d.ts +0 -22
  212. package/dist/utils/tasks.js +0 -81
  213. package/dist/utils/tasks.js.map +0 -1
  214. package/dist/watch.d.ts +0 -62
  215. package/dist/watch.js +0 -405
  216. package/dist/watch.js.map +0 -1
  217. package/scripts/cleanup-issues.js +0 -141
  218. package/scripts/copy-guides.js +0 -18
  219. package/scripts/demo.js +0 -201
  220. package/scripts/import-csv.js +0 -250
  221. package/scripts/sample-tasks.csv +0 -11
  222. package/scripts/setup.js +0 -163
package/dist/watch.js DELETED
@@ -1,405 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.WATCH_HELP = exports.DEFAULT_PROMPT = exports.DEFAULT_COMMAND = void 0;
7
- exports.splitCommand = splitCommand;
8
- exports.fill = fill;
9
- exports.parseEnvFile = parseEnvFile;
10
- exports.parseWatchArgs = parseWatchArgs;
11
- exports.loadState = loadState;
12
- exports.saveState = saveState;
13
- exports.findCandidates = findCandidates;
14
- exports.writeMcpConfig = writeMcpConfig;
15
- exports.processIssue = processIssue;
16
- exports.watchOnce = watchOnce;
17
- exports.runWatch = runWatch;
18
- // `huly-mcp watch`: Huly hands work to an agent.
19
- // Polls for open issues that carry a trigger label or are assigned to the connected account,
20
- // claims each one (claim_issue), runs a command for it — by default `claude -p` — and releases
21
- // the claim afterwards. A state file remembers which issues already ran.
22
- const node_child_process_1 = require("node:child_process");
23
- const node_fs_1 = require("node:fs");
24
- const node_os_1 = require("node:os");
25
- const node_path_1 = require("node:path");
26
- const tracker_1 = __importDefault(require("@hcengineering/tracker"));
27
- const task_1 = __importDefault(require("@hcengineering/task"));
28
- const connection_1 = require("./connection");
29
- const env_1 = require("./env");
30
- const guard_1 = require("./guard");
31
- const people_1 = require("./utils/people");
32
- const agent_1 = require("./tools/agent");
33
- const comments_1 = require("./tools/comments");
34
- exports.DEFAULT_COMMAND = 'claude -p {prompt} --mcp-config {mcpConfig} --strict-mcp-config --allowedTools mcp__huly --permission-mode acceptEdits';
35
- exports.DEFAULT_PROMPT = [
36
- 'Huly issue {issue} ("{title}") in workspace {workspace} was handed to you ({trigger}).',
37
- 'You are the Huly agent "{agent}" and already hold the claim on it.',
38
- '1. Read everything with get_issue_context {issue}.',
39
- '2. Do the work in the current directory.',
40
- '3. Hand back with finish_work: a short summary of what you did and what is left.',
41
- 'If you cannot finish, add a comment that says what is missing, then stop. Never delete anything.'
42
- ].join('\n');
43
- exports.WATCH_HELP = `Usage: huly-mcp watch [options]
44
-
45
- Hands Huly issues to an agent: open issues with --label, or assigned to this account
46
- (--assigned, the default), are claimed, passed to --command and released afterwards.
47
-
48
- --workspace <ws> Workspace slug/name (required with more than one)
49
- --project <KEY> Only these projects (repeat or comma-separate); default: all,
50
- limited to HULY_WRITE_PROJECTS when set
51
- --label <name> Trigger label (e.g. "claude")
52
- --assigned Trigger: assigned to this account (default if no --label)
53
- --command <cmd> Command per issue; placeholders {prompt} {issue} {title}
54
- {workspace} {agent} {trigger} {mcpConfig}
55
- default: ${exports.DEFAULT_COMMAND}
56
- --prompt <text> Prompt template (same placeholders, except {prompt})
57
- --cwd <dir> Working directory for the command (default: current)
58
- --interval <sec> Poll interval (default 60)
59
- --timeout <min> Stop a run after this many minutes (default 60)
60
- --once One pass, then exit
61
- --dry-run Only list what would run
62
- --state <file> State file (default ~/.huly-mcp/watch-<workspace>.json)
63
- --agent <name> Agent name for claims (default HULY_AGENT_NAME or claude-watch)
64
- --env-file <file> Load HULY_* credentials from this file (the agent's own account)
65
- `;
66
- /** Splits a command line into words; supports "double" and 'single' quotes. No shell involved. */
67
- function splitCommand(line) {
68
- const out = [];
69
- let cur = '';
70
- let quote = null;
71
- let started = false;
72
- for (const ch of line) {
73
- if (quote != null) {
74
- if (ch === quote)
75
- quote = null;
76
- else
77
- cur += ch;
78
- }
79
- else if (ch === '"' || ch === "'") {
80
- quote = ch;
81
- started = true;
82
- }
83
- else if (/\s/.test(ch)) {
84
- if (started || cur !== '')
85
- out.push(cur);
86
- cur = '';
87
- started = false;
88
- }
89
- else {
90
- cur += ch;
91
- }
92
- }
93
- if (quote != null)
94
- throw new Error(`Unclosed ${quote} in --command.`);
95
- if (started || cur !== '')
96
- out.push(cur);
97
- return out;
98
- }
99
- /** Replaces {name} placeholders. Unknown placeholders stay as they are. */
100
- function fill(template, vars) {
101
- return template.replace(/\{(\w+)\}/g, (m, k) => vars[k] ?? m);
102
- }
103
- /** KEY=value lines (comments, export prefix and quotes allowed). */
104
- function parseEnvFile(content) {
105
- const out = {};
106
- for (const raw of content.split(/\r?\n/)) {
107
- const line = raw.trim();
108
- if (line === '' || line.startsWith('#'))
109
- continue;
110
- const m = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(line);
111
- if (m == null)
112
- continue;
113
- let v = m[2].trim();
114
- if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'")))
115
- v = v.slice(1, -1);
116
- else
117
- v = v.replace(/\s+#.*$/, '');
118
- out[m[1]] = v;
119
- }
120
- return out;
121
- }
122
- function parseWatchArgs(argv, env = process.env) {
123
- const opts = {
124
- projects: [],
125
- assigned: false,
126
- command: exports.DEFAULT_COMMAND,
127
- prompt: exports.DEFAULT_PROMPT,
128
- cwd: process.cwd(),
129
- intervalSec: 60,
130
- once: false,
131
- dryRun: false,
132
- timeoutMin: 60,
133
- agent: env.HULY_AGENT_NAME ?? 'claude-watch'
134
- };
135
- const value = (i, flag) => {
136
- const v = argv[i + 1];
137
- if (v == null || v.startsWith('--'))
138
- throw new Error(`${flag} needs a value.`);
139
- return v;
140
- };
141
- const number = (v, flag, min) => {
142
- const n = Number(v);
143
- if (!Number.isFinite(n) || n < min)
144
- throw new Error(`${flag} must be a number ≥ ${min}.`);
145
- return n;
146
- };
147
- for (let i = 0; i < argv.length; i++) {
148
- const flag = argv[i];
149
- switch (flag) {
150
- case '--workspace':
151
- opts.workspace = value(i, flag);
152
- i++;
153
- break;
154
- case '--project':
155
- opts.projects.push(...value(i, flag).split(',').map((p) => p.trim().toUpperCase()).filter((p) => p !== ''));
156
- i++;
157
- break;
158
- case '--label':
159
- opts.label = value(i, flag);
160
- i++;
161
- break;
162
- case '--assigned':
163
- opts.assigned = true;
164
- break;
165
- case '--command':
166
- opts.command = value(i, flag);
167
- i++;
168
- break;
169
- case '--prompt':
170
- opts.prompt = value(i, flag);
171
- i++;
172
- break;
173
- case '--cwd':
174
- opts.cwd = (0, node_path_1.resolve)(value(i, flag));
175
- i++;
176
- break;
177
- case '--interval':
178
- opts.intervalSec = number(value(i, flag), flag, 5);
179
- i++;
180
- break;
181
- case '--timeout':
182
- opts.timeoutMin = number(value(i, flag), flag, 1);
183
- i++;
184
- break;
185
- case '--once':
186
- opts.once = true;
187
- break;
188
- case '--dry-run':
189
- opts.dryRun = true;
190
- break;
191
- case '--state':
192
- opts.statePath = (0, node_path_1.resolve)(value(i, flag));
193
- i++;
194
- break;
195
- case '--agent':
196
- opts.agent = value(i, flag).replace(/\s+/g, '-');
197
- i++;
198
- break;
199
- case '--env-file':
200
- opts.envFile = (0, node_path_1.resolve)(value(i, flag));
201
- i++;
202
- break;
203
- default: throw new Error(`Unknown option '${flag}'. See huly-mcp watch --help.`);
204
- }
205
- }
206
- if (opts.label == null)
207
- opts.assigned = true;
208
- if (splitCommand(opts.command).length === 0)
209
- throw new Error('--command is empty.');
210
- return opts;
211
- }
212
- function loadState(path) {
213
- if (!(0, node_fs_1.existsSync)(path))
214
- return {};
215
- try {
216
- return JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
217
- }
218
- catch {
219
- throw new Error(`State file ${path} is not valid JSON — fix or delete it.`);
220
- }
221
- }
222
- function saveState(path, state) {
223
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(path), { recursive: true });
224
- (0, node_fs_1.writeFileSync)(path, JSON.stringify(state, null, 2) + '\n');
225
- }
226
- /**
227
- * Open issues that match a trigger and have not run yet. An issue runs again only when its
228
- * trigger label was added again after the last run (remove + add the label to retry).
229
- */
230
- async function findCandidates(client, opts, state) {
231
- const projects = await client.findAll(tracker_1.default.class.Project, opts.projects.length > 0 ? { identifier: { $in: opts.projects } } : {});
232
- const missing = opts.projects.filter((p) => !projects.some((x) => x.identifier === p));
233
- if (missing.length > 0)
234
- throw new Error(`Project(s) not found: ${missing.join(', ')}.`);
235
- const spaces = new Set(projects.map((p) => p._id));
236
- const statuses = await client.findAll(tracker_1.default.class.IssueStatus, {});
237
- const closed = new Set(statuses.filter((s) => s.category === task_1.default.statusCategory.Won || s.category === task_1.default.statusCategory.Lost).map((s) => s._id));
238
- const open = (i) => spaces.has(i.space) && !closed.has(i.status);
239
- const found = new Map();
240
- if (opts.label != null) {
241
- const want = opts.label.toLowerCase();
242
- const refs = (await client.findAll('tags:class:TagReference', { attachedToClass: tracker_1.default.class.Issue }))
243
- .filter((r) => String(r.title ?? '').toLowerCase() === want);
244
- if (refs.length > 0) {
245
- const issues = await client.findAll(tracker_1.default.class.Issue, { _id: { $in: refs.map((r) => r.attachedTo) } });
246
- for (const issue of issues.filter(open)) {
247
- const ref = refs.find((r) => r.attachedTo === issue._id);
248
- found.set(issue._id, { issue, trigger: 'label', since: ref?.createdOn ?? ref?.modifiedOn ?? 0 });
249
- }
250
- }
251
- }
252
- if (opts.assigned) {
253
- const me = await (0, people_1.currentPerson)(client);
254
- const issues = await client.findAll(tracker_1.default.class.Issue, { assignee: me._id });
255
- for (const issue of issues.filter(open))
256
- if (!found.has(issue._id))
257
- found.set(issue._id, { issue, trigger: 'assigned', since: 0 });
258
- }
259
- return [...found.values()]
260
- .filter((c) => { const prev = state[c.issue._id]; return prev == null || (c.trigger === 'label' && c.since > prev.ranAt); })
261
- .sort((a, b) => (a.issue.createdOn ?? 0) - (b.issue.createdOn ?? 0));
262
- }
263
- /** MCP config for the child Claude: this server, same credentials (inherited env), one workspace. */
264
- function writeMcpConfig(dir, entry, env) {
265
- const path = (0, node_path_1.join)(dir, 'mcp.json');
266
- (0, node_fs_1.writeFileSync)(path, JSON.stringify({ mcpServers: { huly: { command: process.execPath, args: [entry], env } } }, null, 2), { mode: 0o600 });
267
- return path;
268
- }
269
- async function processIssue(c, opts, deps) {
270
- const { issue } = c;
271
- const id = issue.identifier;
272
- const ws = deps.workspace;
273
- try {
274
- await (0, agent_1.claimIssue)({ workspace: ws, identifier: id, agent: opts.agent, minutes: opts.timeoutMin + 5, force: false });
275
- }
276
- catch (e) {
277
- deps.log(`skip ${id}: ${e.message.replace(/^Huly MCP: /, '')}`);
278
- return undefined;
279
- }
280
- const childEnv = {
281
- ...deps.env,
282
- HULY_WORKSPACE: ws,
283
- HULY_AGENT_NAME: opts.agent,
284
- HULY_CONFIRM: deps.env.HULY_CONFIRM ?? 'strict',
285
- HULY_ISSUE: id,
286
- HULY_ISSUE_TITLE: String(issue.title ?? '')
287
- };
288
- const vars = { issue: id, title: String(issue.title ?? ''), workspace: ws, agent: opts.agent, trigger: c.trigger === 'label' ? `label "${opts.label ?? ''}"` : 'assigned to you' };
289
- vars.prompt = fill(opts.prompt, vars);
290
- let tmp;
291
- let code;
292
- try {
293
- if (opts.command.includes('{mcpConfig}')) {
294
- tmp = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'huly-watch-'));
295
- const pass = {};
296
- for (const k of ['HULY_WORKSPACE', 'HULY_AGENT_NAME', 'HULY_CONFIRM', 'HULY_TOOLSETS', 'HULY_WRITE_PROJECTS', 'HULY_AUDIT_LOG'])
297
- if (childEnv[k] != null)
298
- pass[k] = childEnv[k];
299
- vars.mcpConfig = writeMcpConfig(tmp, opts.serverEntry ?? process.argv[1], pass);
300
- }
301
- const argv = splitCommand(opts.command).map((w) => fill(w, vars));
302
- deps.log(`run ${id} (${c.trigger}): ${argv[0]} …`);
303
- code = await deps.exec(argv, opts.cwd, childEnv, opts.timeoutMin * 60_000);
304
- }
305
- catch (e) {
306
- deps.log(`run ${id} failed to start: ${e.message}`);
307
- code = -1;
308
- }
309
- finally {
310
- if (tmp != null)
311
- (0, node_fs_1.rmSync)(tmp, { recursive: true, force: true });
312
- }
313
- const result = code === 0 ? 'ok' : code == null ? `timeout after ${opts.timeoutMin} min` : `exit ${code}`;
314
- if (code !== 0) {
315
- await (0, comments_1.addComment)({ workspace: ws, identifier: id, message: `🤖 Agent run by **${opts.agent}** ended: ${result}. The issue is free again.` });
316
- }
317
- // finish_work releases the claim; release it here when the run did not.
318
- const labels = await deps.client.findAll('tags:class:TagReference', { attachedTo: issue._id });
319
- if (labels.some((l) => l.title === agent_1.CLAIM_LABEL))
320
- await (0, agent_1.releaseIssue)({ workspace: ws, identifier: id, agent: opts.agent });
321
- deps.log(`done ${id}: ${result}`);
322
- return { identifier: id, trigger: c.trigger, ranAt: (deps.now ?? Date.now)(), result };
323
- }
324
- /** One poll: find candidates and run them one after another. */
325
- async function watchOnce(opts, deps, state, save) {
326
- const candidates = await findCandidates(deps.client, opts, state);
327
- if (opts.dryRun) {
328
- for (const c of candidates)
329
- deps.log(`would run ${c.issue.identifier} (${c.trigger}): ${c.issue.title}`);
330
- if (candidates.length === 0)
331
- deps.log('nothing to do');
332
- return candidates.length;
333
- }
334
- for (const c of candidates) {
335
- const record = await processIssue(c, opts, deps);
336
- if (record != null) {
337
- state[c.issue._id] = record;
338
- save(state);
339
- }
340
- }
341
- return candidates.length;
342
- }
343
- function execChild(argv, cwd, env, timeoutMs) {
344
- return new Promise((resolvePromise, reject) => {
345
- const child = (0, node_child_process_1.spawn)(argv[0], argv.slice(1), { cwd, env, stdio: ['ignore', 'inherit', 'inherit'] });
346
- let killed = false;
347
- const timer = setTimeout(() => { killed = true; child.kill('SIGTERM'); }, timeoutMs);
348
- child.on('error', (e) => { clearTimeout(timer); reject(e); });
349
- child.on('exit', (code) => { clearTimeout(timer); resolvePromise(killed ? null : code); });
350
- });
351
- }
352
- async function runWatch(argv) {
353
- if (argv.includes('--help') || argv.includes('-h')) {
354
- process.stdout.write(exports.WATCH_HELP);
355
- return;
356
- }
357
- const opts = parseWatchArgs(argv);
358
- if (opts.envFile != null) {
359
- const vars = parseEnvFile((0, node_fs_1.readFileSync)(opts.envFile, 'utf8'));
360
- for (const [k, v] of Object.entries(vars))
361
- process.env[k] = v;
362
- }
363
- (0, env_1.normalizeEnv)();
364
- const allowed = (0, guard_1.parseWriteProjects)(process.env.HULY_WRITE_PROJECTS);
365
- if (allowed != null) {
366
- const outside = opts.projects.filter((p) => !allowed.has(p));
367
- if (outside.length > 0)
368
- throw new Error(`--project ${outside.join(', ')} is outside HULY_WRITE_PROJECTS (${[...allowed].join(', ')}).`);
369
- if (opts.projects.length === 0)
370
- opts.projects = [...allowed];
371
- }
372
- const conn = await (0, connection_1.getWorkspace)(opts.workspace);
373
- const ws = conn.workspace.url;
374
- const me = await (0, people_1.currentPerson)(conn.client);
375
- const statePath = opts.statePath ?? (0, node_path_1.join)((0, node_os_1.homedir)(), '.huly-mcp', `watch-${ws}.json`);
376
- const state = loadState(statePath);
377
- const log = (line) => { process.stderr.write(`[${new Date().toISOString()}] ${line}\n`); };
378
- const triggers = [opts.label != null ? `label "${opts.label}"` : undefined, opts.assigned ? `assigned to ${me.name}` : undefined].filter((t) => t != null).join(' or ');
379
- log(`watching ${ws}${opts.projects.length > 0 ? ` (${opts.projects.join(', ')})` : ''} as ${me.name}, agent "${opts.agent}": ${triggers}${opts.dryRun ? ' — dry run' : ''}`);
380
- let stop = false;
381
- const onSignal = () => { stop = true; log('stopping after the current run…'); };
382
- process.on('SIGINT', onSignal);
383
- process.on('SIGTERM', onSignal);
384
- const deps = { client: conn.client, workspace: ws, exec: execChild, log, env: process.env };
385
- try {
386
- while (!stop) {
387
- try {
388
- await watchOnce(opts, deps, state, (s) => saveState(statePath, s));
389
- }
390
- catch (e) {
391
- log(`poll failed: ${e.message}`);
392
- if (opts.once || opts.dryRun)
393
- process.exitCode = 1;
394
- }
395
- if (opts.once || opts.dryRun)
396
- break;
397
- for (let waited = 0; waited < opts.intervalSec * 1000 && !stop; waited += 500)
398
- await new Promise((r) => setTimeout(r, 500));
399
- }
400
- }
401
- finally {
402
- await (0, connection_1.closeConnection)();
403
- }
404
- }
405
- //# sourceMappingURL=watch.js.map
package/dist/watch.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
@@ -1,141 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Delete a range of issues from a Huly project.
4
- *
5
- * Usage:
6
- * node scripts/cleanup-issues.js <project> <start> <end> [--confirm]
7
- *
8
- * Example (dry run — shows what would be deleted):
9
- * node scripts/cleanup-issues.js VISIO 59 68 --workspace=myteam
10
- *
11
- * Example (actually delete):
12
- * node scripts/cleanup-issues.js VISIO 59 68 --workspace=myteam --confirm
13
- *
14
- * Auth is read from .env (HULY_TOKEN, or HULY_EMAIL + HULY_PASSWORD). The target
15
- * workspace is required: --workspace=<slug> (or HULY_WORKSPACE).
16
- */
17
-
18
- 'use strict'
19
-
20
- const fs = require('fs')
21
- const path = require('path')
22
-
23
- // Load .env
24
- const envPath = path.join(__dirname, '..', '.env')
25
- if (fs.existsSync(envPath)) {
26
- for (const line of fs.readFileSync(envPath, 'utf8').split('\n')) {
27
- const m = line.match(/^([^#=\s]+)\s*=\s*(.*)$/)
28
- if (m) process.env[m[1]] = m[2].trim()
29
- }
30
- }
31
-
32
- // Target workspace (these scripts write data, so it must be explicit):
33
- // --workspace=<slug|name|id>, or HULY_WORKSPACE as a fallback.
34
- const workspace = process.argv.find(a => a.startsWith('--workspace='))?.slice('--workspace='.length) || process.env.HULY_WORKSPACE
35
- if (!workspace) {
36
- console.error('❌ No workspace given. Pass --workspace=<slug> (see list_workspaces / npm run setup).')
37
- process.exit(1)
38
- }
39
-
40
- // Load compiled modules
41
- const distDir = path.join(__dirname, '..', 'dist')
42
- if (!fs.existsSync(path.join(distDir, 'connection.js'))) {
43
- console.error('❌ dist/ not found. Run `npm run build` first.')
44
- process.exit(1)
45
- }
46
- const { getConnection, closeConnection } = require(path.join(distDir, 'connection'))
47
- const tracker = require('@hcengineering/tracker')
48
-
49
- // Parse args
50
- const args = process.argv.slice(2)
51
- const confirm = args.includes('--confirm')
52
- const positional = args.filter(a => !a.startsWith('--'))
53
-
54
- const [projectIdentifier, startStr, endStr] = positional
55
- if (!projectIdentifier || !startStr || !endStr) {
56
- console.error('Usage: node scripts/cleanup-issues.js <project> <start> <end> --workspace=<slug> [--confirm]')
57
- console.error('Example: node scripts/cleanup-issues.js VISIO 59 68 --workspace=myteam --confirm')
58
- process.exit(1)
59
- }
60
-
61
- const start = parseInt(startStr, 10)
62
- const end = parseInt(endStr, 10)
63
- if (isNaN(start) || isNaN(end) || start > end) {
64
- console.error('❌ start and end must be valid numbers with start <= end')
65
- process.exit(1)
66
- }
67
-
68
- async function main () {
69
- const identifiers = []
70
- for (let n = start; n <= end; n++) {
71
- identifiers.push(`${projectIdentifier}-${n}`)
72
- }
73
-
74
- console.log(`\n🔍 Huly Issue Cleanup`)
75
- console.log(` Project: ${projectIdentifier}`)
76
- console.log(` Range: ${projectIdentifier}-${start} → ${projectIdentifier}-${end} (${identifiers.length} issues)`)
77
- console.log(` Mode: ${confirm ? '⚠️ DELETING for real' : '👁 DRY RUN (pass --confirm to delete)'}\n`)
78
-
79
- console.log('🔌 Connecting to Huly...')
80
- const client = await getConnection(workspace)
81
- console.log('✅ Connected.\n')
82
-
83
- // Find all issues in the range
84
- const issues = await client.findAll(
85
- tracker.default.class.Issue,
86
- { identifier: { $in: identifiers } }
87
- )
88
-
89
- if (issues.length === 0) {
90
- console.log('✅ No matching issues found — nothing to delete.')
91
- await closeConnection()
92
- return
93
- }
94
-
95
- console.log(`Found ${issues.length} issue(s) to delete:\n`)
96
- for (const issue of issues) {
97
- console.log(` • ${issue.identifier} "${issue.title}"`)
98
- }
99
- console.log()
100
-
101
- if (!confirm) {
102
- console.log('ℹ️ This was a DRY RUN. To actually delete, run:')
103
- console.log(` node scripts/cleanup-issues.js ${projectIdentifier} ${start} ${end} --confirm\n`)
104
- await closeConnection()
105
- return
106
- }
107
-
108
- // Delete
109
- let deleted = 0
110
- let failed = 0
111
-
112
- for (const issue of issues) {
113
- process.stdout.write(` Deleting ${issue.identifier}... `)
114
- try {
115
- await client.removeCollection(
116
- tracker.default.class.Issue,
117
- issue.space,
118
- issue._id,
119
- issue.attachedTo,
120
- issue.attachedToClass,
121
- issue.collection
122
- )
123
- console.log('✅')
124
- deleted++
125
- } catch (err) {
126
- console.log(`❌ ${err.message}`)
127
- failed++
128
- }
129
- }
130
-
131
- await closeConnection()
132
-
133
- console.log(`\n${'─'.repeat(50)}`)
134
- console.log(`✅ Deleted: ${deleted} ❌ Failed: ${failed}`)
135
- console.log(`${'─'.repeat(50)}\n`)
136
- }
137
-
138
- main().catch(err => {
139
- console.error('\n❌ Fatal error:', err.message)
140
- process.exit(1)
141
- })
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env node
2
- // Build step: the plugin skill files are the one source for the agent guides. They are copied to
3
- // dist/guides/ (without the skill frontmatter) so every MCP client can read them as huly://guide/*.
4
- 'use strict'
5
- const fs = require('fs')
6
- const path = require('path')
7
-
8
- const root = path.join(__dirname, '..')
9
- const src = path.join(root, 'plugin', 'skills', 'huly')
10
- const out = path.join(root, 'dist', 'guides')
11
- const GUIDES = { workflow: 'SKILL.md', costs: 'costs.md', onboarding: 'onboarding.md', features: 'features.md' }
12
-
13
- fs.mkdirSync(out, { recursive: true })
14
- for (const [name, file] of Object.entries(GUIDES)) {
15
- const text = fs.readFileSync(path.join(src, file), 'utf8').replace(/\r\n/g, '\n').replace(/^---\n[\s\S]*?\n---\n+/, '')
16
- fs.writeFileSync(path.join(out, `${name}.md`), text)
17
- }
18
- console.log(`guides: ${Object.keys(GUIDES).length} copied to dist/guides`)