loop-task 1.0.1 → 1.0.2

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.
package/dist/cli.js CHANGED
@@ -1,60 +1,96 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from "commander";
3
2
  import { parseDuration } from "./duration.js";
4
3
  import { Logger } from "./logger.js";
5
4
  import { runLoop } from "./loop.js";
6
- const program = new Command();
7
- program
8
- .name("loop-task")
9
- .description("Repeatedly execute a shell command at a human-readable interval")
10
- .version("1.0.0")
11
- .argument("<interval>", "Interval between runs (e.g. 10s, 5m, 1h, 1d, 1w)")
12
- .argument("<command...>", "Command to execute")
13
- .option("--immediate", "Run immediately before waiting", false)
14
- .option("--max-runs <n>", "Stop after N executions", (v) => {
15
- const n = parseInt(v, 10);
16
- if (isNaN(n) || n < 1) {
17
- throw new Error("--max-runs must be a positive integer");
5
+ const args = process.argv.slice(2);
6
+ const loopOptions = {
7
+ immediate: false,
8
+ maxRuns: null,
9
+ verbose: false,
10
+ };
11
+ const commandParts = [];
12
+ let i = 0;
13
+ while (i < args.length) {
14
+ const arg = args[i];
15
+ if (arg === "--immediate") {
16
+ loopOptions.immediate = true;
17
+ i++;
18
18
  }
19
- return n;
20
- }, null)
21
- .option("--verbose", "Show execution details", false)
22
- .enablePositionalOptions()
23
- .passThroughOptions()
24
- .addHelpText("before", `
19
+ else if (arg === "--max-runs") {
20
+ i++;
21
+ const n = parseInt(args[i], 10);
22
+ if (isNaN(n) || n < 1) {
23
+ console.error("Error: --max-runs must be a positive integer");
24
+ process.exit(1);
25
+ }
26
+ loopOptions.maxRuns = n;
27
+ i++;
28
+ }
29
+ else if (arg === "--verbose") {
30
+ loopOptions.verbose = true;
31
+ i++;
32
+ }
33
+ else if (arg === "--help" || arg === "-h") {
34
+ console.log(`
25
35
  Usage:
26
36
  loop-task [options] <interval> <command>
27
37
 
28
38
  Examples:
29
39
  loop-task 30m npm test
30
40
  loop-task 1h opencode --prompt '/ob-init'
31
- loop-task --immediate 1h npm test
41
+ loop-task 30s --immediate -- echo hello
32
42
  loop-task --max-runs 5 5m npm test
33
- `)
34
- .action(async (intervalStr, commandParts, opts) => {
35
- const logger = new Logger(opts.verbose);
36
- let interval;
37
- try {
38
- interval = parseDuration(intervalStr);
43
+
44
+ Options:
45
+ --immediate Run immediately before waiting
46
+ --max-runs <n> Stop after N executions
47
+ --verbose Show execution details
48
+ -h, --help Display help
49
+ -V, --version Display version
50
+ `);
51
+ process.exit(0);
52
+ }
53
+ else if (arg === "--version" || arg === "-V") {
54
+ console.log("1.0.0");
55
+ process.exit(0);
56
+ }
57
+ else if (arg === "--") {
58
+ i++;
59
+ commandParts.push(...args.slice(i));
60
+ break;
39
61
  }
40
- catch (error) {
41
- const message = error instanceof Error ? error.message : String(error);
42
- logger.error(`Error: ${message}`);
43
- process.exit(1);
62
+ else {
63
+ commandParts.push(arg);
64
+ i++;
44
65
  }
45
- const command = commandParts.join(" ");
46
- const options = {
47
- interval,
48
- command,
49
- immediate: opts.immediate,
50
- maxRuns: opts.maxRuns,
51
- verbose: opts.verbose,
52
- };
53
- const controller = new AbortController();
54
- process.on("SIGINT", () => controller.abort());
55
- process.on("SIGTERM", () => controller.abort());
56
- await runLoop(options, logger, controller.signal);
57
- process.exit(0);
58
- });
59
- program.parse();
66
+ }
67
+ if (commandParts.length < 2) {
68
+ console.error("Error: missing required arguments");
69
+ console.error("Usage: loop-task [options] <interval> <command>");
70
+ process.exit(1);
71
+ }
72
+ const intervalStr = commandParts[0];
73
+ const command = commandParts.slice(1).join(" ");
74
+ const logger = new Logger(loopOptions.verbose);
75
+ let interval;
76
+ try {
77
+ interval = parseDuration(intervalStr);
78
+ }
79
+ catch (error) {
80
+ const message = error instanceof Error ? error.message : String(error);
81
+ logger.error(`Error: ${message}`);
82
+ process.exit(1);
83
+ }
84
+ const options = {
85
+ interval,
86
+ command,
87
+ immediate: loopOptions.immediate,
88
+ maxRuns: loopOptions.maxRuns,
89
+ verbose: loopOptions.verbose,
90
+ };
91
+ const controller = new AbortController();
92
+ process.on("SIGINT", () => controller.abort());
93
+ process.on("SIGTERM", () => controller.abort());
94
+ await runLoop(options, logger, controller.signal);
95
+ process.exit(0);
60
96
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CACV,iEAAiE,CAClE;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,YAAY,EAAE,kDAAkD,CAAC;KAC1E,QAAQ,CAAC,cAAc,EAAE,oBAAoB,CAAC;KAC9C,MAAM,CAAC,aAAa,EAAE,gCAAgC,EAAE,KAAK,CAAC;KAC9D,MAAM,CAAC,gBAAgB,EAAE,yBAAyB,EAAE,CAAC,CAAC,EAAE,EAAE;IACzD,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1B,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,EAAE,IAAI,CAAC;KACP,MAAM,CAAC,WAAW,EAAE,wBAAwB,EAAE,KAAK,CAAC;KACpD,uBAAuB,EAAE;KACzB,kBAAkB,EAAE;KACpB,WAAW,CACV,QAAQ,EACR;;;;;;;;;CASH,CACE;KACA,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,YAAsB,EAAE,IAA6B,EAAE,EAAE;IAC3F,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAkB,CAAC,CAAC;IAEnD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAgB;QAC3B,QAAQ;QACR,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,SAAoB;QACpC,OAAO,EAAE,IAAI,CAAC,OAAwB;QACtC,OAAO,EAAE,IAAI,CAAC,OAAkB;KACjC,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IAEzC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IAEhD,MAAM,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loop-task",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A cross-platform CLI that repeatedly executes a shell command at a human-readable interval",
5
5
  "type": "module",
6
6
  "bin": {