@simonfestl/husky-cli 1.34.0 → 1.35.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.
@@ -215,5 +215,100 @@ program
215
215
  process.exit(1);
216
216
  }
217
217
  });
218
+ /**
219
+ * Wait for plan approval (worker command)
220
+ *
221
+ * Exit codes:
222
+ * 0 = approved
223
+ * 1 = rejected
224
+ * 2 = revision_requested
225
+ * 3 = timeout
226
+ */
227
+ program
228
+ .command("await")
229
+ .description("Wait for supervisor to approve/reject a plan (worker)")
230
+ .argument("<id>", "Plan ID to wait for")
231
+ .option("--timeout <seconds>", "Timeout in seconds (default: 300)", "300")
232
+ .option("--interval <seconds>", "Poll interval in seconds (default: 5)", "5")
233
+ .option("--json", "Output result as JSON")
234
+ .action(async (id, options) => {
235
+ const timeout = parseInt(options.timeout, 10) * 1000;
236
+ const interval = parseInt(options.interval, 10) * 1000;
237
+ const startTime = Date.now();
238
+ const api = getApiClient();
239
+ if (!options.json) {
240
+ console.log(chalk.yellow(`⏳ Waiting for plan ${id} approval...`));
241
+ console.log(chalk.dim(` Timeout: ${options.timeout}s, Poll interval: ${options.interval}s`));
242
+ }
243
+ while (true) {
244
+ try {
245
+ const result = await api.get(`/api/plans/${id}`);
246
+ const { plan } = result;
247
+ if (plan.status === "approved") {
248
+ if (options.json) {
249
+ console.log(JSON.stringify({ status: "approved", notes: plan.supervisorNotes }));
250
+ }
251
+ else {
252
+ console.log(chalk.green("\n✓ Plan approved!"));
253
+ if (plan.supervisorNotes) {
254
+ console.log(chalk.dim(` Supervisor notes: ${plan.supervisorNotes}`));
255
+ }
256
+ console.log(chalk.dim(" You may proceed with implementation."));
257
+ }
258
+ process.exit(0);
259
+ }
260
+ if (plan.status === "rejected") {
261
+ if (options.json) {
262
+ console.log(JSON.stringify({ status: "rejected", notes: plan.supervisorNotes }));
263
+ }
264
+ else {
265
+ console.log(chalk.red("\n✗ Plan rejected"));
266
+ if (plan.supervisorNotes) {
267
+ console.log(chalk.dim(` Reason: ${plan.supervisorNotes}`));
268
+ }
269
+ }
270
+ process.exit(1);
271
+ }
272
+ if (plan.status === "revision_requested") {
273
+ if (options.json) {
274
+ console.log(JSON.stringify({ status: "revision_requested", notes: plan.supervisorNotes }));
275
+ }
276
+ else {
277
+ console.log(chalk.blue("\n🔄 Revision requested"));
278
+ if (plan.supervisorNotes) {
279
+ console.log(chalk.dim(` Feedback: ${plan.supervisorNotes}`));
280
+ }
281
+ console.log(chalk.dim(" Please update and resubmit the plan."));
282
+ }
283
+ process.exit(2);
284
+ }
285
+ // Still pending - check timeout
286
+ if (Date.now() - startTime >= timeout) {
287
+ if (options.json) {
288
+ console.log(JSON.stringify({ status: "timeout", elapsed: Math.round((Date.now() - startTime) / 1000) }));
289
+ }
290
+ else {
291
+ console.log(chalk.yellow("\n⏱️ Timeout reached"));
292
+ console.log(chalk.dim(` Plan is still pending after ${options.timeout}s`));
293
+ }
294
+ process.exit(3);
295
+ }
296
+ // Wait before next poll
297
+ if (!options.json) {
298
+ process.stdout.write(".");
299
+ }
300
+ await new Promise((resolve) => setTimeout(resolve, interval));
301
+ }
302
+ catch (error) {
303
+ if (options.json) {
304
+ console.log(JSON.stringify({ status: "error", message: error instanceof Error ? error.message : String(error) }));
305
+ }
306
+ else {
307
+ console.error(chalk.red("\n✗ Error checking plan status:"), error instanceof Error ? error.message : error);
308
+ }
309
+ process.exit(1);
310
+ }
311
+ }
312
+ });
218
313
  export const planCommand = program;
219
314
  export default program;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonfestl/husky-cli",
3
- "version": "1.34.0",
3
+ "version": "1.35.0",
4
4
  "description": "CLI for Huskyv0 Task Orchestration with Claude Agent SDK",
5
5
  "type": "module",
6
6
  "bin": {