@markjaquith/agency 0.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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/cli.ts +569 -0
  4. package/index.ts +1 -0
  5. package/package.json +65 -0
  6. package/src/commands/base.test.ts +198 -0
  7. package/src/commands/base.ts +198 -0
  8. package/src/commands/clean.test.ts +299 -0
  9. package/src/commands/clean.ts +320 -0
  10. package/src/commands/emit.test.ts +412 -0
  11. package/src/commands/emit.ts +521 -0
  12. package/src/commands/emitted.test.ts +226 -0
  13. package/src/commands/emitted.ts +57 -0
  14. package/src/commands/init.test.ts +311 -0
  15. package/src/commands/init.ts +140 -0
  16. package/src/commands/merge.test.ts +365 -0
  17. package/src/commands/merge.ts +253 -0
  18. package/src/commands/pull.test.ts +385 -0
  19. package/src/commands/pull.ts +205 -0
  20. package/src/commands/push.test.ts +394 -0
  21. package/src/commands/push.ts +346 -0
  22. package/src/commands/save.test.ts +247 -0
  23. package/src/commands/save.ts +162 -0
  24. package/src/commands/source.test.ts +195 -0
  25. package/src/commands/source.ts +72 -0
  26. package/src/commands/status.test.ts +489 -0
  27. package/src/commands/status.ts +258 -0
  28. package/src/commands/switch.test.ts +194 -0
  29. package/src/commands/switch.ts +84 -0
  30. package/src/commands/task-branching.test.ts +334 -0
  31. package/src/commands/task-edit.test.ts +141 -0
  32. package/src/commands/task-main.test.ts +872 -0
  33. package/src/commands/task.ts +712 -0
  34. package/src/commands/tasks.test.ts +335 -0
  35. package/src/commands/tasks.ts +155 -0
  36. package/src/commands/template-delete.test.ts +178 -0
  37. package/src/commands/template-delete.ts +98 -0
  38. package/src/commands/template-list.test.ts +135 -0
  39. package/src/commands/template-list.ts +87 -0
  40. package/src/commands/template-view.test.ts +158 -0
  41. package/src/commands/template-view.ts +86 -0
  42. package/src/commands/template.test.ts +32 -0
  43. package/src/commands/template.ts +96 -0
  44. package/src/commands/use.test.ts +87 -0
  45. package/src/commands/use.ts +97 -0
  46. package/src/commands/work.test.ts +462 -0
  47. package/src/commands/work.ts +193 -0
  48. package/src/errors.ts +17 -0
  49. package/src/schemas.ts +33 -0
  50. package/src/services/AgencyMetadataService.ts +287 -0
  51. package/src/services/ClaudeService.test.ts +184 -0
  52. package/src/services/ClaudeService.ts +91 -0
  53. package/src/services/ConfigService.ts +115 -0
  54. package/src/services/FileSystemService.ts +222 -0
  55. package/src/services/GitService.ts +751 -0
  56. package/src/services/OpencodeService.ts +263 -0
  57. package/src/services/PromptService.ts +183 -0
  58. package/src/services/TemplateService.ts +75 -0
  59. package/src/test-utils.ts +362 -0
  60. package/src/types/native-exec.d.ts +8 -0
  61. package/src/types.ts +216 -0
  62. package/src/utils/colors.ts +178 -0
  63. package/src/utils/command.ts +17 -0
  64. package/src/utils/effect.ts +281 -0
  65. package/src/utils/exec.ts +48 -0
  66. package/src/utils/paths.ts +51 -0
  67. package/src/utils/pr-branch.test.ts +372 -0
  68. package/src/utils/pr-branch.ts +473 -0
  69. package/src/utils/process.ts +110 -0
  70. package/src/utils/spinner.ts +82 -0
  71. package/templates/AGENCY.md +20 -0
  72. package/templates/AGENTS.md +11 -0
  73. package/templates/CLAUDE.md +3 -0
  74. package/templates/TASK.md +5 -0
  75. package/templates/opencode.json +4 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mark Jaquith
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # @markjaquith/agency
2
+
3
+ Smuggle project-level LLM instruction into any Git repo. Plan your tasks. Commit your plans. Execute your plans using Opencode. Filter those plans out out your PRs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun install -g @markjaquith/agency
9
+ ```
10
+
11
+ ## Primary Commands
12
+
13
+ ### `agency task [branch-name]`
14
+
15
+ Initialize `AGENTS.md` and `TASK.md` files using the template you've set for this repo. Commits smuggled files and lands you on that branch.
16
+
17
+ ### `agency task edit`
18
+
19
+ Open `TASK.md` in the system editor for editing. Nice if you have to paste in large amounts of context.
20
+
21
+ ### `agency work`
22
+
23
+ Launch Opencode to work on the current task defined in `TASK.md`. All your context will be loaded.
24
+
25
+ ### `agency pr [base-branch]`
26
+
27
+ Create an emit branch with smuggled files reverted to their merge-base state (removes additions/modifications to those files made on feature branch). Default branch name is current branch with `--PR` suffix.
28
+
29
+ ### `agency push`
30
+
31
+ Runs `agency pr`, pushes the branch, and then switches back to the source branch.
32
+
33
+ ### `agency merge`
34
+
35
+ Runs `agency pr`, and then merges the PR back into the base branch locally.
36
+
37
+ ## Other Commands
38
+
39
+ ### `agency template use [template]`
40
+
41
+ Set which template to use for this repository. Shows interactive selection if no template name provided. Saves to `.git/config`.
42
+
43
+ ### `agency template save <files...>`
44
+
45
+ Save the specified files back to the configured template directory (so they will be used for future `agency task` commands).
46
+
47
+ ### `agency base get`
48
+
49
+ Get the base branch for the current feature branch.
50
+
51
+ ### `agency base set <branch>`
52
+
53
+ Set the base branch for the current feature branch.
54
+
55
+ ### `agency switch`
56
+
57
+ Toggle between source branch and emit branch. If on an emit branch (e.g., `foo--PR`), switches to source branch (e.g., `foo`). If on source branch and emit branch exists, switches to emit branch.
58
+
59
+ ### `agency source`
60
+
61
+ Switch to the source branch for the current emit branch.
62
+
63
+ ## Requirements
64
+
65
+ - [Bun](https://bun.sh) >= 1.0.0 (recommended)
66
+ - TypeScript ^5
67
+
68
+ ## Development
69
+
70
+ To install dependencies:
71
+
72
+ ```bash
73
+ bun install
74
+ ```
75
+
76
+ To run:
77
+
78
+ ```bash
79
+ bun run index.ts
80
+ ```
81
+
82
+ ### Git Hooks
83
+
84
+ This project uses [hk](https://github.com/jdx/hk) for git hook management. The configuration is in `hk.pkl`.
85
+
86
+ To install the git hooks:
87
+
88
+ ```bash
89
+ hk install
90
+ ```
91
+
92
+ **Pre-commit hook runs:**
93
+
94
+ - Prettier formatting
95
+ - Knip (unused code detection)
96
+ - TypeScript type checking
97
+
98
+ **Commit-msg hook validates:**
99
+
100
+ - Conventional commits format
101
+ - Commit message history
102
+
103
+ **Pre-push hook runs the same checks as pre-commit.**
104
+
105
+ Note: Tests are intentionally excluded from git hooks as they are slow. Run them manually with `bun test`.
106
+
107
+ ## License
108
+
109
+ MIT
package/cli.ts ADDED
@@ -0,0 +1,569 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { parseArgs } from "util"
4
+ import { Effect, Layer } from "effect"
5
+ import { clean, help as cleanHelp } from "./src/commands/clean"
6
+ import { init, help as initHelp } from "./src/commands/init"
7
+ import { task, taskEdit, help as taskHelp } from "./src/commands/task"
8
+ import { tasks, help as tasksHelp } from "./src/commands/tasks"
9
+ import { emit, help as emitHelp } from "./src/commands/emit"
10
+ import { emitted, help as emittedHelp } from "./src/commands/emitted"
11
+ import { push, help as pushHelp } from "./src/commands/push"
12
+ import { pull, help as pullHelp } from "./src/commands/pull"
13
+ import { base, help as baseHelp } from "./src/commands/base"
14
+ import { switchBranch, help as switchHelp } from "./src/commands/switch"
15
+ import { source, help as sourceHelp } from "./src/commands/source"
16
+ import { merge, help as mergeHelp } from "./src/commands/merge"
17
+ import { template, help as templateHelp } from "./src/commands/template"
18
+ import { work, help as workHelp } from "./src/commands/work"
19
+ import { status, help as statusHelp } from "./src/commands/status"
20
+ import type { Command } from "./src/types"
21
+ import { setColorsEnabled } from "./src/utils/colors"
22
+ import { GitService } from "./src/services/GitService"
23
+ import { ConfigService } from "./src/services/ConfigService"
24
+ import { FileSystemService } from "./src/services/FileSystemService"
25
+ import { PromptService } from "./src/services/PromptService"
26
+ import { TemplateService } from "./src/services/TemplateService"
27
+ import { OpencodeService } from "./src/services/OpencodeService"
28
+ import { ClaudeService } from "./src/services/ClaudeService"
29
+
30
+ // Create CLI layer with all services
31
+ const CliLayer = Layer.mergeAll(
32
+ GitService.Default,
33
+ ConfigService.Default,
34
+ FileSystemService.Default,
35
+ PromptService.Default,
36
+ TemplateService.Default,
37
+ OpencodeService.Default,
38
+ ClaudeService.Default,
39
+ )
40
+
41
+ /**
42
+ * Run a command Effect with all services provided
43
+ */
44
+ async function runCommand<E>(
45
+ effect: Effect.Effect<void, E, any>,
46
+ ): Promise<void> {
47
+ const providedEffect = Effect.provide(effect, CliLayer) as Effect.Effect<
48
+ void,
49
+ E,
50
+ never
51
+ >
52
+ const program = Effect.catchAllDefect(providedEffect, (defect) =>
53
+ Effect.fail(defect instanceof Error ? defect : new Error(String(defect))),
54
+ ) as Effect.Effect<void, E | Error, never>
55
+
56
+ await Effect.runPromise(program)
57
+ }
58
+
59
+ // Read version from package.json
60
+ const packageJson = await Bun.file(
61
+ new URL("./package.json", import.meta.url),
62
+ ).json()
63
+ const VERSION = packageJson.version
64
+
65
+ // Define commands
66
+ const commands: Record<string, Command> = {
67
+ init: {
68
+ name: "init",
69
+ description: "Initialize agency with template selection",
70
+ run: async (_args: string[], options: Record<string, any>) => {
71
+ if (options.help) {
72
+ console.log(initHelp)
73
+ return
74
+ }
75
+ await runCommand(
76
+ init({
77
+ template: options.template,
78
+ silent: options.silent,
79
+ verbose: options.verbose,
80
+ }),
81
+ )
82
+ },
83
+ help: initHelp,
84
+ },
85
+ emit: {
86
+ name: "emit",
87
+ description: "Emit a branch without backpack files",
88
+ run: async (args: string[], options: Record<string, any>) => {
89
+ if (options.help) {
90
+ console.log(emitHelp)
91
+ return
92
+ }
93
+ await runCommand(
94
+ emit({
95
+ baseBranch: args[0],
96
+ branch: options.branch,
97
+ silent: options.silent,
98
+ force: options.verbose,
99
+ verbose: options.verbose,
100
+ }),
101
+ )
102
+ },
103
+ help: emitHelp,
104
+ },
105
+ emitted: {
106
+ name: "emitted",
107
+ description: "Get the name of the emitted branch",
108
+ run: async (_args: string[], options: Record<string, any>) => {
109
+ if (options.help) {
110
+ console.log(emittedHelp)
111
+ return
112
+ }
113
+ await runCommand(
114
+ emitted({ silent: options.silent, verbose: options.verbose }),
115
+ )
116
+ },
117
+ help: emittedHelp,
118
+ },
119
+ push: {
120
+ name: "push",
121
+ description: "Emit, push to remote, return to source",
122
+ run: async (args: string[], options: Record<string, any>) => {
123
+ if (options.help) {
124
+ console.log(pushHelp)
125
+ return
126
+ }
127
+ await runCommand(
128
+ push({
129
+ baseBranch: args[0],
130
+ branch: options.branch,
131
+ silent: options.silent,
132
+ force: options.force,
133
+ verbose: options.verbose,
134
+ pr: options.pr,
135
+ }),
136
+ )
137
+ },
138
+ help: pushHelp,
139
+ },
140
+ pull: {
141
+ name: "pull",
142
+ description: "Pull commits from remote emit branch to source",
143
+ run: async (_args: string[], options: Record<string, any>) => {
144
+ if (options.help) {
145
+ console.log(pullHelp)
146
+ return
147
+ }
148
+ await runCommand(
149
+ pull({
150
+ remote: options.remote,
151
+ silent: options.silent,
152
+ verbose: options.verbose,
153
+ }),
154
+ )
155
+ },
156
+ help: pullHelp,
157
+ },
158
+ template: {
159
+ name: "template",
160
+ description: "Template management commands",
161
+ run: async (args: string[], options: Record<string, any>) => {
162
+ if (options.help) {
163
+ console.log(templateHelp)
164
+ return
165
+ }
166
+ await runCommand(
167
+ template({
168
+ subcommand: args[0],
169
+ args: args.slice(1),
170
+ silent: options.silent,
171
+ verbose: options.verbose,
172
+ template: options.template,
173
+ }),
174
+ )
175
+ },
176
+ help: templateHelp,
177
+ },
178
+ base: {
179
+ name: "base",
180
+ description: "Get or set the base branch",
181
+ run: async (args: string[], options: Record<string, any>) => {
182
+ if (options.help) {
183
+ console.log(baseHelp)
184
+ return
185
+ }
186
+ await runCommand(
187
+ base({
188
+ subcommand: args[0],
189
+ args: args.slice(1),
190
+ repo: options.repo,
191
+ silent: options.silent,
192
+ verbose: options.verbose,
193
+ }),
194
+ )
195
+ },
196
+ help: baseHelp,
197
+ },
198
+ switch: {
199
+ name: "switch",
200
+ description: "Toggle between source and emitted branch",
201
+ run: async (_args: string[], options: Record<string, any>) => {
202
+ if (options.help) {
203
+ console.log(switchHelp)
204
+ return
205
+ }
206
+ await runCommand(
207
+ switchBranch({ silent: options.silent, verbose: options.verbose }),
208
+ )
209
+ },
210
+ help: switchHelp,
211
+ },
212
+ source: {
213
+ name: "source",
214
+ description: "Switch to source branch from emitted branch",
215
+ run: async (_args: string[], options: Record<string, any>) => {
216
+ if (options.help) {
217
+ console.log(sourceHelp)
218
+ return
219
+ }
220
+ await runCommand(
221
+ source({ silent: options.silent, verbose: options.verbose }),
222
+ )
223
+ },
224
+ help: sourceHelp,
225
+ },
226
+ merge: {
227
+ name: "merge",
228
+ description: "Merge emitted branch into base branch",
229
+ run: async (_args: string[], options: Record<string, any>) => {
230
+ if (options.help) {
231
+ console.log(mergeHelp)
232
+ return
233
+ }
234
+ await runCommand(
235
+ merge({
236
+ silent: options.silent,
237
+ verbose: options.verbose,
238
+ squash: options.squash,
239
+ push: options.push,
240
+ }),
241
+ )
242
+ },
243
+ help: mergeHelp,
244
+ },
245
+ task: {
246
+ name: "task",
247
+ description: "Task management commands",
248
+ run: async (args: string[], options: Record<string, any>) => {
249
+ if (options.help) {
250
+ console.log(taskHelp)
251
+ return
252
+ }
253
+ // Initialize with optional branch name
254
+ const branch = args[0] || options.branch
255
+ await runCommand(
256
+ task({
257
+ branch,
258
+ silent: options.silent,
259
+ verbose: options.verbose,
260
+ task: options.task,
261
+ from: options.from,
262
+ fromCurrent: options["from-current"],
263
+ }),
264
+ )
265
+ },
266
+ help: taskHelp,
267
+ },
268
+ tasks: {
269
+ name: "tasks",
270
+ description: "List all task branches",
271
+ run: async (_args: string[], options: Record<string, any>) => {
272
+ if (options.help) {
273
+ console.log(tasksHelp)
274
+ return
275
+ }
276
+ await runCommand(
277
+ tasks({
278
+ silent: options.silent,
279
+ verbose: options.verbose,
280
+ json: options.json,
281
+ }),
282
+ )
283
+ },
284
+ help: tasksHelp,
285
+ },
286
+ edit: {
287
+ name: "edit",
288
+ description: "Open TASK.md in system editor",
289
+ run: async (_args: string[], options: Record<string, any>) => {
290
+ if (options.help) {
291
+ console.log(`
292
+ Usage: agency edit [options]
293
+
294
+ Open TASK.md in the system editor for editing.
295
+
296
+ Notes:
297
+ - Requires TASK.md to exist (run 'agency task' first)
298
+ - Respects VISUAL and EDITOR environment variables
299
+ - On macOS, defaults to 'open' which uses the default app for .md files
300
+ - On other platforms, defaults to 'vim'
301
+ - The command waits for the editor to close before returning
302
+
303
+ Example:
304
+ agency edit # Open TASK.md in default editor
305
+ `)
306
+ return
307
+ }
308
+ await runCommand(
309
+ taskEdit({
310
+ silent: options.silent,
311
+ verbose: options.verbose,
312
+ }),
313
+ )
314
+ },
315
+ help: `Open TASK.md in system editor`,
316
+ },
317
+ work: {
318
+ name: "work",
319
+ description: "Start working on TASK.md with OpenCode",
320
+ run: async (args: string[], options: Record<string, any>) => {
321
+ if (options.help) {
322
+ console.log(workHelp)
323
+ return
324
+ }
325
+
326
+ // Extract extra args (anything after --)
327
+ // Note: parseArgs with strict:false and allowPositionals:true will put
328
+ // args after -- in the positionals array
329
+ const extraArgs = args.length > 0 ? args : undefined
330
+
331
+ await runCommand(
332
+ work({
333
+ silent: options.silent,
334
+ verbose: options.verbose,
335
+ opencode: options.opencode,
336
+ claude: options.claude,
337
+ extraArgs,
338
+ }),
339
+ )
340
+ },
341
+ help: workHelp,
342
+ },
343
+ status: {
344
+ name: "status",
345
+ description: "Show agency status for this repository",
346
+ run: async (_args: string[], options: Record<string, any>) => {
347
+ if (options.help) {
348
+ console.log(statusHelp)
349
+ return
350
+ }
351
+ await runCommand(
352
+ status({
353
+ silent: options.silent,
354
+ verbose: options.verbose,
355
+ json: options.json,
356
+ }),
357
+ )
358
+ },
359
+ help: statusHelp,
360
+ },
361
+ clean: {
362
+ name: "clean",
363
+ description: "Delete branches merged into a specified branch",
364
+ run: async (_args: string[], options: Record<string, any>) => {
365
+ if (options.help) {
366
+ console.log(cleanHelp)
367
+ return
368
+ }
369
+ await runCommand(
370
+ clean({
371
+ silent: options.silent,
372
+ verbose: options.verbose,
373
+ dryRun: options["dry-run"],
374
+ mergedInto: options["merged-into"],
375
+ }),
376
+ )
377
+ },
378
+ help: cleanHelp,
379
+ },
380
+ }
381
+
382
+ function showMainHelp() {
383
+ console.log(`
384
+ agency v${VERSION}
385
+
386
+ Usage: agency <command> [options]
387
+
388
+ Commands:
389
+ init Initialize agency with template selection (run first)
390
+ task [branch] Initialize template files on a feature branch
391
+ tasks List all task branches
392
+ edit Open TASK.md in system editor
393
+ work Start working on TASK.md with OpenCode
394
+ template Template management commands
395
+ use [template] Set template for this repository
396
+ save <file|dir> ... Save files/dirs to configured template
397
+ list List all files in configured template
398
+ view <file> View contents of a file in template
399
+ delete <file> ... Delete files from configured template
400
+ emit [base-branch] Emit a branch with backpack files reverted
401
+ emitted Get the name of the emitted branch
402
+ push [base-branch] Emit, push to remote, return to source
403
+ pull Pull commits from remote emit branch to source
404
+ base Get or set the base branch
405
+ set <branch> Set the base branch for the current feature branch
406
+ get Get the configured base branch
407
+ switch Toggle between source and emitted branch
408
+ source Switch to source branch from emitted branch
409
+ merge Merge emitted branch into base branch
410
+ status Show agency status for this repository
411
+
412
+ Global Options:
413
+ -h, --help Show help for a command
414
+ -v, --version Show version number
415
+ --no-color Disable color output
416
+ -s, --silent Suppress output messages
417
+ -v, --verbose Show verbose output including detailed debugging info
418
+
419
+ Examples:
420
+ agency init # Initialize with template (run first)
421
+ agency task # Initialize on current feature branch
422
+ agency task my-feature # Create 'my-feature' branch and initialize
423
+ agency emit # Emit a branch (prompts for base branch)
424
+ agency switch # Toggle between source and emitted branch
425
+
426
+ For more information about a command, run:
427
+ agency <command> --help
428
+ `)
429
+ }
430
+
431
+ // Parse global arguments
432
+ try {
433
+ const { values, positionals } = parseArgs({
434
+ args: process.argv.slice(2),
435
+ options: {
436
+ help: {
437
+ type: "boolean",
438
+ short: "h",
439
+ },
440
+ version: {
441
+ type: "boolean",
442
+ short: "v",
443
+ },
444
+ "no-color": {
445
+ type: "boolean",
446
+ },
447
+ },
448
+ strict: false,
449
+ allowPositionals: true,
450
+ })
451
+
452
+ // Handle --no-color flag
453
+ if (values["no-color"]) {
454
+ setColorsEnabled(false)
455
+ }
456
+
457
+ // Handle global flags
458
+ if (values.version) {
459
+ console.log(`v${VERSION}`)
460
+ process.exit(0)
461
+ }
462
+
463
+ // Get command
464
+ const commandName = positionals[0]
465
+
466
+ // Show help if no command
467
+ if (!commandName) {
468
+ showMainHelp()
469
+ process.exit(1)
470
+ }
471
+
472
+ // Show main help if --help with no command
473
+ if (values.help && !commandName) {
474
+ showMainHelp()
475
+ process.exit(0)
476
+ }
477
+
478
+ // Check if command exists
479
+ const command = commands[commandName]
480
+ if (!command) {
481
+ console.error(`Error: Unknown command '${commandName}'`)
482
+ console.error("\nRun 'agency --help' for usage information.")
483
+ process.exit(1)
484
+ }
485
+
486
+ // Parse command-specific arguments
487
+ const commandArgs = process.argv.slice(3)
488
+ const { values: cmdValues, positionals: cmdPositionals } = parseArgs({
489
+ args: commandArgs,
490
+ options: {
491
+ help: {
492
+ type: "boolean",
493
+ short: "h",
494
+ },
495
+ silent: {
496
+ type: "boolean",
497
+ short: "s",
498
+ },
499
+ force: {
500
+ type: "boolean",
501
+ short: "f",
502
+ },
503
+ verbose: {
504
+ type: "boolean",
505
+ short: "v",
506
+ },
507
+ template: {
508
+ type: "string",
509
+ short: "t",
510
+ },
511
+ branch: {
512
+ type: "string",
513
+ short: "b",
514
+ },
515
+ task: {
516
+ type: "string",
517
+ },
518
+ from: {
519
+ type: "string",
520
+ },
521
+ "from-current": {
522
+ type: "boolean",
523
+ },
524
+ json: {
525
+ type: "boolean",
526
+ },
527
+ repo: {
528
+ type: "boolean",
529
+ },
530
+ pr: {
531
+ type: "boolean",
532
+ },
533
+ squash: {
534
+ type: "boolean",
535
+ },
536
+ push: {
537
+ type: "boolean",
538
+ },
539
+ remote: {
540
+ type: "string",
541
+ short: "r",
542
+ },
543
+ "merged-into": {
544
+ type: "string",
545
+ },
546
+ "dry-run": {
547
+ type: "boolean",
548
+ },
549
+ opencode: {
550
+ type: "boolean",
551
+ },
552
+ claude: {
553
+ type: "boolean",
554
+ },
555
+ },
556
+ strict: false,
557
+ allowPositionals: true,
558
+ })
559
+
560
+ // Run the command
561
+ await command.run(cmdPositionals, cmdValues)
562
+ } catch (error) {
563
+ if (error instanceof Error) {
564
+ console.error(`ⓘ ${error.message}`)
565
+ } else {
566
+ console.error("An unexpected error occurred:", error)
567
+ }
568
+ process.exit(1)
569
+ }
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ console.log("Hello via Bun!")