huly-mcp-selfhost 3.3.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 (217) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +126 -17
  4. package/dist/guides/costs.md +2 -1
  5. package/dist/guides/workflow.md +3 -1
  6. package/dist/index.js +105034 -46
  7. package/dist/setup.js +4 -0
  8. package/package.json +12 -11
  9. package/dist/connection.d.ts +0 -78
  10. package/dist/connection.js +0 -271
  11. package/dist/connection.js.map +0 -1
  12. package/dist/env.d.ts +0 -1
  13. package/dist/env.js +0 -17
  14. package/dist/env.js.map +0 -1
  15. package/dist/guard.d.ts +0 -39
  16. package/dist/guard.js +0 -165
  17. package/dist/guard.js.map +0 -1
  18. package/dist/index.d.ts +0 -2
  19. package/dist/index.js.map +0 -1
  20. package/dist/junit-cli.d.ts +0 -8
  21. package/dist/junit-cli.js +0 -106
  22. package/dist/junit-cli.js.map +0 -1
  23. package/dist/registry.d.ts +0 -18
  24. package/dist/registry.js +0 -318
  25. package/dist/registry.js.map +0 -1
  26. package/dist/resources.d.ts +0 -19
  27. package/dist/resources.js +0 -255
  28. package/dist/resources.js.map +0 -1
  29. package/dist/schemas.d.ts +0 -1559
  30. package/dist/schemas.js +0 -1086
  31. package/dist/schemas.js.map +0 -1
  32. package/dist/server.d.ts +0 -29
  33. package/dist/server.js +0 -215
  34. package/dist/server.js.map +0 -1
  35. package/dist/tools/activity.d.ts +0 -10
  36. package/dist/tools/activity.js +0 -62
  37. package/dist/tools/activity.js.map +0 -1
  38. package/dist/tools/agent.d.ts +0 -156
  39. package/dist/tools/agent.js +0 -523
  40. package/dist/tools/agent.js.map +0 -1
  41. package/dist/tools/attachments.d.ts +0 -31
  42. package/dist/tools/attachments.js +0 -61
  43. package/dist/tools/attachments.js.map +0 -1
  44. package/dist/tools/calendar.d.ts +0 -49
  45. package/dist/tools/calendar.js +0 -116
  46. package/dist/tools/calendar.js.map +0 -1
  47. package/dist/tools/cards.d.ts +0 -87
  48. package/dist/tools/cards.js +0 -246
  49. package/dist/tools/cards.js.map +0 -1
  50. package/dist/tools/channels.d.ts +0 -118
  51. package/dist/tools/channels.js +0 -211
  52. package/dist/tools/channels.js.map +0 -1
  53. package/dist/tools/comments.d.ts +0 -42
  54. package/dist/tools/comments.js +0 -77
  55. package/dist/tools/comments.js.map +0 -1
  56. package/dist/tools/components.d.ts +0 -45
  57. package/dist/tools/components.js +0 -107
  58. package/dist/tools/components.js.map +0 -1
  59. package/dist/tools/contacts.d.ts +0 -69
  60. package/dist/tools/contacts.js +0 -130
  61. package/dist/tools/contacts.js.map +0 -1
  62. package/dist/tools/crm.d.ts +0 -61
  63. package/dist/tools/crm.js +0 -117
  64. package/dist/tools/crm.js.map +0 -1
  65. package/dist/tools/documents.d.ts +0 -100
  66. package/dist/tools/documents.js +0 -294
  67. package/dist/tools/documents.js.map +0 -1
  68. package/dist/tools/drive.d.ts +0 -107
  69. package/dist/tools/drive.js +0 -277
  70. package/dist/tools/drive.js.map +0 -1
  71. package/dist/tools/fields.d.ts +0 -33
  72. package/dist/tools/fields.js +0 -124
  73. package/dist/tools/fields.js.map +0 -1
  74. package/dist/tools/generic.d.ts +0 -72
  75. package/dist/tools/generic.js +0 -242
  76. package/dist/tools/generic.js.map +0 -1
  77. package/dist/tools/github.d.ts +0 -21
  78. package/dist/tools/github.js +0 -80
  79. package/dist/tools/github.js.map +0 -1
  80. package/dist/tools/hr.d.ts +0 -97
  81. package/dist/tools/hr.js +0 -150
  82. package/dist/tools/hr.js.map +0 -1
  83. package/dist/tools/inbox.d.ts +0 -23
  84. package/dist/tools/inbox.js +0 -76
  85. package/dist/tools/inbox.js.map +0 -1
  86. package/dist/tools/inventory.d.ts +0 -61
  87. package/dist/tools/inventory.js +0 -103
  88. package/dist/tools/inventory.js.map +0 -1
  89. package/dist/tools/issues.d.ts +0 -112
  90. package/dist/tools/issues.js +0 -474
  91. package/dist/tools/issues.js.map +0 -1
  92. package/dist/tools/labels.d.ts +0 -87
  93. package/dist/tools/labels.js +0 -232
  94. package/dist/tools/labels.js.map +0 -1
  95. package/dist/tools/log-time.d.ts +0 -25
  96. package/dist/tools/log-time.js +0 -95
  97. package/dist/tools/log-time.js.map +0 -1
  98. package/dist/tools/meetings.d.ts +0 -30
  99. package/dist/tools/meetings.js +0 -78
  100. package/dist/tools/meetings.js.map +0 -1
  101. package/dist/tools/members.d.ts +0 -8
  102. package/dist/tools/members.js +0 -33
  103. package/dist/tools/members.js.map +0 -1
  104. package/dist/tools/message-templates.d.ts +0 -54
  105. package/dist/tools/message-templates.js +0 -88
  106. package/dist/tools/message-templates.js.map +0 -1
  107. package/dist/tools/milestones.d.ts +0 -56
  108. package/dist/tools/milestones.js +0 -172
  109. package/dist/tools/milestones.js.map +0 -1
  110. package/dist/tools/organizations.d.ts +0 -37
  111. package/dist/tools/organizations.js +0 -88
  112. package/dist/tools/organizations.js.map +0 -1
  113. package/dist/tools/overview.d.ts +0 -55
  114. package/dist/tools/overview.js +0 -395
  115. package/dist/tools/overview.js.map +0 -1
  116. package/dist/tools/planner.d.ts +0 -60
  117. package/dist/tools/planner.js +0 -145
  118. package/dist/tools/planner.js.map +0 -1
  119. package/dist/tools/process.d.ts +0 -50
  120. package/dist/tools/process.js +0 -137
  121. package/dist/tools/process.js.map +0 -1
  122. package/dist/tools/products.d.ts +0 -17
  123. package/dist/tools/products.js +0 -45
  124. package/dist/tools/products.js.map +0 -1
  125. package/dist/tools/projects.d.ts +0 -41
  126. package/dist/tools/projects.js +0 -93
  127. package/dist/tools/projects.js.map +0 -1
  128. package/dist/tools/qms.d.ts +0 -57
  129. package/dist/tools/qms.js +0 -171
  130. package/dist/tools/qms.js.map +0 -1
  131. package/dist/tools/recruiting.d.ts +0 -112
  132. package/dist/tools/recruiting.js +0 -203
  133. package/dist/tools/recruiting.js.map +0 -1
  134. package/dist/tools/relations.d.ts +0 -72
  135. package/dist/tools/relations.js +0 -192
  136. package/dist/tools/relations.js.map +0 -1
  137. package/dist/tools/search.d.ts +0 -23
  138. package/dist/tools/search.js +0 -60
  139. package/dist/tools/search.js.map +0 -1
  140. package/dist/tools/sharing.d.ts +0 -62
  141. package/dist/tools/sharing.js +0 -149
  142. package/dist/tools/sharing.js.map +0 -1
  143. package/dist/tools/statuses.d.ts +0 -19
  144. package/dist/tools/statuses.js +0 -93
  145. package/dist/tools/statuses.js.map +0 -1
  146. package/dist/tools/surveys.d.ts +0 -22
  147. package/dist/tools/surveys.js +0 -53
  148. package/dist/tools/surveys.js.map +0 -1
  149. package/dist/tools/templates.d.ts +0 -95
  150. package/dist/tools/templates.js +0 -260
  151. package/dist/tools/templates.js.map +0 -1
  152. package/dist/tools/test-automation.d.ts +0 -81
  153. package/dist/tools/test-automation.js +0 -225
  154. package/dist/tools/test-automation.js.map +0 -1
  155. package/dist/tools/testing.d.ts +0 -234
  156. package/dist/tools/testing.js +0 -401
  157. package/dist/tools/testing.js.map +0 -1
  158. package/dist/tools/workspace-admin.d.ts +0 -55
  159. package/dist/tools/workspace-admin.js +0 -117
  160. package/dist/tools/workspace-admin.js.map +0 -1
  161. package/dist/tools/workspaces.d.ts +0 -6
  162. package/dist/tools/workspaces.js +0 -19
  163. package/dist/tools/workspaces.js.map +0 -1
  164. package/dist/utils/attributes.d.ts +0 -37
  165. package/dist/utils/attributes.js +0 -188
  166. package/dist/utils/attributes.js.map +0 -1
  167. package/dist/utils/classes.d.ts +0 -51
  168. package/dist/utils/classes.js +0 -73
  169. package/dist/utils/classes.js.map +0 -1
  170. package/dist/utils/content.d.ts +0 -11
  171. package/dist/utils/content.js +0 -86
  172. package/dist/utils/content.js.map +0 -1
  173. package/dist/utils/errors.d.ts +0 -11
  174. package/dist/utils/errors.js +0 -24
  175. package/dist/utils/errors.js.map +0 -1
  176. package/dist/utils/files.d.ts +0 -5
  177. package/dist/utils/files.js +0 -50
  178. package/dist/utils/files.js.map +0 -1
  179. package/dist/utils/format.d.ts +0 -8
  180. package/dist/utils/format.js +0 -57
  181. package/dist/utils/format.js.map +0 -1
  182. package/dist/utils/junit.d.ts +0 -13
  183. package/dist/utils/junit.js +0 -81
  184. package/dist/utils/junit.js.map +0 -1
  185. package/dist/utils/markdown.d.ts +0 -14
  186. package/dist/utils/markdown.js +0 -149
  187. package/dist/utils/markdown.js.map +0 -1
  188. package/dist/utils/meeting.d.ts +0 -13
  189. package/dist/utils/meeting.js +0 -118
  190. package/dist/utils/meeting.js.map +0 -1
  191. package/dist/utils/people.d.ts +0 -25
  192. package/dist/utils/people.js +0 -80
  193. package/dist/utils/people.js.map +0 -1
  194. package/dist/utils/redact.d.ts +0 -3
  195. package/dist/utils/redact.js +0 -26
  196. package/dist/utils/redact.js.map +0 -1
  197. package/dist/utils/resolve.d.ts +0 -17
  198. package/dist/utils/resolve.js +0 -54
  199. package/dist/utils/resolve.js.map +0 -1
  200. package/dist/utils/spec.d.ts +0 -10
  201. package/dist/utils/spec.js +0 -90
  202. package/dist/utils/spec.js.map +0 -1
  203. package/dist/utils/storage.d.ts +0 -7
  204. package/dist/utils/storage.js +0 -86
  205. package/dist/utils/storage.js.map +0 -1
  206. package/dist/utils/tasks.d.ts +0 -22
  207. package/dist/utils/tasks.js +0 -81
  208. package/dist/utils/tasks.js.map +0 -1
  209. package/dist/watch.d.ts +0 -62
  210. package/dist/watch.js +0 -405
  211. package/dist/watch.js.map +0 -1
  212. package/scripts/cleanup-issues.js +0 -141
  213. package/scripts/copy-guides.js +0 -18
  214. package/scripts/demo.js +0 -201
  215. package/scripts/import-csv.js +0 -250
  216. package/scripts/sample-tasks.csv +0 -11
  217. 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`)