rootless-config 1.7.0 → 1.7.1
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 +3 -2
- package/src/cli/commands/activate.js +40 -30
- package/src/cli/index.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rootless-config",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Store project config files outside the project root, auto-deploy them where tools expect them.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"test:watch": "vitest",
|
|
24
24
|
"test:coverage": "vitest run --coverage",
|
|
25
|
-
"lint": "eslint src bin"
|
|
25
|
+
"lint": "eslint src bin",
|
|
26
|
+
"postinstall": "node bin/rootless.js activate --profile-only || exit 0"
|
|
26
27
|
},
|
|
27
28
|
"dependencies": {
|
|
28
29
|
"chokidar": "^3.6.0",
|
|
@@ -7,6 +7,17 @@ import { spawn } from 'node:child_process'
|
|
|
7
7
|
import { fileExists } from '../../utils/fsUtils.js'
|
|
8
8
|
import { createLogger } from '../../utils/logger.js'
|
|
9
9
|
|
|
10
|
+
// Logger that always writes to stderr — safe to use when stdout is piped to Invoke-Expression
|
|
11
|
+
function createStderrLogger() {
|
|
12
|
+
const w = msg => process.stderr.write(msg + '\n')
|
|
13
|
+
return {
|
|
14
|
+
info: msg => w(`\x1b[32m[ROOTLESS] ${msg}\x1b[0m`),
|
|
15
|
+
success: msg => w(`\x1b[32m✔ ${msg}\x1b[0m`),
|
|
16
|
+
warn: msg => w(`\x1b[33m[ROOTLESS] ${msg}\x1b[0m`),
|
|
17
|
+
fail: msg => w(`\x1b[31m✖ ${msg}\x1b[0m`),
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
// The block we inject into $PROFILE — delimited so we can detect/remove it
|
|
11
22
|
const HOOK_START = '# <rootless-hook>'
|
|
12
23
|
const HOOK_END = '# </rootless-hook>'
|
|
@@ -91,7 +102,13 @@ export default {
|
|
|
91
102
|
description: 'Install PowerShell profile hook — .root/ files become available as commands automatically',
|
|
92
103
|
|
|
93
104
|
async handler(args) {
|
|
94
|
-
const logger =
|
|
105
|
+
const logger = createStderrLogger()
|
|
106
|
+
|
|
107
|
+
// Работает только на Windows (нужен PowerShell)
|
|
108
|
+
if (process.platform !== 'win32') {
|
|
109
|
+
logger.info('PS profile hook is Windows-only. Skipping.')
|
|
110
|
+
return
|
|
111
|
+
}
|
|
95
112
|
|
|
96
113
|
// --remove flag
|
|
97
114
|
if (args.remove) {
|
|
@@ -105,40 +122,33 @@ export default {
|
|
|
105
122
|
return
|
|
106
123
|
}
|
|
107
124
|
|
|
108
|
-
// --env flag: just print the activation snippet for current session
|
|
109
|
-
if (args.env) {
|
|
110
|
-
process.stdout.write(HOOK_BODY + '\n')
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
|
|
114
125
|
const profilePath = await getProfilePath()
|
|
126
|
+
const alreadyInstalled = await isHookInstalled(profilePath)
|
|
115
127
|
|
|
116
|
-
if (
|
|
117
|
-
|
|
128
|
+
if (!alreadyInstalled) {
|
|
129
|
+
await installHook(profilePath)
|
|
130
|
+
logger.success('Rootless hook installed in PowerShell profile!')
|
|
118
131
|
logger.info(`Profile: ${profilePath}`)
|
|
132
|
+
} else {
|
|
133
|
+
logger.success('Rootless hook already installed.')
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// --profile-only: только установить профиль, без вывода кода в stdout
|
|
137
|
+
// Используется в postinstall при npm install -g
|
|
138
|
+
if (args.profileOnly) return
|
|
139
|
+
|
|
140
|
+
// Если stdout пайпится (Invoke-Expression) — выводим HOOK_BODY
|
|
141
|
+
// Если терминал — показываем подсказку
|
|
142
|
+
if (!process.stdout.isTTY) {
|
|
143
|
+
process.stdout.write(HOOK_BODY + '\n')
|
|
144
|
+
} else {
|
|
119
145
|
logger.info('')
|
|
120
|
-
logger.info('
|
|
121
|
-
logger.info('To activate in THIS session right now:')
|
|
146
|
+
logger.info('To activate the CURRENT session, run:')
|
|
122
147
|
logger.info('')
|
|
123
|
-
logger.info(' rootless activate
|
|
124
|
-
|
|
148
|
+
logger.info(' rootless activate | Invoke-Expression')
|
|
149
|
+
logger.info('')
|
|
150
|
+
logger.info('New PowerShell windows will activate automatically.')
|
|
151
|
+
logger.info('To remove the hook: rootless activate --remove')
|
|
125
152
|
}
|
|
126
|
-
|
|
127
|
-
await installHook(profilePath)
|
|
128
|
-
|
|
129
|
-
logger.success('Rootless hook installed!')
|
|
130
|
-
logger.info(`Profile: ${profilePath}`)
|
|
131
|
-
logger.info('')
|
|
132
|
-
logger.info('From now on, in ANY new PowerShell session:')
|
|
133
|
-
logger.info(' → navigate to a project with .root/')
|
|
134
|
-
logger.info(' → all files in .root/assets/ and .root/configs/ are in PATH')
|
|
135
|
-
logger.info(' → type .server.run, .server.ps1 etc. directly')
|
|
136
|
-
logger.info('')
|
|
137
|
-
logger.info('To activate in THIS session right now:')
|
|
138
|
-
logger.info('')
|
|
139
|
-
logger.info(' rootless activate --env | Invoke-Expression')
|
|
140
|
-
logger.info('')
|
|
141
|
-
logger.info('To remove the hook later:')
|
|
142
|
-
logger.info(' rootless activate --remove')
|
|
143
153
|
},
|
|
144
154
|
}
|
package/src/cli/index.js
CHANGED
|
@@ -27,8 +27,8 @@ async function run(argv) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (cmd.name === 'activate') {
|
|
30
|
-
sub.option('--remove',
|
|
31
|
-
sub.option('--
|
|
30
|
+
sub.option('--remove', 'Remove the hook from PowerShell profile')
|
|
31
|
+
sub.option('--profile-only', 'Install profile hook only, do not activate current session')
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
if (cmd.name === 'serve') {
|