Compare commits
1 Commits
7e80d350b1
...
7e1f256c1b
| Author | SHA1 | Date |
|---|---|---|
|
|
7e1f256c1b |
|
|
@ -19,6 +19,7 @@
|
||||||
"fs-extra": "^11.3.0",
|
"fs-extra": "^11.3.0",
|
||||||
"glob": "^11.0.3",
|
"glob": "^11.0.3",
|
||||||
"ignore": "^7.0.5",
|
"ignore": "^7.0.5",
|
||||||
|
"inquirer": "^9.3.8",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"ora": "^5.4.1",
|
"ora": "^5.4.1",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
|
|
@ -2020,6 +2021,36 @@
|
||||||
"url": "https://opencollective.com/libvips"
|
"url": "https://opencollective.com/libvips"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@inquirer/external-editor": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"chardet": "^2.1.1",
|
||||||
|
"iconv-lite": "^0.7.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/figures": {
|
||||||
|
"version": "1.0.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz",
|
||||||
|
"integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@isaacs/balanced-match": {
|
"node_modules/@isaacs/balanced-match": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
||||||
|
|
@ -3633,7 +3664,7 @@
|
||||||
"version": "25.0.3",
|
"version": "25.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
|
||||||
"integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
|
"integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.16.0"
|
"undici-types": "~7.16.0"
|
||||||
|
|
@ -4021,7 +4052,6 @@
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
||||||
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
|
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"type-fest": "^0.21.3"
|
"type-fest": "^0.21.3"
|
||||||
|
|
@ -4037,7 +4067,6 @@
|
||||||
"version": "0.21.3",
|
"version": "0.21.3",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
|
||||||
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
|
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
|
||||||
"dev": true,
|
|
||||||
"license": "(MIT OR CC0-1.0)",
|
"license": "(MIT OR CC0-1.0)",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
|
|
@ -5591,6 +5620,12 @@
|
||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chardet": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||||
|
|
@ -5771,6 +5806,15 @@
|
||||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cli-width": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cliui": {
|
"node_modules/cliui": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||||
|
|
@ -8243,6 +8287,22 @@
|
||||||
"@babel/runtime": "^7.23.2"
|
"@babel/runtime": "^7.23.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ieee754": {
|
"node_modules/ieee754": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
|
@ -8378,6 +8438,43 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/inquirer": {
|
||||||
|
"version": "9.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.8.tgz",
|
||||||
|
"integrity": "sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/external-editor": "^1.0.2",
|
||||||
|
"@inquirer/figures": "^1.0.3",
|
||||||
|
"ansi-escapes": "^4.3.2",
|
||||||
|
"cli-width": "^4.1.0",
|
||||||
|
"mute-stream": "1.0.0",
|
||||||
|
"ora": "^5.4.1",
|
||||||
|
"run-async": "^3.0.0",
|
||||||
|
"rxjs": "^7.8.1",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"wrap-ansi": "^6.2.0",
|
||||||
|
"yoctocolors-cjs": "^2.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inquirer/node_modules/wrap-ansi": {
|
||||||
|
"version": "6.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||||
|
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/iron-webcrypto": {
|
"node_modules/iron-webcrypto": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
|
||||||
|
|
@ -11496,6 +11593,15 @@
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/mute-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nano-spawn": {
|
"node_modules/nano-spawn": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz",
|
||||||
|
|
@ -13218,6 +13324,15 @@
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/run-async": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-parallel": {
|
"node_modules/run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
|
|
@ -13242,6 +13357,15 @@
|
||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rxjs": {
|
||||||
|
"version": "7.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
|
||||||
|
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/safe-buffer": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
|
@ -13262,6 +13386,12 @@
|
||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/sax": {
|
"node_modules/sax": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
|
||||||
|
|
@ -14135,7 +14265,6 @@
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"dev": true,
|
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
|
|
@ -14220,7 +14349,7 @@
|
||||||
"version": "7.16.0",
|
"version": "7.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||||
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unicode-properties": {
|
"node_modules/unicode-properties": {
|
||||||
|
|
@ -15153,6 +15282,18 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/yoctocolors-cjs": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/zip-stream": {
|
"node_modules/zip-stream": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clack/prompts": "^0.11.0",
|
|
||||||
"@kayvan/markdown-tree-parser": "^1.6.1",
|
"@kayvan/markdown-tree-parser": "^1.6.1",
|
||||||
"boxen": "^5.1.2",
|
"boxen": "^5.1.2",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
|
|
@ -78,6 +77,7 @@
|
||||||
"fs-extra": "^11.3.0",
|
"fs-extra": "^11.3.0",
|
||||||
"glob": "^11.0.3",
|
"glob": "^11.0.3",
|
||||||
"ignore": "^7.0.5",
|
"ignore": "^7.0.5",
|
||||||
|
"inquirer": "^9.3.8",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"ora": "^5.4.1",
|
"ora": "^5.4.1",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
|
|
@ -88,6 +88,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/sitemap": "^3.6.0",
|
"@astrojs/sitemap": "^3.6.0",
|
||||||
"@astrojs/starlight": "^0.37.0",
|
"@astrojs/starlight": "^0.37.0",
|
||||||
|
"@clack/prompts": "^0.11.0",
|
||||||
"@eslint/js": "^9.33.0",
|
"@eslint/js": "^9.33.0",
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"astro": "^5.16.0",
|
"astro": "^5.16.0",
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const path = require('node:path');
|
||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
|
|
||||||
// Fix for stdin issues when running through npm on Windows
|
// Fix for stdin issues when running through npm on Windows
|
||||||
// Ensures keyboard interaction works properly with CLI prompts
|
// Ensures keyboard interaction works properly with inquirer prompts
|
||||||
if (process.stdin.isTTY) {
|
if (process.stdin.isTTY) {
|
||||||
try {
|
try {
|
||||||
process.stdin.resume();
|
process.stdin.resume();
|
||||||
|
|
|
||||||
|
|
@ -835,7 +835,7 @@ class ConfigCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a prompt question from a config item
|
* Build an inquirer question from a config item
|
||||||
* @param {string} moduleName - Module name
|
* @param {string} moduleName - Module name
|
||||||
* @param {string} key - Config key
|
* @param {string} key - Config key
|
||||||
* @param {Object} item - Config item definition
|
* @param {Object} item - Config item definition
|
||||||
|
|
@ -997,7 +997,7 @@ class ConfigCollector {
|
||||||
message: message,
|
message: message,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set default - if it's dynamic, use a function that the prompt will evaluate with current answers
|
// Set default - if it's dynamic, use a function that inquirer will evaluate with current answers
|
||||||
// But if we have an existing value, always use that instead
|
// But if we have an existing value, always use that instead
|
||||||
if (existingValue !== null && existingValue !== undefined && questionType !== 'list') {
|
if (existingValue !== null && existingValue !== undefined && questionType !== 'list') {
|
||||||
question.default = existingValue;
|
question.default = existingValue;
|
||||||
|
|
|
||||||
|
|
@ -759,9 +759,6 @@ class Installer {
|
||||||
config.skipIde = toolSelection.skipIde;
|
config.skipIde = toolSelection.skipIde;
|
||||||
const ideConfigurations = toolSelection.configurations;
|
const ideConfigurations = toolSelection.configurations;
|
||||||
|
|
||||||
// Add spacing after prompts before installation progress
|
|
||||||
console.log('');
|
|
||||||
|
|
||||||
if (spinner.isSpinning) {
|
if (spinner.isSpinning) {
|
||||||
spinner.text = 'Continuing installation...';
|
spinner.text = 'Continuing installation...';
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2535,20 +2532,20 @@ class Installer {
|
||||||
|
|
||||||
if (typedConfirm === 'DELETE') {
|
if (typedConfirm === 'DELETE') {
|
||||||
// Remove the module from filesystem and manifest
|
// Remove the module from filesystem and manifest
|
||||||
const modulePath = path.join(bmadDir, missing.id);
|
const modulePath = path.join(bmadDir, moduleId);
|
||||||
if (await fs.pathExists(modulePath)) {
|
if (await fs.pathExists(modulePath)) {
|
||||||
const fsExtra = require('fs-extra');
|
const fsExtra = require('fs-extra');
|
||||||
await fsExtra.remove(modulePath);
|
await fsExtra.remove(modulePath);
|
||||||
console.log(chalk.yellow(` ✓ Deleted module directory: ${path.relative(projectRoot, modulePath)}`));
|
console.log(chalk.yellow(` ✓ Deleted module directory: ${path.relative(projectRoot, modulePath)}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.manifest.removeModule(bmadDir, missing.id);
|
await this.manifest.removeModule(bmadDir, moduleId);
|
||||||
await this.manifest.removeCustomModule(bmadDir, missing.id);
|
await this.manifest.removeCustomModule(bmadDir, moduleId);
|
||||||
console.log(chalk.yellow(` ✓ Removed from manifest`));
|
console.log(chalk.yellow(` ✓ Removed from manifest`));
|
||||||
|
|
||||||
// Also remove from installedModules list
|
// Also remove from installedModules list
|
||||||
if (installedModules && installedModules.includes(missing.id)) {
|
if (installedModules && installedModules.includes(moduleId)) {
|
||||||
const index = installedModules.indexOf(missing.id);
|
const index = installedModules.indexOf(moduleId);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
installedModules.splice(index, 1);
|
installedModules.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
@ -2569,7 +2566,7 @@ class Installer {
|
||||||
}
|
}
|
||||||
case 'keep': {
|
case 'keep': {
|
||||||
keptCount++;
|
keptCount++;
|
||||||
keptModulesWithoutSources.push(missing.id);
|
keptModulesWithoutSources.push(moduleId);
|
||||||
console.log(chalk.dim(` Module will be kept as-is`));
|
console.log(chalk.dim(` Module will be kept as-is`));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
this.workflowsDir = 'workflows';
|
this.workflowsDir = 'workflows';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt for subagent installation location
|
|
||||||
* @returns {Promise<string>} Selected location ('project' or 'user')
|
|
||||||
*/
|
|
||||||
async _promptInstallLocation() {
|
|
||||||
return prompts.select({
|
|
||||||
message: 'Where would you like to install Antigravity subagents?',
|
|
||||||
choices: [
|
|
||||||
{ name: 'Project level (.agent/agents/)', value: 'project' },
|
|
||||||
{ name: 'User level (~/.agent/agents/)', value: 'user' },
|
|
||||||
],
|
|
||||||
default: 'project',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect configuration choices before installation
|
* Collect configuration choices before installation
|
||||||
* @param {Object} options - Configuration options
|
* @param {Object} options - Configuration options
|
||||||
|
|
@ -73,7 +58,15 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
config.subagentChoices = await this.promptSubagentInstallation(injectionConfig.subagents);
|
config.subagentChoices = await this.promptSubagentInstallation(injectionConfig.subagents);
|
||||||
|
|
||||||
if (config.subagentChoices.install !== 'none') {
|
if (config.subagentChoices.install !== 'none') {
|
||||||
config.installLocation = await this._promptInstallLocation();
|
// Ask for installation location
|
||||||
|
config.installLocation = await prompts.select({
|
||||||
|
message: 'Where would you like to install Antigravity subagents?',
|
||||||
|
choices: [
|
||||||
|
{ name: 'Project level (.agent/agents/)', value: 'project' },
|
||||||
|
{ name: 'User level (~/.agent/agents/)', value: 'user' },
|
||||||
|
],
|
||||||
|
default: 'project',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -299,7 +292,14 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
choices = await this.promptSubagentInstallation(config.subagents);
|
choices = await this.promptSubagentInstallation(config.subagents);
|
||||||
|
|
||||||
if (choices.install !== 'none') {
|
if (choices.install !== 'none') {
|
||||||
location = await this._promptInstallLocation();
|
location = await prompts.select({
|
||||||
|
message: 'Where would you like to install Antigravity subagents?',
|
||||||
|
choices: [
|
||||||
|
{ name: 'Project level (.agent/agents/)', value: 'project' },
|
||||||
|
{ name: 'User level (~/.agent/agents/)', value: 'user' },
|
||||||
|
],
|
||||||
|
default: 'project',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
this.agentsDir = 'agents';
|
this.agentsDir = 'agents';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt for subagent installation location
|
|
||||||
* @returns {Promise<string>} Selected location ('project' or 'user')
|
|
||||||
*/
|
|
||||||
async promptInstallLocation() {
|
|
||||||
return prompts.select({
|
|
||||||
message: 'Where would you like to install Claude Code subagents?',
|
|
||||||
choices: [
|
|
||||||
{ name: 'Project level (.claude/agents/)', value: 'project' },
|
|
||||||
{ name: 'User level (~/.claude/agents/)', value: 'user' },
|
|
||||||
],
|
|
||||||
default: 'project',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect configuration choices before installation
|
* Collect configuration choices before installation
|
||||||
* @param {Object} options - Configuration options
|
* @param {Object} options - Configuration options
|
||||||
|
|
@ -72,7 +57,15 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
config.subagentChoices = await this.promptSubagentInstallation(injectionConfig.subagents);
|
config.subagentChoices = await this.promptSubagentInstallation(injectionConfig.subagents);
|
||||||
|
|
||||||
if (config.subagentChoices.install !== 'none') {
|
if (config.subagentChoices.install !== 'none') {
|
||||||
config.installLocation = await this.promptInstallLocation();
|
// Ask for installation location
|
||||||
|
config.installLocation = await prompts.select({
|
||||||
|
message: 'Where would you like to install Claude Code subagents?',
|
||||||
|
choices: [
|
||||||
|
{ name: 'Project level (.claude/agents/)', value: 'project' },
|
||||||
|
{ name: 'User level (~/.claude/agents/)', value: 'user' },
|
||||||
|
],
|
||||||
|
default: 'project',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -307,7 +300,14 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
choices = await this.promptSubagentInstallation(config.subagents);
|
choices = await this.promptSubagentInstallation(config.subagents);
|
||||||
|
|
||||||
if (choices.install !== 'none') {
|
if (choices.install !== 'none') {
|
||||||
location = await this.promptInstallLocation();
|
location = await prompts.select({
|
||||||
|
message: 'Where would you like to install Claude Code subagents?',
|
||||||
|
choices: [
|
||||||
|
{ name: 'Project level (.claude/agents/)', value: 'project' },
|
||||||
|
{ name: 'User level (~/.claude/agents/)', value: 'user' },
|
||||||
|
],
|
||||||
|
default: 'project',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -354,11 +354,11 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
|
|
||||||
const selected = await prompts.multiselect({
|
const selected = await prompts.multiselect({
|
||||||
message: 'Select subagents to install:',
|
message: 'Select subagents to install:',
|
||||||
options: subagentConfig.files.map((file) => ({
|
choices: subagentConfig.files.map((file) => ({
|
||||||
label: `${file.replace('.md', '')} - ${subagentInfo[file] || 'Specialized assistant'}`,
|
name: `${file.replace('.md', '')} - ${subagentInfo[file] || 'Specialized assistant'}`,
|
||||||
value: file,
|
value: file,
|
||||||
|
checked: true,
|
||||||
})),
|
})),
|
||||||
initialValues: subagentConfig.files,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { install: 'selective', selected };
|
return { install: 'selective', selected };
|
||||||
|
|
|
||||||
|
|
@ -125,18 +125,9 @@ async function select(options) {
|
||||||
async function multiselect(options) {
|
async function multiselect(options) {
|
||||||
const clack = await getClack();
|
const clack = await getClack();
|
||||||
|
|
||||||
// Support both clack-native (options) and Inquirer-style (choices) APIs
|
|
||||||
let clackOptions;
|
|
||||||
let initialValues;
|
|
||||||
|
|
||||||
if (options.options) {
|
|
||||||
// Native clack format: options with label/value
|
|
||||||
clackOptions = options.options;
|
|
||||||
initialValues = options.initialValues || [];
|
|
||||||
} else {
|
|
||||||
// Convert Inquirer-style choices to clack format
|
// Convert Inquirer-style choices to clack format
|
||||||
// Handle both object choices {name, value, hint} and primitive choices (string/number)
|
// Handle both object choices {name, value, hint} and primitive choices (string/number)
|
||||||
clackOptions = options.choices
|
const clackOptions = options.choices
|
||||||
.filter((c) => c.type !== 'separator') // Skip separators
|
.filter((c) => c.type !== 'separator') // Skip separators
|
||||||
.map((choice) => {
|
.map((choice) => {
|
||||||
if (typeof choice === 'string' || typeof choice === 'number') {
|
if (typeof choice === 'string' || typeof choice === 'number') {
|
||||||
|
|
@ -150,10 +141,9 @@ async function multiselect(options) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find initial values (pre-checked items)
|
// Find initial values (pre-checked items)
|
||||||
initialValues = options.choices
|
const initialValues = options.choices
|
||||||
.filter((c) => c.checked && c.type !== 'separator')
|
.filter((c) => c.checked && c.type !== 'separator')
|
||||||
.map((c) => (c.value === undefined ? c.name : c.value));
|
.map((c) => (c.value === undefined ? c.name : c.value));
|
||||||
}
|
|
||||||
|
|
||||||
const result = await clack.multiselect({
|
const result = await clack.multiselect({
|
||||||
message: options.message,
|
message: options.message,
|
||||||
|
|
@ -320,9 +310,6 @@ async function prompt(questions) {
|
||||||
validate: validate
|
validate: validate
|
||||||
? (val) => {
|
? (val) => {
|
||||||
const result = validate(val, answers);
|
const result = validate(val, answers);
|
||||||
if (result instanceof Promise) {
|
|
||||||
throw new TypeError('Async validation is not supported by @clack/prompts. Please use synchronous validation.');
|
|
||||||
}
|
|
||||||
return result === true ? undefined : result;
|
return result === true ? undefined : result;
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
@ -363,9 +350,6 @@ async function prompt(questions) {
|
||||||
validate: validate
|
validate: validate
|
||||||
? (val) => {
|
? (val) => {
|
||||||
const result = validate(val, answers);
|
const result = validate(val, answers);
|
||||||
if (result instanceof Promise) {
|
|
||||||
throw new TypeError('Async validation is not supported by @clack/prompts. Please use synchronous validation.');
|
|
||||||
}
|
|
||||||
return result === true ? undefined : result;
|
return result === true ? undefined : result;
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ class Separator {
|
||||||
type = 'separator';
|
type = 'separator';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separator for choice lists (compatible interface)
|
// Provide a compatible interface
|
||||||
const choiceUtils = { Separator };
|
const inquirer = { Separator };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UI utilities for the installer
|
* UI utilities for the installer
|
||||||
|
|
@ -448,7 +448,7 @@ class UI {
|
||||||
|
|
||||||
// First, add previously configured IDEs at the top, marked with ✅
|
// First, add previously configured IDEs at the top, marked with ✅
|
||||||
if (configuredIdes.length > 0) {
|
if (configuredIdes.length > 0) {
|
||||||
ideChoices.push(new choiceUtils.Separator('── Previously Configured ──'));
|
ideChoices.push(new inquirer.Separator('── Previously Configured ──'));
|
||||||
for (const ideValue of configuredIdes) {
|
for (const ideValue of configuredIdes) {
|
||||||
// Skip empty or invalid IDE values
|
// Skip empty or invalid IDE values
|
||||||
if (!ideValue || typeof ideValue !== 'string') {
|
if (!ideValue || typeof ideValue !== 'string') {
|
||||||
|
|
@ -477,7 +477,7 @@ class UI {
|
||||||
// Add preferred tools (excluding already processed)
|
// Add preferred tools (excluding already processed)
|
||||||
const remainingPreferred = preferredIdes.filter((ide) => !processedIdes.has(ide.value));
|
const remainingPreferred = preferredIdes.filter((ide) => !processedIdes.has(ide.value));
|
||||||
if (remainingPreferred.length > 0) {
|
if (remainingPreferred.length > 0) {
|
||||||
ideChoices.push(new choiceUtils.Separator('── Recommended Tools ──'));
|
ideChoices.push(new inquirer.Separator('── Recommended Tools ──'));
|
||||||
for (const ide of remainingPreferred) {
|
for (const ide of remainingPreferred) {
|
||||||
ideChoices.push({
|
ideChoices.push({
|
||||||
name: `${ide.name} ⭐`,
|
name: `${ide.name} ⭐`,
|
||||||
|
|
@ -491,7 +491,7 @@ class UI {
|
||||||
// Add other tools (excluding already processed)
|
// Add other tools (excluding already processed)
|
||||||
const remainingOther = otherIdes.filter((ide) => !processedIdes.has(ide.value));
|
const remainingOther = otherIdes.filter((ide) => !processedIdes.has(ide.value));
|
||||||
if (remainingOther.length > 0) {
|
if (remainingOther.length > 0) {
|
||||||
ideChoices.push(new choiceUtils.Separator('── Additional Tools ──'));
|
ideChoices.push(new inquirer.Separator('── Additional Tools ──'));
|
||||||
for (const ide of remainingOther) {
|
for (const ide of remainingOther) {
|
||||||
ideChoices.push({
|
ideChoices.push({
|
||||||
name: ide.name,
|
name: ide.name,
|
||||||
|
|
@ -685,7 +685,7 @@ class UI {
|
||||||
* Get module choices for selection
|
* Get module choices for selection
|
||||||
* @param {Set} installedModuleIds - Currently installed module IDs
|
* @param {Set} installedModuleIds - Currently installed module IDs
|
||||||
* @param {Object} customContentConfig - Custom content configuration
|
* @param {Object} customContentConfig - Custom content configuration
|
||||||
* @returns {Array} Module choices for prompt
|
* @returns {Array} Module choices for inquirer
|
||||||
*/
|
*/
|
||||||
async getModuleChoices(installedModuleIds, customContentConfig = null) {
|
async getModuleChoices(installedModuleIds, customContentConfig = null) {
|
||||||
const moduleChoices = [];
|
const moduleChoices = [];
|
||||||
|
|
@ -742,9 +742,9 @@ class UI {
|
||||||
if (allCustomModules.length > 0) {
|
if (allCustomModules.length > 0) {
|
||||||
// Add separator for custom content, all custom modules, and official content separator
|
// Add separator for custom content, all custom modules, and official content separator
|
||||||
moduleChoices.push(
|
moduleChoices.push(
|
||||||
new choiceUtils.Separator('── Custom Content ──'),
|
new inquirer.Separator('── Custom Content ──'),
|
||||||
...allCustomModules,
|
...allCustomModules,
|
||||||
new choiceUtils.Separator('── Official Content ──'),
|
new inquirer.Separator('── Official Content ──'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -785,7 +785,7 @@ class UI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompt for directory selection
|
* Prompt for directory selection
|
||||||
* @returns {Object} Directory answer from prompt
|
* @returns {Object} Directory answer from inquirer
|
||||||
*/
|
*/
|
||||||
async promptForDirectory() {
|
async promptForDirectory() {
|
||||||
// Use sync validation because @clack/prompts doesn't support async validate
|
// Use sync validation because @clack/prompts doesn't support async validate
|
||||||
|
|
@ -1069,7 +1069,7 @@ class UI {
|
||||||
* @sideeffects None - pure user input collection, no files written
|
* @sideeffects None - pure user input collection, no files written
|
||||||
* @edgecases Shows warning if user enables TTS but AgentVibes not detected
|
* @edgecases Shows warning if user enables TTS but AgentVibes not detected
|
||||||
* @calledby promptInstall() during installation flow, after core config, before IDE selection
|
* @calledby promptInstall() during installation flow, after core config, before IDE selection
|
||||||
* @calls checkAgentVibesInstalled(), prompts.select(), chalk.green/yellow/dim()
|
* @calls checkAgentVibesInstalled(), inquirer.prompt(), chalk.green/yellow/dim()
|
||||||
*
|
*
|
||||||
* AI NOTE: This prompt is strategically positioned in installation flow:
|
* AI NOTE: This prompt is strategically positioned in installation flow:
|
||||||
* - AFTER core config (user_name, etc)
|
* - AFTER core config (user_name, etc)
|
||||||
|
|
@ -1242,11 +1242,38 @@ class UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate custom content path synchronously
|
* Prompt user for custom content source location
|
||||||
* @param {string} input - User input path
|
* @returns {Object} Custom content configuration
|
||||||
* @returns {string|undefined} Error message or undefined if valid
|
|
||||||
*/
|
*/
|
||||||
validateCustomContentPathSync(input) {
|
async promptCustomContentSource() {
|
||||||
|
const customContentConfig = { hasCustomContent: true, sources: [] };
|
||||||
|
|
||||||
|
// Keep asking for more sources until user is done
|
||||||
|
while (true) {
|
||||||
|
// First ask if user wants to add another module or continue
|
||||||
|
if (customContentConfig.sources.length > 0) {
|
||||||
|
const action = await prompts.select({
|
||||||
|
message: 'Would you like to:',
|
||||||
|
choices: [
|
||||||
|
{ name: 'Add another custom module', value: 'add' },
|
||||||
|
{ name: 'Continue with installation', value: 'continue' },
|
||||||
|
],
|
||||||
|
default: 'continue',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (action === 'continue') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sourcePath;
|
||||||
|
let isValid = false;
|
||||||
|
|
||||||
|
while (!isValid) {
|
||||||
|
// Use sync validation because @clack/prompts doesn't support async validate
|
||||||
|
const inputPath = await prompts.text({
|
||||||
|
message: 'Enter the path to your custom content folder (or press Enter to cancel):',
|
||||||
|
validate: (input) => {
|
||||||
// Allow empty input to cancel
|
// Allow empty input to cancel
|
||||||
if (!input || input.trim() === '') {
|
if (!input || input.trim() === '') {
|
||||||
return; // Allow empty to exit
|
return; // Allow empty to exit
|
||||||
|
|
@ -1289,41 +1316,7 @@ class UI {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return 'Error validating path: ' + error.message;
|
return 'Error validating path: ' + error.message;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt user for custom content source location
|
|
||||||
* @returns {Object} Custom content configuration
|
|
||||||
*/
|
|
||||||
async promptCustomContentSource() {
|
|
||||||
const customContentConfig = { hasCustomContent: true, sources: [] };
|
|
||||||
|
|
||||||
// Keep asking for more sources until user is done
|
|
||||||
while (true) {
|
|
||||||
// First ask if user wants to add another module or continue
|
|
||||||
if (customContentConfig.sources.length > 0) {
|
|
||||||
const action = await prompts.select({
|
|
||||||
message: 'Would you like to:',
|
|
||||||
choices: [
|
|
||||||
{ name: 'Add another custom module', value: 'add' },
|
|
||||||
{ name: 'Continue with installation', value: 'continue' },
|
|
||||||
],
|
|
||||||
default: 'continue',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (action === 'continue') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let sourcePath;
|
|
||||||
let isValid = false;
|
|
||||||
|
|
||||||
while (!isValid) {
|
|
||||||
// Use sync validation because @clack/prompts doesn't support async validate
|
|
||||||
const inputPath = await prompts.text({
|
|
||||||
message: 'Enter the path to your custom content folder (or press Enter to cancel):',
|
|
||||||
validate: (input) => this.validateCustomContentPathSync(input),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// If user pressed Enter without typing anything, exit the loop
|
// If user pressed Enter without typing anything, exit the loop
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue