devvami 1.1.1 → 1.2.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.
@@ -273,6 +273,29 @@
273
273
  "upgrade.js"
274
274
  ]
275
275
  },
276
+ "welcome": {
277
+ "aliases": [],
278
+ "args": {},
279
+ "description": "Show the dvmi mission dashboard with animated intro",
280
+ "examples": [
281
+ "<%= config.bin %> welcome"
282
+ ],
283
+ "flags": {},
284
+ "hasDynamicHelp": false,
285
+ "hiddenAliases": [],
286
+ "id": "welcome",
287
+ "pluginAlias": "devvami",
288
+ "pluginName": "devvami",
289
+ "pluginType": "core",
290
+ "strict": true,
291
+ "enableJsonFlag": false,
292
+ "isESM": true,
293
+ "relativePath": [
294
+ "src",
295
+ "commands",
296
+ "welcome.js"
297
+ ]
298
+ },
276
299
  "whoami": {
277
300
  "aliases": [],
278
301
  "args": {},
@@ -703,14 +726,19 @@
703
726
  "search.js"
704
727
  ]
705
728
  },
706
- "pr:create": {
729
+ "pipeline:logs": {
707
730
  "aliases": [],
708
- "args": {},
709
- "description": "Apri Pull Request precompilata con template, label e reviewer",
731
+ "args": {
732
+ "run-id": {
733
+ "description": "ID del workflow run",
734
+ "name": "run-id",
735
+ "required": true
736
+ }
737
+ },
738
+ "description": "Log di un workflow run specifico",
710
739
  "examples": [
711
- "<%= config.bin %> pr create",
712
- "<%= config.bin %> pr create --draft",
713
- "<%= config.bin %> pr create --title \"My PR\" --dry-run"
740
+ "<%= config.bin %> pipeline logs 12345",
741
+ "<%= config.bin %> pipeline logs 12345 --job test"
714
742
  ],
715
743
  "flags": {
716
744
  "json": {
@@ -720,29 +748,17 @@
720
748
  "allowNo": false,
721
749
  "type": "boolean"
722
750
  },
723
- "title": {
724
- "description": "Titolo PR (default: auto-generated)",
725
- "name": "title",
751
+ "job": {
752
+ "description": "Filtra per job name",
753
+ "name": "job",
726
754
  "hasDynamicHelp": false,
727
755
  "multiple": false,
728
756
  "type": "option"
729
- },
730
- "draft": {
731
- "description": "Crea come draft",
732
- "name": "draft",
733
- "allowNo": false,
734
- "type": "boolean"
735
- },
736
- "dry-run": {
737
- "description": "Preview senza eseguire",
738
- "name": "dry-run",
739
- "allowNo": false,
740
- "type": "boolean"
741
757
  }
742
758
  },
743
759
  "hasDynamicHelp": false,
744
760
  "hiddenAliases": [],
745
- "id": "pr:create",
761
+ "id": "pipeline:logs",
746
762
  "pluginAlias": "devvami",
747
763
  "pluginName": "devvami",
748
764
  "pluginType": "core",
@@ -752,24 +768,18 @@
752
768
  "relativePath": [
753
769
  "src",
754
770
  "commands",
755
- "pr",
756
- "create.js"
771
+ "pipeline",
772
+ "logs.js"
757
773
  ]
758
774
  },
759
- "pr:detail": {
775
+ "pipeline:rerun": {
760
776
  "aliases": [],
761
- "args": {
762
- "number": {
763
- "description": "Numero della PR",
764
- "name": "number",
765
- "required": true
766
- }
767
- },
768
- "description": "Dettaglio PR con commenti QA e checklist degli step",
777
+ "args": {},
778
+ "description": "Rilancia l'ultimo workflow fallito",
769
779
  "examples": [
770
- "<%= config.bin %> pr detail 42",
771
- "<%= config.bin %> pr detail 42 --repo devvami/my-api",
772
- "<%= config.bin %> pr detail 42 --json"
780
+ "<%= config.bin %> pipeline rerun",
781
+ "<%= config.bin %> pipeline rerun --failed-only",
782
+ "<%= config.bin %> pipeline rerun --run-id 12345"
773
783
  ],
774
784
  "flags": {
775
785
  "json": {
@@ -779,17 +789,23 @@
779
789
  "allowNo": false,
780
790
  "type": "boolean"
781
791
  },
782
- "repo": {
783
- "description": "Repository nel formato owner/repo (default: rilevato da git remote)",
784
- "name": "repo",
792
+ "run-id": {
793
+ "description": "ID specifico del run",
794
+ "name": "run-id",
785
795
  "hasDynamicHelp": false,
786
796
  "multiple": false,
787
797
  "type": "option"
798
+ },
799
+ "failed-only": {
800
+ "description": "Rilancia solo i job falliti",
801
+ "name": "failed-only",
802
+ "allowNo": false,
803
+ "type": "boolean"
788
804
  }
789
805
  },
790
806
  "hasDynamicHelp": false,
791
807
  "hiddenAliases": [],
792
- "id": "pr:detail",
808
+ "id": "pipeline:rerun",
793
809
  "pluginAlias": "devvami",
794
810
  "pluginName": "devvami",
795
811
  "pluginType": "core",
@@ -799,17 +815,18 @@
799
815
  "relativePath": [
800
816
  "src",
801
817
  "commands",
802
- "pr",
803
- "detail.js"
818
+ "pipeline",
819
+ "rerun.js"
804
820
  ]
805
821
  },
806
- "pr:review": {
822
+ "pipeline:status": {
807
823
  "aliases": [],
808
824
  "args": {},
809
- "description": "Lista PR assegnate a te per la code review",
825
+ "description": "Stato GitHub Actions per il repo corrente",
810
826
  "examples": [
811
- "<%= config.bin %> pr review",
812
- "<%= config.bin %> pr review --json"
827
+ "<%= config.bin %> pipeline status",
828
+ "<%= config.bin %> pipeline status --branch main",
829
+ "<%= config.bin %> pipeline status --limit 20 --json"
813
830
  ],
814
831
  "flags": {
815
832
  "json": {
@@ -818,11 +835,26 @@
818
835
  "name": "json",
819
836
  "allowNo": false,
820
837
  "type": "boolean"
838
+ },
839
+ "branch": {
840
+ "description": "Filtra per branch",
841
+ "name": "branch",
842
+ "hasDynamicHelp": false,
843
+ "multiple": false,
844
+ "type": "option"
845
+ },
846
+ "limit": {
847
+ "description": "Numero di run da mostrare",
848
+ "name": "limit",
849
+ "default": 10,
850
+ "hasDynamicHelp": false,
851
+ "multiple": false,
852
+ "type": "option"
821
853
  }
822
854
  },
823
855
  "hasDynamicHelp": false,
824
856
  "hiddenAliases": [],
825
- "id": "pr:review",
857
+ "id": "pipeline:status",
826
858
  "pluginAlias": "devvami",
827
859
  "pluginName": "devvami",
828
860
  "pluginType": "core",
@@ -832,18 +864,18 @@
832
864
  "relativePath": [
833
865
  "src",
834
866
  "commands",
835
- "pr",
836
- "review.js"
867
+ "pipeline",
868
+ "status.js"
837
869
  ]
838
870
  },
839
- "pr:status": {
871
+ "pr:create": {
840
872
  "aliases": [],
841
873
  "args": {},
842
- "description": "Stato delle tue PR aperte (come autore e come reviewer)",
874
+ "description": "Apri Pull Request precompilata con template, label e reviewer",
843
875
  "examples": [
844
- "<%= config.bin %> pr status",
845
- "<%= config.bin %> pr status --author",
846
- "<%= config.bin %> pr status --json"
876
+ "<%= config.bin %> pr create",
877
+ "<%= config.bin %> pr create --draft",
878
+ "<%= config.bin %> pr create --title \"My PR\" --dry-run"
847
879
  ],
848
880
  "flags": {
849
881
  "json": {
@@ -853,22 +885,29 @@
853
885
  "allowNo": false,
854
886
  "type": "boolean"
855
887
  },
856
- "author": {
857
- "description": "Solo PR dove sei autore",
858
- "name": "author",
888
+ "title": {
889
+ "description": "Titolo PR (default: auto-generated)",
890
+ "name": "title",
891
+ "hasDynamicHelp": false,
892
+ "multiple": false,
893
+ "type": "option"
894
+ },
895
+ "draft": {
896
+ "description": "Crea come draft",
897
+ "name": "draft",
859
898
  "allowNo": false,
860
899
  "type": "boolean"
861
900
  },
862
- "reviewer": {
863
- "description": "Solo PR dove sei reviewer",
864
- "name": "reviewer",
901
+ "dry-run": {
902
+ "description": "Preview senza eseguire",
903
+ "name": "dry-run",
865
904
  "allowNo": false,
866
905
  "type": "boolean"
867
906
  }
868
907
  },
869
908
  "hasDynamicHelp": false,
870
909
  "hiddenAliases": [],
871
- "id": "pr:status",
910
+ "id": "pr:create",
872
911
  "pluginAlias": "devvami",
873
912
  "pluginName": "devvami",
874
913
  "pluginType": "core",
@@ -879,22 +918,23 @@
879
918
  "src",
880
919
  "commands",
881
920
  "pr",
882
- "status.js"
921
+ "create.js"
883
922
  ]
884
923
  },
885
- "pipeline:logs": {
924
+ "pr:detail": {
886
925
  "aliases": [],
887
926
  "args": {
888
- "run-id": {
889
- "description": "ID del workflow run",
890
- "name": "run-id",
927
+ "number": {
928
+ "description": "Numero della PR",
929
+ "name": "number",
891
930
  "required": true
892
931
  }
893
932
  },
894
- "description": "Log di un workflow run specifico",
933
+ "description": "Dettaglio PR con commenti QA e checklist degli step",
895
934
  "examples": [
896
- "<%= config.bin %> pipeline logs 12345",
897
- "<%= config.bin %> pipeline logs 12345 --job test"
935
+ "<%= config.bin %> pr detail 42",
936
+ "<%= config.bin %> pr detail 42 --repo devvami/my-api",
937
+ "<%= config.bin %> pr detail 42 --json"
898
938
  ],
899
939
  "flags": {
900
940
  "json": {
@@ -904,9 +944,9 @@
904
944
  "allowNo": false,
905
945
  "type": "boolean"
906
946
  },
907
- "job": {
908
- "description": "Filtra per job name",
909
- "name": "job",
947
+ "repo": {
948
+ "description": "Repository nel formato owner/repo (default: rilevato da git remote)",
949
+ "name": "repo",
910
950
  "hasDynamicHelp": false,
911
951
  "multiple": false,
912
952
  "type": "option"
@@ -914,7 +954,7 @@
914
954
  },
915
955
  "hasDynamicHelp": false,
916
956
  "hiddenAliases": [],
917
- "id": "pipeline:logs",
957
+ "id": "pr:detail",
918
958
  "pluginAlias": "devvami",
919
959
  "pluginName": "devvami",
920
960
  "pluginType": "core",
@@ -924,18 +964,17 @@
924
964
  "relativePath": [
925
965
  "src",
926
966
  "commands",
927
- "pipeline",
928
- "logs.js"
967
+ "pr",
968
+ "detail.js"
929
969
  ]
930
970
  },
931
- "pipeline:rerun": {
971
+ "pr:review": {
932
972
  "aliases": [],
933
973
  "args": {},
934
- "description": "Rilancia l'ultimo workflow fallito",
974
+ "description": "Lista PR assegnate a te per la code review",
935
975
  "examples": [
936
- "<%= config.bin %> pipeline rerun",
937
- "<%= config.bin %> pipeline rerun --failed-only",
938
- "<%= config.bin %> pipeline rerun --run-id 12345"
976
+ "<%= config.bin %> pr review",
977
+ "<%= config.bin %> pr review --json"
939
978
  ],
940
979
  "flags": {
941
980
  "json": {
@@ -944,24 +983,11 @@
944
983
  "name": "json",
945
984
  "allowNo": false,
946
985
  "type": "boolean"
947
- },
948
- "run-id": {
949
- "description": "ID specifico del run",
950
- "name": "run-id",
951
- "hasDynamicHelp": false,
952
- "multiple": false,
953
- "type": "option"
954
- },
955
- "failed-only": {
956
- "description": "Rilancia solo i job falliti",
957
- "name": "failed-only",
958
- "allowNo": false,
959
- "type": "boolean"
960
986
  }
961
987
  },
962
988
  "hasDynamicHelp": false,
963
989
  "hiddenAliases": [],
964
- "id": "pipeline:rerun",
990
+ "id": "pr:review",
965
991
  "pluginAlias": "devvami",
966
992
  "pluginName": "devvami",
967
993
  "pluginType": "core",
@@ -971,18 +997,18 @@
971
997
  "relativePath": [
972
998
  "src",
973
999
  "commands",
974
- "pipeline",
975
- "rerun.js"
1000
+ "pr",
1001
+ "review.js"
976
1002
  ]
977
1003
  },
978
- "pipeline:status": {
1004
+ "pr:status": {
979
1005
  "aliases": [],
980
1006
  "args": {},
981
- "description": "Stato GitHub Actions per il repo corrente",
1007
+ "description": "Stato delle tue PR aperte (come autore e come reviewer)",
982
1008
  "examples": [
983
- "<%= config.bin %> pipeline status",
984
- "<%= config.bin %> pipeline status --branch main",
985
- "<%= config.bin %> pipeline status --limit 20 --json"
1009
+ "<%= config.bin %> pr status",
1010
+ "<%= config.bin %> pr status --author",
1011
+ "<%= config.bin %> pr status --json"
986
1012
  ],
987
1013
  "flags": {
988
1014
  "json": {
@@ -992,25 +1018,22 @@
992
1018
  "allowNo": false,
993
1019
  "type": "boolean"
994
1020
  },
995
- "branch": {
996
- "description": "Filtra per branch",
997
- "name": "branch",
998
- "hasDynamicHelp": false,
999
- "multiple": false,
1000
- "type": "option"
1021
+ "author": {
1022
+ "description": "Solo PR dove sei autore",
1023
+ "name": "author",
1024
+ "allowNo": false,
1025
+ "type": "boolean"
1001
1026
  },
1002
- "limit": {
1003
- "description": "Numero di run da mostrare",
1004
- "name": "limit",
1005
- "default": 10,
1006
- "hasDynamicHelp": false,
1007
- "multiple": false,
1008
- "type": "option"
1027
+ "reviewer": {
1028
+ "description": "Solo PR dove sei reviewer",
1029
+ "name": "reviewer",
1030
+ "allowNo": false,
1031
+ "type": "boolean"
1009
1032
  }
1010
1033
  },
1011
1034
  "hasDynamicHelp": false,
1012
1035
  "hiddenAliases": [],
1013
- "id": "pipeline:status",
1036
+ "id": "pr:status",
1014
1037
  "pluginAlias": "devvami",
1015
1038
  "pluginName": "devvami",
1016
1039
  "pluginType": "core",
@@ -1020,7 +1043,7 @@
1020
1043
  "relativePath": [
1021
1044
  "src",
1022
1045
  "commands",
1023
- "pipeline",
1046
+ "pr",
1024
1047
  "status.js"
1025
1048
  ]
1026
1049
  },
@@ -1346,6 +1369,46 @@
1346
1369
  "list.js"
1347
1370
  ]
1348
1371
  },
1372
+ "security:setup": {
1373
+ "aliases": [],
1374
+ "args": {},
1375
+ "description": "Interactive wizard to install and configure credential protection tools (aws-vault, pass, GPG, Git Credential Manager, macOS Keychain)",
1376
+ "examples": [
1377
+ "<%= config.bin %> security setup",
1378
+ "<%= config.bin %> security setup --json"
1379
+ ],
1380
+ "flags": {
1381
+ "json": {
1382
+ "description": "Format output as json.",
1383
+ "helpGroup": "GLOBAL",
1384
+ "name": "json",
1385
+ "allowNo": false,
1386
+ "type": "boolean"
1387
+ },
1388
+ "help": {
1389
+ "char": "h",
1390
+ "description": "Show CLI help.",
1391
+ "name": "help",
1392
+ "allowNo": false,
1393
+ "type": "boolean"
1394
+ }
1395
+ },
1396
+ "hasDynamicHelp": false,
1397
+ "hiddenAliases": [],
1398
+ "id": "security:setup",
1399
+ "pluginAlias": "devvami",
1400
+ "pluginName": "devvami",
1401
+ "pluginType": "core",
1402
+ "strict": true,
1403
+ "enableJsonFlag": true,
1404
+ "isESM": true,
1405
+ "relativePath": [
1406
+ "src",
1407
+ "commands",
1408
+ "security",
1409
+ "setup.js"
1410
+ ]
1411
+ },
1349
1412
  "tasks:assigned": {
1350
1413
  "aliases": [],
1351
1414
  "args": {},
@@ -1498,5 +1561,5 @@
1498
1561
  ]
1499
1562
  }
1500
1563
  },
1501
- "version": "1.1.1"
1564
+ "version": "1.2.0"
1502
1565
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "devvami",
3
3
  "description": "DevEx CLI for developers and teams — manage repos, PRs, pipelines, tasks, and costs from the terminal",
4
- "version": "1.1.1",
4
+ "version": "1.2.0",
5
5
  "author": "",
6
6
  "type": "module",
7
7
  "bin": {
@@ -2,7 +2,7 @@ import { Command, Flags } from '@oclif/core'
2
2
  import chalk from 'chalk'
3
3
  import ora from 'ora'
4
4
  import { confirm, input, select } from '@inquirer/prompts'
5
- import { printBanner } from '../utils/banner.js'
5
+ import { printWelcomeScreen } from '../utils/welcome.js'
6
6
  import { typewriterLine } from '../utils/typewriter.js'
7
7
  import { detectPlatform } from '../services/platform.js'
8
8
  import { exec, which } from '../services/shell.js'
@@ -32,7 +32,7 @@ export default class Init extends Command {
32
32
  const isDryRun = flags['dry-run']
33
33
  const isJson = flags.json
34
34
 
35
- if (!isJson) await printBanner()
35
+ if (!isJson) await printWelcomeScreen(this.config.version)
36
36
 
37
37
  const platform = await detectPlatform()
38
38
  const steps = []
@@ -80,6 +80,8 @@ export default class Init extends Command {
80
80
  let config = await loadConfig()
81
81
 
82
82
  if (!configExists() && !isDryRun && !isJson) {
83
+ // Stop the spinner before interactive prompts to avoid TTY contention on macOS
84
+ configSpinner?.stop()
83
85
  const useOrg = await confirm({ message: 'Do you use a GitHub organization? (y/n)', default: true })
84
86
  let org = ''
85
87
  if (useOrg) {
@@ -1,7 +1,7 @@
1
1
  import { Command, Args, Flags } from '@oclif/core'
2
2
  import ora from 'ora'
3
3
  import chalk from 'chalk'
4
- import { select } from '@inquirer/prompts'
4
+ import { select, confirm } from '@inquirer/prompts'
5
5
  import { join } from 'node:path'
6
6
  import { readdir } from 'node:fs/promises'
7
7
  import { resolveLocalPrompt, invokeTool, SUPPORTED_TOOLS } from '../../services/prompts.js'
@@ -176,6 +176,24 @@ export default class PromptsRun extends Command {
176
176
  this.log(chalk.bold(`\nRunning: ${chalk.hex('#FF9A5C')(prompt.title)}`))
177
177
  this.log(chalk.dim(` Tool: ${toolName}`) + '\n')
178
178
 
179
+ // Security: show a preview of the prompt content and ask for confirmation.
180
+ // This protects against prompt injection from tampered local files (originally
181
+ // downloaded from remote repositories). Skipped in CI/non-interactive environments.
182
+ if (!process.env.CI && process.stdin.isTTY) {
183
+ const preview = prompt.body.length > 500
184
+ ? prompt.body.slice(0, 500) + chalk.dim('\n…[truncated]')
185
+ : prompt.body
186
+ this.log(chalk.yellow('Prompt preview:'))
187
+ this.log(chalk.dim('─'.repeat(50)))
188
+ this.log(chalk.dim(preview))
189
+ this.log(chalk.dim('─'.repeat(50)) + '\n')
190
+ const ok = await confirm({ message: `Run this prompt with ${toolName}?`, default: true })
191
+ if (!ok) {
192
+ this.log(chalk.dim('Aborted.'))
193
+ return
194
+ }
195
+ }
196
+
179
197
  // Invoke tool
180
198
  try {
181
199
  await invokeTool(toolName, prompt.body)