@wyxos/zephyr 0.1.9 → 0.1.11
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 +41 -24
package/package.json
CHANGED
package/src/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ const SERVERS_FILE = path.join(GLOBAL_CONFIG_DIR, 'servers.json')
|
|
|
13
13
|
const PROJECT_LOCK_FILE = 'deploy.lock'
|
|
14
14
|
const PENDING_TASKS_FILE = 'pending-tasks.json'
|
|
15
15
|
const RELEASE_SCRIPT_NAME = 'release'
|
|
16
|
-
const RELEASE_SCRIPT_COMMAND = 'npx @wyxos/zephyr@
|
|
16
|
+
const RELEASE_SCRIPT_COMMAND = 'npx @wyxos/zephyr@latest'
|
|
17
17
|
|
|
18
18
|
const logProcessing = (message = '') => console.log(chalk.yellow(message))
|
|
19
19
|
const logSuccess = (message = '') => console.log(chalk.green(message))
|
|
@@ -336,7 +336,7 @@ async function ensureProjectReleaseScript(rootDir) {
|
|
|
336
336
|
{
|
|
337
337
|
type: 'confirm',
|
|
338
338
|
name: 'installReleaseScript',
|
|
339
|
-
message: 'Add "release" script to package.json that runs "npx @wyxos/zephyr@
|
|
339
|
+
message: 'Add "release" script to package.json that runs "npx @wyxos/zephyr@latest"?',
|
|
340
340
|
default: true
|
|
341
341
|
}
|
|
342
342
|
])
|
|
@@ -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
|
)
|
|
@@ -899,8 +917,7 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
899
917
|
.join('\n')
|
|
900
918
|
|
|
901
919
|
logProcessing(
|
|
902
|
-
`Detected ${changedFiles.length} changed file(s):\n${preview}${
|
|
903
|
-
changedFiles.length > 20 ? '\n - ...' : ''
|
|
920
|
+
`Detected ${changedFiles.length} changed file(s):\n${preview}${changedFiles.length > 20 ? '\n - ...' : ''
|
|
904
921
|
}`
|
|
905
922
|
)
|
|
906
923
|
} else {
|
|
@@ -1062,7 +1079,7 @@ async function runRemoteTasks(config, options = {}) {
|
|
|
1062
1079
|
}
|
|
1063
1080
|
|
|
1064
1081
|
logSuccess('\nDeployment commands completed successfully.')
|
|
1065
|
-
|
|
1082
|
+
|
|
1066
1083
|
const logPath = await getLogFilePath(rootDir)
|
|
1067
1084
|
logSuccess(`\nAll task output has been logged to: ${logPath}`)
|
|
1068
1085
|
} catch (error) {
|