@simplysf/simply-gitlab 0.4.0 → 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.
@@ -325,13 +325,14 @@
325
325
  "list:branch:gitlab"
326
326
  ]
327
327
  },
328
- "gitlab:commit:create": {
328
+ "gitlab:config:apply": {
329
329
  "aliases": [],
330
330
  "args": {},
331
- "description": "Sends one commit containing a batch of actions — create, update, delete, move, chmod — which is how GitLab writes more than one file atomically. The actions are JSON, supplied with --actions or inside a --body-file, because there is no readable flag form for a list of file operations.\n\nEach action is an object with an \"action\" and a \"file_path\"; create and update also need \"content\", move needs \"previous_path\", and chmod needs \"execute_filemode\". Those rules are checked before anything is sent, so a bad entry names its own index.\n\nUse --dry-run to see exactly what would be sent.",
331
+ "description": "Computes the same plan as config plan, then executes it. Only what the plan showed is sent, so a preview is a guarantee rather than an approximation, and a second run against a converged project sends no requests at all.\n\nSections are applied in a fixed order — settings, protected branches, protected tags, approval settings, approval rules, push rules — because an approval rule scoped to a branch needs that branch protected before it can reference it.\n\nBy default the config only adds and corrects what it declares. A section that sets \"prune\": true also deletes entries the config does not mention.\n\nOne target failing does not abandon the rest; the summary says which ones failed and where they stopped. There is no transaction across GitLab endpoints, so a target that failed part-way keeps the sections already applied — run config plan afterwards to see what is left.",
332
332
  "examples": [
333
- "<%= config.bin %> <%= command.id %> --project group/project --branch main --message \"chore: tidy\" --actions '[{\"action\":\"delete\",\"file_path\":\"old.txt\"}]'",
334
- "<%= config.bin %> <%= command.id %> --project group/project --branch main --message \"feat: batch\" --body-file ./commit.json --dry-run"
333
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json --dry-run",
334
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json",
335
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json --target group/project"
335
336
  ],
336
337
  "flags": {
337
338
  "json": {
@@ -369,103 +370,53 @@
369
370
  "multiple": false,
370
371
  "type": "option"
371
372
  },
372
- "project": {
373
- "char": "p",
374
- "env": "GITLAB_PROJECT",
375
- "name": "project",
373
+ "config": {
374
+ "char": "c",
375
+ "name": "config",
376
376
  "required": true,
377
- "summary": "Project id, or its full path such as group/subgroup/project.",
378
- "hasDynamicHelp": false,
379
- "multiple": false,
380
- "type": "option"
381
- },
382
- "dry-run": {
383
- "name": "dry-run",
384
- "summary": "Print the request that would be sent and exit without sending it.",
385
- "allowNo": false,
386
- "type": "boolean"
387
- },
388
- "branch": {
389
- "name": "branch",
390
- "summary": "Branch to commit to.",
391
- "hasDynamicHelp": false,
392
- "multiple": false,
393
- "type": "option"
394
- },
395
- "message": {
396
- "name": "message",
397
- "summary": "Commit message.",
398
- "hasDynamicHelp": false,
399
- "multiple": false,
400
- "type": "option"
401
- },
402
- "actions": {
403
- "name": "actions",
404
- "summary": "JSON array of file actions.",
405
- "hasDynamicHelp": false,
406
- "multiple": false,
407
- "type": "option"
408
- },
409
- "start-branch": {
410
- "name": "start-branch",
411
- "summary": "Branch to create --branch from, if it does not exist.",
412
- "hasDynamicHelp": false,
413
- "multiple": false,
414
- "type": "option"
415
- },
416
- "start-sha": {
417
- "name": "start-sha",
418
- "summary": "Commit SHA to start the new commit from.",
377
+ "summary": "Path to the baseline configuration file.",
419
378
  "hasDynamicHelp": false,
420
379
  "multiple": false,
421
380
  "type": "option"
422
381
  },
423
- "author-email": {
424
- "name": "author-email",
425
- "summary": "Commit author email.",
382
+ "target": {
383
+ "description": "Narrows a run without editing the config, for the loop of fixing one project and checking it again. Naming a project the config does not target is an error rather than a silent no-op.",
384
+ "name": "target",
385
+ "summary": "Limit the run to this project path. Repeatable.",
426
386
  "hasDynamicHelp": false,
427
- "multiple": false,
387
+ "multiple": true,
428
388
  "type": "option"
429
389
  },
430
- "author-name": {
431
- "name": "author-name",
432
- "summary": "Commit author name.",
390
+ "concurrency": {
391
+ "description": "Small by default. The client already retries a rate-limited request with a capped Retry-After, so raising this trades a shared instance responsiveness for very little wall-clock time.",
392
+ "name": "concurrency",
393
+ "summary": "How many targets to work on at once.",
394
+ "default": 4,
433
395
  "hasDynamicHelp": false,
434
396
  "multiple": false,
435
397
  "type": "option"
436
398
  },
437
- "force": {
438
- "name": "force",
439
- "summary": "Overwrite the branch with the new commit.",
399
+ "fail-fast": {
400
+ "name": "fail-fast",
401
+ "summary": "Stop at the first target that fails instead of continuing.",
440
402
  "allowNo": false,
441
403
  "type": "boolean"
442
404
  },
443
- "body": {
444
- "exclusive": [
445
- "body-file"
446
- ],
447
- "name": "body",
448
- "summary": "Raw JSON request body.",
449
- "hasDynamicHelp": false,
450
- "multiple": false,
451
- "type": "option"
452
- },
453
- "body-file": {
454
- "name": "body-file",
455
- "summary": "Path to a file holding the raw JSON request body.",
456
- "hasDynamicHelp": false,
457
- "multiple": false,
458
- "type": "option"
405
+ "dry-run": {
406
+ "name": "dry-run",
407
+ "summary": "Print the request that would be sent and exit without sending it.",
408
+ "allowNo": false,
409
+ "type": "boolean"
459
410
  }
460
411
  },
461
412
  "hasDynamicHelp": false,
462
413
  "hiddenAliases": [],
463
- "id": "gitlab:commit:create",
414
+ "id": "gitlab:config:apply",
464
415
  "pluginAlias": "@simplysf/simply-gitlab",
465
416
  "pluginName": "@simplysf/simply-gitlab",
466
417
  "pluginType": "core",
467
418
  "strict": true,
468
- "summary": "Commit several file changes at once.",
419
+ "summary": "Bring projects onto a baseline config.",
469
420
  "enableJsonFlag": true,
470
421
  "isWrite": true,
471
422
  "isESM": true,
@@ -473,26 +424,26 @@
473
424
  "lib",
474
425
  "commands",
475
426
  "gitlab",
476
- "commit",
477
- "create.js"
427
+ "config",
428
+ "apply.js"
478
429
  ],
479
430
  "aliasPermutations": [],
480
431
  "permutations": [
481
- "gitlab:commit:create",
482
- "commit:gitlab:create",
483
- "commit:create:gitlab",
484
- "gitlab:create:commit",
485
- "create:gitlab:commit",
486
- "create:commit:gitlab"
432
+ "gitlab:config:apply",
433
+ "config:gitlab:apply",
434
+ "config:apply:gitlab",
435
+ "gitlab:apply:config",
436
+ "apply:gitlab:config",
437
+ "apply:config:gitlab"
487
438
  ]
488
439
  },
489
- "gitlab:commit:diff": {
440
+ "gitlab:config:export": {
490
441
  "aliases": [],
491
442
  "args": {},
492
- "description": "Prints the unified diff for each file the commit touched. GitLab truncates very large diffs server-side and says so in the payload, so --stat is worth reaching for first on a big commit: it lists the files without any hunks.",
443
+ "description": "Reads one project and prints a configuration file that describes it, ready to be edited and pointed at the rest of your projects. Writing a baseline by hand against forty attributes is miserable and the first draft is wrong; exporting the project that already looks right and deleting what you do not care about is the way to start.\n\nThe output is deliberately verbose — every supported key, not a curated subset — because deleting a line is easier than discovering that a key exists. Variables are exported as metadata only: keys, scopes, and flags, never values.\n\nThe exported targets name only the project it came from. Widen that on purpose rather than inheriting a blast radius from an export.",
493
444
  "examples": [
494
- "<%= config.bin %> <%= command.id %> --project group/project --sha 9a1b2c3",
495
- "<%= config.bin %> <%= command.id %> --project group/project --sha 9a1b2c3 --stat"
445
+ "<%= config.bin %> <%= command.id %> --project group/project > baseline.json",
446
+ "<%= config.bin %> <%= command.id %> --project group/project --section settings,protectedBranches"
496
447
  ],
497
448
  "flags": {
498
449
  "json": {
@@ -540,29 +491,32 @@
540
491
  "multiple": false,
541
492
  "type": "option"
542
493
  },
543
- "sha": {
544
- "name": "sha",
545
- "required": true,
546
- "summary": "Commit SHA, or the name of a branch or tag.",
494
+ "section": {
495
+ "name": "section",
496
+ "summary": "Comma-separated sections to export. Defaults to all of them.",
497
+ "delimiter": ",",
547
498
  "hasDynamicHelp": false,
548
- "multiple": false,
499
+ "multiple": true,
500
+ "options": [
501
+ "settings",
502
+ "protectedBranches",
503
+ "protectedTags",
504
+ "approvals",
505
+ "approvalRules",
506
+ "pushRules",
507
+ "variables"
508
+ ],
549
509
  "type": "option"
550
- },
551
- "stat": {
552
- "name": "stat",
553
- "summary": "List the changed files without printing the hunks.",
554
- "allowNo": false,
555
- "type": "boolean"
556
510
  }
557
511
  },
558
512
  "hasDynamicHelp": false,
559
513
  "hiddenAliases": [],
560
- "id": "gitlab:commit:diff",
514
+ "id": "gitlab:config:export",
561
515
  "pluginAlias": "@simplysf/simply-gitlab",
562
516
  "pluginName": "@simplysf/simply-gitlab",
563
517
  "pluginType": "core",
564
518
  "strict": true,
565
- "summary": "Show the changes a commit made.",
519
+ "summary": "Write a baseline config describing an existing project.",
566
520
  "enableJsonFlag": true,
567
521
  "isWrite": false,
568
522
  "isESM": true,
@@ -570,27 +524,28 @@
570
524
  "lib",
571
525
  "commands",
572
526
  "gitlab",
573
- "commit",
574
- "diff.js"
527
+ "config",
528
+ "export.js"
575
529
  ],
576
530
  "aliasPermutations": [],
577
531
  "permutations": [
578
- "gitlab:commit:diff",
579
- "commit:gitlab:diff",
580
- "commit:diff:gitlab",
581
- "gitlab:diff:commit",
582
- "diff:gitlab:commit",
583
- "diff:commit:gitlab"
532
+ "gitlab:config:export",
533
+ "config:gitlab:export",
534
+ "config:export:gitlab",
535
+ "gitlab:export:config",
536
+ "export:gitlab:config",
537
+ "export:config:gitlab"
584
538
  ]
585
539
  },
586
- "gitlab:commit:list": {
540
+ "gitlab:config:plan": {
587
541
  "aliases": [],
588
542
  "args": {},
589
- "description": "Walks the history of a ref, newest first. --path narrows to commits that touched one file or directory, which is the fastest way to answer \"when did this change and who changed it\".\n\n--since and --until take ISO 8601 timestamps (2026-01-31T00:00:00Z); a bare date works too.",
543
+ "description": "Reads the baseline, expands its targets, and prints what differs on each one. Nothing is sent that changes anything, so this is safe to run against every project you have.\n\nOnly the attributes the config declares are compared. A project with forty settings the config never mentions shows nothing for them — that is what makes a baseline safe to point at projects that already exist.\n\nEntries that exist on the instance but are not in the config are shown as removals, marked as not pruned unless that section opts into pruning. Seeing what you are choosing not to fix is most of the value of running this across fifty projects.\n\nUse --fail-on-drift in a scheduled job: it exits 1 when anything differs, so CI can tell you that something drifted without anyone having to read the output.",
590
544
  "examples": [
591
- "<%= config.bin %> <%= command.id %> --project group/project --ref main --limit 10",
592
- "<%= config.bin %> <%= command.id %> --project group/project --path src/index.ts",
593
- "<%= config.bin %> <%= command.id %> --project group/project --since 2026-01-01 --until 2026-02-01"
545
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json",
546
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json --target group/project",
547
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json --fail-on-drift",
548
+ "<%= config.bin %> <%= command.id %> --config ./baseline.json --json | jq .summary"
594
549
  ],
595
550
  "flags": {
596
551
  "json": {
@@ -628,74 +583,53 @@
628
583
  "multiple": false,
629
584
  "type": "option"
630
585
  },
631
- "project": {
632
- "char": "p",
633
- "env": "GITLAB_PROJECT",
634
- "name": "project",
586
+ "config": {
587
+ "char": "c",
588
+ "name": "config",
635
589
  "required": true,
636
- "summary": "Project id, or its full path such as group/subgroup/project.",
637
- "hasDynamicHelp": false,
638
- "multiple": false,
639
- "type": "option"
640
- },
641
- "limit": {
642
- "name": "limit",
643
- "summary": "Maximum number of commits to return across all pages.",
644
- "default": 20,
645
- "hasDynamicHelp": false,
646
- "multiple": false,
647
- "type": "option"
648
- },
649
- "ref": {
650
- "name": "ref",
651
- "summary": "Branch, tag, or SHA to list from. Defaults to the default branch.",
652
- "hasDynamicHelp": false,
653
- "multiple": false,
654
- "type": "option"
655
- },
656
- "path": {
657
- "name": "path",
658
- "summary": "Only commits that touched this file or directory.",
590
+ "summary": "Path to the baseline configuration file.",
659
591
  "hasDynamicHelp": false,
660
592
  "multiple": false,
661
593
  "type": "option"
662
594
  },
663
- "since": {
664
- "name": "since",
665
- "summary": "Only commits on or after this ISO 8601 timestamp.",
595
+ "target": {
596
+ "description": "Narrows a run without editing the config, for the loop of fixing one project and checking it again. Naming a project the config does not target is an error rather than a silent no-op.",
597
+ "name": "target",
598
+ "summary": "Limit the run to this project path. Repeatable.",
666
599
  "hasDynamicHelp": false,
667
- "multiple": false,
600
+ "multiple": true,
668
601
  "type": "option"
669
602
  },
670
- "until": {
671
- "name": "until",
672
- "summary": "Only commits on or before this ISO 8601 timestamp.",
603
+ "concurrency": {
604
+ "description": "Small by default. The client already retries a rate-limited request with a capped Retry-After, so raising this trades a shared instance responsiveness for very little wall-clock time.",
605
+ "name": "concurrency",
606
+ "summary": "How many targets to work on at once.",
607
+ "default": 4,
673
608
  "hasDynamicHelp": false,
674
609
  "multiple": false,
675
610
  "type": "option"
676
611
  },
677
- "author": {
678
- "name": "author",
679
- "summary": "Only commits by this author name or email.",
680
- "hasDynamicHelp": false,
681
- "multiple": false,
682
- "type": "option"
612
+ "fail-fast": {
613
+ "name": "fail-fast",
614
+ "summary": "Stop at the first target that fails instead of continuing.",
615
+ "allowNo": false,
616
+ "type": "boolean"
683
617
  },
684
- "stats": {
685
- "name": "stats",
686
- "summary": "Include per-commit line counts in the JSON payload.",
618
+ "fail-on-drift": {
619
+ "name": "fail-on-drift",
620
+ "summary": "Exit 1 when any target differs from the baseline.",
687
621
  "allowNo": false,
688
622
  "type": "boolean"
689
623
  }
690
624
  },
691
625
  "hasDynamicHelp": false,
692
626
  "hiddenAliases": [],
693
- "id": "gitlab:commit:list",
627
+ "id": "gitlab:config:plan",
694
628
  "pluginAlias": "@simplysf/simply-gitlab",
695
629
  "pluginName": "@simplysf/simply-gitlab",
696
630
  "pluginType": "core",
697
631
  "strict": true,
698
- "summary": "List repository commits.",
632
+ "summary": "Report how projects differ from a baseline config.",
699
633
  "enableJsonFlag": true,
700
634
  "isWrite": false,
701
635
  "isESM": true,
@@ -703,26 +637,26 @@
703
637
  "lib",
704
638
  "commands",
705
639
  "gitlab",
706
- "commit",
707
- "list.js"
640
+ "config",
641
+ "plan.js"
708
642
  ],
709
643
  "aliasPermutations": [],
710
644
  "permutations": [
711
- "gitlab:commit:list",
712
- "commit:gitlab:list",
713
- "commit:list:gitlab",
714
- "gitlab:list:commit",
715
- "list:gitlab:commit",
716
- "list:commit:gitlab"
645
+ "gitlab:config:plan",
646
+ "config:gitlab:plan",
647
+ "config:plan:gitlab",
648
+ "gitlab:plan:config",
649
+ "plan:gitlab:config",
650
+ "plan:config:gitlab"
717
651
  ]
718
652
  },
719
- "gitlab:commit:view": {
653
+ "gitlab:commit:create": {
720
654
  "aliases": [],
721
655
  "args": {},
722
- "description": "Accepts a full or short SHA, or the name of a branch or tag — in which case the commit at its tip is shown, so the answer changes as the branch moves. Use commit diff for the changes themselves.",
656
+ "description": "Sends one commit containing a batch of actions — create, update, delete, move, chmod — which is how GitLab writes more than one file atomically. The actions are JSON, supplied with --actions or inside a --body-file, because there is no readable flag form for a list of file operations.\n\nEach action is an object with an \"action\" and a \"file_path\"; create and update also need \"content\", move needs \"previous_path\", and chmod needs \"execute_filemode\". Those rules are checked before anything is sent, so a bad entry names its own index.\n\nUse --dry-run to see exactly what would be sent.",
723
657
  "examples": [
724
- "<%= config.bin %> <%= command.id %> --project group/project --sha 9a1b2c3",
725
- "<%= config.bin %> <%= command.id %> --project group/project --sha main --json"
658
+ "<%= config.bin %> <%= command.id %> --project group/project --branch main --message \"chore: tidy\" --actions '[{\"action\":\"delete\",\"file_path\":\"old.txt\"}]'",
659
+ "<%= config.bin %> <%= command.id %> --project group/project --branch main --message \"feat: batch\" --body-file ./commit.json --dry-run"
726
660
  ],
727
661
  "flags": {
728
662
  "json": {
@@ -770,10 +704,80 @@
770
704
  "multiple": false,
771
705
  "type": "option"
772
706
  },
773
- "sha": {
774
- "name": "sha",
775
- "required": true,
776
- "summary": "Commit SHA, or the name of a branch or tag.",
707
+ "dry-run": {
708
+ "name": "dry-run",
709
+ "summary": "Print the request that would be sent and exit without sending it.",
710
+ "allowNo": false,
711
+ "type": "boolean"
712
+ },
713
+ "branch": {
714
+ "name": "branch",
715
+ "summary": "Branch to commit to.",
716
+ "hasDynamicHelp": false,
717
+ "multiple": false,
718
+ "type": "option"
719
+ },
720
+ "message": {
721
+ "name": "message",
722
+ "summary": "Commit message.",
723
+ "hasDynamicHelp": false,
724
+ "multiple": false,
725
+ "type": "option"
726
+ },
727
+ "actions": {
728
+ "name": "actions",
729
+ "summary": "JSON array of file actions.",
730
+ "hasDynamicHelp": false,
731
+ "multiple": false,
732
+ "type": "option"
733
+ },
734
+ "start-branch": {
735
+ "name": "start-branch",
736
+ "summary": "Branch to create --branch from, if it does not exist.",
737
+ "hasDynamicHelp": false,
738
+ "multiple": false,
739
+ "type": "option"
740
+ },
741
+ "start-sha": {
742
+ "name": "start-sha",
743
+ "summary": "Commit SHA to start the new commit from.",
744
+ "hasDynamicHelp": false,
745
+ "multiple": false,
746
+ "type": "option"
747
+ },
748
+ "author-email": {
749
+ "name": "author-email",
750
+ "summary": "Commit author email.",
751
+ "hasDynamicHelp": false,
752
+ "multiple": false,
753
+ "type": "option"
754
+ },
755
+ "author-name": {
756
+ "name": "author-name",
757
+ "summary": "Commit author name.",
758
+ "hasDynamicHelp": false,
759
+ "multiple": false,
760
+ "type": "option"
761
+ },
762
+ "force": {
763
+ "name": "force",
764
+ "summary": "Overwrite the branch with the new commit.",
765
+ "allowNo": false,
766
+ "type": "boolean"
767
+ },
768
+ "body": {
769
+ "exclusive": [
770
+ "body-file"
771
+ ],
772
+ "name": "body",
773
+ "summary": "Raw JSON request body.",
774
+ "hasDynamicHelp": false,
775
+ "multiple": false,
776
+ "type": "option"
777
+ },
778
+ "body-file": {
779
+ "name": "body-file",
780
+ "summary": "Path to a file holding the raw JSON request body.",
777
781
  "hasDynamicHelp": false,
778
782
  "multiple": false,
779
783
  "type": "option"
@@ -781,40 +785,39 @@
781
785
  },
782
786
  "hasDynamicHelp": false,
783
787
  "hiddenAliases": [],
784
- "id": "gitlab:commit:view",
788
+ "id": "gitlab:commit:create",
785
789
  "pluginAlias": "@simplysf/simply-gitlab",
786
790
  "pluginName": "@simplysf/simply-gitlab",
787
791
  "pluginType": "core",
788
792
  "strict": true,
789
- "summary": "Show one commit.",
793
+ "summary": "Commit several file changes at once.",
790
794
  "enableJsonFlag": true,
791
- "isWrite": false,
795
+ "isWrite": true,
792
796
  "isESM": true,
793
797
  "relativePath": [
794
798
  "lib",
795
799
  "commands",
796
800
  "gitlab",
797
801
  "commit",
798
- "view.js"
802
+ "create.js"
799
803
  ],
800
804
  "aliasPermutations": [],
801
805
  "permutations": [
802
- "gitlab:commit:view",
803
- "commit:gitlab:view",
804
- "commit:view:gitlab",
805
- "gitlab:view:commit",
806
- "view:gitlab:commit",
807
- "view:commit:gitlab"
806
+ "gitlab:commit:create",
807
+ "commit:gitlab:create",
808
+ "commit:create:gitlab",
809
+ "gitlab:create:commit",
810
+ "create:gitlab:commit",
811
+ "create:commit:gitlab"
808
812
  ]
809
813
  },
810
- "gitlab:config:apply": {
814
+ "gitlab:commit:diff": {
811
815
  "aliases": [],
812
816
  "args": {},
813
- "description": "Computes the same plan as config plan, then executes it. Only what the plan showed is sent, so a preview is a guarantee rather than an approximation, and a second run against a converged project sends no requests at all.\n\nSections are applied in a fixed order — settings, protected branches, protected tags, approval settings, approval rules, push rules — because an approval rule scoped to a branch needs that branch protected before it can reference it.\n\nBy default the config only adds and corrects what it declares. A section that sets \"prune\": true also deletes entries the config does not mention.\n\nOne target failing does not abandon the rest; the summary says which ones failed and where they stopped. There is no transaction across GitLab endpoints, so a target that failed part-way keeps the sections already applied — run config plan afterwards to see what is left.",
817
+ "description": "Prints the unified diff for each file the commit touched. GitLab truncates very large diffs server-side and says so in the payload, so --stat is worth reaching for first on a big commit: it lists the files without any hunks.",
814
818
  "examples": [
815
- "<%= config.bin %> <%= command.id %> --config ./baseline.json --dry-run",
816
- "<%= config.bin %> <%= command.id %> --config ./baseline.json",
817
- "<%= config.bin %> <%= command.id %> --config ./baseline.json --target group/project"
819
+ "<%= config.bin %> <%= command.id %> --project group/project --sha 9a1b2c3",
820
+ "<%= config.bin %> <%= command.id %> --project group/project --sha 9a1b2c3 --stat"
818
821
  ],
819
822
  "flags": {
820
823
  "json": {
@@ -852,80 +855,67 @@
852
855
  "multiple": false,
853
856
  "type": "option"
854
857
  },
855
- "config": {
856
- "char": "c",
857
- "name": "config",
858
+ "project": {
859
+ "char": "p",
860
+ "env": "GITLAB_PROJECT",
861
+ "name": "project",
858
862
  "required": true,
859
- "summary": "Path to the baseline configuration file.",
863
+ "summary": "Project id, or its full path such as group/subgroup/project.",
860
864
  "hasDynamicHelp": false,
861
865
  "multiple": false,
862
866
  "type": "option"
863
867
  },
864
- "target": {
865
- "description": "Narrows a run without editing the config, for the loop of fixing one project and checking it again. Naming a project the config does not target is an error rather than a silent no-op.",
866
- "name": "target",
867
- "summary": "Limit the run to this project path. Repeatable.",
868
- "hasDynamicHelp": false,
869
- "multiple": true,
870
- "type": "option"
871
- },
872
- "concurrency": {
873
- "description": "Small by default. The client already retries a rate-limited request with a capped Retry-After, so raising this trades a shared instance responsiveness for very little wall-clock time.",
874
- "name": "concurrency",
875
- "summary": "How many targets to work on at once.",
876
- "default": 4,
868
+ "sha": {
869
+ "name": "sha",
870
+ "required": true,
871
+ "summary": "Commit SHA, or the name of a branch or tag.",
877
872
  "hasDynamicHelp": false,
878
873
  "multiple": false,
879
874
  "type": "option"
880
875
  },
881
- "fail-fast": {
882
- "name": "fail-fast",
883
- "summary": "Stop at the first target that fails instead of continuing.",
884
- "allowNo": false,
885
- "type": "boolean"
886
- },
887
- "dry-run": {
888
- "name": "dry-run",
889
- "summary": "Print the request that would be sent and exit without sending it.",
876
+ "stat": {
877
+ "name": "stat",
878
+ "summary": "List the changed files without printing the hunks.",
890
879
  "allowNo": false,
891
880
  "type": "boolean"
892
881
  }
893
882
  },
894
883
  "hasDynamicHelp": false,
895
884
  "hiddenAliases": [],
896
- "id": "gitlab:config:apply",
885
+ "id": "gitlab:commit:diff",
897
886
  "pluginAlias": "@simplysf/simply-gitlab",
898
887
  "pluginName": "@simplysf/simply-gitlab",
899
888
  "pluginType": "core",
900
889
  "strict": true,
901
- "summary": "Bring projects onto a baseline config.",
890
+ "summary": "Show the changes a commit made.",
902
891
  "enableJsonFlag": true,
903
- "isWrite": true,
892
+ "isWrite": false,
904
893
  "isESM": true,
905
894
  "relativePath": [
906
895
  "lib",
907
896
  "commands",
908
897
  "gitlab",
909
- "config",
910
- "apply.js"
898
+ "commit",
899
+ "diff.js"
911
900
  ],
912
901
  "aliasPermutations": [],
913
902
  "permutations": [
914
- "gitlab:config:apply",
915
- "config:gitlab:apply",
916
- "config:apply:gitlab",
917
- "gitlab:apply:config",
918
- "apply:gitlab:config",
919
- "apply:config:gitlab"
903
+ "gitlab:commit:diff",
904
+ "commit:gitlab:diff",
905
+ "commit:diff:gitlab",
906
+ "gitlab:diff:commit",
907
+ "diff:gitlab:commit",
908
+ "diff:commit:gitlab"
920
909
  ]
921
910
  },
922
- "gitlab:config:export": {
911
+ "gitlab:commit:list": {
923
912
  "aliases": [],
924
913
  "args": {},
925
- "description": "Reads one project and prints a configuration file that describes it, ready to be edited and pointed at the rest of your projects. Writing a baseline by hand against forty attributes is miserable and the first draft is wrong; exporting the project that already looks right and deleting what you do not care about is the way to start.\n\nThe output is deliberately verbose — every supported key, not a curated subset — because deleting a line is easier than discovering that a key exists. Variables are exported as metadata only: keys, scopes, and flags, never values.\n\nThe exported targets name only the project it came from. Widen that on purpose rather than inheriting a blast radius from an export.",
914
+ "description": "Walks the history of a ref, newest first. --path narrows to commits that touched one file or directory, which is the fastest way to answer \"when did this change and who changed it\".\n\n--since and --until take ISO 8601 timestamps (2026-01-31T00:00:00Z); a bare date works too.",
926
915
  "examples": [
927
- "<%= config.bin %> <%= command.id %> --project group/project > baseline.json",
928
- "<%= config.bin %> <%= command.id %> --project group/project --section settings,protectedBranches"
916
+ "<%= config.bin %> <%= command.id %> --project group/project --ref main --limit 10",
917
+ "<%= config.bin %> <%= command.id %> --project group/project --path src/index.ts",
918
+ "<%= config.bin %> <%= command.id %> --project group/project --since 2026-01-01 --until 2026-02-01"
929
919
  ],
930
920
  "flags": {
931
921
  "json": {
@@ -973,32 +963,64 @@
973
963
  "multiple": false,
974
964
  "type": "option"
975
965
  },
976
- "section": {
977
- "name": "section",
978
- "summary": "Comma-separated sections to export. Defaults to all of them.",
979
- "delimiter": ",",
966
+ "limit": {
967
+ "name": "limit",
968
+ "summary": "Maximum number of commits to return across all pages.",
969
+ "default": 20,
980
970
  "hasDynamicHelp": false,
981
- "multiple": true,
982
- "options": [
983
- "settings",
984
- "protectedBranches",
985
- "protectedTags",
986
- "approvals",
987
- "approvalRules",
988
- "pushRules",
989
- "variables"
990
- ],
971
+ "multiple": false,
972
+ "type": "option"
973
+ },
974
+ "ref": {
975
+ "name": "ref",
976
+ "summary": "Branch, tag, or SHA to list from. Defaults to the default branch.",
977
+ "hasDynamicHelp": false,
978
+ "multiple": false,
979
+ "type": "option"
980
+ },
981
+ "path": {
982
+ "name": "path",
983
+ "summary": "Only commits that touched this file or directory.",
984
+ "hasDynamicHelp": false,
985
+ "multiple": false,
986
+ "type": "option"
987
+ },
988
+ "since": {
989
+ "name": "since",
990
+ "summary": "Only commits on or after this ISO 8601 timestamp.",
991
+ "hasDynamicHelp": false,
992
+ "multiple": false,
993
+ "type": "option"
994
+ },
995
+ "until": {
996
+ "name": "until",
997
+ "summary": "Only commits on or before this ISO 8601 timestamp.",
998
+ "hasDynamicHelp": false,
999
+ "multiple": false,
1000
+ "type": "option"
1001
+ },
1002
+ "author": {
1003
+ "name": "author",
1004
+ "summary": "Only commits by this author name or email.",
1005
+ "hasDynamicHelp": false,
1006
+ "multiple": false,
991
1007
  "type": "option"
1008
+ },
1009
+ "stats": {
1010
+ "name": "stats",
1011
+ "summary": "Include per-commit line counts in the JSON payload.",
1012
+ "allowNo": false,
1013
+ "type": "boolean"
992
1014
  }
993
1015
  },
994
1016
  "hasDynamicHelp": false,
995
1017
  "hiddenAliases": [],
996
- "id": "gitlab:config:export",
1018
+ "id": "gitlab:commit:list",
997
1019
  "pluginAlias": "@simplysf/simply-gitlab",
998
1020
  "pluginName": "@simplysf/simply-gitlab",
999
1021
  "pluginType": "core",
1000
1022
  "strict": true,
1001
- "summary": "Write a baseline config describing an existing project.",
1023
+ "summary": "List repository commits.",
1002
1024
  "enableJsonFlag": true,
1003
1025
  "isWrite": false,
1004
1026
  "isESM": true,
@@ -1006,28 +1028,26 @@
1006
1028
  "lib",
1007
1029
  "commands",
1008
1030
  "gitlab",
1009
- "config",
1010
- "export.js"
1031
+ "commit",
1032
+ "list.js"
1011
1033
  ],
1012
1034
  "aliasPermutations": [],
1013
1035
  "permutations": [
1014
- "gitlab:config:export",
1015
- "config:gitlab:export",
1016
- "config:export:gitlab",
1017
- "gitlab:export:config",
1018
- "export:gitlab:config",
1019
- "export:config:gitlab"
1036
+ "gitlab:commit:list",
1037
+ "commit:gitlab:list",
1038
+ "commit:list:gitlab",
1039
+ "gitlab:list:commit",
1040
+ "list:gitlab:commit",
1041
+ "list:commit:gitlab"
1020
1042
  ]
1021
1043
  },
1022
- "gitlab:config:plan": {
1044
+ "gitlab:commit:view": {
1023
1045
  "aliases": [],
1024
1046
  "args": {},
1025
- "description": "Reads the baseline, expands its targets, and prints what differs on each one. Nothing is sent that changes anything, so this is safe to run against every project you have.\n\nOnly the attributes the config declares are compared. A project with forty settings the config never mentions shows nothing for them — that is what makes a baseline safe to point at projects that already exist.\n\nEntries that exist on the instance but are not in the config are shown as removals, marked as not pruned unless that section opts into pruning. Seeing what you are choosing not to fix is most of the value of running this across fifty projects.\n\nUse --fail-on-drift in a scheduled job: it exits 1 when anything differs, so CI can tell you that something drifted without anyone having to read the output.",
1047
+ "description": "Accepts a full or short SHA, or the name of a branch or tag — in which case the commit at its tip is shown, so the answer changes as the branch moves. Use commit diff for the changes themselves.",
1026
1048
  "examples": [
1027
- "<%= config.bin %> <%= command.id %> --config ./baseline.json",
1028
- "<%= config.bin %> <%= command.id %> --config ./baseline.json --target group/project",
1029
- "<%= config.bin %> <%= command.id %> --config ./baseline.json --fail-on-drift",
1030
- "<%= config.bin %> <%= command.id %> --config ./baseline.json --json | jq .summary"
1049
+ "<%= config.bin %> <%= command.id %> --project group/project --sha 9a1b2c3",
1050
+ "<%= config.bin %> <%= command.id %> --project group/project --sha main --json"
1031
1051
  ],
1032
1052
  "flags": {
1033
1053
  "json": {
@@ -1065,53 +1085,33 @@
1065
1085
  "multiple": false,
1066
1086
  "type": "option"
1067
1087
  },
1068
- "config": {
1069
- "char": "c",
1070
- "name": "config",
1088
+ "project": {
1089
+ "char": "p",
1090
+ "env": "GITLAB_PROJECT",
1091
+ "name": "project",
1071
1092
  "required": true,
1072
- "summary": "Path to the baseline configuration file.",
1093
+ "summary": "Project id, or its full path such as group/subgroup/project.",
1073
1094
  "hasDynamicHelp": false,
1074
1095
  "multiple": false,
1075
1096
  "type": "option"
1076
1097
  },
1077
- "target": {
1078
- "description": "Narrows a run without editing the config, for the loop of fixing one project and checking it again. Naming a project the config does not target is an error rather than a silent no-op.",
1079
- "name": "target",
1080
- "summary": "Limit the run to this project path. Repeatable.",
1081
- "hasDynamicHelp": false,
1082
- "multiple": true,
1083
- "type": "option"
1084
- },
1085
- "concurrency": {
1086
- "description": "Small by default. The client already retries a rate-limited request with a capped Retry-After, so raising this trades a shared instance responsiveness for very little wall-clock time.",
1087
- "name": "concurrency",
1088
- "summary": "How many targets to work on at once.",
1089
- "default": 4,
1098
+ "sha": {
1099
+ "name": "sha",
1100
+ "required": true,
1101
+ "summary": "Commit SHA, or the name of a branch or tag.",
1090
1102
  "hasDynamicHelp": false,
1091
1103
  "multiple": false,
1092
1104
  "type": "option"
1093
- },
1094
- "fail-fast": {
1095
- "name": "fail-fast",
1096
- "summary": "Stop at the first target that fails instead of continuing.",
1097
- "allowNo": false,
1098
- "type": "boolean"
1099
- },
1100
- "fail-on-drift": {
1101
- "name": "fail-on-drift",
1102
- "summary": "Exit 1 when any target differs from the baseline.",
1103
- "allowNo": false,
1104
- "type": "boolean"
1105
1105
  }
1106
1106
  },
1107
1107
  "hasDynamicHelp": false,
1108
1108
  "hiddenAliases": [],
1109
- "id": "gitlab:config:plan",
1109
+ "id": "gitlab:commit:view",
1110
1110
  "pluginAlias": "@simplysf/simply-gitlab",
1111
1111
  "pluginName": "@simplysf/simply-gitlab",
1112
1112
  "pluginType": "core",
1113
1113
  "strict": true,
1114
- "summary": "Report how projects differ from a baseline config.",
1114
+ "summary": "Show one commit.",
1115
1115
  "enableJsonFlag": true,
1116
1116
  "isWrite": false,
1117
1117
  "isESM": true,
@@ -1119,17 +1119,17 @@
1119
1119
  "lib",
1120
1120
  "commands",
1121
1121
  "gitlab",
1122
- "config",
1123
- "plan.js"
1122
+ "commit",
1123
+ "view.js"
1124
1124
  ],
1125
1125
  "aliasPermutations": [],
1126
1126
  "permutations": [
1127
- "gitlab:config:plan",
1128
- "config:gitlab:plan",
1129
- "config:plan:gitlab",
1130
- "gitlab:plan:config",
1131
- "plan:gitlab:config",
1132
- "plan:config:gitlab"
1127
+ "gitlab:commit:view",
1128
+ "commit:gitlab:view",
1129
+ "commit:view:gitlab",
1130
+ "gitlab:view:commit",
1131
+ "view:gitlab:commit",
1132
+ "view:commit:gitlab"
1133
1133
  ]
1134
1134
  },
1135
1135
  "gitlab:file:create": {
@@ -3054,5 +3054,5 @@
3054
3054
  ]
3055
3055
  }
3056
3056
  },
3057
- "version": "0.4.0"
3057
+ "version": "0.5.0"
3058
3058
  }