invoket 0.1.9 → 0.1.10
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/CLAUDE.md +57 -0
- package/README.md +12 -3
- package/package.json +3 -2
- package/src/cli.ts +42 -8
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Add reusable commands to `tasks.ts`. invoket gives them typed args, `--help`, and error handling.
|
|
4
|
+
|
|
5
|
+
Use invoket when a command will be reused. Write a raw script for throwaway one-offs.
|
|
6
|
+
|
|
7
|
+
## Task skeleton
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { Context } from "invoket/context";
|
|
11
|
+
|
|
12
|
+
export class Tasks {
|
|
13
|
+
/** Description (required — no JSDoc = not discovered) */
|
|
14
|
+
async taskName(c: Context, required: string, optional: number = 1) {}
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`async` + JSDoc + `c: Context` first param. `_prefix` = private.
|
|
19
|
+
|
|
20
|
+
## Types → CLI
|
|
21
|
+
|
|
22
|
+
`string` as-is, `number` rejects NaN, `boolean` accepts `true/false/1/0/--flag/--no-flag`, `Interface` and `Record` expect JSON string, `type[]` expects JSON array, `...args: string[]` collects remaining, `= default` and `| null` make optional.
|
|
23
|
+
|
|
24
|
+
## Flags
|
|
25
|
+
|
|
26
|
+
Auto: `--paramName`. For short flags add `@flag` in JSDoc:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
/** @flag env -e --environment */
|
|
30
|
+
async deploy(c: Context, env: string) {}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Namespaces
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
class Db {
|
|
37
|
+
/** Migrate */
|
|
38
|
+
async migrate(c: Context, direction: string = "up") {}
|
|
39
|
+
}
|
|
40
|
+
export class Tasks {
|
|
41
|
+
db = new Db(); // invt db:migrate up
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Context
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
await c.run(cmd); // throw on failure
|
|
49
|
+
await c.run(cmd, { warn: true }); // don't throw
|
|
50
|
+
const { stdout } = await c.run(cmd, { hide: true }); // capture
|
|
51
|
+
await c.run(cmd, { stream: true }); // real-time output
|
|
52
|
+
await c.run(cmd, { echo: true }); // print command first
|
|
53
|
+
await c.sudo(cmd); // sudo prefix
|
|
54
|
+
for await (const _ of c.cd(dir)) { } // temp cd
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Result: `{ stdout, stderr, code, ok, failed }`. Failure throws `CommandError` with `.result`.
|
package/README.md
CHANGED
|
@@ -28,13 +28,21 @@ One script solves one problem. A `tasks.ts` file is a project's command centre.
|
|
|
28
28
|
## Installation
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
bun add -d invoket
|
|
32
|
-
bun
|
|
31
|
+
bun add -d invoket # Add to project (use bunx invt to run)
|
|
32
|
+
bun add -g invoket # Or install globally (invt available on PATH)
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Then scaffold your project:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bunx invt --init # Creates tasks.ts and CLAUDE.md
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`--init` creates a starter `tasks.ts` and copies the `CLAUDE.md` reference card into your project so AI agents know how to write tasks.
|
|
42
|
+
|
|
35
43
|
## Quick Start
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
Edit `tasks.ts`:
|
|
38
46
|
|
|
39
47
|
```typescript
|
|
40
48
|
import { Context } from "invoket/context";
|
|
@@ -153,6 +161,7 @@ Flags and positional args can be freely mixed in any order.
|
|
|
153
161
|
| `<task> -h` | Help for a specific task |
|
|
154
162
|
| `-l`, `--list` | List tasks |
|
|
155
163
|
| `--version` | Show version |
|
|
164
|
+
| `--init` | Scaffold `tasks.ts` and `CLAUDE.md` |
|
|
156
165
|
|
|
157
166
|
## Context API
|
|
158
167
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "invoket",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "TypeScript task runner for Bun - uses type annotations to parse CLI arguments",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"./context": "./src/context.ts"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"src"
|
|
13
|
+
"src",
|
|
14
|
+
"CLAUDE.md"
|
|
14
15
|
],
|
|
15
16
|
"keywords": [
|
|
16
17
|
"task-runner",
|
package/src/cli.ts
CHANGED
|
@@ -27,13 +27,18 @@ async function main() {
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
// --init flag: scaffold tasks.ts and CLAUDE.md
|
|
31
|
+
if (args[0] === "--init") {
|
|
32
|
+
const { existsSync } = await import("fs");
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
|
|
35
|
+
const tasksFile = `${cwd}/tasks.ts`;
|
|
36
|
+
if (existsSync(tasksFile)) {
|
|
37
|
+
console.log("tasks.ts already exists, skipping.");
|
|
38
|
+
} else {
|
|
39
|
+
await Bun.write(
|
|
40
|
+
tasksFile,
|
|
41
|
+
`import { Context } from "invoket/context";
|
|
37
42
|
|
|
38
43
|
export class Tasks {
|
|
39
44
|
/** Say hello */
|
|
@@ -41,7 +46,36 @@ export class Tasks {
|
|
|
41
46
|
console.log("Hello, World!");
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
|
-
|
|
49
|
+
`,
|
|
50
|
+
);
|
|
51
|
+
console.log("Created tasks.ts");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const claudeFile = `${cwd}/CLAUDE.md`;
|
|
55
|
+
const claudeMdPath = new URL("../CLAUDE.md", import.meta.url).pathname;
|
|
56
|
+
const claudeMd = await Bun.file(claudeMdPath).text();
|
|
57
|
+
if (existsSync(claudeFile)) {
|
|
58
|
+
const existing = await Bun.file(claudeFile).text();
|
|
59
|
+
if (existing.includes("invoket")) {
|
|
60
|
+
console.log("CLAUDE.md already has invoket section, skipping.");
|
|
61
|
+
} else {
|
|
62
|
+
await Bun.write(claudeFile, existing.trimEnd() + "\n\n" + claudeMd);
|
|
63
|
+
console.log("Appended invoket guide to CLAUDE.md");
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
await Bun.write(claudeFile, claudeMd);
|
|
67
|
+
console.log("Created CLAUDE.md");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Find tasks.ts
|
|
74
|
+
let tasksPath: string;
|
|
75
|
+
try {
|
|
76
|
+
tasksPath = Bun.resolveSync("./tasks.ts", process.cwd());
|
|
77
|
+
} catch {
|
|
78
|
+
console.log("No tasks.ts found. Run 'invt --init' to get started.");
|
|
45
79
|
process.exit(1);
|
|
46
80
|
}
|
|
47
81
|
|