@wyxos/zephyr 0.1.8 → 0.1.10
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/package.json +1 -1
- package/src/index.mjs +44 -22
package/package.json
CHANGED
package/src/index.mjs
CHANGED
|
@@ -666,22 +666,22 @@ async function promptSshDetails(currentDir, existing = {}) {
|
|
|
666
666
|
|
|
667
667
|
const sshKeyPrompt = sshKeys.length
|
|
668
668
|
? {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
669
|
+
type: 'list',
|
|
670
|
+
name: 'sshKeySelection',
|
|
671
|
+
message: 'SSH key',
|
|
672
|
+
choices: [
|
|
673
|
+
...sshKeys.map((key) => ({ name: key, value: path.join(sshDir, key) })),
|
|
674
|
+
new inquirer.Separator(),
|
|
675
|
+
{ name: 'Enter custom SSH key path…', value: '__custom' }
|
|
676
|
+
],
|
|
677
|
+
default: preselectedKey
|
|
678
|
+
}
|
|
679
679
|
: {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
680
|
+
type: 'input',
|
|
681
|
+
name: 'sshKeySelection',
|
|
682
|
+
message: 'SSH key path',
|
|
683
|
+
default: preselectedKey
|
|
684
|
+
}
|
|
685
685
|
|
|
686
686
|
const answers = await runPrompt([
|
|
687
687
|
{
|
|
@@ -696,7 +696,7 @@ async function promptSshDetails(currentDir, existing = {}) {
|
|
|
696
696
|
let sshKey = answers.sshKeySelection
|
|
697
697
|
|
|
698
698
|
if (sshKey === '__custom') {
|
|
699
|
-
|
|
699
|
+
const { customSshKey } = await runPrompt([
|
|
700
700
|
{
|
|
701
701
|
type: 'input',
|
|
702
702
|
name: 'customSshKey',
|
|
@@ -797,12 +797,30 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
797
797
|
|
|
798
798
|
logProcessing(`Connection established. Running deployment commands in ${remoteCwd}...`)
|
|
799
799
|
|
|
800
|
+
// Robust environment bootstrap that works even when profile files don't export PATH
|
|
801
|
+
// for non-interactive shells. This handles:
|
|
802
|
+
// 1. Sourcing profile files (may not export PATH for non-interactive shells)
|
|
803
|
+
// 2. Loading nvm if available (common Node.js installation method)
|
|
804
|
+
// 3. Finding and adding common Node.js/npm installation paths
|
|
800
805
|
const profileBootstrap = [
|
|
806
|
+
// Source profile files (may set PATH, but often skip for non-interactive shells)
|
|
801
807
|
'if [ -f "$HOME/.profile" ]; then . "$HOME/.profile"; fi',
|
|
802
808
|
'if [ -f "$HOME/.bash_profile" ]; then . "$HOME/.bash_profile"; fi',
|
|
803
809
|
'if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc"; fi',
|
|
804
810
|
'if [ -f "$HOME/.zprofile" ]; then . "$HOME/.zprofile"; fi',
|
|
805
|
-
'if [ -f "$HOME/.zshrc" ]; then . "$HOME/.zshrc"; fi'
|
|
811
|
+
'if [ -f "$HOME/.zshrc" ]; then . "$HOME/.zshrc"; fi',
|
|
812
|
+
// Load nvm if available (common Node.js installation method)
|
|
813
|
+
'if [ -s "$HOME/.nvm/nvm.sh" ]; then . "$HOME/.nvm/nvm.sh"; fi',
|
|
814
|
+
'if [ -s "$HOME/.config/nvm/nvm.sh" ]; then . "$HOME/.config/nvm/nvm.sh"; fi',
|
|
815
|
+
'if [ -s "/usr/local/opt/nvm/nvm.sh" ]; then . "/usr/local/opt/nvm/nvm.sh"; fi',
|
|
816
|
+
// Try to find npm/node in common locations and add to PATH
|
|
817
|
+
'if command -v npm >/dev/null 2>&1; then :',
|
|
818
|
+
'elif [ -d "$HOME/.nvm/versions/node" ]; then NODE_VERSION=$(ls -1 "$HOME/.nvm/versions/node" | tail -1) && export PATH="$HOME/.nvm/versions/node/$NODE_VERSION/bin:$PATH"',
|
|
819
|
+
'elif [ -d "/usr/local/lib/node_modules/npm/bin" ]; then export PATH="/usr/local/lib/node_modules/npm/bin:$PATH"',
|
|
820
|
+
'elif [ -d "/opt/homebrew/bin" ] && [ -f "/opt/homebrew/bin/npm" ]; then export PATH="/opt/homebrew/bin:$PATH"',
|
|
821
|
+
'elif [ -d "/usr/local/bin" ] && [ -f "/usr/local/bin/npm" ]; then export PATH="/usr/local/bin:$PATH"',
|
|
822
|
+
'elif [ -d "$HOME/.local/bin" ] && [ -f "$HOME/.local/bin/npm" ]; then export PATH="$HOME/.local/bin:$PATH"',
|
|
823
|
+
'fi'
|
|
806
824
|
].join('; ')
|
|
807
825
|
|
|
808
826
|
const escapeForDoubleQuotes = (value) => value.replace(/(["\\$`])/g, '\\$1')
|
|
@@ -836,7 +854,7 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
836
854
|
if (result.stdout && result.stdout.trim()) {
|
|
837
855
|
logError(`\n[${label}] Output:\n${result.stdout.trim()}`)
|
|
838
856
|
}
|
|
839
|
-
|
|
857
|
+
|
|
840
858
|
if (result.stderr && result.stderr.trim()) {
|
|
841
859
|
logError(`\n[${label}] Error:\n${result.stderr.trim()}`)
|
|
842
860
|
}
|
|
@@ -844,7 +862,7 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
844
862
|
|
|
845
863
|
if (result.code !== 0 && !allowFailure) {
|
|
846
864
|
const stderr = result.stderr?.trim() ?? ''
|
|
847
|
-
|
|
865
|
+
if (/command not found/.test(stderr) || /is not recognized/.test(stderr)) {
|
|
848
866
|
throw new Error(
|
|
849
867
|
`Command failed: ${command}. Ensure the remote environment loads required tools for non-interactive shells (e.g. export PATH in profile scripts).`
|
|
850
868
|
)
|
|
@@ -853,6 +871,11 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
853
871
|
throw new Error(`Command failed: ${command}`)
|
|
854
872
|
}
|
|
855
873
|
|
|
874
|
+
// Show success confirmation with command
|
|
875
|
+
if (result.code === 0) {
|
|
876
|
+
logSuccess(`✓ ${command}`)
|
|
877
|
+
}
|
|
878
|
+
|
|
856
879
|
return result
|
|
857
880
|
}
|
|
858
881
|
|
|
@@ -894,8 +917,7 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
894
917
|
.join('\n')
|
|
895
918
|
|
|
896
919
|
logProcessing(
|
|
897
|
-
`Detected ${changedFiles.length} changed file(s):\n${preview}${
|
|
898
|
-
changedFiles.length > 20 ? '\n - ...' : ''
|
|
920
|
+
`Detected ${changedFiles.length} changed file(s):\n${preview}${changedFiles.length > 20 ? '\n - ...' : ''
|
|
899
921
|
}`
|
|
900
922
|
)
|
|
901
923
|
} else {
|
|
@@ -1057,7 +1079,7 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
1057
1079
|
}
|
|
1058
1080
|
|
|
1059
1081
|
logSuccess('\nDeployment commands completed successfully.')
|
|
1060
|
-
|
|
1082
|
+
|
|
1061
1083
|
const logPath = await getLogFilePath(rootDir)
|
|
1062
1084
|
logSuccess(`\nAll task output has been logged to: ${logPath}`)
|
|
1063
1085
|
} catch (error) {
|