@polterware/polter 0.4.1 → 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 (45) hide show
  1. package/README.md +0 -70
  2. package/dist/api.js +68 -26
  3. package/dist/app-HGIGWI7F.js +393 -0
  4. package/dist/appPanel-EZOHLTBX.js +1365 -0
  5. package/dist/applier-OEXIUYYO.js +10 -0
  6. package/dist/chunk-3RG5ZIWI.js +10 -0
  7. package/dist/chunk-45CQFZU7.js +262 -0
  8. package/dist/chunk-57CZSEY5.js +5398 -0
  9. package/dist/chunk-6IBRTRLX.js +257 -0
  10. package/dist/chunk-AK3NTS3Y.js +220 -0
  11. package/dist/chunk-BGT5TT2A.js +32 -0
  12. package/dist/chunk-BIN7BDA2.js +77 -0
  13. package/dist/chunk-E2B5FFBU.js +81 -0
  14. package/dist/chunk-EAMHFQKU.js +222 -0
  15. package/dist/chunk-ELSIHPJL.js +455 -0
  16. package/dist/{chunk-VYHW3UNY.js → chunk-GCS7JEYU.js} +7 -3
  17. package/dist/chunk-GKROVUDG.js +15 -0
  18. package/dist/chunk-GVIKF6UI.js +738 -0
  19. package/dist/chunk-JQB2A3CA.js +72 -0
  20. package/dist/chunk-KEGROLGX.js +50 -0
  21. package/dist/chunk-OKHPN6X7.js +49 -0
  22. package/dist/chunk-RVMOIUSL.js +22 -0
  23. package/dist/chunk-TD6YNU6L.js +22 -0
  24. package/dist/chunk-U64WZOJ3.js +101 -0
  25. package/dist/chunk-U6725U7K.js +138 -0
  26. package/dist/chunk-XNRIN3VM.js +125 -0
  27. package/dist/chunk-ZU5VZHYD.js +28 -0
  28. package/dist/commands-BIIWGCVS.js +15 -0
  29. package/dist/editor-AUFJZ4PE.js +11 -0
  30. package/dist/engine-EZQ26HDJ.js +11 -0
  31. package/dist/globalConf-AGMMIKSL.js +7 -0
  32. package/dist/index.js +55 -7464
  33. package/dist/ipcServer-HXOPKNBP.js +10 -0
  34. package/dist/mcp.js +182 -13892
  35. package/dist/mcpInstaller-J2AGFNWR.js +19 -0
  36. package/dist/parser-4ZBGSI2U.js +10 -0
  37. package/dist/planner-ZVBA66V6.js +9 -0
  38. package/dist/processManager-6T5DBURV.js +37 -0
  39. package/dist/projectConfig-TRCJS3VI.js +21 -0
  40. package/dist/skillSetup-ZQEHJ5ZG.js +14 -0
  41. package/dist/status-QMRCV4XJ.js +8 -0
  42. package/dist/storage-C3D7TLJW.js +17 -0
  43. package/dist/toolResolver-A2BUT3NK.js +17 -0
  44. package/package.json +20 -2
  45. package/dist/chunk-ZHVOYB5M.js +0 -2447
@@ -1,2447 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/data/commands/supabase.ts
8
- var supabaseCommands = [
9
- // Quick Start
10
- {
11
- id: "supabase:bootstrap",
12
- tool: "supabase",
13
- base: ["bootstrap"],
14
- label: "bootstrap",
15
- hint: "Bootstrap from a starter template",
16
- interactive: true
17
- },
18
- {
19
- id: "supabase:init",
20
- tool: "supabase",
21
- base: ["init"],
22
- label: "init",
23
- hint: "Initialize a local project",
24
- interactive: true
25
- },
26
- {
27
- id: "supabase:login",
28
- tool: "supabase",
29
- base: ["login"],
30
- label: "login",
31
- hint: "Authenticate with access token",
32
- interactive: true
33
- },
34
- {
35
- id: "supabase:logout",
36
- tool: "supabase",
37
- base: ["logout"],
38
- label: "logout",
39
- hint: "Remove local auth token"
40
- },
41
- // Local Dev
42
- {
43
- id: "supabase:start",
44
- tool: "supabase",
45
- base: ["start"],
46
- label: "start",
47
- hint: "Start local Supabase containers"
48
- },
49
- {
50
- id: "supabase:stop",
51
- tool: "supabase",
52
- base: ["stop"],
53
- label: "stop",
54
- hint: "Stop local Supabase containers"
55
- },
56
- {
57
- id: "supabase:status",
58
- tool: "supabase",
59
- base: ["status"],
60
- label: "status",
61
- hint: "Show container status"
62
- },
63
- {
64
- id: "supabase:db",
65
- tool: "supabase",
66
- base: ["db"],
67
- label: "db",
68
- hint: "Manage Postgres databases",
69
- suggestedArgs: [
70
- { value: "pull", label: "pull", hint: "Pull schema from remote", args: ["pull"] },
71
- { value: "push", label: "push", hint: "Push local migrations", args: ["push"] },
72
- { value: "reset", label: "reset", hint: "Reset local database", args: ["reset"] },
73
- { value: "dump", label: "dump", hint: "Dump schema/data", args: ["dump"] },
74
- { value: "diff", label: "diff", hint: "Show migration diff", args: ["diff"] },
75
- { value: "lint", label: "lint", hint: "Lint SQL migrations", args: ["lint"] }
76
- ]
77
- },
78
- {
79
- id: "supabase:migration",
80
- tool: "supabase",
81
- base: ["migration"],
82
- label: "migration",
83
- hint: "Manage migration scripts",
84
- suggestedArgs: [
85
- { value: "new", label: "new <name>", hint: "Create migration file", args: ["new"] },
86
- { value: "up", label: "up", hint: "Apply pending migrations", args: ["up"] },
87
- { value: "down", label: "down", hint: "Rollback last migration", args: ["down"] },
88
- { value: "list", label: "list", hint: "List local migrations", args: ["list"] },
89
- { value: "repair", label: "repair", hint: "Repair migration history", args: ["repair"] },
90
- { value: "fetch", label: "fetch", hint: "Fetch migration history", args: ["fetch"] }
91
- ]
92
- },
93
- {
94
- id: "supabase:seed",
95
- tool: "supabase",
96
- base: ["seed"],
97
- label: "seed",
98
- hint: "Seed from config.toml",
99
- suggestedArgs: [
100
- { value: "run", label: "run", hint: "Run configured seed file", args: ["run"] }
101
- ]
102
- },
103
- {
104
- id: "supabase:test",
105
- tool: "supabase",
106
- base: ["test"],
107
- label: "test",
108
- hint: "Run tests on local stack"
109
- },
110
- // Inspect & Generate
111
- {
112
- id: "supabase:inspect",
113
- tool: "supabase",
114
- base: ["inspect"],
115
- label: "inspect",
116
- hint: "Inspect project resources"
117
- },
118
- {
119
- id: "supabase:gen",
120
- tool: "supabase",
121
- base: ["gen"],
122
- label: "gen",
123
- hint: "Run code generation tools"
124
- },
125
- {
126
- id: "supabase:services",
127
- tool: "supabase",
128
- base: ["services"],
129
- label: "services",
130
- hint: "Show service versions"
131
- },
132
- {
133
- id: "supabase:link",
134
- tool: "supabase",
135
- base: ["link"],
136
- label: "link",
137
- hint: "Link to remote project",
138
- interactive: true
139
- },
140
- {
141
- id: "supabase:unlink",
142
- tool: "supabase",
143
- base: ["unlink"],
144
- label: "unlink",
145
- hint: "Unlink remote project"
146
- },
147
- // Cloud Management
148
- {
149
- id: "supabase:projects",
150
- tool: "supabase",
151
- base: ["projects"],
152
- label: "projects",
153
- hint: "Manage Supabase projects",
154
- suggestedArgs: [
155
- { value: "list", label: "list", hint: "List projects", args: ["list"] },
156
- { value: "create", label: "create", hint: "Create project", args: ["create"] },
157
- { value: "delete", label: "delete", hint: "Delete project", args: ["delete"] }
158
- ]
159
- },
160
- {
161
- id: "supabase:functions",
162
- tool: "supabase",
163
- base: ["functions"],
164
- label: "functions",
165
- hint: "Manage Edge Functions",
166
- suggestedArgs: [
167
- { value: "list", label: "list", hint: "List functions", args: ["list"] },
168
- { value: "new", label: "new <name>", hint: "Create a function", args: ["new"] },
169
- { value: "serve", label: "serve", hint: "Serve functions locally", args: ["serve"] },
170
- { value: "deploy", label: "deploy <name>", hint: "Deploy function", args: ["deploy"] },
171
- { value: "delete", label: "delete <name>", hint: "Delete function", args: ["delete"] }
172
- ]
173
- },
174
- {
175
- id: "supabase:secrets",
176
- tool: "supabase",
177
- base: ["secrets"],
178
- label: "secrets",
179
- hint: "Manage project secrets"
180
- },
181
- {
182
- id: "supabase:config",
183
- tool: "supabase",
184
- base: ["config"],
185
- label: "config",
186
- hint: "Manage project configuration"
187
- },
188
- {
189
- id: "supabase:storage",
190
- tool: "supabase",
191
- base: ["storage"],
192
- label: "storage",
193
- hint: "Manage Storage objects",
194
- suggestedArgs: [
195
- { value: "ls", label: "ls", hint: "List storage objects", args: ["ls"] },
196
- { value: "cp", label: "cp", hint: "Copy storage object", args: ["cp"] },
197
- { value: "mv", label: "mv", hint: "Move storage object", args: ["mv"] },
198
- { value: "rm", label: "rm", hint: "Remove storage object", args: ["rm"] }
199
- ]
200
- },
201
- // Networking & Security
202
- {
203
- id: "supabase:domains",
204
- tool: "supabase",
205
- base: ["domains"],
206
- label: "domains",
207
- hint: "Manage custom domains"
208
- },
209
- {
210
- id: "supabase:ssl-enforcement",
211
- tool: "supabase",
212
- base: ["ssl-enforcement"],
213
- label: "ssl-enforcement",
214
- hint: "Manage SSL config"
215
- },
216
- {
217
- id: "supabase:network-bans",
218
- tool: "supabase",
219
- base: ["network-bans"],
220
- label: "network-bans",
221
- hint: "Manage network bans"
222
- },
223
- {
224
- id: "supabase:network-restrictions",
225
- tool: "supabase",
226
- base: ["network-restrictions"],
227
- label: "network-restrictions",
228
- hint: "Manage network restrictions"
229
- },
230
- {
231
- id: "supabase:vanity-subdomains",
232
- tool: "supabase",
233
- base: ["vanity-subdomains"],
234
- label: "vanity-subdomains",
235
- hint: "Manage vanity subdomains"
236
- },
237
- {
238
- id: "supabase:encryption",
239
- tool: "supabase",
240
- base: ["encryption"],
241
- label: "encryption",
242
- hint: "Manage encryption keys"
243
- },
244
- // Organizations & Admin
245
- {
246
- id: "supabase:orgs",
247
- tool: "supabase",
248
- base: ["orgs"],
249
- label: "orgs",
250
- hint: "Manage organizations",
251
- suggestedArgs: [
252
- { value: "list", label: "list", hint: "List organizations", args: ["list"] },
253
- { value: "create", label: "create", hint: "Create organization", args: ["create"] }
254
- ]
255
- },
256
- {
257
- id: "supabase:sso",
258
- tool: "supabase",
259
- base: ["sso"],
260
- label: "sso",
261
- hint: "Manage Single Sign-On"
262
- },
263
- {
264
- id: "supabase:branches",
265
- tool: "supabase",
266
- base: ["branches"],
267
- label: "branches",
268
- hint: "Manage preview branches"
269
- },
270
- {
271
- id: "supabase:backups",
272
- tool: "supabase",
273
- base: ["backups"],
274
- label: "backups",
275
- hint: "Manage physical backups",
276
- suggestedArgs: [
277
- { value: "list", label: "list", hint: "List backups", args: ["list"] },
278
- { value: "download", label: "download", hint: "Download backup", args: ["download"] }
279
- ]
280
- },
281
- {
282
- id: "supabase:snippets",
283
- tool: "supabase",
284
- base: ["snippets"],
285
- label: "snippets",
286
- hint: "Manage SQL snippets",
287
- suggestedArgs: [
288
- { value: "list", label: "list", hint: "List SQL snippets", args: ["list"] },
289
- { value: "create", label: "create", hint: "Create SQL snippet", args: ["create"] },
290
- { value: "delete", label: "delete", hint: "Delete SQL snippet", args: ["delete"] }
291
- ]
292
- },
293
- {
294
- id: "supabase:postgres-config",
295
- tool: "supabase",
296
- base: ["postgres-config"],
297
- label: "postgres-config",
298
- hint: "Manage Postgres config"
299
- },
300
- // Utilities
301
- {
302
- id: "supabase:completion",
303
- tool: "supabase",
304
- base: ["completion"],
305
- label: "completion",
306
- hint: "Generate shell completion script"
307
- },
308
- {
309
- id: "supabase:help",
310
- tool: "supabase",
311
- base: ["help"],
312
- label: "help",
313
- hint: "Help about any command"
314
- }
315
- ];
316
-
317
- // src/data/commands/gh.ts
318
- var ghCommands = [
319
- // Repository
320
- {
321
- id: "gh:repo:clone",
322
- tool: "gh",
323
- base: ["repo", "clone"],
324
- label: "repo clone",
325
- hint: "Clone a repository"
326
- },
327
- {
328
- id: "gh:repo:create",
329
- tool: "gh",
330
- base: ["repo", "create"],
331
- label: "repo create",
332
- hint: "Create a new repository",
333
- interactive: true
334
- },
335
- {
336
- id: "gh:repo:view",
337
- tool: "gh",
338
- base: ["repo", "view"],
339
- label: "repo view",
340
- hint: "View repository details"
341
- },
342
- {
343
- id: "gh:repo:list",
344
- tool: "gh",
345
- base: ["repo", "list"],
346
- label: "repo list",
347
- hint: "List your repositories"
348
- },
349
- // Pull Requests
350
- {
351
- id: "gh:pr:create",
352
- tool: "gh",
353
- base: ["pr", "create"],
354
- label: "pr create",
355
- hint: "Create a pull request"
356
- },
357
- {
358
- id: "gh:pr:list",
359
- tool: "gh",
360
- base: ["pr", "list"],
361
- label: "pr list",
362
- hint: "List pull requests"
363
- },
364
- {
365
- id: "gh:pr:view",
366
- tool: "gh",
367
- base: ["pr", "view"],
368
- label: "pr view",
369
- hint: "View a pull request"
370
- },
371
- {
372
- id: "gh:pr:merge",
373
- tool: "gh",
374
- base: ["pr", "merge"],
375
- label: "pr merge",
376
- hint: "Merge a pull request"
377
- },
378
- {
379
- id: "gh:pr:checkout",
380
- tool: "gh",
381
- base: ["pr", "checkout"],
382
- label: "pr checkout",
383
- hint: "Check out a pull request"
384
- },
385
- {
386
- id: "gh:pr:review",
387
- tool: "gh",
388
- base: ["pr", "review"],
389
- label: "pr review",
390
- hint: "Review a pull request",
391
- suggestedArgs: [
392
- { value: "approve", label: "Approve", hint: "Approve the PR", args: ["--approve"] },
393
- { value: "comment", label: "Comment", hint: "Leave a comment", args: ["--comment"] },
394
- { value: "request-changes", label: "Request Changes", hint: "Request changes", args: ["--request-changes"] }
395
- ]
396
- },
397
- // Issues
398
- {
399
- id: "gh:issue:create",
400
- tool: "gh",
401
- base: ["issue", "create"],
402
- label: "issue create",
403
- hint: "Create an issue"
404
- },
405
- {
406
- id: "gh:issue:list",
407
- tool: "gh",
408
- base: ["issue", "list"],
409
- label: "issue list",
410
- hint: "List issues"
411
- },
412
- {
413
- id: "gh:issue:view",
414
- tool: "gh",
415
- base: ["issue", "view"],
416
- label: "issue view",
417
- hint: "View an issue"
418
- },
419
- {
420
- id: "gh:issue:close",
421
- tool: "gh",
422
- base: ["issue", "close"],
423
- label: "issue close",
424
- hint: "Close an issue"
425
- },
426
- // Workflows & Runs
427
- {
428
- id: "gh:workflow:list",
429
- tool: "gh",
430
- base: ["workflow", "list"],
431
- label: "workflow list",
432
- hint: "List workflows"
433
- },
434
- {
435
- id: "gh:workflow:run",
436
- tool: "gh",
437
- base: ["workflow", "run"],
438
- label: "workflow run",
439
- hint: "Run a workflow"
440
- },
441
- {
442
- id: "gh:workflow:view",
443
- tool: "gh",
444
- base: ["workflow", "view"],
445
- label: "workflow view",
446
- hint: "View a workflow"
447
- },
448
- {
449
- id: "gh:run:list",
450
- tool: "gh",
451
- base: ["run", "list"],
452
- label: "run list",
453
- hint: "List workflow runs"
454
- },
455
- {
456
- id: "gh:run:view",
457
- tool: "gh",
458
- base: ["run", "view"],
459
- label: "run view",
460
- hint: "View a workflow run"
461
- },
462
- {
463
- id: "gh:run:watch",
464
- tool: "gh",
465
- base: ["run", "watch"],
466
- label: "run watch",
467
- hint: "Watch a workflow run"
468
- },
469
- // Releases
470
- {
471
- id: "gh:release:create",
472
- tool: "gh",
473
- base: ["release", "create"],
474
- label: "release create",
475
- hint: "Create a release"
476
- },
477
- {
478
- id: "gh:release:list",
479
- tool: "gh",
480
- base: ["release", "list"],
481
- label: "release list",
482
- hint: "List releases"
483
- },
484
- {
485
- id: "gh:release:view",
486
- tool: "gh",
487
- base: ["release", "view"],
488
- label: "release view",
489
- hint: "View a release"
490
- },
491
- // Auth
492
- {
493
- id: "gh:auth:login",
494
- tool: "gh",
495
- base: ["auth", "login"],
496
- label: "auth login",
497
- hint: "Log in to GitHub",
498
- interactive: true
499
- },
500
- {
501
- id: "gh:auth:status",
502
- tool: "gh",
503
- base: ["auth", "status"],
504
- label: "auth status",
505
- hint: "View auth status"
506
- }
507
- ];
508
-
509
- // src/data/commands/vercel.ts
510
- var vercelCommands = [
511
- // Deploy
512
- {
513
- id: "vercel:deploy",
514
- tool: "vercel",
515
- base: ["deploy"],
516
- label: "deploy",
517
- hint: "Deploy to Vercel"
518
- },
519
- {
520
- id: "vercel:deploy:prod",
521
- tool: "vercel",
522
- base: ["deploy", "--prod"],
523
- label: "deploy --prod",
524
- hint: "Deploy to production"
525
- },
526
- {
527
- id: "vercel:promote",
528
- tool: "vercel",
529
- base: ["promote"],
530
- label: "promote",
531
- hint: "Promote a deployment"
532
- },
533
- {
534
- id: "vercel:rollback",
535
- tool: "vercel",
536
- base: ["rollback"],
537
- label: "rollback",
538
- hint: "Rollback to previous deployment"
539
- },
540
- // Domains
541
- {
542
- id: "vercel:domains:list",
543
- tool: "vercel",
544
- base: ["domains", "ls"],
545
- label: "domains ls",
546
- hint: "List domains"
547
- },
548
- {
549
- id: "vercel:domains:add",
550
- tool: "vercel",
551
- base: ["domains", "add"],
552
- label: "domains add",
553
- hint: "Add a domain"
554
- },
555
- {
556
- id: "vercel:domains:rm",
557
- tool: "vercel",
558
- base: ["domains", "rm"],
559
- label: "domains rm",
560
- hint: "Remove a domain"
561
- },
562
- // Environment Variables
563
- {
564
- id: "vercel:env:ls",
565
- tool: "vercel",
566
- base: ["env", "ls"],
567
- label: "env ls",
568
- hint: "List environment variables"
569
- },
570
- {
571
- id: "vercel:env:add",
572
- tool: "vercel",
573
- base: ["env", "add"],
574
- label: "env add",
575
- hint: "Add an environment variable"
576
- },
577
- {
578
- id: "vercel:env:rm",
579
- tool: "vercel",
580
- base: ["env", "rm"],
581
- label: "env rm",
582
- hint: "Remove an environment variable"
583
- },
584
- {
585
- id: "vercel:env:pull",
586
- tool: "vercel",
587
- base: ["env", "pull"],
588
- label: "env pull",
589
- hint: "Pull env vars to .env file"
590
- },
591
- // Project
592
- {
593
- id: "vercel:project:ls",
594
- tool: "vercel",
595
- base: ["project", "ls"],
596
- label: "project ls",
597
- hint: "List projects"
598
- },
599
- {
600
- id: "vercel:project:add",
601
- tool: "vercel",
602
- base: ["project", "add"],
603
- label: "project add",
604
- hint: "Add a project"
605
- },
606
- {
607
- id: "vercel:project:rm",
608
- tool: "vercel",
609
- base: ["project", "rm"],
610
- label: "project rm",
611
- hint: "Remove a project"
612
- },
613
- // Setup
614
- {
615
- id: "vercel:link",
616
- tool: "vercel",
617
- base: ["link"],
618
- label: "link",
619
- hint: "Link to a Vercel project",
620
- interactive: true
621
- },
622
- {
623
- id: "vercel:login",
624
- tool: "vercel",
625
- base: ["login"],
626
- label: "login",
627
- hint: "Log in to Vercel",
628
- interactive: true
629
- },
630
- {
631
- id: "vercel:whoami",
632
- tool: "vercel",
633
- base: ["whoami"],
634
- label: "whoami",
635
- hint: "Show current user"
636
- },
637
- // Logs & Inspect
638
- {
639
- id: "vercel:logs",
640
- tool: "vercel",
641
- base: ["logs"],
642
- label: "logs",
643
- hint: "View deployment logs"
644
- },
645
- {
646
- id: "vercel:inspect",
647
- tool: "vercel",
648
- base: ["inspect"],
649
- label: "inspect",
650
- hint: "Inspect a deployment"
651
- },
652
- {
653
- id: "vercel:ls",
654
- tool: "vercel",
655
- base: ["ls"],
656
- label: "ls",
657
- hint: "List deployments"
658
- }
659
- ];
660
-
661
- // src/data/commands/git.ts
662
- var gitCommands = [
663
- { id: "git:status", tool: "git", base: ["status"], label: "status", hint: "Show working tree status" },
664
- { id: "git:add", tool: "git", base: ["add"], label: "add", hint: "Stage changes" },
665
- { id: "git:commit", tool: "git", base: ["commit"], label: "commit", hint: "Create a commit" },
666
- { id: "git:push", tool: "git", base: ["push"], label: "push", hint: "Push to remote" },
667
- { id: "git:pull", tool: "git", base: ["pull"], label: "pull", hint: "Pull from remote" },
668
- { id: "git:checkout", tool: "git", base: ["checkout"], label: "checkout", hint: "Switch branches" },
669
- { id: "git:branch", tool: "git", base: ["branch"], label: "branch", hint: "List or create branches" },
670
- { id: "git:stash", tool: "git", base: ["stash"], label: "stash", hint: "Stash changes" },
671
- { id: "git:diff", tool: "git", base: ["diff"], label: "diff", hint: "Show changes" },
672
- { id: "git:log", tool: "git", base: ["log"], label: "log", hint: "View commit history" },
673
- { id: "git:merge", tool: "git", base: ["merge"], label: "merge", hint: "Merge branches" }
674
- ];
675
-
676
- // src/data/commands/pkg.ts
677
- var pkgCommands = [
678
- // Publish & Version
679
- { id: "pkg:publish", tool: "pkg", base: ["publish"], label: "publish", hint: "Publish package to registry" },
680
- { id: "pkg:pack", tool: "pkg", base: ["pack"], label: "pack", hint: "Create tarball from package" },
681
- { id: "pkg:version:patch", tool: "pkg", base: ["version", "patch"], label: "version patch", hint: "Bump patch version" },
682
- { id: "pkg:version:minor", tool: "pkg", base: ["version", "minor"], label: "version minor", hint: "Bump minor version" },
683
- { id: "pkg:version:major", tool: "pkg", base: ["version", "major"], label: "version major", hint: "Bump major version" },
684
- { id: "pkg:login", tool: "pkg", base: ["login"], label: "login", hint: "Log in to registry" },
685
- { id: "pkg:logout", tool: "pkg", base: ["logout"], label: "logout", hint: "Log out from registry" },
686
- // Dependency Management
687
- { id: "pkg:install", tool: "pkg", base: ["install"], label: "install", hint: "Install all dependencies" },
688
- { id: "pkg:add", tool: "pkg", base: ["add"], label: "add", hint: "Add a dependency" },
689
- { id: "pkg:remove", tool: "pkg", base: ["remove"], label: "remove", hint: "Remove a dependency" },
690
- { id: "pkg:update", tool: "pkg", base: ["update"], label: "update", hint: "Update dependencies" },
691
- { id: "pkg:outdated", tool: "pkg", base: ["outdated"], label: "outdated", hint: "List outdated packages" },
692
- { id: "pkg:audit", tool: "pkg", base: ["audit"], label: "audit", hint: "Run security audit" },
693
- { id: "pkg:ls", tool: "pkg", base: ["ls"], label: "ls", hint: "List installed packages" },
694
- // Registry & Config
695
- { id: "pkg:config:list", tool: "pkg", base: ["config", "list"], label: "config list", hint: "Show config" },
696
- { id: "pkg:whoami", tool: "pkg", base: ["whoami"], label: "whoami", hint: "Show logged-in user" },
697
- // Info & Registry
698
- { id: "pkg:info", tool: "pkg", base: ["info"], label: "info", hint: "Show package info" },
699
- { id: "pkg:search", tool: "pkg", base: ["search"], label: "search", hint: "Search packages in registry" },
700
- { id: "pkg:init", tool: "pkg", base: ["init"], label: "init", hint: "Initialize a new package.json" }
701
- ];
702
-
703
- // src/data/commands/index.ts
704
- var allCommands = [
705
- ...supabaseCommands,
706
- ...ghCommands,
707
- ...vercelCommands,
708
- ...gitCommands,
709
- ...pkgCommands
710
- ];
711
- var commandById = new Map(allCommands.map((cmd) => [cmd.id, cmd]));
712
- var commandByValue = new Map(
713
- allCommands.map((cmd) => [getCommandValue(cmd), cmd])
714
- );
715
- function getCommandById(id) {
716
- return commandById.get(id);
717
- }
718
- function getCommandsByTool(tool) {
719
- return allCommands.filter((cmd) => cmd.tool === tool);
720
- }
721
- function getCommandValue(cmd) {
722
- if (cmd.tool === "supabase") {
723
- return cmd.base.join(" ");
724
- }
725
- return `${cmd.tool}:${cmd.base.join(" ")}`;
726
- }
727
- function findCommandByValue(value) {
728
- const byId = commandById.get(value);
729
- if (byId) return byId;
730
- return commandByValue.get(value);
731
- }
732
-
733
- // src/data/features.ts
734
- var allSources = [...supabaseCommands, ...ghCommands, ...vercelCommands, ...gitCommands, ...pkgCommands];
735
- function pick(ids) {
736
- const idSet = new Set(ids);
737
- return allSources.filter((cmd) => idSet.has(cmd.id));
738
- }
739
- var features = [
740
- {
741
- id: "database",
742
- icon: "\u{1F5C4}\uFE0F",
743
- label: "Database",
744
- commands: pick([
745
- "supabase:db",
746
- "supabase:migration",
747
- "supabase:seed",
748
- "supabase:inspect"
749
- ])
750
- },
751
- {
752
- id: "functions",
753
- icon: "\u26A1",
754
- label: "Functions",
755
- commands: pick([
756
- "supabase:functions"
757
- ])
758
- },
759
- {
760
- id: "deploy",
761
- icon: "\u{1F680}",
762
- label: "Deploy",
763
- commands: pick([
764
- "supabase:db",
765
- "supabase:functions",
766
- "vercel:deploy",
767
- "vercel:deploy:prod",
768
- "vercel:promote",
769
- "vercel:rollback",
770
- "git:commit",
771
- "git:push"
772
- ])
773
- },
774
- {
775
- id: "repo",
776
- icon: "\u{1F5C3}\uFE0F",
777
- label: "Repo",
778
- commands: pick([
779
- "git:status",
780
- "git:add",
781
- "git:commit",
782
- "git:push",
783
- "git:pull",
784
- "git:branch",
785
- "git:checkout",
786
- "git:log",
787
- "git:diff",
788
- "git:merge",
789
- "git:stash",
790
- "gh:repo:clone",
791
- "gh:repo:create",
792
- "gh:repo:view",
793
- "gh:repo:list",
794
- "gh:pr:create",
795
- "gh:pr:list",
796
- "gh:pr:view",
797
- "gh:pr:merge",
798
- "gh:pr:checkout",
799
- "gh:pr:review",
800
- "gh:issue:create",
801
- "gh:issue:list",
802
- "gh:issue:view",
803
- "gh:issue:close",
804
- "gh:release:create",
805
- "gh:release:list",
806
- "gh:release:view"
807
- ])
808
- },
809
- {
810
- id: "cicd",
811
- icon: "\u{1F504}",
812
- label: "CI/CD",
813
- commands: pick([
814
- "vercel:env:ls",
815
- "vercel:env:add",
816
- "vercel:env:rm",
817
- "vercel:env:pull",
818
- "gh:workflow:list",
819
- "gh:workflow:run",
820
- "gh:workflow:view",
821
- "gh:run:list",
822
- "gh:run:view",
823
- "gh:run:watch"
824
- ])
825
- },
826
- {
827
- id: "auth-storage",
828
- icon: "\u{1F510}",
829
- label: "Auth & Storage",
830
- commands: pick([
831
- "supabase:storage",
832
- "supabase:secrets",
833
- "supabase:sso"
834
- ])
835
- },
836
- {
837
- id: "networking",
838
- icon: "\u{1F310}",
839
- label: "Networking",
840
- commands: pick([
841
- "supabase:domains",
842
- "supabase:ssl-enforcement",
843
- "supabase:network-bans",
844
- "supabase:network-restrictions",
845
- "supabase:vanity-subdomains",
846
- "supabase:encryption",
847
- "vercel:domains:list",
848
- "vercel:domains:add",
849
- "vercel:domains:rm"
850
- ])
851
- },
852
- {
853
- id: "packages",
854
- icon: "\u{1F4CB}",
855
- label: "Packages",
856
- commands: pick([
857
- "pkg:install",
858
- "pkg:add",
859
- "pkg:remove",
860
- "pkg:update",
861
- "pkg:outdated",
862
- "pkg:audit",
863
- "pkg:ls",
864
- "pkg:publish",
865
- "pkg:pack",
866
- "pkg:version:patch",
867
- "pkg:version:minor",
868
- "pkg:version:major",
869
- "pkg:login",
870
- "pkg:logout",
871
- "pkg:config:list",
872
- "pkg:whoami",
873
- "pkg:info",
874
- "pkg:search",
875
- "pkg:init"
876
- ])
877
- },
878
- {
879
- id: "setup",
880
- icon: "\u2699\uFE0F",
881
- label: "Setup",
882
- commands: pick([
883
- "supabase:init",
884
- "supabase:link",
885
- "supabase:login",
886
- "vercel:link",
887
- "vercel:login",
888
- "gh:auth:login",
889
- "gh:auth:status"
890
- ])
891
- }
892
- ];
893
- var featureById = new Map(features.map((f) => [f.id, f]));
894
- function getFeatureById(id) {
895
- return featureById.get(id);
896
- }
897
-
898
- // src/data/flags.ts
899
- var globalFlags = [
900
- { value: "--debug", label: "--debug", hint: "Output debug logs to stderr" },
901
- { value: "--yes", label: "--yes", hint: "Answer yes to all prompts" },
902
- {
903
- value: "--create-ticket",
904
- label: "--create-ticket",
905
- hint: "Create support ticket on error"
906
- },
907
- {
908
- value: "--experimental",
909
- label: "--experimental",
910
- hint: "Enable experimental features"
911
- }
912
- ];
913
- var toolFlags = {
914
- supabase: globalFlags,
915
- gh: [],
916
- vercel: [
917
- { value: "--yes", label: "--yes", hint: "Skip confirmation prompts" },
918
- { value: "--debug", label: "--debug", hint: "Debug mode" }
919
- ],
920
- git: [],
921
- pkg: [
922
- { value: "--save-dev", label: "--save-dev", hint: "Save as dev dependency" },
923
- { value: "--global", label: "--global", hint: "Install globally" },
924
- { value: "--dry-run", label: "--dry-run", hint: "Show what would happen" }
925
- ]
926
- };
927
- function getFlagsForTool(toolId) {
928
- return toolFlags[toolId] ?? globalFlags;
929
- }
930
-
931
- // src/lib/runner.ts
932
- import { spawn, spawnSync } from "child_process";
933
- import { existsSync } from "fs";
934
- import { delimiter, dirname, join, resolve } from "path";
935
- function getSupabaseBinaryCandidates() {
936
- if (process.platform === "win32") {
937
- return ["supabase.cmd", "supabase.exe", "supabase"];
938
- }
939
- return ["supabase"];
940
- }
941
- function hasLocalSupabaseBinary(binDir) {
942
- return getSupabaseBinaryCandidates().some(
943
- (candidate) => existsSync(join(binDir, candidate))
944
- );
945
- }
946
- function getPathEnvKey(env) {
947
- return Object.keys(env).find((key) => key.toLowerCase() === "path") ?? "PATH";
948
- }
949
- function findLocalSupabaseBinDir(startDir = process.cwd()) {
950
- let currentDir = resolve(startDir);
951
- while (true) {
952
- const binDir = join(currentDir, "node_modules", ".bin");
953
- if (hasLocalSupabaseBinary(binDir)) {
954
- return binDir;
955
- }
956
- const parentDir = dirname(currentDir);
957
- if (parentDir === currentDir) {
958
- return void 0;
959
- }
960
- currentDir = parentDir;
961
- }
962
- }
963
- function resolveSupabaseCommand(startDir = process.cwd(), env = process.env) {
964
- const localBinDir = findLocalSupabaseBinDir(startDir);
965
- if (!localBinDir) {
966
- return {
967
- command: "supabase",
968
- env: { ...env },
969
- source: "path"
970
- };
971
- }
972
- const pathKey = getPathEnvKey(env);
973
- const currentPath = env[pathKey];
974
- return {
975
- command: "supabase",
976
- env: {
977
- ...env,
978
- [pathKey]: currentPath ? `${localBinDir}${delimiter}${currentPath}` : localBinDir
979
- },
980
- source: "repository",
981
- localBinDir
982
- };
983
- }
984
- function runCommand(execution, args, cwd = process.cwd(), options) {
985
- let stdout = "";
986
- let stderr = "";
987
- const resolvedExecution = typeof execution === "string" ? { command: execution } : execution;
988
- const child = spawn(resolvedExecution.command, args, {
989
- cwd,
990
- env: resolvedExecution.env,
991
- shell: true,
992
- detached: true,
993
- stdio: [options?.quiet ? "pipe" : "inherit", "pipe", "pipe"]
994
- });
995
- if (options?.quiet) {
996
- child.stdin?.end();
997
- }
998
- const promise = new Promise((resolve3) => {
999
- child.stdout?.on("data", (data) => {
1000
- const text = data.toString();
1001
- stdout += text;
1002
- if (!options?.quiet) process.stdout.write(text);
1003
- options?.onData?.(stdout, stderr);
1004
- });
1005
- child.stderr?.on("data", (data) => {
1006
- const text = data.toString();
1007
- stderr += text;
1008
- if (!options?.quiet) process.stderr.write(text);
1009
- options?.onData?.(stdout, stderr);
1010
- });
1011
- child.on("error", (err) => {
1012
- resolve3({
1013
- exitCode: null,
1014
- signal: null,
1015
- stdout,
1016
- stderr,
1017
- spawnError: err.message
1018
- });
1019
- });
1020
- child.on("exit", (code, signal) => {
1021
- resolve3({ exitCode: code, signal, stdout, stderr });
1022
- });
1023
- });
1024
- return {
1025
- promise,
1026
- abort: () => {
1027
- if (child.pid) {
1028
- try {
1029
- process.kill(-child.pid, "SIGTERM");
1030
- } catch {
1031
- }
1032
- }
1033
- }
1034
- };
1035
- }
1036
- function runInteractiveCommand(execution, args, cwd = process.cwd()) {
1037
- const resolved = typeof execution === "string" ? { command: execution } : execution;
1038
- const result = spawnSync(resolved.command, args, {
1039
- cwd,
1040
- env: resolved.env,
1041
- shell: true,
1042
- stdio: "inherit"
1043
- });
1044
- return {
1045
- exitCode: result.status,
1046
- signal: result.signal,
1047
- stdout: "",
1048
- stderr: "",
1049
- spawnError: result.error?.message
1050
- };
1051
- }
1052
- async function runSupabaseCommand(args, cwd = process.cwd()) {
1053
- return runCommand(resolveSupabaseCommand(cwd), args, cwd).promise;
1054
- }
1055
-
1056
- // src/lib/pkgManager.ts
1057
- import { existsSync as existsSync2 } from "fs";
1058
- import { join as join2, dirname as dirname2 } from "path";
1059
- var LOCK_FILES = [
1060
- { file: "bun.lockb", id: "bun" },
1061
- { file: "bun.lock", id: "bun" },
1062
- { file: "pnpm-lock.yaml", id: "pnpm" },
1063
- { file: "yarn.lock", id: "yarn" },
1064
- { file: "package-lock.json", id: "npm" }
1065
- ];
1066
- var MANAGER_META = {
1067
- npm: { lockFile: "package-lock.json", command: "npm" },
1068
- pnpm: { lockFile: "pnpm-lock.yaml", command: "pnpm" },
1069
- yarn: { lockFile: "yarn.lock", command: "yarn" },
1070
- bun: { lockFile: "bun.lockb", command: "bun" }
1071
- };
1072
- function detectPkgManager(cwd = process.cwd()) {
1073
- let dir = cwd;
1074
- const root = dirname2(dir) === dir ? dir : void 0;
1075
- while (true) {
1076
- for (const { file, id } of LOCK_FILES) {
1077
- if (existsSync2(join2(dir, file))) {
1078
- const meta = MANAGER_META[id];
1079
- return { id, lockFile: meta.lockFile, command: meta.command };
1080
- }
1081
- }
1082
- const parent = dirname2(dir);
1083
- if (parent === dir || parent === root) break;
1084
- dir = parent;
1085
- }
1086
- return { id: "npm", lockFile: "package-lock.json", command: "npm" };
1087
- }
1088
- var TRANSLATIONS = {
1089
- "install": {},
1090
- // same for all
1091
- "add": {
1092
- npm: ["install"]
1093
- },
1094
- "remove": {
1095
- npm: ["uninstall"]
1096
- },
1097
- "run": {},
1098
- // same for all
1099
- "publish": {
1100
- bun: null
1101
- },
1102
- "audit": {
1103
- bun: null
1104
- },
1105
- "outdated": {
1106
- bun: null
1107
- },
1108
- "ls": {
1109
- yarn: ["list"],
1110
- bun: null
1111
- },
1112
- "pack": {
1113
- bun: null
1114
- },
1115
- "version": {},
1116
- // same for all
1117
- "login": {
1118
- bun: null
1119
- },
1120
- "logout": {
1121
- bun: null
1122
- },
1123
- "config": {},
1124
- // same for all
1125
- "whoami": {
1126
- bun: null
1127
- },
1128
- "info": {
1129
- npm: ["info"],
1130
- pnpm: ["info"],
1131
- yarn: ["info"],
1132
- bun: null
1133
- },
1134
- "search": {
1135
- pnpm: null,
1136
- yarn: null,
1137
- bun: null
1138
- },
1139
- "init": {}
1140
- // same for all
1141
- };
1142
- var UnsupportedCommandError = class extends Error {
1143
- constructor(command, manager) {
1144
- super(`"${command}" is not supported by ${manager}`);
1145
- this.name = "UnsupportedCommandError";
1146
- }
1147
- };
1148
- function translateCommand(base, manager) {
1149
- const [subcommand, ...rest] = base;
1150
- if (!subcommand) {
1151
- return { command: manager, args: [] };
1152
- }
1153
- const translation = TRANSLATIONS[subcommand];
1154
- if (translation) {
1155
- const managerEntry = translation[manager];
1156
- if (managerEntry === null) {
1157
- throw new UnsupportedCommandError(subcommand, manager);
1158
- }
1159
- if (managerEntry !== void 0) {
1160
- return { command: manager, args: [...managerEntry, ...rest] };
1161
- }
1162
- }
1163
- return { command: manager, args: [subcommand, ...rest] };
1164
- }
1165
- function resolvePkgArgs(base, cwd = process.cwd()) {
1166
- const mgr = detectPkgManager(cwd);
1167
- return translateCommand(base, mgr.id);
1168
- }
1169
-
1170
- // src/lib/toolResolver.ts
1171
- import { existsSync as existsSync3, readFileSync } from "fs";
1172
- import { join as join3 } from "path";
1173
-
1174
- // src/lib/system.ts
1175
- import { execSync } from "child_process";
1176
- function commandExists(command) {
1177
- try {
1178
- execSync(`command -v ${command}`, { stdio: "ignore" });
1179
- return true;
1180
- } catch {
1181
- return false;
1182
- }
1183
- }
1184
- function execCapture(command) {
1185
- return execSync(command, {
1186
- encoding: "utf-8",
1187
- stdio: ["pipe", "pipe", "pipe"]
1188
- }).trim();
1189
- }
1190
-
1191
- // src/lib/toolResolver.ts
1192
- function getToolDisplayName(toolId, cwd = process.cwd()) {
1193
- if (toolId === "pkg") {
1194
- const mgr = detectPkgManager(cwd);
1195
- return mgr.id;
1196
- }
1197
- const names = {
1198
- supabase: "supabase",
1199
- gh: "github",
1200
- vercel: "vercel",
1201
- git: "git",
1202
- pkg: "npm"
1203
- };
1204
- return names[toolId];
1205
- }
1206
- function resolveToolCommand(toolId, cwd = process.cwd()) {
1207
- if (toolId === "supabase") {
1208
- const resolved = resolveSupabaseCommand(cwd);
1209
- return {
1210
- command: resolved.command,
1211
- env: resolved.env,
1212
- source: resolved.source
1213
- };
1214
- }
1215
- if (toolId === "pkg") {
1216
- const mgr = detectPkgManager(cwd);
1217
- if (!commandExists(mgr.command)) {
1218
- return { command: mgr.command, source: "not-found" };
1219
- }
1220
- return { command: mgr.command, env: { ...process.env }, source: "path" };
1221
- }
1222
- const command = toolId;
1223
- if (!commandExists(command)) {
1224
- return { command, source: "not-found" };
1225
- }
1226
- return { command, env: { ...process.env }, source: "path" };
1227
- }
1228
- function getToolVersion(toolId) {
1229
- try {
1230
- switch (toolId) {
1231
- case "supabase":
1232
- return execCapture("supabase --version").replace(/^supabase\s+/i, "");
1233
- case "gh":
1234
- return execCapture("gh --version").split("\n")[0]?.replace(/^gh\s+version\s+/i, "").split(" ")[0];
1235
- case "vercel":
1236
- return execCapture("vercel --version").split("\n")[0]?.trim();
1237
- case "git":
1238
- return execCapture("git --version").replace(/^git version\s+/i, "").trim();
1239
- case "pkg": {
1240
- const mgr = detectPkgManager();
1241
- return execCapture(`${mgr.command} --version`).split("\n")[0]?.trim();
1242
- }
1243
- default:
1244
- return void 0;
1245
- }
1246
- } catch {
1247
- return void 0;
1248
- }
1249
- }
1250
- var toolInfoCache = /* @__PURE__ */ new Map();
1251
- function getToolInfo(toolId) {
1252
- const cached = toolInfoCache.get(toolId);
1253
- if (cached) return cached;
1254
- const labels = {
1255
- supabase: "Supabase CLI",
1256
- gh: "GitHub CLI",
1257
- vercel: "Vercel CLI",
1258
- git: "Git",
1259
- pkg: "Package Manager"
1260
- };
1261
- const commandName = toolId === "supabase" ? "supabase" : toolId === "pkg" ? detectPkgManager().command : toolId;
1262
- const installed = commandExists(commandName);
1263
- const version = installed ? getToolVersion(toolId) : void 0;
1264
- const info = {
1265
- id: toolId,
1266
- label: labels[toolId],
1267
- installed,
1268
- version
1269
- };
1270
- toolInfoCache.set(toolId, info);
1271
- return info;
1272
- }
1273
- function detectSupabaseLink(cwd) {
1274
- try {
1275
- const configPath = join3(cwd, ".supabase", "config.toml");
1276
- if (existsSync3(configPath)) {
1277
- const content = readFileSync(configPath, "utf-8");
1278
- const match = content.match(/project_id\s*=\s*"([^"]+)"/);
1279
- return { linked: true, project: match?.[1] };
1280
- }
1281
- } catch {
1282
- }
1283
- return { linked: false };
1284
- }
1285
- function detectVercelLink(cwd) {
1286
- try {
1287
- const projectPath = join3(cwd, ".vercel", "project.json");
1288
- if (existsSync3(projectPath)) {
1289
- const data = JSON.parse(readFileSync(projectPath, "utf-8"));
1290
- return { linked: true, project: data.projectId };
1291
- }
1292
- } catch {
1293
- }
1294
- return { linked: false };
1295
- }
1296
- function detectPkgLink(cwd) {
1297
- try {
1298
- const pkgPath = join3(cwd, "package.json");
1299
- if (existsSync3(pkgPath)) {
1300
- const data = JSON.parse(readFileSync(pkgPath, "utf-8"));
1301
- const mgr = detectPkgManager(cwd);
1302
- return { linked: true, project: data.name ? `${data.name} (${mgr.id})` : mgr.id };
1303
- }
1304
- } catch {
1305
- }
1306
- return { linked: false };
1307
- }
1308
- function detectGhLink(cwd) {
1309
- try {
1310
- const remote = execCapture(`git -C "${cwd}" remote get-url origin 2>/dev/null`);
1311
- if (remote) {
1312
- const match = remote.match(/[/:]([\w.-]+\/[\w.-]+?)(?:\.git)?$/);
1313
- return { linked: true, project: match?.[1] ?? remote };
1314
- }
1315
- } catch {
1316
- }
1317
- return { linked: false };
1318
- }
1319
- var toolLinkCache = /* @__PURE__ */ new Map();
1320
- function getToolLinkInfo(toolId, cwd = process.cwd()) {
1321
- const cached = toolLinkCache.get(toolId);
1322
- if (cached) return cached;
1323
- const base = getToolInfo(toolId);
1324
- let linkStatus = { linked: false };
1325
- if (base.installed) {
1326
- switch (toolId) {
1327
- case "supabase":
1328
- linkStatus = detectSupabaseLink(cwd);
1329
- break;
1330
- case "vercel":
1331
- linkStatus = detectVercelLink(cwd);
1332
- break;
1333
- case "gh":
1334
- linkStatus = detectGhLink(cwd);
1335
- break;
1336
- case "pkg":
1337
- linkStatus = detectPkgLink(cwd);
1338
- break;
1339
- }
1340
- }
1341
- const info = { ...base, ...linkStatus };
1342
- toolLinkCache.set(toolId, info);
1343
- return info;
1344
- }
1345
-
1346
- // src/lib/processManager.ts
1347
- import { spawn as spawn2 } from "child_process";
1348
- import { join as join5 } from "path";
1349
-
1350
- // src/lib/packageRoot.ts
1351
- import { existsSync as existsSync4 } from "fs";
1352
- import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
1353
- var rootCache = /* @__PURE__ */ new Map();
1354
- function findNearestPackageRoot(startDir = process.cwd()) {
1355
- const resolvedStart = resolve2(startDir);
1356
- if (rootCache.has(resolvedStart)) return rootCache.get(resolvedStart);
1357
- let currentDir = resolvedStart;
1358
- while (true) {
1359
- if (existsSync4(join4(currentDir, "package.json"))) {
1360
- rootCache.set(resolvedStart, currentDir);
1361
- return currentDir;
1362
- }
1363
- const parentDir = dirname3(currentDir);
1364
- if (parentDir === currentDir) {
1365
- rootCache.set(resolvedStart, void 0);
1366
- return void 0;
1367
- }
1368
- currentDir = parentDir;
1369
- }
1370
- }
1371
-
1372
- // src/lib/processManager.ts
1373
- var DEFAULT_BUFFER_CAP = 1e3;
1374
- function createRingBuffer(cap = DEFAULT_BUFFER_CAP) {
1375
- return { lines: [], cap, totalLines: 0 };
1376
- }
1377
- function appendToBuffer(buf, data) {
1378
- const newLines = data.split("\n");
1379
- if (newLines.length > 0 && newLines[newLines.length - 1] === "") {
1380
- newLines.pop();
1381
- }
1382
- if (newLines.length === 0) return;
1383
- buf.lines.push(...newLines);
1384
- buf.totalLines += newLines.length;
1385
- if (buf.lines.length > buf.cap) {
1386
- buf.lines.splice(0, buf.lines.length - buf.cap);
1387
- }
1388
- }
1389
- function tailBuffer(buf, n) {
1390
- if (n === void 0 || n >= buf.lines.length) return [...buf.lines];
1391
- return buf.lines.slice(-n);
1392
- }
1393
- var registry = /* @__PURE__ */ new Map();
1394
- var cleanupRegistered = false;
1395
- function registerCleanup() {
1396
- if (cleanupRegistered) return;
1397
- cleanupRegistered = true;
1398
- const cleanup = () => {
1399
- for (const proc of registry.values()) {
1400
- if (proc.status === "running" && proc.child.pid) {
1401
- try {
1402
- process.kill(-proc.child.pid, "SIGKILL");
1403
- } catch {
1404
- }
1405
- }
1406
- }
1407
- };
1408
- process.on("exit", cleanup);
1409
- process.on("SIGINT", () => {
1410
- cleanup();
1411
- process.exit(130);
1412
- });
1413
- process.on("SIGTERM", () => {
1414
- cleanup();
1415
- process.exit(143);
1416
- });
1417
- }
1418
- function generateProcessId(command, args) {
1419
- const slug = [command, ...args].join("-").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
1420
- if (!registry.has(slug)) return slug;
1421
- let i = 2;
1422
- while (registry.has(`${slug}-${i}`)) i++;
1423
- return `${slug}-${i}`;
1424
- }
1425
- function startProcess(id, command, args = [], cwd = process.cwd(), env) {
1426
- const existing = registry.get(id);
1427
- if (existing && existing.status === "running") {
1428
- throw new Error(`Process "${id}" is already running (pid ${existing.child.pid})`);
1429
- }
1430
- registerCleanup();
1431
- const child = spawn2(command, args, {
1432
- cwd,
1433
- env: env ?? process.env,
1434
- detached: true,
1435
- stdio: ["ignore", "pipe", "pipe"],
1436
- shell: true
1437
- });
1438
- const tracked = {
1439
- id,
1440
- command,
1441
- args,
1442
- cwd,
1443
- child,
1444
- status: "running",
1445
- exitCode: null,
1446
- signal: null,
1447
- startedAt: /* @__PURE__ */ new Date(),
1448
- exitedAt: null,
1449
- stdout: createRingBuffer(),
1450
- stderr: createRingBuffer()
1451
- };
1452
- child.stdout?.on("data", (data) => {
1453
- appendToBuffer(tracked.stdout, data.toString());
1454
- });
1455
- child.stderr?.on("data", (data) => {
1456
- appendToBuffer(tracked.stderr, data.toString());
1457
- });
1458
- child.on("exit", (code, signal) => {
1459
- tracked.status = "exited";
1460
- tracked.exitCode = code;
1461
- tracked.signal = signal;
1462
- tracked.exitedAt = /* @__PURE__ */ new Date();
1463
- });
1464
- child.on("error", (err) => {
1465
- tracked.status = "errored";
1466
- tracked.exitedAt = /* @__PURE__ */ new Date();
1467
- appendToBuffer(tracked.stderr, `spawn error: ${err.message}
1468
- `);
1469
- });
1470
- registry.set(id, tracked);
1471
- return toProcessInfo(tracked);
1472
- }
1473
- function stopProcess(id) {
1474
- const proc = registry.get(id);
1475
- if (!proc) throw new Error(`No tracked process with id "${id}"`);
1476
- if (proc.status !== "running") return Promise.resolve(toProcessInfo(proc));
1477
- return new Promise((resolve3) => {
1478
- const escalateTimer = setTimeout(() => {
1479
- if (proc.status === "running" && proc.child.pid) {
1480
- try {
1481
- process.kill(-proc.child.pid, "SIGKILL");
1482
- } catch {
1483
- }
1484
- }
1485
- }, 5e3);
1486
- const onDone = () => {
1487
- clearTimeout(escalateTimer);
1488
- resolve3(toProcessInfo(proc));
1489
- };
1490
- proc.child.once("exit", onDone);
1491
- if (proc.child.pid) {
1492
- try {
1493
- process.kill(-proc.child.pid, "SIGTERM");
1494
- } catch {
1495
- }
1496
- }
1497
- if (proc.status !== "running") {
1498
- clearTimeout(escalateTimer);
1499
- proc.child.removeListener("exit", onDone);
1500
- resolve3(toProcessInfo(proc));
1501
- }
1502
- });
1503
- }
1504
- function listProcesses() {
1505
- return Array.from(registry.values()).map(toProcessInfo);
1506
- }
1507
- function getProcessOutput(id, tail, stream) {
1508
- const proc = registry.get(id);
1509
- if (!proc) throw new Error(`No tracked process with id "${id}"`);
1510
- const which = stream ?? "both";
1511
- return {
1512
- stdout: which === "stderr" ? [] : tailBuffer(proc.stdout, tail),
1513
- stderr: which === "stdout" ? [] : tailBuffer(proc.stderr, tail),
1514
- stdoutLineCount: proc.stdout.totalLines,
1515
- stderrLineCount: proc.stderr.totalLines
1516
- };
1517
- }
1518
- function isProcessRunning(id) {
1519
- const proc = registry.get(id);
1520
- if (!proc) return false;
1521
- if (proc.status !== "running") return false;
1522
- if (proc.child.pid) {
1523
- try {
1524
- process.kill(proc.child.pid, 0);
1525
- return true;
1526
- } catch {
1527
- return false;
1528
- }
1529
- }
1530
- return false;
1531
- }
1532
- function removeProcess(id) {
1533
- const proc = registry.get(id);
1534
- if (!proc) throw new Error(`No tracked process with id "${id}"`);
1535
- if (proc.status === "running") {
1536
- throw new Error(`Cannot remove running process "${id}". Stop it first.`);
1537
- }
1538
- registry.delete(id);
1539
- }
1540
- function findProcessesByCwd(cwd) {
1541
- const normalized = cwd.replace(/\/+$/, "");
1542
- return Array.from(registry.values()).filter((proc) => proc.cwd.replace(/\/+$/, "") === normalized).map(toProcessInfo);
1543
- }
1544
- function findRunningByCommand(cwd, command, args) {
1545
- const normalized = cwd.replace(/\/+$/, "");
1546
- const argsStr = args.join(" ");
1547
- for (const proc of registry.values()) {
1548
- if (proc.cwd.replace(/\/+$/, "") === normalized && proc.status === "running" && proc.command === command && proc.args.join(" ") === argsStr) {
1549
- return toProcessInfo(proc);
1550
- }
1551
- }
1552
- return void 0;
1553
- }
1554
- function toProcessInfo(proc) {
1555
- const now = Date.now();
1556
- const start = proc.startedAt.getTime();
1557
- const end = proc.exitedAt ? proc.exitedAt.getTime() : now;
1558
- return {
1559
- id: proc.id,
1560
- command: proc.command,
1561
- args: proc.args,
1562
- cwd: proc.cwd,
1563
- pid: proc.child.pid,
1564
- status: proc.status,
1565
- exitCode: proc.exitCode,
1566
- signal: proc.signal,
1567
- startedAt: proc.startedAt.toISOString(),
1568
- exitedAt: proc.exitedAt?.toISOString() ?? null,
1569
- uptime: end - start
1570
- };
1571
- }
1572
- function getSocketPath(cwd) {
1573
- const root = findNearestPackageRoot(cwd);
1574
- if (!root) return void 0;
1575
- return join5(root, ".polter", "polter.sock");
1576
- }
1577
-
1578
- // src/lib/ipcServer.ts
1579
- import net from "net";
1580
- import { mkdirSync, unlinkSync, existsSync as existsSync5 } from "fs";
1581
- import { dirname as dirname4 } from "path";
1582
-
1583
- // src/lib/ipcProtocol.ts
1584
- var DELIMITER = "\n";
1585
- function serializeMessage(msg) {
1586
- return JSON.stringify(msg) + DELIMITER;
1587
- }
1588
- function parseMessages(buffer) {
1589
- const messages = [];
1590
- let remainder = buffer;
1591
- let idx;
1592
- while ((idx = remainder.indexOf(DELIMITER)) !== -1) {
1593
- const line = remainder.slice(0, idx);
1594
- remainder = remainder.slice(idx + 1);
1595
- if (line.length === 0) continue;
1596
- try {
1597
- messages.push(JSON.parse(line));
1598
- } catch {
1599
- }
1600
- }
1601
- return { messages, remainder };
1602
- }
1603
-
1604
- // src/lib/ipcServer.ts
1605
- var handlers = {
1606
- "ps.list": () => listProcesses(),
1607
- "ps.start": (params) => {
1608
- const { command, args, cwd, id } = params;
1609
- const processArgs = args ?? [];
1610
- const processId = id ?? generateProcessId(command, processArgs);
1611
- const processCwd = cwd ?? process.cwd();
1612
- return startProcess(processId, command, processArgs, processCwd);
1613
- },
1614
- "ps.stop": async (params) => {
1615
- const { id } = params;
1616
- return stopProcess(id);
1617
- },
1618
- "ps.logs": (params) => {
1619
- const { id, tail, stream } = params;
1620
- return getProcessOutput(id, tail, stream);
1621
- },
1622
- "ps.remove": (params) => {
1623
- const { id } = params;
1624
- removeProcess(id);
1625
- return null;
1626
- },
1627
- "ps.find_by_cwd": (params) => {
1628
- const { cwd, filter } = params;
1629
- let processes = findProcessesByCwd(cwd);
1630
- if (filter) {
1631
- const f = filter.toLowerCase();
1632
- processes = processes.filter(
1633
- (p) => (p.command + " " + p.args.join(" ")).toLowerCase().includes(f)
1634
- );
1635
- }
1636
- return processes;
1637
- },
1638
- "ps.find_running": (params) => {
1639
- const { cwd, command, args } = params;
1640
- return findRunningByCommand(cwd, command, args) ?? null;
1641
- },
1642
- "ps.generate_id": (params) => {
1643
- const { command, args } = params;
1644
- return generateProcessId(command, args);
1645
- },
1646
- status: () => ({ tui: true, pid: process.pid })
1647
- };
1648
- async function handleRequest(req) {
1649
- const handler = handlers[req.method];
1650
- if (!handler) {
1651
- return {
1652
- jsonrpc: "2.0",
1653
- id: req.id,
1654
- error: { code: -32601, message: `Method not found: ${req.method}` }
1655
- };
1656
- }
1657
- try {
1658
- const result = await handler(req.params ?? {});
1659
- return { jsonrpc: "2.0", id: req.id, result };
1660
- } catch (err) {
1661
- return {
1662
- jsonrpc: "2.0",
1663
- id: req.id,
1664
- error: { code: -32e3, message: err.message }
1665
- };
1666
- }
1667
- }
1668
- function createIpcServer(socketPath) {
1669
- let server = null;
1670
- const connections = /* @__PURE__ */ new Set();
1671
- function handleConnection(socket) {
1672
- connections.add(socket);
1673
- let buffer = "";
1674
- socket.on("data", async (data) => {
1675
- buffer += data.toString();
1676
- const { messages, remainder } = parseMessages(buffer);
1677
- buffer = remainder;
1678
- for (const msg of messages) {
1679
- if ("method" in msg) {
1680
- const response = await handleRequest(msg);
1681
- try {
1682
- socket.write(serializeMessage(response));
1683
- } catch {
1684
- }
1685
- }
1686
- }
1687
- });
1688
- socket.on("close", () => {
1689
- connections.delete(socket);
1690
- });
1691
- socket.on("error", () => {
1692
- connections.delete(socket);
1693
- });
1694
- }
1695
- async function cleanStaleSocket() {
1696
- if (!existsSync5(socketPath)) return;
1697
- return new Promise((resolve3) => {
1698
- const probe = net.createConnection(socketPath);
1699
- probe.on("connect", () => {
1700
- probe.destroy();
1701
- resolve3();
1702
- });
1703
- probe.on("error", () => {
1704
- try {
1705
- unlinkSync(socketPath);
1706
- } catch {
1707
- }
1708
- resolve3();
1709
- });
1710
- });
1711
- }
1712
- return {
1713
- async start() {
1714
- mkdirSync(dirname4(socketPath), { recursive: true });
1715
- await cleanStaleSocket();
1716
- return new Promise((resolve3, reject) => {
1717
- server = net.createServer(handleConnection);
1718
- server.on("error", (err) => {
1719
- if (err.code === "EADDRINUSE") {
1720
- try {
1721
- unlinkSync(socketPath);
1722
- } catch {
1723
- }
1724
- server.listen(socketPath, () => resolve3());
1725
- } else {
1726
- reject(err);
1727
- }
1728
- });
1729
- server.listen(socketPath, () => resolve3());
1730
- });
1731
- },
1732
- async stop() {
1733
- for (const conn of connections) {
1734
- conn.destroy();
1735
- }
1736
- connections.clear();
1737
- return new Promise((resolve3) => {
1738
- if (!server) {
1739
- resolve3();
1740
- return;
1741
- }
1742
- server.close(() => {
1743
- try {
1744
- unlinkSync(socketPath);
1745
- } catch {
1746
- }
1747
- server = null;
1748
- resolve3();
1749
- });
1750
- });
1751
- }
1752
- };
1753
- }
1754
-
1755
- // src/pipeline/engine.ts
1756
- async function executePipeline(pipeline, onProgress, cwd = process.cwd()) {
1757
- const stepResults = pipeline.steps.map((step) => ({
1758
- step,
1759
- status: "pending"
1760
- }));
1761
- let aborted = false;
1762
- for (let i = 0; i < pipeline.steps.length; i++) {
1763
- const step = pipeline.steps[i];
1764
- if (aborted) {
1765
- stepResults[i] = { step, status: "skipped" };
1766
- onProgress({ stepResults: [...stepResults], currentStepIndex: i, done: false });
1767
- continue;
1768
- }
1769
- stepResults[i] = { step, status: "running" };
1770
- onProgress({ stepResults: [...stepResults], currentStepIndex: i, done: false });
1771
- const cmdDef = getCommandById(step.commandId);
1772
- const toolId = cmdDef?.tool ?? "supabase";
1773
- const resolved = resolveToolCommand(toolId, cwd);
1774
- let baseArgs = cmdDef?.base ?? [];
1775
- if (toolId === "pkg" && cmdDef) {
1776
- try {
1777
- const translated = resolvePkgArgs(cmdDef.base, cwd);
1778
- baseArgs = translated.args;
1779
- } catch {
1780
- }
1781
- }
1782
- const allArgs = [...baseArgs, ...step.args, ...step.flags];
1783
- const result = await runCommand(
1784
- { command: resolved.command, env: resolved.env },
1785
- allArgs,
1786
- cwd
1787
- ).promise;
1788
- const success = !result.spawnError && result.exitCode === 0;
1789
- stepResults[i] = {
1790
- step,
1791
- status: success ? "success" : "error",
1792
- result
1793
- };
1794
- if (!success && !step.continueOnError) {
1795
- aborted = true;
1796
- }
1797
- onProgress({ stepResults: [...stepResults], currentStepIndex: i, done: false });
1798
- }
1799
- onProgress({
1800
- stepResults: [...stepResults],
1801
- currentStepIndex: pipeline.steps.length - 1,
1802
- done: true
1803
- });
1804
- return stepResults;
1805
- }
1806
-
1807
- // src/config/projectConfig.ts
1808
- import { existsSync as existsSync6, readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
1809
- import { join as join6 } from "path";
1810
- var CONFIG_DIR = ".polter";
1811
- var CONFIG_FILE = "config.json";
1812
- function defaultConfig() {
1813
- return {
1814
- version: 1,
1815
- tools: {},
1816
- pipelines: []
1817
- };
1818
- }
1819
- function getProjectConfigPath(startDir) {
1820
- const root = findNearestPackageRoot(startDir);
1821
- if (!root) return void 0;
1822
- const dir = join6(root, CONFIG_DIR);
1823
- return { dir, file: join6(dir, CONFIG_FILE) };
1824
- }
1825
- function readProjectConfig(startDir) {
1826
- const paths = getProjectConfigPath(startDir);
1827
- if (!paths) return void 0;
1828
- if (!existsSync6(paths.file)) return void 0;
1829
- try {
1830
- const raw = readFileSync2(paths.file, "utf-8");
1831
- return JSON.parse(raw);
1832
- } catch {
1833
- return void 0;
1834
- }
1835
- }
1836
- function writeProjectConfig(config2, startDir) {
1837
- const paths = getProjectConfigPath(startDir);
1838
- if (!paths) return false;
1839
- mkdirSync2(paths.dir, { recursive: true });
1840
- writeFileSync(paths.file, JSON.stringify(config2, null, 2) + "\n", "utf-8");
1841
- return true;
1842
- }
1843
- function getOrCreateProjectConfig(startDir) {
1844
- return readProjectConfig(startDir) ?? defaultConfig();
1845
- }
1846
- function getProjectPipelines(startDir) {
1847
- const config2 = readProjectConfig(startDir);
1848
- return config2?.pipelines ?? [];
1849
- }
1850
- function saveProjectPipeline(pipeline, startDir) {
1851
- const config2 = getOrCreateProjectConfig(startDir);
1852
- const idx = config2.pipelines.findIndex((p) => p.id === pipeline.id);
1853
- if (idx >= 0) {
1854
- config2.pipelines[idx] = pipeline;
1855
- } else {
1856
- config2.pipelines.push(pipeline);
1857
- }
1858
- return writeProjectConfig(config2, startDir);
1859
- }
1860
- function deleteProjectPipeline(pipelineId, startDir) {
1861
- const config2 = getOrCreateProjectConfig(startDir);
1862
- config2.pipelines = config2.pipelines.filter((p) => p.id !== pipelineId);
1863
- return writeProjectConfig(config2, startDir);
1864
- }
1865
-
1866
- // src/config/store.ts
1867
- import Conf from "conf";
1868
- var config = new Conf({
1869
- projectName: process.env.NODE_ENV === "test" ? "polter-test" : "polter"
1870
- });
1871
- var GLOBAL_PIPELINES_KEY = "globalPipelinesV1";
1872
- function getGlobalPipelines() {
1873
- if (!config.has(GLOBAL_PIPELINES_KEY)) {
1874
- config.set(GLOBAL_PIPELINES_KEY, []);
1875
- }
1876
- return config.get(GLOBAL_PIPELINES_KEY) || [];
1877
- }
1878
- function saveGlobalPipeline(pipeline) {
1879
- const pipelines = getGlobalPipelines();
1880
- const idx = pipelines.findIndex((p) => p.id === pipeline.id);
1881
- if (idx >= 0) {
1882
- pipelines[idx] = pipeline;
1883
- } else {
1884
- pipelines.push(pipeline);
1885
- }
1886
- config.set(GLOBAL_PIPELINES_KEY, pipelines);
1887
- }
1888
- function deleteGlobalPipeline(pipelineId) {
1889
- const pipelines = getGlobalPipelines().filter((p) => p.id !== pipelineId);
1890
- config.set(GLOBAL_PIPELINES_KEY, pipelines);
1891
- }
1892
-
1893
- // src/pipeline/storage.ts
1894
- function getAllPipelines(startDir) {
1895
- const projectPipelines = getProjectPipelines(startDir).map((p) => ({
1896
- ...p,
1897
- source: "project"
1898
- }));
1899
- const globalPipelines = getGlobalPipelines().map((p) => ({
1900
- ...p,
1901
- source: "global"
1902
- }));
1903
- const seen = new Set(projectPipelines.map((p) => p.id));
1904
- const merged = [
1905
- ...projectPipelines,
1906
- ...globalPipelines.filter((p) => !seen.has(p.id))
1907
- ];
1908
- return merged;
1909
- }
1910
- function savePipeline(pipeline, source, startDir) {
1911
- if (source === "project") {
1912
- saveProjectPipeline(pipeline, startDir);
1913
- } else {
1914
- saveGlobalPipeline(pipeline);
1915
- }
1916
- }
1917
- function deletePipeline(pipelineId, source, startDir) {
1918
- if (source === "project") {
1919
- deleteProjectPipeline(pipelineId, startDir);
1920
- } else {
1921
- deleteGlobalPipeline(pipelineId);
1922
- }
1923
- }
1924
- function findPipelineByName(name, startDir) {
1925
- return getAllPipelines(startDir).find((p) => p.name === name);
1926
- }
1927
-
1928
- // src/declarative/parser.ts
1929
- import { existsSync as existsSync7, readFileSync as readFileSync3 } from "fs";
1930
- import { join as join7 } from "path";
1931
- var YAML_FILE = "polter.yaml";
1932
- function parseSimpleYaml(content) {
1933
- const lines = content.split("\n");
1934
- const result = {};
1935
- const stack = [
1936
- { obj: result, indent: -1 }
1937
- ];
1938
- for (let i = 0; i < lines.length; i++) {
1939
- const line = lines[i];
1940
- const trimmed = line.replace(/\s+$/, "");
1941
- if (!trimmed || trimmed.match(/^\s*#/)) continue;
1942
- const indent = line.search(/\S/);
1943
- if (indent < 0) continue;
1944
- while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
1945
- stack.pop();
1946
- }
1947
- const current = stack[stack.length - 1].obj;
1948
- const content_ = trimmed.trim();
1949
- if (content_.startsWith("- ")) {
1950
- const parentKey = Object.keys(current).pop();
1951
- if (parentKey) {
1952
- const arr = current[parentKey];
1953
- if (Array.isArray(arr)) {
1954
- const val = content_.slice(2).trim();
1955
- const colonIdx2 = val.indexOf(":");
1956
- if (colonIdx2 > 0 && !val.startsWith('"') && !val.startsWith("'")) {
1957
- const key = val.slice(0, colonIdx2).trim();
1958
- const rest = val.slice(colonIdx2 + 1).trim();
1959
- const obj = { [key]: parseValue(rest) };
1960
- arr.push(obj);
1961
- stack.push({ obj, indent: indent + 2 });
1962
- } else {
1963
- arr.push(parseValue(val));
1964
- }
1965
- }
1966
- }
1967
- continue;
1968
- }
1969
- const colonIdx = content_.indexOf(":");
1970
- if (colonIdx > 0) {
1971
- const key = content_.slice(0, colonIdx).trim();
1972
- const rest = content_.slice(colonIdx + 1).trim();
1973
- if (rest === "" || rest === "|" || rest === ">") {
1974
- const nextLine = lines[i + 1];
1975
- const nextTrimmed = nextLine?.trim();
1976
- if (nextTrimmed?.startsWith("- ")) {
1977
- current[key] = [];
1978
- } else {
1979
- const nested = {};
1980
- current[key] = nested;
1981
- stack.push({ obj: nested, indent });
1982
- }
1983
- } else {
1984
- current[key] = parseValue(rest);
1985
- }
1986
- }
1987
- }
1988
- return result;
1989
- }
1990
- function parseValue(raw) {
1991
- if (!raw) return "";
1992
- if (raw.startsWith('"') && raw.endsWith('"') || raw.startsWith("'") && raw.endsWith("'")) {
1993
- return raw.slice(1, -1);
1994
- }
1995
- if (raw === "true") return true;
1996
- if (raw === "false") return false;
1997
- const num = Number(raw);
1998
- if (!isNaN(num) && raw !== "") return num;
1999
- return raw;
2000
- }
2001
- function findPolterYaml(startDir = process.cwd()) {
2002
- const filePath = join7(startDir, YAML_FILE);
2003
- return existsSync7(filePath) ? filePath : void 0;
2004
- }
2005
- function parsePolterYaml(startDir = process.cwd()) {
2006
- const filePath = findPolterYaml(startDir);
2007
- if (!filePath) return void 0;
2008
- const content = readFileSync3(filePath, "utf-8");
2009
- const raw = parseSimpleYaml(content);
2010
- return raw;
2011
- }
2012
-
2013
- // src/declarative/status.ts
2014
- import { execSync as execSync2 } from "child_process";
2015
- function safeExec(cmd) {
2016
- try {
2017
- return execSync2(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
2018
- } catch {
2019
- return void 0;
2020
- }
2021
- }
2022
- function getCurrentStatus(cwd = process.cwd()) {
2023
- const result = {};
2024
- if (commandExists("supabase")) {
2025
- const linked = safeExec(`cd "${cwd}" && supabase projects list 2>/dev/null`) !== void 0;
2026
- result.supabase = {
2027
- linked,
2028
- projectRef: void 0,
2029
- functions: []
2030
- };
2031
- const functionsOutput = safeExec(`cd "${cwd}" && supabase functions list 2>/dev/null`);
2032
- if (functionsOutput) {
2033
- result.supabase.functions = functionsOutput.split("\n").filter((line) => line.trim() && !line.startsWith("\u2502") && !line.startsWith("\u250C")).slice(1);
2034
- }
2035
- }
2036
- if (commandExists("vercel")) {
2037
- const whoami = safeExec("vercel whoami 2>/dev/null");
2038
- result.vercel = {
2039
- linked: !!whoami,
2040
- projectId: void 0
2041
- };
2042
- }
2043
- if (commandExists("gh")) {
2044
- const authStatus = safeExec("gh auth status 2>&1");
2045
- const authenticated = authStatus?.includes("Logged in") ?? false;
2046
- const repoOutput = safeExec(`cd "${cwd}" && gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null`);
2047
- result.github = {
2048
- repo: repoOutput || void 0,
2049
- authenticated
2050
- };
2051
- }
2052
- return result;
2053
- }
2054
-
2055
- // src/declarative/planner.ts
2056
- function planChanges(desired, cwd = process.cwd()) {
2057
- const current = getCurrentStatus(cwd);
2058
- const actions = [];
2059
- if (desired.supabase?.functions) {
2060
- const currentFunctions = new Set(current.supabase?.functions ?? []);
2061
- for (const fn of desired.supabase.functions) {
2062
- if (!currentFunctions.has(fn.name)) {
2063
- const args = ["functions", "deploy", fn.name];
2064
- if (fn.verify_jwt === false) {
2065
- args.push("--no-verify-jwt");
2066
- }
2067
- actions.push({
2068
- tool: "supabase",
2069
- action: "create",
2070
- resource: `function:${fn.name}`,
2071
- description: `Deploy function "${fn.name}"`,
2072
- args
2073
- });
2074
- }
2075
- }
2076
- }
2077
- if (desired.supabase?.secrets) {
2078
- for (const secret of desired.supabase.secrets) {
2079
- actions.push({
2080
- tool: "supabase",
2081
- action: "update",
2082
- resource: `secret:${secret}`,
2083
- description: `Ensure secret "${secret}" is set`,
2084
- args: ["secrets", "set", secret]
2085
- });
2086
- }
2087
- }
2088
- if (desired.vercel?.domains) {
2089
- for (const domain of desired.vercel.domains) {
2090
- actions.push({
2091
- tool: "vercel",
2092
- action: "create",
2093
- resource: `domain:${domain}`,
2094
- description: `Add domain "${domain}"`,
2095
- args: ["domains", "add", domain]
2096
- });
2097
- }
2098
- }
2099
- if (desired.vercel?.env) {
2100
- for (const [env, vars] of Object.entries(desired.vercel.env)) {
2101
- for (const [key, value] of Object.entries(vars)) {
2102
- actions.push({
2103
- tool: "vercel",
2104
- action: "update",
2105
- resource: `env:${env}:${key}`,
2106
- description: `Set env var "${key}" for ${env}`,
2107
- args: ["env", "add", key, env]
2108
- });
2109
- }
2110
- }
2111
- }
2112
- if (desired.github?.secrets) {
2113
- for (const secret of desired.github.secrets) {
2114
- actions.push({
2115
- tool: "gh",
2116
- action: "update",
2117
- resource: `secret:${secret}`,
2118
- description: `Ensure GitHub secret "${secret}" is set`,
2119
- args: ["secret", "set", secret]
2120
- });
2121
- }
2122
- }
2123
- return {
2124
- actions,
2125
- noChanges: actions.length === 0
2126
- };
2127
- }
2128
-
2129
- // src/declarative/applier.ts
2130
- async function applyActions(actions, cwd = process.cwd(), onProgress) {
2131
- const results = [];
2132
- for (let i = 0; i < actions.length; i++) {
2133
- const action = actions[i];
2134
- onProgress?.(i, actions.length, action);
2135
- const resolved = resolveToolCommand(action.tool, cwd);
2136
- const result = await runCommand(
2137
- { command: resolved.command, env: resolved.env },
2138
- action.args,
2139
- cwd
2140
- ).promise;
2141
- const success = !result.spawnError && result.exitCode === 0;
2142
- results.push({ action, success, result });
2143
- }
2144
- return results;
2145
- }
2146
-
2147
- // src/lib/mcpInstaller.ts
2148
- import { spawnSync as spawnSync2 } from "child_process";
2149
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync8 } from "fs";
2150
- import { join as join8, dirname as dirname5 } from "path";
2151
- import { fileURLToPath } from "url";
2152
- import { homedir } from "os";
2153
- import pc from "picocolors";
2154
- var __dirname = dirname5(fileURLToPath(import.meta.url));
2155
- function readPkgVersion() {
2156
- for (const rel of ["../../package.json", "../package.json"]) {
2157
- const p = join8(__dirname, rel);
2158
- if (existsSync8(p)) {
2159
- const pkg = JSON.parse(readFileSync4(p, "utf-8"));
2160
- return pkg.version;
2161
- }
2162
- }
2163
- return "0.0.0";
2164
- }
2165
- var MCP_ARGS = ["npx", "-y", "-p", "@polterware/polter@latest", "polter-mcp"];
2166
- var SCOPE_LABELS = {
2167
- local: "local (this machine)",
2168
- project: "project (shared via repo)",
2169
- user: "global (all projects)"
2170
- };
2171
- function tryClaudeCli(scope) {
2172
- if (!commandExists("claude")) return false;
2173
- const result = spawnSync2("claude", ["mcp", "add", "-s", scope, "polter", "--", ...MCP_ARGS], {
2174
- stdio: "inherit",
2175
- shell: true
2176
- });
2177
- return result.status === 0;
2178
- }
2179
- function getSettingsPath(scope) {
2180
- if (scope === "project") {
2181
- return join8(process.cwd(), ".mcp.json");
2182
- }
2183
- return join8(homedir(), ".claude", "settings.json");
2184
- }
2185
- function tryManualInstall(scope) {
2186
- const settingsPath = getSettingsPath(scope);
2187
- const dir = join8(settingsPath, "..");
2188
- let settings = {};
2189
- if (existsSync8(settingsPath)) {
2190
- try {
2191
- settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
2192
- } catch {
2193
- process.stderr.write(pc.red(`Failed to parse ${settingsPath}
2194
- `));
2195
- return false;
2196
- }
2197
- } else {
2198
- mkdirSync3(dir, { recursive: true });
2199
- }
2200
- const mcpServers = settings.mcpServers ?? {};
2201
- mcpServers.polter = {
2202
- command: "npx",
2203
- args: ["-y", "-p", "@polterware/polter@latest", "polter-mcp"]
2204
- };
2205
- settings.mcpServers = mcpServers;
2206
- writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
2207
- return true;
2208
- }
2209
- async function installMcpServer(scope) {
2210
- process.stdout.write(pc.bold(`Installing Polter MCP server \u2014 ${SCOPE_LABELS[scope]}
2211
-
2212
- `));
2213
- if (commandExists("claude")) {
2214
- process.stdout.write(` Using 'claude mcp add -s ${scope}'...
2215
- `);
2216
- if (tryClaudeCli(scope)) {
2217
- process.stdout.write(pc.green("\n Done! Restart Claude Code to use Polter tools.\n"));
2218
- return;
2219
- }
2220
- process.stdout.write(pc.yellow(" 'claude mcp add' failed, falling back to manual install...\n\n"));
2221
- }
2222
- const settingsPath = getSettingsPath(scope);
2223
- process.stdout.write(` Writing to ${settingsPath}...
2224
- `);
2225
- if (tryManualInstall(scope)) {
2226
- process.stdout.write(pc.green("\n Done! Restart Claude Code to use Polter tools.\n"));
2227
- } else {
2228
- process.stderr.write(pc.red("\n Failed to install. Add manually:\n\n"));
2229
- process.stderr.write(` ${pc.dim(JSON.stringify({ mcpServers: { polter: { command: "npx", args: ["-y", "-p", "@polterware/polter@latest", "polter-mcp"] } } }, null, 2))}
2230
- `);
2231
- process.exit(1);
2232
- }
2233
- }
2234
- async function removeMcpServer(scope) {
2235
- process.stdout.write(pc.bold(`Removing Polter MCP server \u2014 ${SCOPE_LABELS[scope]}
2236
-
2237
- `));
2238
- if (commandExists("claude")) {
2239
- const result = spawnSync2("claude", ["mcp", "remove", "-s", scope, "polter"], {
2240
- stdio: "inherit",
2241
- shell: true
2242
- });
2243
- if (result.status === 0) {
2244
- process.stdout.write(pc.green("\n Done! Polter MCP server removed.\n"));
2245
- return;
2246
- }
2247
- process.stdout.write(pc.yellow(" 'claude mcp remove' failed, falling back to manual removal...\n\n"));
2248
- }
2249
- const settingsPath = getSettingsPath(scope);
2250
- if (!existsSync8(settingsPath)) {
2251
- process.stdout.write(pc.yellow(" No settings file found. Nothing to remove.\n"));
2252
- return;
2253
- }
2254
- let settings;
2255
- try {
2256
- settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
2257
- } catch {
2258
- process.stderr.write(pc.red(` Failed to parse ${settingsPath}
2259
- `));
2260
- process.exit(1);
2261
- return;
2262
- }
2263
- const mcpServers = settings.mcpServers;
2264
- if (!mcpServers?.polter) {
2265
- process.stdout.write(pc.yellow(" Polter MCP server not found in settings. Nothing to remove.\n"));
2266
- return;
2267
- }
2268
- delete mcpServers.polter;
2269
- settings.mcpServers = mcpServers;
2270
- writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
2271
- process.stdout.write(pc.green(" Done! Polter MCP server removed.\n"));
2272
- }
2273
- function getMcpStatusInfo() {
2274
- const version = readPkgVersion();
2275
- const scopeDefs = [
2276
- { label: "Project (.mcp.json)", path: join8(process.cwd(), ".mcp.json"), scope: "project" },
2277
- { label: "User (~/.claude/settings.json)", path: join8(homedir(), ".claude", "settings.json"), scope: "user" }
2278
- ];
2279
- const scopes = scopeDefs.map((s) => {
2280
- if (!existsSync8(s.path)) {
2281
- return { label: s.label, scope: s.scope, registered: false };
2282
- }
2283
- try {
2284
- const settings = JSON.parse(readFileSync4(s.path, "utf-8"));
2285
- const mcpServers = settings.mcpServers;
2286
- return { label: s.label, scope: s.scope, registered: !!mcpServers?.polter };
2287
- } catch {
2288
- return { label: s.label, scope: s.scope, registered: false, error: "error reading file" };
2289
- }
2290
- });
2291
- return { installedVersion: version, latestVersion: null, scopes };
2292
- }
2293
- async function installMcpServerSilent(scope) {
2294
- const messages = [];
2295
- messages.push(`Installing Polter MCP server \u2014 ${SCOPE_LABELS[scope]}`);
2296
- if (commandExists("claude")) {
2297
- messages.push(`Using 'claude mcp add -s ${scope}'...`);
2298
- if (tryClaudeCli(scope)) {
2299
- messages.push("Done! Restart Claude Code to use Polter tools.");
2300
- return { success: true, message: messages.join("\n") };
2301
- }
2302
- messages.push("'claude mcp add' failed, falling back to manual install...");
2303
- }
2304
- const settingsPath = getSettingsPath(scope);
2305
- messages.push(`Writing to ${settingsPath}...`);
2306
- if (tryManualInstall(scope)) {
2307
- messages.push("Done! Restart Claude Code to use Polter tools.");
2308
- return { success: true, message: messages.join("\n") };
2309
- }
2310
- return { success: false, message: "Failed to install. Try manual installation." };
2311
- }
2312
- async function removeMcpServerSilent(scope) {
2313
- const messages = [];
2314
- messages.push(`Removing Polter MCP server \u2014 ${SCOPE_LABELS[scope]}`);
2315
- if (commandExists("claude")) {
2316
- const result = spawnSync2("claude", ["mcp", "remove", "-s", scope, "polter"], {
2317
- encoding: "utf-8",
2318
- shell: true
2319
- });
2320
- if (result.status === 0) {
2321
- messages.push("Done! Polter MCP server removed.");
2322
- return { success: true, message: messages.join("\n") };
2323
- }
2324
- messages.push("'claude mcp remove' failed, falling back to manual removal...");
2325
- }
2326
- const settingsPath = getSettingsPath(scope);
2327
- if (!existsSync8(settingsPath)) {
2328
- messages.push("No settings file found. Nothing to remove.");
2329
- return { success: true, message: messages.join("\n") };
2330
- }
2331
- let settings;
2332
- try {
2333
- settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
2334
- } catch {
2335
- return { success: false, message: `Failed to parse ${settingsPath}` };
2336
- }
2337
- const mcpServers = settings.mcpServers;
2338
- if (!mcpServers?.polter) {
2339
- messages.push("Polter MCP server not found in settings. Nothing to remove.");
2340
- return { success: true, message: messages.join("\n") };
2341
- }
2342
- delete mcpServers.polter;
2343
- settings.mcpServers = mcpServers;
2344
- writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
2345
- messages.push("Done! Polter MCP server removed.");
2346
- return { success: true, message: messages.join("\n") };
2347
- }
2348
- async function mcpStatus() {
2349
- process.stdout.write(pc.bold("Polter MCP Server Status\n\n"));
2350
- const pkgVersion = readPkgVersion();
2351
- process.stdout.write(` Installed version: ${pc.cyan(pkgVersion)}
2352
- `);
2353
- const latestResult = spawnSync2("npm", ["view", "@polterware/polter", "version"], {
2354
- encoding: "utf-8",
2355
- shell: true,
2356
- timeout: 1e4
2357
- });
2358
- const latest = latestResult.stdout?.trim();
2359
- if (latest) {
2360
- const upToDate = latest === pkgVersion;
2361
- process.stdout.write(` Latest version: ${upToDate ? pc.green(latest) : pc.yellow(`${latest} (update available)`)}
2362
- `);
2363
- }
2364
- process.stdout.write("\n");
2365
- const scopes = [
2366
- { label: "Project (.mcp.json)", path: join8(process.cwd(), ".mcp.json"), key: "project" },
2367
- { label: "User (~/.claude/settings.json)", path: join8(homedir(), ".claude", "settings.json"), key: "user" }
2368
- ];
2369
- for (const scope of scopes) {
2370
- if (!existsSync8(scope.path)) {
2371
- process.stdout.write(` ${scope.label}: ${pc.dim("not found")}
2372
- `);
2373
- continue;
2374
- }
2375
- try {
2376
- const settings = JSON.parse(readFileSync4(scope.path, "utf-8"));
2377
- const mcpServers = settings.mcpServers;
2378
- if (mcpServers?.polter) {
2379
- process.stdout.write(` ${scope.label}: ${pc.green("registered")}
2380
- `);
2381
- } else {
2382
- process.stdout.write(` ${scope.label}: ${pc.dim("not registered")}
2383
- `);
2384
- }
2385
- } catch {
2386
- process.stdout.write(` ${scope.label}: ${pc.red("error reading file")}
2387
- `);
2388
- }
2389
- }
2390
- }
2391
-
2392
- export {
2393
- __export,
2394
- allCommands,
2395
- getCommandById,
2396
- getCommandsByTool,
2397
- getCommandValue,
2398
- findCommandByValue,
2399
- features,
2400
- getFeatureById,
2401
- toolFlags,
2402
- getFlagsForTool,
2403
- runCommand,
2404
- runInteractiveCommand,
2405
- runSupabaseCommand,
2406
- commandExists,
2407
- detectPkgManager,
2408
- translateCommand,
2409
- resolvePkgArgs,
2410
- getToolDisplayName,
2411
- resolveToolCommand,
2412
- getToolInfo,
2413
- getToolLinkInfo,
2414
- findNearestPackageRoot,
2415
- generateProcessId,
2416
- startProcess,
2417
- stopProcess,
2418
- listProcesses,
2419
- getProcessOutput,
2420
- isProcessRunning,
2421
- removeProcess,
2422
- findProcessesByCwd,
2423
- findRunningByCommand,
2424
- getSocketPath,
2425
- serializeMessage,
2426
- parseMessages,
2427
- createIpcServer,
2428
- executePipeline,
2429
- getProjectConfigPath,
2430
- writeProjectConfig,
2431
- getOrCreateProjectConfig,
2432
- getAllPipelines,
2433
- savePipeline,
2434
- deletePipeline,
2435
- findPipelineByName,
2436
- findPolterYaml,
2437
- parsePolterYaml,
2438
- getCurrentStatus,
2439
- planChanges,
2440
- applyActions,
2441
- installMcpServer,
2442
- removeMcpServer,
2443
- getMcpStatusInfo,
2444
- installMcpServerSilent,
2445
- removeMcpServerSilent,
2446
- mcpStatus
2447
- };