pull-request-split-advisor 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +52 -0
- package/README.md +168 -0
- package/dist/ai/config-wizard.js +282 -0
- package/dist/ai/enricher.js +290 -0
- package/dist/ai/prompts.js +231 -0
- package/dist/ai/provider.js +265 -0
- package/dist/cli.js +442 -0
- package/dist/config/config.js +315 -0
- package/dist/config/default-config.js +223 -0
- package/dist/core/blocks.js +145 -0
- package/dist/core/commit-planner.js +273 -0
- package/dist/core/dependency.js +284 -0
- package/dist/core/file-stats.js +341 -0
- package/dist/core/history.js +72 -0
- package/dist/core/planner.js +25 -0
- package/dist/core/scoring.js +166 -0
- package/dist/core/strategy.js +486 -0
- package/dist/git/branch-naming.js +120 -0
- package/dist/git/executor.js +378 -0
- package/dist/git/git.js +239 -0
- package/dist/output/report-styles.generated.js +10 -0
- package/dist/output/report.js +726 -0
- package/dist/output/ui.js +417 -0
- package/dist/shared/constants.js +59 -0
- package/dist/shared/types.js +7 -0
- package/dist/shared/utils.js +73 -0
- package/node_modules/@colors/colors/LICENSE +26 -0
- package/node_modules/@colors/colors/README.md +219 -0
- package/node_modules/@colors/colors/examples/normal-usage.js +83 -0
- package/node_modules/@colors/colors/examples/safe-string.js +80 -0
- package/node_modules/@colors/colors/index.d.ts +136 -0
- package/node_modules/@colors/colors/lib/colors.js +211 -0
- package/node_modules/@colors/colors/lib/custom/trap.js +46 -0
- package/node_modules/@colors/colors/lib/custom/zalgo.js +110 -0
- package/node_modules/@colors/colors/lib/extendStringPrototype.js +110 -0
- package/node_modules/@colors/colors/lib/index.js +13 -0
- package/node_modules/@colors/colors/lib/maps/america.js +10 -0
- package/node_modules/@colors/colors/lib/maps/rainbow.js +12 -0
- package/node_modules/@colors/colors/lib/maps/random.js +11 -0
- package/node_modules/@colors/colors/lib/maps/zebra.js +5 -0
- package/node_modules/@colors/colors/lib/styles.js +95 -0
- package/node_modules/@colors/colors/lib/system/has-flag.js +35 -0
- package/node_modules/@colors/colors/lib/system/supports-colors.js +151 -0
- package/node_modules/@colors/colors/package.json +45 -0
- package/node_modules/@colors/colors/safe.d.ts +48 -0
- package/node_modules/@colors/colors/safe.js +10 -0
- package/node_modules/@colors/colors/themes/generic-logging.js +12 -0
- package/node_modules/ansi-align/LICENSE +13 -0
- package/node_modules/ansi-align/README.md +80 -0
- package/node_modules/ansi-align/index.js +61 -0
- package/node_modules/ansi-align/node_modules/ansi-regex/index.d.ts +37 -0
- package/node_modules/ansi-align/node_modules/ansi-regex/index.js +10 -0
- package/node_modules/ansi-align/node_modules/ansi-regex/license +9 -0
- package/node_modules/ansi-align/node_modules/ansi-regex/package.json +55 -0
- package/node_modules/ansi-align/node_modules/ansi-regex/readme.md +78 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/README.md +73 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/es2015/index.js +6 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/es2015/text.js +6 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/index.d.ts +23 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/index.js +6 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/package.json +50 -0
- package/node_modules/ansi-align/node_modules/emoji-regex/text.js +6 -0
- package/node_modules/ansi-align/node_modules/string-width/index.d.ts +29 -0
- package/node_modules/ansi-align/node_modules/string-width/index.js +47 -0
- package/node_modules/ansi-align/node_modules/string-width/license +9 -0
- package/node_modules/ansi-align/node_modules/string-width/package.json +56 -0
- package/node_modules/ansi-align/node_modules/string-width/readme.md +50 -0
- package/node_modules/ansi-align/node_modules/strip-ansi/index.d.ts +17 -0
- package/node_modules/ansi-align/node_modules/strip-ansi/index.js +4 -0
- package/node_modules/ansi-align/node_modules/strip-ansi/license +9 -0
- package/node_modules/ansi-align/node_modules/strip-ansi/package.json +54 -0
- package/node_modules/ansi-align/node_modules/strip-ansi/readme.md +46 -0
- package/node_modules/ansi-align/package.json +43 -0
- package/node_modules/ansi-regex/index.d.ts +33 -0
- package/node_modules/ansi-regex/index.js +14 -0
- package/node_modules/ansi-regex/license +9 -0
- package/node_modules/ansi-regex/package.json +61 -0
- package/node_modules/ansi-regex/readme.md +66 -0
- package/node_modules/ansi-styles/index.d.ts +236 -0
- package/node_modules/ansi-styles/index.js +223 -0
- package/node_modules/ansi-styles/license +9 -0
- package/node_modules/ansi-styles/package.json +54 -0
- package/node_modules/ansi-styles/readme.md +173 -0
- package/node_modules/boxen/index.d.ts +267 -0
- package/node_modules/boxen/index.js +376 -0
- package/node_modules/boxen/license +9 -0
- package/node_modules/boxen/package.json +69 -0
- package/node_modules/boxen/readme.md +300 -0
- package/node_modules/camelcase/index.d.ts +102 -0
- package/node_modules/camelcase/index.js +110 -0
- package/node_modules/camelcase/license +9 -0
- package/node_modules/camelcase/package.json +47 -0
- package/node_modules/camelcase/readme.md +135 -0
- package/node_modules/chalk/license +9 -0
- package/node_modules/chalk/package.json +83 -0
- package/node_modules/chalk/readme.md +297 -0
- package/node_modules/chalk/source/index.d.ts +325 -0
- package/node_modules/chalk/source/index.js +225 -0
- package/node_modules/chalk/source/utilities.js +33 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/node_modules/cli-boxes/boxes.json +82 -0
- package/node_modules/cli-boxes/index.d.ts +127 -0
- package/node_modules/cli-boxes/index.js +6 -0
- package/node_modules/cli-boxes/license +9 -0
- package/node_modules/cli-boxes/package.json +42 -0
- package/node_modules/cli-boxes/readme.md +115 -0
- package/node_modules/cli-table3/LICENSE +21 -0
- package/node_modules/cli-table3/README.md +236 -0
- package/node_modules/cli-table3/index.d.ts +96 -0
- package/node_modules/cli-table3/index.js +1 -0
- package/node_modules/cli-table3/node_modules/ansi-regex/index.d.ts +37 -0
- package/node_modules/cli-table3/node_modules/ansi-regex/index.js +10 -0
- package/node_modules/cli-table3/node_modules/ansi-regex/license +9 -0
- package/node_modules/cli-table3/node_modules/ansi-regex/package.json +55 -0
- package/node_modules/cli-table3/node_modules/ansi-regex/readme.md +78 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/README.md +73 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/es2015/index.js +6 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/es2015/text.js +6 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/index.d.ts +23 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/index.js +6 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/package.json +50 -0
- package/node_modules/cli-table3/node_modules/emoji-regex/text.js +6 -0
- package/node_modules/cli-table3/node_modules/string-width/index.d.ts +29 -0
- package/node_modules/cli-table3/node_modules/string-width/index.js +47 -0
- package/node_modules/cli-table3/node_modules/string-width/license +9 -0
- package/node_modules/cli-table3/node_modules/string-width/package.json +56 -0
- package/node_modules/cli-table3/node_modules/string-width/readme.md +50 -0
- package/node_modules/cli-table3/node_modules/strip-ansi/index.d.ts +17 -0
- package/node_modules/cli-table3/node_modules/strip-ansi/index.js +4 -0
- package/node_modules/cli-table3/node_modules/strip-ansi/license +9 -0
- package/node_modules/cli-table3/node_modules/strip-ansi/package.json +54 -0
- package/node_modules/cli-table3/node_modules/strip-ansi/readme.md +46 -0
- package/node_modules/cli-table3/package.json +100 -0
- package/node_modules/cli-table3/src/cell.js +409 -0
- package/node_modules/cli-table3/src/debug.js +28 -0
- package/node_modules/cli-table3/src/layout-manager.js +254 -0
- package/node_modules/cli-table3/src/table.js +106 -0
- package/node_modules/cli-table3/src/utils.js +344 -0
- package/node_modules/commander/LICENSE +22 -0
- package/node_modules/commander/Readme.md +1157 -0
- package/node_modules/commander/esm.mjs +16 -0
- package/node_modules/commander/index.js +24 -0
- package/node_modules/commander/lib/argument.js +149 -0
- package/node_modules/commander/lib/command.js +2509 -0
- package/node_modules/commander/lib/error.js +39 -0
- package/node_modules/commander/lib/help.js +520 -0
- package/node_modules/commander/lib/option.js +330 -0
- package/node_modules/commander/lib/suggestSimilar.js +101 -0
- package/node_modules/commander/package-support.json +16 -0
- package/node_modules/commander/package.json +84 -0
- package/node_modules/commander/typings/esm.d.mts +3 -0
- package/node_modules/commander/typings/index.d.ts +969 -0
- package/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
- package/node_modules/emoji-regex/README.md +107 -0
- package/node_modules/emoji-regex/index.d.ts +3 -0
- package/node_modules/emoji-regex/index.js +4 -0
- package/node_modules/emoji-regex/index.mjs +4 -0
- package/node_modules/emoji-regex/package.json +45 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +18 -0
- package/node_modules/get-east-asian-width/lookup.js +135 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
- package/node_modules/is-fullwidth-code-point/index.js +50 -0
- package/node_modules/is-fullwidth-code-point/license +9 -0
- package/node_modules/is-fullwidth-code-point/package.json +42 -0
- package/node_modules/is-fullwidth-code-point/readme.md +39 -0
- package/node_modules/isbinaryfile/LICENSE.txt +22 -0
- package/node_modules/isbinaryfile/README.md +70 -0
- package/node_modules/isbinaryfile/lib/index.d.ts +3 -0
- package/node_modules/isbinaryfile/lib/index.js +256 -0
- package/node_modules/isbinaryfile/package.json +64 -0
- package/node_modules/string-width/index.d.ts +39 -0
- package/node_modules/string-width/index.js +82 -0
- package/node_modules/string-width/license +9 -0
- package/node_modules/string-width/package.json +64 -0
- package/node_modules/string-width/readme.md +66 -0
- package/node_modules/strip-ansi/index.d.ts +15 -0
- package/node_modules/strip-ansi/index.js +19 -0
- package/node_modules/strip-ansi/license +9 -0
- package/node_modules/strip-ansi/package.json +59 -0
- package/node_modules/strip-ansi/readme.md +37 -0
- package/node_modules/type-fest/index.d.ts +178 -0
- package/node_modules/type-fest/license-cc0 +121 -0
- package/node_modules/type-fest/license-mit +9 -0
- package/node_modules/type-fest/package.json +91 -0
- package/node_modules/type-fest/readme.md +1060 -0
- package/node_modules/type-fest/source/all-union-fields.d.ts +88 -0
- package/node_modules/type-fest/source/and.d.ts +25 -0
- package/node_modules/type-fest/source/array-indices.d.ts +23 -0
- package/node_modules/type-fest/source/array-slice.d.ts +109 -0
- package/node_modules/type-fest/source/array-splice.d.ts +99 -0
- package/node_modules/type-fest/source/array-tail.d.ts +76 -0
- package/node_modules/type-fest/source/array-values.d.ts +22 -0
- package/node_modules/type-fest/source/arrayable.d.ts +29 -0
- package/node_modules/type-fest/source/async-return-type.d.ts +23 -0
- package/node_modules/type-fest/source/asyncify.d.ts +32 -0
- package/node_modules/type-fest/source/basic.d.ts +68 -0
- package/node_modules/type-fest/source/camel-case.d.ts +89 -0
- package/node_modules/type-fest/source/camel-cased-properties-deep.d.ts +97 -0
- package/node_modules/type-fest/source/camel-cased-properties.d.ts +43 -0
- package/node_modules/type-fest/source/conditional-except.d.ts +45 -0
- package/node_modules/type-fest/source/conditional-keys.d.ts +47 -0
- package/node_modules/type-fest/source/conditional-pick-deep.d.ts +118 -0
- package/node_modules/type-fest/source/conditional-pick.d.ts +44 -0
- package/node_modules/type-fest/source/conditional-simplify.d.ts +32 -0
- package/node_modules/type-fest/source/delimiter-case.d.ts +78 -0
- package/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts +106 -0
- package/node_modules/type-fest/source/delimiter-cased-properties.d.ts +46 -0
- package/node_modules/type-fest/source/distributed-omit.d.ts +89 -0
- package/node_modules/type-fest/source/distributed-pick.d.ts +85 -0
- package/node_modules/type-fest/source/empty-object.d.ts +46 -0
- package/node_modules/type-fest/source/enforce-optional.d.ts +47 -0
- package/node_modules/type-fest/source/entries.d.ts +62 -0
- package/node_modules/type-fest/source/entry.d.ts +65 -0
- package/node_modules/type-fest/source/exact.d.ts +68 -0
- package/node_modules/type-fest/source/except.d.ts +108 -0
- package/node_modules/type-fest/source/find-global-type.d.ts +64 -0
- package/node_modules/type-fest/source/fixed-length-array.d.ts +43 -0
- package/node_modules/type-fest/source/get.d.ts +219 -0
- package/node_modules/type-fest/source/global-this.d.ts +21 -0
- package/node_modules/type-fest/source/greater-than-or-equal.d.ts +22 -0
- package/node_modules/type-fest/source/greater-than.d.ts +56 -0
- package/node_modules/type-fest/source/has-optional-keys.d.ts +21 -0
- package/node_modules/type-fest/source/has-readonly-keys.d.ts +21 -0
- package/node_modules/type-fest/source/has-required-keys.d.ts +59 -0
- package/node_modules/type-fest/source/has-writable-keys.d.ts +21 -0
- package/node_modules/type-fest/source/if-any.d.ts +24 -0
- package/node_modules/type-fest/source/if-empty-object.d.ts +26 -0
- package/node_modules/type-fest/source/if-never.d.ts +24 -0
- package/node_modules/type-fest/source/if-null.d.ts +24 -0
- package/node_modules/type-fest/source/if-unknown.d.ts +24 -0
- package/node_modules/type-fest/source/includes.d.ts +22 -0
- package/node_modules/type-fest/source/int-closed-range.d.ts +35 -0
- package/node_modules/type-fest/source/int-range.d.ts +55 -0
- package/node_modules/type-fest/source/internal/array.d.ts +126 -0
- package/node_modules/type-fest/source/internal/characters.d.ts +67 -0
- package/node_modules/type-fest/source/internal/index.d.ts +8 -0
- package/node_modules/type-fest/source/internal/keys.d.ts +97 -0
- package/node_modules/type-fest/source/internal/numeric.d.ts +118 -0
- package/node_modules/type-fest/source/internal/object.d.ts +236 -0
- package/node_modules/type-fest/source/internal/string.d.ts +210 -0
- package/node_modules/type-fest/source/internal/tuple.d.ts +90 -0
- package/node_modules/type-fest/source/internal/type.d.ts +139 -0
- package/node_modules/type-fest/source/invariant-of.d.ts +76 -0
- package/node_modules/type-fest/source/is-any.d.ts +33 -0
- package/node_modules/type-fest/source/is-equal.d.ts +31 -0
- package/node_modules/type-fest/source/is-float.d.ts +41 -0
- package/node_modules/type-fest/source/is-integer.d.ts +58 -0
- package/node_modules/type-fest/source/is-literal.d.ts +296 -0
- package/node_modules/type-fest/source/is-never.d.ts +42 -0
- package/node_modules/type-fest/source/is-null.d.ts +20 -0
- package/node_modules/type-fest/source/is-tuple.d.ts +89 -0
- package/node_modules/type-fest/source/is-unknown.d.ts +52 -0
- package/node_modules/type-fest/source/iterable-element.d.ts +64 -0
- package/node_modules/type-fest/source/join.d.ts +68 -0
- package/node_modules/type-fest/source/jsonifiable.d.ts +37 -0
- package/node_modules/type-fest/source/jsonify.d.ts +122 -0
- package/node_modules/type-fest/source/kebab-case.d.ts +44 -0
- package/node_modules/type-fest/source/kebab-cased-properties-deep.d.ts +63 -0
- package/node_modules/type-fest/source/kebab-cased-properties.d.ts +40 -0
- package/node_modules/type-fest/source/keys-of-union.d.ts +42 -0
- package/node_modules/type-fest/source/last-array-element.d.ts +38 -0
- package/node_modules/type-fest/source/less-than-or-equal.d.ts +22 -0
- package/node_modules/type-fest/source/less-than.d.ts +26 -0
- package/node_modules/type-fest/source/literal-to-primitive-deep.d.ts +36 -0
- package/node_modules/type-fest/source/literal-to-primitive.d.ts +36 -0
- package/node_modules/type-fest/source/literal-union.d.ts +37 -0
- package/node_modules/type-fest/source/merge-deep.d.ts +486 -0
- package/node_modules/type-fest/source/merge-exclusive.d.ts +41 -0
- package/node_modules/type-fest/source/merge.d.ts +48 -0
- package/node_modules/type-fest/source/multidimensional-array.d.ts +44 -0
- package/node_modules/type-fest/source/multidimensional-readonly-array.d.ts +48 -0
- package/node_modules/type-fest/source/non-empty-object.d.ts +35 -0
- package/node_modules/type-fest/source/non-empty-string.d.ts +28 -0
- package/node_modules/type-fest/source/non-empty-tuple.d.ts +21 -0
- package/node_modules/type-fest/source/numeric.d.ts +222 -0
- package/node_modules/type-fest/source/observable-like.d.ts +63 -0
- package/node_modules/type-fest/source/omit-deep.d.ts +167 -0
- package/node_modules/type-fest/source/omit-index-signature.d.ts +95 -0
- package/node_modules/type-fest/source/opaque.d.ts +1 -0
- package/node_modules/type-fest/source/optional-keys-of.d.ts +39 -0
- package/node_modules/type-fest/source/or.d.ts +25 -0
- package/node_modules/type-fest/source/override-properties.d.ts +36 -0
- package/node_modules/type-fest/source/package-json.d.ts +676 -0
- package/node_modules/type-fest/source/partial-deep.d.ts +151 -0
- package/node_modules/type-fest/source/partial-on-undefined-deep.d.ts +78 -0
- package/node_modules/type-fest/source/pascal-case.d.ts +42 -0
- package/node_modules/type-fest/source/pascal-cased-properties-deep.d.ts +62 -0
- package/node_modules/type-fest/source/pascal-cased-properties.d.ts +36 -0
- package/node_modules/type-fest/source/paths.d.ts +262 -0
- package/node_modules/type-fest/source/pick-deep.d.ts +149 -0
- package/node_modules/type-fest/source/pick-index-signature.d.ts +50 -0
- package/node_modules/type-fest/source/primitive.d.ts +13 -0
- package/node_modules/type-fest/source/promisable.d.ts +25 -0
- package/node_modules/type-fest/source/readonly-deep.d.ts +81 -0
- package/node_modules/type-fest/source/readonly-keys-of.d.ts +30 -0
- package/node_modules/type-fest/source/readonly-tuple.d.ts +41 -0
- package/node_modules/type-fest/source/replace.d.ts +85 -0
- package/node_modules/type-fest/source/require-all-or-none.d.ts +51 -0
- package/node_modules/type-fest/source/require-at-least-one.d.ts +47 -0
- package/node_modules/type-fest/source/require-exactly-one.d.ts +45 -0
- package/node_modules/type-fest/source/require-one-or-none.d.ts +46 -0
- package/node_modules/type-fest/source/required-deep.d.ts +78 -0
- package/node_modules/type-fest/source/required-keys-of.d.ts +30 -0
- package/node_modules/type-fest/source/schema.d.ts +114 -0
- package/node_modules/type-fest/source/screaming-snake-case.d.ts +28 -0
- package/node_modules/type-fest/source/set-field-type.d.ts +65 -0
- package/node_modules/type-fest/source/set-non-nullable-deep.d.ts +83 -0
- package/node_modules/type-fest/source/set-non-nullable.d.ts +39 -0
- package/node_modules/type-fest/source/set-optional.d.ts +38 -0
- package/node_modules/type-fest/source/set-parameter-type.d.ts +117 -0
- package/node_modules/type-fest/source/set-readonly.d.ts +39 -0
- package/node_modules/type-fest/source/set-required-deep.d.ts +68 -0
- package/node_modules/type-fest/source/set-required.d.ts +70 -0
- package/node_modules/type-fest/source/set-return-type.d.ts +29 -0
- package/node_modules/type-fest/source/shared-union-fields-deep.d.ts +178 -0
- package/node_modules/type-fest/source/shared-union-fields.d.ts +76 -0
- package/node_modules/type-fest/source/simplify-deep.d.ts +115 -0
- package/node_modules/type-fest/source/simplify.d.ts +58 -0
- package/node_modules/type-fest/source/single-key-object.d.ts +29 -0
- package/node_modules/type-fest/source/snake-case.d.ts +45 -0
- package/node_modules/type-fest/source/snake-cased-properties-deep.d.ts +63 -0
- package/node_modules/type-fest/source/snake-cased-properties.d.ts +40 -0
- package/node_modules/type-fest/source/split.d.ts +88 -0
- package/node_modules/type-fest/source/spread.d.ts +84 -0
- package/node_modules/type-fest/source/string-key-of.d.ts +25 -0
- package/node_modules/type-fest/source/string-repeat.d.ts +47 -0
- package/node_modules/type-fest/source/string-slice.d.ts +37 -0
- package/node_modules/type-fest/source/stringified.d.ts +23 -0
- package/node_modules/type-fest/source/structured-cloneable.d.ts +92 -0
- package/node_modules/type-fest/source/subtract.d.ts +83 -0
- package/node_modules/type-fest/source/sum.d.ts +78 -0
- package/node_modules/type-fest/source/tagged-union.d.ts +51 -0
- package/node_modules/type-fest/source/tagged.d.ts +256 -0
- package/node_modules/type-fest/source/trim.d.ts +27 -0
- package/node_modules/type-fest/source/tsconfig-json.d.ts +1294 -0
- package/node_modules/type-fest/source/tuple-to-object.d.ts +42 -0
- package/node_modules/type-fest/source/tuple-to-union.d.ts +51 -0
- package/node_modules/type-fest/source/typed-array.d.ts +17 -0
- package/node_modules/type-fest/source/undefined-on-partial-deep.d.ts +80 -0
- package/node_modules/type-fest/source/union-to-intersection.d.ts +61 -0
- package/node_modules/type-fest/source/union-to-tuple.d.ts +56 -0
- package/node_modules/type-fest/source/unknown-array.d.ts +25 -0
- package/node_modules/type-fest/source/unknown-map.d.ts +24 -0
- package/node_modules/type-fest/source/unknown-record.d.ts +31 -0
- package/node_modules/type-fest/source/unknown-set.d.ts +24 -0
- package/node_modules/type-fest/source/value-of.d.ts +42 -0
- package/node_modules/type-fest/source/words.d.ts +118 -0
- package/node_modules/type-fest/source/writable-deep.d.ts +83 -0
- package/node_modules/type-fest/source/writable-keys-of.d.ts +33 -0
- package/node_modules/type-fest/source/writable.d.ts +68 -0
- package/node_modules/widest-line/index.d.ts +12 -0
- package/node_modules/widest-line/index.js +11 -0
- package/node_modules/widest-line/license +9 -0
- package/node_modules/widest-line/package.json +60 -0
- package/node_modules/widest-line/readme.md +26 -0
- package/node_modules/wrap-ansi/index.d.ts +41 -0
- package/node_modules/wrap-ansi/index.js +222 -0
- package/node_modules/wrap-ansi/license +9 -0
- package/node_modules/wrap-ansi/package.json +69 -0
- package/node_modules/wrap-ansi/readme.md +75 -0
- package/package.json +78 -0
- package/scripts/postinstall.cjs +122 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
LICENCIA FREEWARE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Felix Junior Chacaliaza Gutierrez
|
|
4
|
+
Contacto: felixchacaliaza@outlook.com
|
|
5
|
+
|
|
6
|
+
Todos los derechos reservados.
|
|
7
|
+
|
|
8
|
+
Este software y su documentación asociada (el "Software") son propiedad
|
|
9
|
+
exclusiva de Felix Junior Chacaliaza Gutierrez.
|
|
10
|
+
|
|
11
|
+
USO PERMITIDO
|
|
12
|
+
|
|
13
|
+
Se concede permiso, de forma gratuita, a cualquier persona que obtenga una
|
|
14
|
+
copia de este Software, para utilizarlo con fines personales, educativos o
|
|
15
|
+
de uso interno en organizaciones, sujeto a las siguientes condiciones:
|
|
16
|
+
|
|
17
|
+
1. El aviso de copyright anterior y este aviso de permiso deben incluirse
|
|
18
|
+
en todas las copias o partes sustanciales del Software.
|
|
19
|
+
|
|
20
|
+
RESTRICCIONES
|
|
21
|
+
|
|
22
|
+
Las siguientes acciones están estrictamente prohibidas sin el consentimiento
|
|
23
|
+
previo y por escrito del titular de los derechos:
|
|
24
|
+
|
|
25
|
+
1. MODIFICACIÓN — Queda prohibido alterar, adaptar, traducir o crear obras
|
|
26
|
+
derivadas basadas en el Software.
|
|
27
|
+
|
|
28
|
+
2. REDISTRIBUCIÓN — Queda prohibido copiar, distribuir, sublicenciar,
|
|
29
|
+
publicar o poner a disposición de terceros el Software, ya sea en su
|
|
30
|
+
forma original o modificada.
|
|
31
|
+
|
|
32
|
+
3. EXPLOTACIÓN COMERCIAL — Queda prohibido vender, alquilar, arrendar o
|
|
33
|
+
comercializar de cualquier forma el Software o cualquier parte del mismo.
|
|
34
|
+
|
|
35
|
+
4. INGENIERÍA INVERSA — Queda prohibido realizar ingeniería inversa,
|
|
36
|
+
desensamblar o descompilar el Software.
|
|
37
|
+
|
|
38
|
+
5. ELIMINACIÓN DE AVISOS — Queda prohibido eliminar o modificar cualquier
|
|
39
|
+
aviso de copyright, marca registrada u otro aviso de propiedad incluido
|
|
40
|
+
en el Software.
|
|
41
|
+
|
|
42
|
+
Para solicitar autorización para cualquier uso no contemplado en esta
|
|
43
|
+
licencia, contacte al titular en: felixchacaliaza@outlook.com
|
|
44
|
+
|
|
45
|
+
DESCARGO DE RESPONSABILIDAD
|
|
46
|
+
|
|
47
|
+
EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA
|
|
48
|
+
O IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A LAS GARANTÍAS DE COMERCIABILIDAD,
|
|
49
|
+
IDONEIDAD PARA UN FIN DETERMINADO Y NO INFRACCIÓN. EN NINGÚN CASO EL TITULAR
|
|
50
|
+
DE LOS DERECHOS SERÁ RESPONSABLE DE NINGUNA RECLAMACIÓN, DAÑO U OTRA
|
|
51
|
+
RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, EXTRACONTRACTUAL O DE
|
|
52
|
+
OTRO TIPO, QUE SURJA DE, O ESTÉ RELACIONADA CON EL SOFTWARE O SU USO.
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Pull Request Split Advisor
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Análisis estático de cambios Git para una división óptima en Pull Requests.</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img alt="npm version" src="https://img.shields.io/npm/v/pull-request-split-advisor" />
|
|
9
|
+
<img alt="npm downloads" src="https://img.shields.io/npm/dm/pull-request-split-advisor" />
|
|
10
|
+
<img alt="Node.js ≥ 18" src="https://img.shields.io/badge/node-%E2%89%A518-brightgreen" />
|
|
11
|
+
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5.x-blue" />
|
|
12
|
+
<img alt="Tests" src="https://img.shields.io/badge/tests-199%20passed-brightgreen" />
|
|
13
|
+
<img alt="License" src="https://img.shields.io/badge/license-Freeware-blue" />
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Descripción
|
|
19
|
+
|
|
20
|
+
`pr-split-advisor` examina los archivos modificados en la rama de trabajo respecto a la rama base, los agrupa en bloques semánticos mediante análisis heurístico de dependencias y calcula la distribución óptima en ramas y commits para maximizar la revisabilidad de cada Pull Request.
|
|
21
|
+
|
|
22
|
+
A partir de la **v2.0.0**, la herramienta puede también **aplicar el plan directamente** en el repositorio: crea las ramas derivadas en cascada (*stacked branches*), realiza los commits con los archivos asignados y opcionalmente publica las ramas en el remoto. Si algo falla en mitad del proceso, ejecuta un rollback automático que deja el repositorio en el estado inicial.
|
|
23
|
+
|
|
24
|
+
A partir de la **v3.0.0**, se incorpora una **capa de IA opcional** que enriquece los planes generados heurísticamente mediante un registro extensible de proveedores (`PROVIDER_REGISTRY`). Los prompts incluyen ejemplos few-shot y contexto de módulos para maximizar la calidad de las sugerencias. Proveedores disponibles: [Groq](https://console.groq.com) (Llama 3.3 70B, free tier) y **GitHub Copilot** (usa automáticamente las credenciales de `gh` CLI / VS Code, sin token adicional).
|
|
25
|
+
|
|
26
|
+
La capa de IA ofrece tres puntos de enriquecimiento: **mejora de mensajes de commit** (subjects semánticos con imperative mood), **mejora de slugs de rama** (kebab-case descriptivo orientado al negocio) y **rebalanceo del plan** (redistribución de archivos entre commits y ramas por cohesión semántica — `features.planRebalance`). El rebalanceo es opt-in y está desactivado por defecto; cuando se activa, la IA recibe el plan completo y propone movimientos que pasan una validación estricta antes de aplicarse.
|
|
27
|
+
|
|
28
|
+
La v3.0.0 también mejora el **apply**: rama de respaldo con snapshot completo del working tree, re-prompt en nombres duplicados en lugar de rollback, y nomenclatura de ramas con mayúsculas en la descripción (p. ej. `feature/TEAM-123-PRUEBA-IA`). Si la IA no está configurada o falla en cualquier punto, la herramienta continúa en modo heurístico sin interrupciones.
|
|
29
|
+
|
|
30
|
+
A partir de la **v3.1.0**, el proyecto incluye una **suite completa de tests** (Vitest, 199 tests, 12 suites) que cubre todos los módulos core, AI, git y configuración con mocks de dependencias externas (git, fs). A partir de la **v3.1.1**, el proveedor `copilot` solo puede activarse dentro de **Visual Studio Code** — fuera del IDE se emite un aviso y se desactiva automáticamente sin interrumpir el análisis.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Características principales
|
|
35
|
+
|
|
36
|
+
- Detección automática de archivos modificados, creados, eliminados y renombrados
|
|
37
|
+
- Agrupación semántica por dependencias, módulo y tipo de cambio
|
|
38
|
+
- Cálculo de score de calidad por rama (0–5) con factores ponderados
|
|
39
|
+
- Generación de nombres de rama y mensajes de commit convencionales
|
|
40
|
+
- Reporte HTML interactivo exportado automáticamente (8 secciones: hero ejecutivo, resumen de cambios, TOC con barras de score, detalle de archivos, dependencias, bloques, plan de commits con línea de tiempo y comandos git listos para ejecutar) — ver [formato completo](docs/FEATURES.md#reporte-html-interactivo)
|
|
41
|
+
- Exportación del plan en formato JSON para integraciones externas
|
|
42
|
+
- Historial de scores con seguimiento entre análisis
|
|
43
|
+
- Validaciones de nomenclatura de ramas y estado del working tree
|
|
44
|
+
- **`--apply`**: aplicación del plan en git con ramas apiladas (*stacked branches*) y rollback automático ante fallos
|
|
45
|
+
- **Capa de IA multi-proveedor** (v3.0.0+): tres niveles de enriquecimiento — mensajes de commit semánticos, slugs de rama orientados al negocio y **rebalanceo del plan** (redistribución de archivos entre commits y ramas por cohesión semántica) — soporta Groq (Llama 3.3 70B, free tier) y GitHub Copilot (sin token adicional, usa credenciales de VS Code / `gh` CLI) — sin configuración funciona en modo heurístico puro
|
|
46
|
+
|
|
47
|
+
Consulte [docs/FEATURES.md](docs/FEATURES.md) para la descripción detallada de cada característica.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Instalación
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Instalación global (recomendado)
|
|
55
|
+
npm install -g pull-request-split-advisor
|
|
56
|
+
|
|
57
|
+
# Como dependencia de desarrollo
|
|
58
|
+
npm install --save-dev pull-request-split-advisor
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Al instalar se genera automáticamente `pr-split-advisor.config.json` en la raíz del proyecto con todos los parámetros y sus valores por defecto. Si el archivo ya existe, no se sobreescribe.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Uso rápido
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Analizar: al finalizar pregunta si deseas aplicar el plan (crear ramas y commits)
|
|
69
|
+
pr-split-advisor
|
|
70
|
+
|
|
71
|
+
# Saltarse la pregunta y aplicar el plan directamente
|
|
72
|
+
pr-split-advisor --apply
|
|
73
|
+
|
|
74
|
+
# Especificar rama base de forma explícita
|
|
75
|
+
pr-split-advisor --base develop
|
|
76
|
+
|
|
77
|
+
# Consultar historial de análisis anteriores
|
|
78
|
+
pr-split-advisor --stats
|
|
79
|
+
|
|
80
|
+
# Configurar la capa de IA interactivamente
|
|
81
|
+
pr-split-advisor config
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Consulte [docs/USAGE.md](docs/USAGE.md) para la referencia completa de comandos, opciones y configuración.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Configuración
|
|
89
|
+
|
|
90
|
+
`pr-split-advisor.config.json` en la raíz del proyecto:
|
|
91
|
+
|
|
92
|
+
```jsonc
|
|
93
|
+
{
|
|
94
|
+
"targetScore": 4, // Score mínimo aceptable (0–5)
|
|
95
|
+
"baseBranch": "master", // Rama base para el análisis
|
|
96
|
+
"maxFilesPerCommit": 8, // Máximo de archivos por commit
|
|
97
|
+
"maxLinesPerCommitIdeal": 120, // Líneas ideales por commit
|
|
98
|
+
"idealLinesPerPR": 99, // Líneas ideales por PR
|
|
99
|
+
"largeFileThreshold": 400, // Umbral para marcar archivos grandes
|
|
100
|
+
"maxCommitsPerBranchIdeal": 2, // Commits ideales por rama
|
|
101
|
+
"hardMaxCommitsPerBranch": 4, // Límite absoluto de commits por rama
|
|
102
|
+
"exportJson": true, // Exportar plan a pr-split-plan.json
|
|
103
|
+
"verbose": false, // Mostrar logs de diagnóstico
|
|
104
|
+
|
|
105
|
+
// ── Capa de IA (v3.0.0+ — opcional) ───────────────────────────────────────────────
|
|
106
|
+
// Si "enabled" es false o no hay credenciales, se usa el modo heurístico puro.
|
|
107
|
+
// Proveedores disponibles: "groq", "copilot"
|
|
108
|
+
// Nota: "copilot" solo funciona dentro de Visual Studio Code.
|
|
109
|
+
// Configura interactivamente con: pr-split-advisor config
|
|
110
|
+
"ai": {
|
|
111
|
+
"enabled": false,
|
|
112
|
+
"provider": "groq", // "groq" | "copilot" (copilot: solo en VS Code)
|
|
113
|
+
"model": "llama-3.3-70b-versatile",
|
|
114
|
+
"apiKey": "", // API key literal (solo para "groq")
|
|
115
|
+
"features": {
|
|
116
|
+
"commitMessages": true, // Mejorar subjects de commit (habilitado automáticamente)
|
|
117
|
+
"branchDescriptions": true, // Mejorar slugs de nombre de rama (habilitado automáticamente)
|
|
118
|
+
"planRebalance": false // Redistribuir archivos entre commits y ramas (opt-in)
|
|
119
|
+
},
|
|
120
|
+
"timeoutMs": 15000,
|
|
121
|
+
"maxTokens": 1024
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Configura el proveedor de IA con el asistente interactivo:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pr-split-advisor config
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Groq** (free tier, [console.groq.com](https://console.groq.com)) — la API key se guarda en `pr-split-advisor.config.json` mediante el wizard:
|
|
133
|
+
```bash
|
|
134
|
+
pr-split-advisor config
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**GitHub Copilot** (sin token adicional — usa credenciales de VS Code / `gh` CLI):
|
|
138
|
+
> ⚠️ El proveedor `copilot` solo está disponible dentro de **Visual Studio Code**. Fuera del IDE, la herramienta lo desactiva automáticamente y continúa en modo heurístico. Usa `groq` para entornos de CI/CD o terminal independiente.
|
|
139
|
+
```bash
|
|
140
|
+
# Solo requiere tener gh autenticado:
|
|
141
|
+
gh auth login
|
|
142
|
+
# Y suscripción activa a GitHub Copilot en tu cuenta GitHub
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Requisitos
|
|
148
|
+
|
|
149
|
+
| Requisito | Versión mínima |
|
|
150
|
+
|-----------|---------------|
|
|
151
|
+
| Node.js | ≥ 18 |
|
|
152
|
+
| Git | Cualquier versión moderna en `PATH` |
|
|
153
|
+
| Repositorio | Con rama base accesible en el remoto |
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Licencia
|
|
158
|
+
|
|
159
|
+
© 2026 Felix Junior Chacaliaza Gutierrez — [felixchacaliaza@outlook.com](mailto:felixchacaliaza@outlook.com)
|
|
160
|
+
|
|
161
|
+
Este software se distribuye bajo los términos de una **licencia freeware**:
|
|
162
|
+
|
|
163
|
+
- ✅ Uso personal, educativo e interno permitido de forma gratuita
|
|
164
|
+
- ❌ Modificación o creación de obras derivadas no permitida
|
|
165
|
+
- ❌ Redistribución o publicación no permitida
|
|
166
|
+
- ❌ Uso comercial o venta no permitidos
|
|
167
|
+
|
|
168
|
+
Para cualquier uso no contemplado, contacte al autor. Consulte el archivo [LICENSE](LICENSE) para los términos completos.
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config-wizard.ts — Asistente interactivo para configurar pr-split-advisor.
|
|
3
|
+
*
|
|
4
|
+
* Invocado mediante el subcomando `pr-split-advisor config`.
|
|
5
|
+
* No requiere estar en un repositorio git.
|
|
6
|
+
*
|
|
7
|
+
* ### Flujo del asistente
|
|
8
|
+
* ```
|
|
9
|
+
* 1. Detectar si existe pr-split-advisor.config.json en el directorio actual.
|
|
10
|
+
* 2. Leer la configuración actual (o empezar desde cero).
|
|
11
|
+
* 3. Mostrar resumen del estado actual de IA.
|
|
12
|
+
* 4. Preguntar si se quiere habilitar / desactivar / actualizar la IA.
|
|
13
|
+
* 5. Recoger: proveedor, modelo, método de API key, features.
|
|
14
|
+
* 6. Escribir la sección `ai` actualizada en el archivo de configuración.
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* ### Comportamiento con archivos inexistentes
|
|
18
|
+
* Si `pr-split-advisor.config.json` no existe en el CWD, el asistente crea
|
|
19
|
+
* un archivo nuevo con la sección `ai` configurada (útil en proyectos donde
|
|
20
|
+
* el postinstall no pudo crear el archivo).
|
|
21
|
+
*/
|
|
22
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
23
|
+
import { resolve } from "node:path";
|
|
24
|
+
import { execSync } from "node:child_process";
|
|
25
|
+
import { ui } from "../output/ui.js";
|
|
26
|
+
import { PROVIDER_REGISTRY, callAI } from "./provider.js";
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Constantes
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
const CONFIG_FILE = "pr-split-advisor.config.json";
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Lectura y escritura del archivo de configuración
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
function readConfigFile(configPath) {
|
|
35
|
+
if (!existsSync(configPath))
|
|
36
|
+
return {};
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(readFileSync(configPath, "utf-8"));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function writeConfigFile(configPath, config) {
|
|
45
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Validación de API key
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Realiza una llamada mínima al proveedor para verificar que la API key es válida.
|
|
52
|
+
* Devuelve `null` si la conexión fue exitosa, o el mensaje de error en caso contrario.
|
|
53
|
+
*/
|
|
54
|
+
async function testApiKeyConnection(provider, model, apiKey, apiKeyEnvVar) {
|
|
55
|
+
// Construimos solo los campos que callAI realmente consume (config.ai)
|
|
56
|
+
const testConfig = {
|
|
57
|
+
ai: {
|
|
58
|
+
enabled: true,
|
|
59
|
+
provider,
|
|
60
|
+
model,
|
|
61
|
+
apiKey,
|
|
62
|
+
apiKeyEnvVar,
|
|
63
|
+
features: { commitMessages: false, branchDescriptions: false },
|
|
64
|
+
timeoutMs: 10000,
|
|
65
|
+
maxTokens: 16,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
await callAI([{ role: "user", content: "Reply with a json object: {\"ok\":true}" }], testConfig);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
return err instanceof Error ? err.message : String(err);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Helpers de display
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
function displayCurrentState(ai) {
|
|
80
|
+
ui.section("ESTADO ACTUAL DE LA CONFIGURACION IA", "#");
|
|
81
|
+
if (!ai || !ai.enabled) {
|
|
82
|
+
ui.warn("La IA NO está habilitada. Se utiliza el modo heurístico.");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const providerDesc = PROVIDER_REGISTRY.get(ai.provider ?? "groq");
|
|
86
|
+
ui.ok("La IA está HABILITADA.");
|
|
87
|
+
ui.kv("Proveedor", providerDesc?.label ?? (ai.provider ?? "groq"));
|
|
88
|
+
ui.kv("Modelo", ai.model ?? providerDesc?.defaultModel ?? "llama-3.3-70b-versatile");
|
|
89
|
+
if (ai.provider === "copilot") {
|
|
90
|
+
ui.kv("Autenticación", "gh CLI automático (cuenta de VS Code)");
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
ui.kv("API Key", ai.apiKey ? "*** (guardada en config)" : "no configurada");
|
|
94
|
+
}
|
|
95
|
+
ui.kv("Mensajes de commit con IA", ai.features?.commitMessages ? "Sí" : "No");
|
|
96
|
+
ui.kv("Descripciones de rama con IA", ai.features?.branchDescriptions ? "Sí" : "No");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Asistente principal
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
/**
|
|
103
|
+
* Ejecuta el asistente de configuración de forma interactiva.
|
|
104
|
+
* Escribe los cambios en `pr-split-advisor.config.json` del directorio actual.
|
|
105
|
+
*/
|
|
106
|
+
export async function runConfigWizard() {
|
|
107
|
+
const configPath = resolve(process.cwd(), CONFIG_FILE);
|
|
108
|
+
ui.section("ASISTENTE DE CONFIGURACION — pr-split-advisor", "#");
|
|
109
|
+
ui.info(existsSync(configPath)
|
|
110
|
+
? `Archivo de configuración detectado: ${configPath}`
|
|
111
|
+
: `No se encontró ${CONFIG_FILE} — se creará uno nuevo.`);
|
|
112
|
+
const raw = readConfigFile(configPath);
|
|
113
|
+
const currentAi = (raw["ai"] ?? {});
|
|
114
|
+
displayCurrentState(currentAi);
|
|
115
|
+
// ── Paso 1: decisión según estado actual ─────────────────────────────────
|
|
116
|
+
if (currentAi.enabled) {
|
|
117
|
+
// IA ya configurada: preguntar si desea cambiar de proveedor
|
|
118
|
+
const changeProvider = await ui.confirm("¿Deseas cambiar de proveedor de IA?");
|
|
119
|
+
if (!changeProvider) {
|
|
120
|
+
ui.info("Sin cambios. La IA continúa activa con la configuración actual.");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// IA no configurada: preguntar si desea habilitarla
|
|
126
|
+
const enableAi = await ui.confirm("¿Habilitar la capa de IA para enriquecer los planes de PR?");
|
|
127
|
+
if (!enableAi) {
|
|
128
|
+
ui.info("Sin cambios. La herramienta continuará en modo heurístico.");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ── Paso 2: proveedor ────────────────────────────────────────────────────
|
|
133
|
+
ui.section("PROVEEDOR DE IA", "─");
|
|
134
|
+
ui.muted(" 1. Groq (Llama 3.3 70B) — API key gratuita en console.groq.com");
|
|
135
|
+
ui.muted(" 2. GitHub Copilot — usa tu cuenta de VS Code automáticamente");
|
|
136
|
+
const currentIsGroq = (currentAi.provider ?? "groq") !== "copilot";
|
|
137
|
+
const providerChoice = await ui.prompt("Elige proveedor (1 o 2)", currentIsGroq ? "1" : "2");
|
|
138
|
+
const provider = providerChoice.trim() === "2" ? "copilot" : "groq";
|
|
139
|
+
const providerDesc = PROVIDER_REGISTRY.get(provider);
|
|
140
|
+
ui.ok(`Proveedor: ${providerDesc.label}`);
|
|
141
|
+
// ── Paso 3: credenciales ─────────────────────────────────────────────────
|
|
142
|
+
let apiKey = "";
|
|
143
|
+
if (provider === "copilot") {
|
|
144
|
+
ui.section("AUTENTICACION COPILOT", "─");
|
|
145
|
+
ui.ok("GitHub Copilot usa tu cuenta de VS Code / gh CLI automáticamente.");
|
|
146
|
+
ui.info("No necesitas configurar ningún token adicional.");
|
|
147
|
+
try {
|
|
148
|
+
const ghToken = execSync("gh auth token", {
|
|
149
|
+
encoding: "utf-8",
|
|
150
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
151
|
+
}).trim();
|
|
152
|
+
if (ghToken) {
|
|
153
|
+
ui.ok(`Cuenta de GitHub detectada (•••${ghToken.slice(-6)}).`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
ui.error("gh CLI no tiene sesión activa — sin token no es posible usar GitHub Copilot.\n" +
|
|
157
|
+
"Autentícate ejecutando: gh auth login\n" +
|
|
158
|
+
"La configuración de IA no se ha guardado.");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
ui.error("gh CLI no está instalado o no responde.\n" +
|
|
164
|
+
"Instálalo desde https://cli.github.com y ejecuta: gh auth login\n" +
|
|
165
|
+
"La configuración de IA no se ha guardado.");
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Groq: solo pedir la key directamente
|
|
171
|
+
ui.section("API KEY DE GROQ", "─");
|
|
172
|
+
ui.info("Obtén tu API key gratuita en: https://console.groq.com");
|
|
173
|
+
const entered = await ui.prompt("Ingresa tu API key de Groq (Enter para cancelar)", "");
|
|
174
|
+
apiKey = entered.trim();
|
|
175
|
+
if (!apiKey) {
|
|
176
|
+
ui.error("No ingresaste una API key — sin ella no es posible usar Groq.\n" +
|
|
177
|
+
"Obtén una gratis en: https://console.groq.com\n" +
|
|
178
|
+
"La configuración de IA no se ha guardado.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
ui.info("Verificando conexión con Groq…");
|
|
182
|
+
const connError = await testApiKeyConnection(provider, providerDesc.defaultModel, apiKey, "");
|
|
183
|
+
if (connError) {
|
|
184
|
+
ui.error(`La API key fue rechazada por Groq.\n` +
|
|
185
|
+
`Causa: ${connError}\n` +
|
|
186
|
+
`Verifica la key en https://console.groq.com\n` +
|
|
187
|
+
`La configuración de IA no se ha guardado.`);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
ui.ok("Conexión verificada correctamente.");
|
|
191
|
+
}
|
|
192
|
+
// ── Paso 4: escribir configuración ──────────────────────────────────────
|
|
193
|
+
const newAiConfig = {
|
|
194
|
+
enabled: true,
|
|
195
|
+
provider,
|
|
196
|
+
model: providerDesc.defaultModel,
|
|
197
|
+
apiKey,
|
|
198
|
+
apiKeyEnvVar: "",
|
|
199
|
+
features: { commitMessages: true, branchDescriptions: true, planRebalance: false },
|
|
200
|
+
timeoutMs: currentAi.timeoutMs ?? 15000,
|
|
201
|
+
maxTokens: currentAi.maxTokens ?? 1024,
|
|
202
|
+
};
|
|
203
|
+
raw["ai"] = newAiConfig;
|
|
204
|
+
writeConfigFile(configPath, raw);
|
|
205
|
+
ui.section("CONFIGURACION GUARDADA", "#");
|
|
206
|
+
ui.ok(`Archivo actualizado: ${configPath}`);
|
|
207
|
+
ui.kv("Proveedor", providerDesc.label);
|
|
208
|
+
ui.kv("Modelo", providerDesc.defaultModel);
|
|
209
|
+
if (provider === "copilot") {
|
|
210
|
+
ui.kv("Autenticación", "gh CLI automático (cuenta VS Code)");
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
ui.kv("API Key", "*** (guardada en config)");
|
|
214
|
+
ui.warn(`La API key queda en texto plano en ${CONFIG_FILE}. Añádelo a .gitignore si el repo es público.`);
|
|
215
|
+
}
|
|
216
|
+
ui.kv("Mensajes de commit con IA", "Sí (automático)");
|
|
217
|
+
ui.kv("Descripciones de rama con IA", "Sí (automático)");
|
|
218
|
+
ui.info("\nPara verificar la integración ejecuta el análisis en un repositorio git:\n" +
|
|
219
|
+
" pr-split-advisor");
|
|
220
|
+
}
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Configuración rápida con API key directa (--api-key)
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
/**
|
|
225
|
+
* Configura pr-split-advisor con una API key pasada directamente, sin wizard interactivo.
|
|
226
|
+
*
|
|
227
|
+
* Valida la key contra el proveedor antes de guardar. Si falla, aborta con error.
|
|
228
|
+
*
|
|
229
|
+
* @param apiKey - La API key del proveedor (literal, no nombre de env var).
|
|
230
|
+
* @param provider - ID del proveedor: "groq" | "github" | "copilot". Predeterminado: "groq".
|
|
231
|
+
*/
|
|
232
|
+
export async function runConfigWithKey(apiKey, provider = "groq") {
|
|
233
|
+
const configPath = resolve(process.cwd(), CONFIG_FILE);
|
|
234
|
+
const providerDesc = PROVIDER_REGISTRY.get(provider);
|
|
235
|
+
if (!providerDesc) {
|
|
236
|
+
ui.error(`Proveedor desconocido: "${provider}".\n` +
|
|
237
|
+
`Proveedores disponibles: groq, copilot`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const model = providerDesc.defaultModel;
|
|
241
|
+
ui.section("CONFIGURACION RAPIDA — pr-split-advisor", "#");
|
|
242
|
+
ui.kv("Proveedor", `${providerDesc.label} (${provider})`);
|
|
243
|
+
ui.kv("Modelo", model);
|
|
244
|
+
ui.kv("API Key", `${apiKey.slice(0, 8)}${"*".repeat(Math.max(0, apiKey.length - 8))}`);
|
|
245
|
+
ui.info("Verificando conexión con el proveedor…");
|
|
246
|
+
const connError = await testApiKeyConnection(provider, model, apiKey, "");
|
|
247
|
+
if (connError) {
|
|
248
|
+
ui.error(`La API key fue rechazada por ${providerDesc.label}.\n` +
|
|
249
|
+
`Causa: ${connError}\n` +
|
|
250
|
+
`Verifica que la key es correcta y vuelve a intentarlo.\n` +
|
|
251
|
+
`La configuración de IA no se ha guardado.`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
ui.ok("Conexión verificada correctamente.");
|
|
255
|
+
const raw = readConfigFile(configPath);
|
|
256
|
+
const currentAi = (raw["ai"] ?? {});
|
|
257
|
+
const newAiConfig = {
|
|
258
|
+
enabled: true,
|
|
259
|
+
provider,
|
|
260
|
+
model,
|
|
261
|
+
apiKey,
|
|
262
|
+
apiKeyEnvVar: providerDesc.defaultApiKeyEnvVar,
|
|
263
|
+
features: {
|
|
264
|
+
commitMessages: currentAi.features?.commitMessages ?? true,
|
|
265
|
+
branchDescriptions: currentAi.features?.branchDescriptions ?? true,
|
|
266
|
+
planRebalance: currentAi.features?.planRebalance ?? false,
|
|
267
|
+
},
|
|
268
|
+
timeoutMs: currentAi.timeoutMs ?? 15000,
|
|
269
|
+
maxTokens: currentAi.maxTokens ?? 1024,
|
|
270
|
+
};
|
|
271
|
+
raw["ai"] = newAiConfig;
|
|
272
|
+
writeConfigFile(configPath, raw);
|
|
273
|
+
ui.section("CONFIGURACION GUARDADA", "#");
|
|
274
|
+
ui.ok(`Archivo actualizado: ${configPath}`);
|
|
275
|
+
ui.kv("Proveedor", `${providerDesc.label} (${provider})`);
|
|
276
|
+
ui.kv("Modelo", model);
|
|
277
|
+
ui.kv("API Key", "*** (literal en config)");
|
|
278
|
+
ui.kv("Mensajes de commit con IA", newAiConfig.features.commitMessages ? "Sí" : "No");
|
|
279
|
+
ui.kv("Descripciones de rama con IA", newAiConfig.features.branchDescriptions ? "Sí" : "No");
|
|
280
|
+
ui.warn("La API key está guardada en texto plano en el archivo de configuración.\n" +
|
|
281
|
+
`Añade ${CONFIG_FILE} a tu .gitignore si el proyecto es público.`);
|
|
282
|
+
}
|