@reconcrap/boss-recommend-mcp 2.1.21 → 2.1.22
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/README.md +5 -2
- package/bin/boss-recommend-mcp.js +4 -4
- package/config/screening-config.example.json +33 -33
- package/package.json +8 -8
- package/scripts/install-macos.sh +280 -280
- package/scripts/postinstall.cjs +44 -44
- package/skills/boss-chat/README.md +42 -42
- package/skills/boss-chat/SKILL.md +106 -106
- package/skills/boss-recommend-pipeline/README.md +13 -13
- package/skills/boss-recommend-pipeline/SKILL.md +219 -214
- package/skills/boss-recruit-pipeline/README.md +19 -19
- package/skills/boss-recruit-pipeline/SKILL.md +89 -89
- package/src/chat-mcp.js +127 -127
- package/src/chat-runtime-config.js +775 -775
- package/src/cli.js +573 -573
- package/src/core/boss-cards/index.js +199 -199
- package/src/core/browser/index.js +2419 -2415
- package/src/core/capture/index.js +1201 -1201
- package/src/core/cv-acquisition/index.js +238 -238
- package/src/core/cv-capture-target/index.js +299 -299
- package/src/core/greet-quota/index.js +71 -71
- package/src/core/infinite-list/index.js +1326 -1326
- package/src/core/reporting/legacy-csv.js +334 -332
- package/src/core/run/index.js +32 -32
- package/src/core/run/timing.js +33 -33
- package/src/core/screening/index.js +2135 -2135
- package/src/core/self-heal/index.js +973 -973
- package/src/core/self-heal/viewport.js +564 -564
- package/src/detached-worker.js +99 -99
- package/src/domains/chat/cards.js +137 -137
- package/src/domains/chat/constants.js +9 -9
- package/src/domains/chat/detail.js +113 -113
- package/src/domains/chat/index.js +7 -7
- package/src/domains/chat/jobs.js +620 -620
- package/src/domains/chat/page-guard.js +122 -122
- package/src/domains/chat/roots.js +56 -56
- package/src/domains/chat/run-service.js +571 -571
- package/src/domains/common/account-rights-panel.js +314 -314
- package/src/domains/common/recovery-settle.js +159 -159
- package/src/domains/recommend/actions.js +472 -472
- package/src/domains/recommend/cards.js +243 -243
- package/src/domains/recommend/colleague-contact.js +333 -333
- package/src/domains/recommend/constants.js +228 -159
- package/src/domains/recommend/detail.js +650 -650
- package/src/domains/recommend/filters.js +748 -377
- package/src/domains/recommend/index.js +4 -3
- package/src/domains/recommend/jobs.js +542 -542
- package/src/domains/recommend/location.js +736 -0
- package/src/domains/recommend/refresh.js +504 -361
- package/src/domains/recommend/roots.js +80 -80
- package/src/domains/recommend/run-service.js +987 -854
- package/src/domains/recommend/scopes.js +246 -246
- package/src/domains/recruit/actions.js +277 -277
- package/src/domains/recruit/cards.js +74 -74
- package/src/domains/recruit/constants.js +236 -236
- package/src/domains/recruit/detail.js +588 -588
- package/src/domains/recruit/index.js +9 -9
- package/src/domains/recruit/instruction-parser.js +866 -866
- package/src/domains/recruit/refresh.js +45 -45
- package/src/domains/recruit/roots.js +68 -68
- package/src/domains/recruit/run-service.js +1620 -1620
- package/src/domains/recruit/search.js +3229 -3229
- package/src/index.js +13 -0
- package/src/parser.js +376 -8
- package/src/recommend-mcp.js +929 -915
- package/src/recommend-scheduler.js +496 -496
- package/src/recruit-mcp.js +2121 -2121
package/scripts/install-macos.sh
CHANGED
|
@@ -1,280 +1,280 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
PACKAGE_NAME="@reconcrap/boss-recommend-mcp"
|
|
5
|
-
DEFAULT_NODE_VERSION="${BOSS_RECOMMEND_NODE_VERSION:-22}"
|
|
6
|
-
DEFAULT_NVM_VERSION="${BOSS_RECOMMEND_NVM_VERSION:-v0.40.4}"
|
|
7
|
-
|
|
8
|
-
NODE_VERSION="$DEFAULT_NODE_VERSION"
|
|
9
|
-
NVM_VERSION="$DEFAULT_NVM_VERSION"
|
|
10
|
-
AGENT="${BOSS_RECOMMEND_AGENT:-}"
|
|
11
|
-
DRY_RUN=0
|
|
12
|
-
SKIP_DOCTOR=0
|
|
13
|
-
SKIP_LLM_CONFIG=0
|
|
14
|
-
BASE_URL="${BOSS_RECOMMEND_BASE_URL:-https://api.openai.com/v1}"
|
|
15
|
-
API_KEY="${BOSS_RECOMMEND_API_KEY:-}"
|
|
16
|
-
MODEL="${BOSS_RECOMMEND_MODEL:-gpt-4.1-mini}"
|
|
17
|
-
THINKING_LEVEL="${BOSS_RECOMMEND_THINKING_LEVEL:-low}"
|
|
18
|
-
GREETING_MESSAGE="${BOSS_RECOMMEND_GREETING_MESSAGE:-Hi同学,能麻烦发下简历吗?}"
|
|
19
|
-
|
|
20
|
-
usage() {
|
|
21
|
-
cat <<'EOF'
|
|
22
|
-
Install boss-recommend-mcp on macOS with nvm-backed npm globals.
|
|
23
|
-
|
|
24
|
-
Usage:
|
|
25
|
-
install-macos.sh [--agent <agent|all>] [--node-version <version>] [--nvm-version <tag>] [--dry-run] [--skip-doctor] [--skip-llm-config]
|
|
26
|
-
|
|
27
|
-
Examples:
|
|
28
|
-
curl -fsSL https://raw.githubusercontent.com/reconcrap-cpu/boss-recommend-mcp/main/scripts/install-macos.sh | bash
|
|
29
|
-
curl -fsSL https://raw.githubusercontent.com/reconcrap-cpu/boss-recommend-mcp/main/scripts/install-macos.sh | bash -s -- --agent openclaw
|
|
30
|
-
|
|
31
|
-
Supported agents: cursor, trae, trae-cn, claude, openclaw, qclaw, all
|
|
32
|
-
|
|
33
|
-
LLM config can be supplied non-interactively with:
|
|
34
|
-
BOSS_RECOMMEND_BASE_URL, BOSS_RECOMMEND_API_KEY, BOSS_RECOMMEND_MODEL,
|
|
35
|
-
BOSS_RECOMMEND_THINKING_LEVEL, BOSS_RECOMMEND_GREETING_MESSAGE
|
|
36
|
-
EOF
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
log() {
|
|
40
|
-
printf '%s\n' "[boss-recommend-mcp] $*"
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
die() {
|
|
44
|
-
printf '%s\n' "[boss-recommend-mcp] ERROR: $*" >&2
|
|
45
|
-
exit 1
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
run() {
|
|
49
|
-
log "+ $*"
|
|
50
|
-
if [ "$DRY_RUN" -eq 0 ]; then
|
|
51
|
-
"$@"
|
|
52
|
-
fi
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
while [ "$#" -gt 0 ]; do
|
|
56
|
-
case "$1" in
|
|
57
|
-
--agent)
|
|
58
|
-
[ "$#" -ge 2 ] || die "--agent requires a value"
|
|
59
|
-
AGENT="$2"
|
|
60
|
-
shift 2
|
|
61
|
-
;;
|
|
62
|
-
--node-version)
|
|
63
|
-
[ "$#" -ge 2 ] || die "--node-version requires a value"
|
|
64
|
-
NODE_VERSION="$2"
|
|
65
|
-
shift 2
|
|
66
|
-
;;
|
|
67
|
-
--nvm-version)
|
|
68
|
-
[ "$#" -ge 2 ] || die "--nvm-version requires a value"
|
|
69
|
-
NVM_VERSION="$2"
|
|
70
|
-
shift 2
|
|
71
|
-
;;
|
|
72
|
-
--dry-run)
|
|
73
|
-
DRY_RUN=1
|
|
74
|
-
shift
|
|
75
|
-
;;
|
|
76
|
-
--skip-doctor)
|
|
77
|
-
SKIP_DOCTOR=1
|
|
78
|
-
shift
|
|
79
|
-
;;
|
|
80
|
-
--skip-llm-config)
|
|
81
|
-
SKIP_LLM_CONFIG=1
|
|
82
|
-
shift
|
|
83
|
-
;;
|
|
84
|
-
--base-url)
|
|
85
|
-
[ "$#" -ge 2 ] || die "--base-url requires a value"
|
|
86
|
-
BASE_URL="$2"
|
|
87
|
-
shift 2
|
|
88
|
-
;;
|
|
89
|
-
--api-key)
|
|
90
|
-
[ "$#" -ge 2 ] || die "--api-key requires a value"
|
|
91
|
-
API_KEY="$2"
|
|
92
|
-
shift 2
|
|
93
|
-
;;
|
|
94
|
-
--model)
|
|
95
|
-
[ "$#" -ge 2 ] || die "--model requires a value"
|
|
96
|
-
MODEL="$2"
|
|
97
|
-
shift 2
|
|
98
|
-
;;
|
|
99
|
-
--thinking-level)
|
|
100
|
-
[ "$#" -ge 2 ] || die "--thinking-level requires a value"
|
|
101
|
-
THINKING_LEVEL="$2"
|
|
102
|
-
shift 2
|
|
103
|
-
;;
|
|
104
|
-
--greeting-message)
|
|
105
|
-
[ "$#" -ge 2 ] || die "--greeting-message requires a value"
|
|
106
|
-
GREETING_MESSAGE="$2"
|
|
107
|
-
shift 2
|
|
108
|
-
;;
|
|
109
|
-
-h|--help)
|
|
110
|
-
usage
|
|
111
|
-
exit 0
|
|
112
|
-
;;
|
|
113
|
-
*)
|
|
114
|
-
die "Unknown option: $1"
|
|
115
|
-
;;
|
|
116
|
-
esac
|
|
117
|
-
done
|
|
118
|
-
|
|
119
|
-
prompt_text() {
|
|
120
|
-
local label="$1"
|
|
121
|
-
local default_value="$2"
|
|
122
|
-
local secret="${3:-0}"
|
|
123
|
-
local value
|
|
124
|
-
if [ ! -r /dev/tty ]; then
|
|
125
|
-
return 1
|
|
126
|
-
fi
|
|
127
|
-
if [ "$secret" -eq 1 ]; then
|
|
128
|
-
printf '%s' "${label}: " > /dev/tty
|
|
129
|
-
IFS= read -r -s value < /dev/tty || return 1
|
|
130
|
-
printf '\n' > /dev/tty
|
|
131
|
-
elif [ -n "$default_value" ]; then
|
|
132
|
-
printf '%s' "${label} [${default_value}]: " > /dev/tty
|
|
133
|
-
IFS= read -r value < /dev/tty || return 1
|
|
134
|
-
if [ -z "$value" ]; then
|
|
135
|
-
value="$default_value"
|
|
136
|
-
fi
|
|
137
|
-
else
|
|
138
|
-
printf '%s' "${label}: " > /dev/tty
|
|
139
|
-
IFS= read -r value < /dev/tty || return 1
|
|
140
|
-
fi
|
|
141
|
-
printf '%s' "$value"
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if [ "$(uname -s)" != "Darwin" ]; then
|
|
145
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
146
|
-
log "dry-run on non-macOS host; skipping platform enforcement"
|
|
147
|
-
else
|
|
148
|
-
die "This bootstrap script is for macOS. Use npm install -g ${PACKAGE_NAME}@latest on other platforms."
|
|
149
|
-
fi
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
153
|
-
|
|
154
|
-
load_nvm() {
|
|
155
|
-
if [ -s "$NVM_DIR/nvm.sh" ]; then
|
|
156
|
-
# shellcheck disable=SC1090
|
|
157
|
-
. "$NVM_DIR/nvm.sh"
|
|
158
|
-
elif [ -s "$HOME/.nvm/nvm.sh" ]; then
|
|
159
|
-
export NVM_DIR="$HOME/.nvm"
|
|
160
|
-
# shellcheck disable=SC1091
|
|
161
|
-
. "$HOME/.nvm/nvm.sh"
|
|
162
|
-
fi
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
install_nvm() {
|
|
166
|
-
if command -v nvm >/dev/null 2>&1; then
|
|
167
|
-
return
|
|
168
|
-
fi
|
|
169
|
-
log "nvm was not found; installing ${NVM_VERSION} into ${NVM_DIR}"
|
|
170
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
171
|
-
log "+ curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh | bash"
|
|
172
|
-
return
|
|
173
|
-
fi
|
|
174
|
-
curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash
|
|
175
|
-
load_nvm
|
|
176
|
-
command -v nvm >/dev/null 2>&1 || die "nvm installed but is not available in this shell. Open a new terminal and rerun this script."
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
load_nvm
|
|
180
|
-
install_nvm
|
|
181
|
-
|
|
182
|
-
run nvm install "$NODE_VERSION"
|
|
183
|
-
run nvm alias default "$NODE_VERSION"
|
|
184
|
-
run nvm use "$NODE_VERSION"
|
|
185
|
-
|
|
186
|
-
if [ "$DRY_RUN" -eq 0 ]; then
|
|
187
|
-
NODE_PATH="$(command -v node || true)"
|
|
188
|
-
NPM_PATH="$(command -v npm || true)"
|
|
189
|
-
NPM_PREFIX="$(npm config get prefix || true)"
|
|
190
|
-
log "node: ${NODE_PATH}"
|
|
191
|
-
log "npm: ${NPM_PATH}"
|
|
192
|
-
log "npm prefix: ${NPM_PREFIX}"
|
|
193
|
-
|
|
194
|
-
case "$NPM_PREFIX" in
|
|
195
|
-
/usr/local|/usr/local/*)
|
|
196
|
-
die "npm is still using /usr/local. Reload nvm and rerun this script; do not use sudo npm install -g."
|
|
197
|
-
;;
|
|
198
|
-
esac
|
|
199
|
-
case "$NPM_PREFIX" in
|
|
200
|
-
"$NVM_DIR"/*)
|
|
201
|
-
;;
|
|
202
|
-
*)
|
|
203
|
-
die "npm prefix is not under ${NVM_DIR}. Current prefix: ${NPM_PREFIX}"
|
|
204
|
-
;;
|
|
205
|
-
esac
|
|
206
|
-
else
|
|
207
|
-
log "+ verify: npm config get prefix must be under ${NVM_DIR}, not /usr/local"
|
|
208
|
-
fi
|
|
209
|
-
|
|
210
|
-
run npm -g i "${PACKAGE_NAME}@latest"
|
|
211
|
-
run boss-recommend-mcp where
|
|
212
|
-
|
|
213
|
-
INSTALL_ARGS=(install --mcp-launch global-wrapper)
|
|
214
|
-
DOCTOR_ARGS=(doctor)
|
|
215
|
-
if [ -n "$AGENT" ]; then
|
|
216
|
-
INSTALL_ARGS+=(--agent "$AGENT")
|
|
217
|
-
DOCTOR_ARGS+=(--agent "$AGENT")
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
run boss-recommend-mcp "${INSTALL_ARGS[@]}"
|
|
221
|
-
|
|
222
|
-
if [ "$SKIP_LLM_CONFIG" -eq 0 ]; then
|
|
223
|
-
log "LLM screening config is required before running candidate screening."
|
|
224
|
-
if [ "$DRY_RUN" -eq 0 ]; then
|
|
225
|
-
if [ -r /dev/tty ]; then
|
|
226
|
-
BASE_URL="$(prompt_text "LLM base URL" "$BASE_URL")"
|
|
227
|
-
MODEL="$(prompt_text "LLM model" "$MODEL")"
|
|
228
|
-
THINKING_LEVEL="$(prompt_text "LLM thinking level" "$THINKING_LEVEL")"
|
|
229
|
-
GREETING_MESSAGE="$(prompt_text "Greeting message for candidates" "$GREETING_MESSAGE")"
|
|
230
|
-
if [ -z "$API_KEY" ]; then
|
|
231
|
-
API_KEY="$(prompt_text "LLM API key (input hidden)" "" 1)"
|
|
232
|
-
fi
|
|
233
|
-
fi
|
|
234
|
-
if [ -z "$BASE_URL" ] || [ -z "$API_KEY" ] || [ -z "$MODEL" ]; then
|
|
235
|
-
cat >&2 <<EOF
|
|
236
|
-
[boss-recommend-mcp] LLM config is still required.
|
|
237
|
-
[boss-recommend-mcp] Ask the user for:
|
|
238
|
-
1. LLM base URL
|
|
239
|
-
2. LLM API key
|
|
240
|
-
3. LLM model name
|
|
241
|
-
[boss-recommend-mcp] Then run:
|
|
242
|
-
boss-recommend-mcp config set --base-url <baseUrl> --api-key <apiKey> --model <model> --thinking-level ${THINKING_LEVEL}
|
|
243
|
-
EOF
|
|
244
|
-
exit 2
|
|
245
|
-
fi
|
|
246
|
-
fi
|
|
247
|
-
|
|
248
|
-
CONFIG_ARGS=(config set --base-url "$BASE_URL" --api-key "$API_KEY" --model "$MODEL")
|
|
249
|
-
if [ -n "$THINKING_LEVEL" ]; then
|
|
250
|
-
CONFIG_ARGS+=(--thinking-level "$THINKING_LEVEL")
|
|
251
|
-
fi
|
|
252
|
-
if [ -n "$GREETING_MESSAGE" ]; then
|
|
253
|
-
CONFIG_ARGS+=(--greeting-message "$GREETING_MESSAGE")
|
|
254
|
-
fi
|
|
255
|
-
|
|
256
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
257
|
-
log "+ boss-recommend-mcp config set --base-url ${BASE_URL:-<baseUrl>} --api-key <hidden> --model ${MODEL:-<model>} --thinking-level ${THINKING_LEVEL:-<level>}"
|
|
258
|
-
else
|
|
259
|
-
log "+ boss-recommend-mcp config set --base-url ${BASE_URL} --api-key <hidden> --model ${MODEL}"
|
|
260
|
-
boss-recommend-mcp "${CONFIG_ARGS[@]}"
|
|
261
|
-
fi
|
|
262
|
-
else
|
|
263
|
-
log "Skipping LLM config because --skip-llm-config was provided."
|
|
264
|
-
fi
|
|
265
|
-
|
|
266
|
-
if [ "$SKIP_DOCTOR" -eq 0 ]; then
|
|
267
|
-
log "+ boss-recommend-mcp ${DOCTOR_ARGS[*]}"
|
|
268
|
-
if [ "$DRY_RUN" -eq 0 ]; then
|
|
269
|
-
if ! boss-recommend-mcp "${DOCTOR_ARGS[@]}"; then
|
|
270
|
-
log "doctor reported follow-up work. The npm package install still completed."
|
|
271
|
-
fi
|
|
272
|
-
fi
|
|
273
|
-
fi
|
|
274
|
-
|
|
275
|
-
cat <<EOF
|
|
276
|
-
[boss-recommend-mcp] install complete.
|
|
277
|
-
[boss-recommend-mcp] Future upgrades:
|
|
278
|
-
npm -g i ${PACKAGE_NAME}@latest
|
|
279
|
-
boss-recommend-mcp where
|
|
280
|
-
EOF
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PACKAGE_NAME="@reconcrap/boss-recommend-mcp"
|
|
5
|
+
DEFAULT_NODE_VERSION="${BOSS_RECOMMEND_NODE_VERSION:-22}"
|
|
6
|
+
DEFAULT_NVM_VERSION="${BOSS_RECOMMEND_NVM_VERSION:-v0.40.4}"
|
|
7
|
+
|
|
8
|
+
NODE_VERSION="$DEFAULT_NODE_VERSION"
|
|
9
|
+
NVM_VERSION="$DEFAULT_NVM_VERSION"
|
|
10
|
+
AGENT="${BOSS_RECOMMEND_AGENT:-}"
|
|
11
|
+
DRY_RUN=0
|
|
12
|
+
SKIP_DOCTOR=0
|
|
13
|
+
SKIP_LLM_CONFIG=0
|
|
14
|
+
BASE_URL="${BOSS_RECOMMEND_BASE_URL:-https://api.openai.com/v1}"
|
|
15
|
+
API_KEY="${BOSS_RECOMMEND_API_KEY:-}"
|
|
16
|
+
MODEL="${BOSS_RECOMMEND_MODEL:-gpt-4.1-mini}"
|
|
17
|
+
THINKING_LEVEL="${BOSS_RECOMMEND_THINKING_LEVEL:-low}"
|
|
18
|
+
GREETING_MESSAGE="${BOSS_RECOMMEND_GREETING_MESSAGE:-Hi同学,能麻烦发下简历吗?}"
|
|
19
|
+
|
|
20
|
+
usage() {
|
|
21
|
+
cat <<'EOF'
|
|
22
|
+
Install boss-recommend-mcp on macOS with nvm-backed npm globals.
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
install-macos.sh [--agent <agent|all>] [--node-version <version>] [--nvm-version <tag>] [--dry-run] [--skip-doctor] [--skip-llm-config]
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
curl -fsSL https://raw.githubusercontent.com/reconcrap-cpu/boss-recommend-mcp/main/scripts/install-macos.sh | bash
|
|
29
|
+
curl -fsSL https://raw.githubusercontent.com/reconcrap-cpu/boss-recommend-mcp/main/scripts/install-macos.sh | bash -s -- --agent openclaw
|
|
30
|
+
|
|
31
|
+
Supported agents: cursor, trae, trae-cn, claude, openclaw, qclaw, all
|
|
32
|
+
|
|
33
|
+
LLM config can be supplied non-interactively with:
|
|
34
|
+
BOSS_RECOMMEND_BASE_URL, BOSS_RECOMMEND_API_KEY, BOSS_RECOMMEND_MODEL,
|
|
35
|
+
BOSS_RECOMMEND_THINKING_LEVEL, BOSS_RECOMMEND_GREETING_MESSAGE
|
|
36
|
+
EOF
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
log() {
|
|
40
|
+
printf '%s\n' "[boss-recommend-mcp] $*"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
die() {
|
|
44
|
+
printf '%s\n' "[boss-recommend-mcp] ERROR: $*" >&2
|
|
45
|
+
exit 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
run() {
|
|
49
|
+
log "+ $*"
|
|
50
|
+
if [ "$DRY_RUN" -eq 0 ]; then
|
|
51
|
+
"$@"
|
|
52
|
+
fi
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
while [ "$#" -gt 0 ]; do
|
|
56
|
+
case "$1" in
|
|
57
|
+
--agent)
|
|
58
|
+
[ "$#" -ge 2 ] || die "--agent requires a value"
|
|
59
|
+
AGENT="$2"
|
|
60
|
+
shift 2
|
|
61
|
+
;;
|
|
62
|
+
--node-version)
|
|
63
|
+
[ "$#" -ge 2 ] || die "--node-version requires a value"
|
|
64
|
+
NODE_VERSION="$2"
|
|
65
|
+
shift 2
|
|
66
|
+
;;
|
|
67
|
+
--nvm-version)
|
|
68
|
+
[ "$#" -ge 2 ] || die "--nvm-version requires a value"
|
|
69
|
+
NVM_VERSION="$2"
|
|
70
|
+
shift 2
|
|
71
|
+
;;
|
|
72
|
+
--dry-run)
|
|
73
|
+
DRY_RUN=1
|
|
74
|
+
shift
|
|
75
|
+
;;
|
|
76
|
+
--skip-doctor)
|
|
77
|
+
SKIP_DOCTOR=1
|
|
78
|
+
shift
|
|
79
|
+
;;
|
|
80
|
+
--skip-llm-config)
|
|
81
|
+
SKIP_LLM_CONFIG=1
|
|
82
|
+
shift
|
|
83
|
+
;;
|
|
84
|
+
--base-url)
|
|
85
|
+
[ "$#" -ge 2 ] || die "--base-url requires a value"
|
|
86
|
+
BASE_URL="$2"
|
|
87
|
+
shift 2
|
|
88
|
+
;;
|
|
89
|
+
--api-key)
|
|
90
|
+
[ "$#" -ge 2 ] || die "--api-key requires a value"
|
|
91
|
+
API_KEY="$2"
|
|
92
|
+
shift 2
|
|
93
|
+
;;
|
|
94
|
+
--model)
|
|
95
|
+
[ "$#" -ge 2 ] || die "--model requires a value"
|
|
96
|
+
MODEL="$2"
|
|
97
|
+
shift 2
|
|
98
|
+
;;
|
|
99
|
+
--thinking-level)
|
|
100
|
+
[ "$#" -ge 2 ] || die "--thinking-level requires a value"
|
|
101
|
+
THINKING_LEVEL="$2"
|
|
102
|
+
shift 2
|
|
103
|
+
;;
|
|
104
|
+
--greeting-message)
|
|
105
|
+
[ "$#" -ge 2 ] || die "--greeting-message requires a value"
|
|
106
|
+
GREETING_MESSAGE="$2"
|
|
107
|
+
shift 2
|
|
108
|
+
;;
|
|
109
|
+
-h|--help)
|
|
110
|
+
usage
|
|
111
|
+
exit 0
|
|
112
|
+
;;
|
|
113
|
+
*)
|
|
114
|
+
die "Unknown option: $1"
|
|
115
|
+
;;
|
|
116
|
+
esac
|
|
117
|
+
done
|
|
118
|
+
|
|
119
|
+
prompt_text() {
|
|
120
|
+
local label="$1"
|
|
121
|
+
local default_value="$2"
|
|
122
|
+
local secret="${3:-0}"
|
|
123
|
+
local value
|
|
124
|
+
if [ ! -r /dev/tty ]; then
|
|
125
|
+
return 1
|
|
126
|
+
fi
|
|
127
|
+
if [ "$secret" -eq 1 ]; then
|
|
128
|
+
printf '%s' "${label}: " > /dev/tty
|
|
129
|
+
IFS= read -r -s value < /dev/tty || return 1
|
|
130
|
+
printf '\n' > /dev/tty
|
|
131
|
+
elif [ -n "$default_value" ]; then
|
|
132
|
+
printf '%s' "${label} [${default_value}]: " > /dev/tty
|
|
133
|
+
IFS= read -r value < /dev/tty || return 1
|
|
134
|
+
if [ -z "$value" ]; then
|
|
135
|
+
value="$default_value"
|
|
136
|
+
fi
|
|
137
|
+
else
|
|
138
|
+
printf '%s' "${label}: " > /dev/tty
|
|
139
|
+
IFS= read -r value < /dev/tty || return 1
|
|
140
|
+
fi
|
|
141
|
+
printf '%s' "$value"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if [ "$(uname -s)" != "Darwin" ]; then
|
|
145
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
146
|
+
log "dry-run on non-macOS host; skipping platform enforcement"
|
|
147
|
+
else
|
|
148
|
+
die "This bootstrap script is for macOS. Use npm install -g ${PACKAGE_NAME}@latest on other platforms."
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
153
|
+
|
|
154
|
+
load_nvm() {
|
|
155
|
+
if [ -s "$NVM_DIR/nvm.sh" ]; then
|
|
156
|
+
# shellcheck disable=SC1090
|
|
157
|
+
. "$NVM_DIR/nvm.sh"
|
|
158
|
+
elif [ -s "$HOME/.nvm/nvm.sh" ]; then
|
|
159
|
+
export NVM_DIR="$HOME/.nvm"
|
|
160
|
+
# shellcheck disable=SC1091
|
|
161
|
+
. "$HOME/.nvm/nvm.sh"
|
|
162
|
+
fi
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
install_nvm() {
|
|
166
|
+
if command -v nvm >/dev/null 2>&1; then
|
|
167
|
+
return
|
|
168
|
+
fi
|
|
169
|
+
log "nvm was not found; installing ${NVM_VERSION} into ${NVM_DIR}"
|
|
170
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
171
|
+
log "+ curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh | bash"
|
|
172
|
+
return
|
|
173
|
+
fi
|
|
174
|
+
curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash
|
|
175
|
+
load_nvm
|
|
176
|
+
command -v nvm >/dev/null 2>&1 || die "nvm installed but is not available in this shell. Open a new terminal and rerun this script."
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
load_nvm
|
|
180
|
+
install_nvm
|
|
181
|
+
|
|
182
|
+
run nvm install "$NODE_VERSION"
|
|
183
|
+
run nvm alias default "$NODE_VERSION"
|
|
184
|
+
run nvm use "$NODE_VERSION"
|
|
185
|
+
|
|
186
|
+
if [ "$DRY_RUN" -eq 0 ]; then
|
|
187
|
+
NODE_PATH="$(command -v node || true)"
|
|
188
|
+
NPM_PATH="$(command -v npm || true)"
|
|
189
|
+
NPM_PREFIX="$(npm config get prefix || true)"
|
|
190
|
+
log "node: ${NODE_PATH}"
|
|
191
|
+
log "npm: ${NPM_PATH}"
|
|
192
|
+
log "npm prefix: ${NPM_PREFIX}"
|
|
193
|
+
|
|
194
|
+
case "$NPM_PREFIX" in
|
|
195
|
+
/usr/local|/usr/local/*)
|
|
196
|
+
die "npm is still using /usr/local. Reload nvm and rerun this script; do not use sudo npm install -g."
|
|
197
|
+
;;
|
|
198
|
+
esac
|
|
199
|
+
case "$NPM_PREFIX" in
|
|
200
|
+
"$NVM_DIR"/*)
|
|
201
|
+
;;
|
|
202
|
+
*)
|
|
203
|
+
die "npm prefix is not under ${NVM_DIR}. Current prefix: ${NPM_PREFIX}"
|
|
204
|
+
;;
|
|
205
|
+
esac
|
|
206
|
+
else
|
|
207
|
+
log "+ verify: npm config get prefix must be under ${NVM_DIR}, not /usr/local"
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
run npm -g i "${PACKAGE_NAME}@latest"
|
|
211
|
+
run boss-recommend-mcp where
|
|
212
|
+
|
|
213
|
+
INSTALL_ARGS=(install --mcp-launch global-wrapper)
|
|
214
|
+
DOCTOR_ARGS=(doctor)
|
|
215
|
+
if [ -n "$AGENT" ]; then
|
|
216
|
+
INSTALL_ARGS+=(--agent "$AGENT")
|
|
217
|
+
DOCTOR_ARGS+=(--agent "$AGENT")
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
run boss-recommend-mcp "${INSTALL_ARGS[@]}"
|
|
221
|
+
|
|
222
|
+
if [ "$SKIP_LLM_CONFIG" -eq 0 ]; then
|
|
223
|
+
log "LLM screening config is required before running candidate screening."
|
|
224
|
+
if [ "$DRY_RUN" -eq 0 ]; then
|
|
225
|
+
if [ -r /dev/tty ]; then
|
|
226
|
+
BASE_URL="$(prompt_text "LLM base URL" "$BASE_URL")"
|
|
227
|
+
MODEL="$(prompt_text "LLM model" "$MODEL")"
|
|
228
|
+
THINKING_LEVEL="$(prompt_text "LLM thinking level" "$THINKING_LEVEL")"
|
|
229
|
+
GREETING_MESSAGE="$(prompt_text "Greeting message for candidates" "$GREETING_MESSAGE")"
|
|
230
|
+
if [ -z "$API_KEY" ]; then
|
|
231
|
+
API_KEY="$(prompt_text "LLM API key (input hidden)" "" 1)"
|
|
232
|
+
fi
|
|
233
|
+
fi
|
|
234
|
+
if [ -z "$BASE_URL" ] || [ -z "$API_KEY" ] || [ -z "$MODEL" ]; then
|
|
235
|
+
cat >&2 <<EOF
|
|
236
|
+
[boss-recommend-mcp] LLM config is still required.
|
|
237
|
+
[boss-recommend-mcp] Ask the user for:
|
|
238
|
+
1. LLM base URL
|
|
239
|
+
2. LLM API key
|
|
240
|
+
3. LLM model name
|
|
241
|
+
[boss-recommend-mcp] Then run:
|
|
242
|
+
boss-recommend-mcp config set --base-url <baseUrl> --api-key <apiKey> --model <model> --thinking-level ${THINKING_LEVEL}
|
|
243
|
+
EOF
|
|
244
|
+
exit 2
|
|
245
|
+
fi
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
CONFIG_ARGS=(config set --base-url "$BASE_URL" --api-key "$API_KEY" --model "$MODEL")
|
|
249
|
+
if [ -n "$THINKING_LEVEL" ]; then
|
|
250
|
+
CONFIG_ARGS+=(--thinking-level "$THINKING_LEVEL")
|
|
251
|
+
fi
|
|
252
|
+
if [ -n "$GREETING_MESSAGE" ]; then
|
|
253
|
+
CONFIG_ARGS+=(--greeting-message "$GREETING_MESSAGE")
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
257
|
+
log "+ boss-recommend-mcp config set --base-url ${BASE_URL:-<baseUrl>} --api-key <hidden> --model ${MODEL:-<model>} --thinking-level ${THINKING_LEVEL:-<level>}"
|
|
258
|
+
else
|
|
259
|
+
log "+ boss-recommend-mcp config set --base-url ${BASE_URL} --api-key <hidden> --model ${MODEL}"
|
|
260
|
+
boss-recommend-mcp "${CONFIG_ARGS[@]}"
|
|
261
|
+
fi
|
|
262
|
+
else
|
|
263
|
+
log "Skipping LLM config because --skip-llm-config was provided."
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
if [ "$SKIP_DOCTOR" -eq 0 ]; then
|
|
267
|
+
log "+ boss-recommend-mcp ${DOCTOR_ARGS[*]}"
|
|
268
|
+
if [ "$DRY_RUN" -eq 0 ]; then
|
|
269
|
+
if ! boss-recommend-mcp "${DOCTOR_ARGS[@]}"; then
|
|
270
|
+
log "doctor reported follow-up work. The npm package install still completed."
|
|
271
|
+
fi
|
|
272
|
+
fi
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
cat <<EOF
|
|
276
|
+
[boss-recommend-mcp] install complete.
|
|
277
|
+
[boss-recommend-mcp] Future upgrades:
|
|
278
|
+
npm -g i ${PACKAGE_NAME}@latest
|
|
279
|
+
boss-recommend-mcp where
|
|
280
|
+
EOF
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const path = require("node:path");
|
|
4
|
-
const { spawnSync } = require("node:child_process");
|
|
5
|
-
|
|
6
|
-
function isGlobalInstall() {
|
|
7
|
-
if (String(process.env.npm_config_global || "").toLowerCase() === "true") return true;
|
|
8
|
-
if (String(process.env.npm_config_location || "").toLowerCase() === "global") return true;
|
|
9
|
-
|
|
10
|
-
const argvRaw = String(process.env.npm_config_argv || "");
|
|
11
|
-
if (argvRaw.includes("--global") || argvRaw.includes(" -g ")) return true;
|
|
12
|
-
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function main() {
|
|
17
|
-
const cliPath = path.join(__dirname, "..", "src", "cli.js");
|
|
18
|
-
if (!fs.existsSync(cliPath)) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const initCwd = String(process.env.INIT_CWD || "").trim();
|
|
23
|
-
const workspaceArgs = initCwd ? ["--workspace-root", path.resolve(initCwd)] : [];
|
|
24
|
-
const cliArgs = isGlobalInstall()
|
|
25
|
-
? [cliPath, "install", ...workspaceArgs]
|
|
26
|
-
: [cliPath, "init-config", ...workspaceArgs];
|
|
27
|
-
|
|
28
|
-
const result = spawnSync(process.execPath, cliArgs, {
|
|
29
|
-
cwd: path.join(__dirname, ".."),
|
|
30
|
-
stdio: "inherit",
|
|
31
|
-
windowsHide: true,
|
|
32
|
-
shell: false
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (result.error) {
|
|
36
|
-
console.warn(`[boss-recommend-mcp] postinstall warning: ${result.error.message}`);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (typeof result.status === "number" && result.status !== 0) {
|
|
40
|
-
console.warn(`[boss-recommend-mcp] postinstall warning: install exited with code ${result.status}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { spawnSync } = require("node:child_process");
|
|
5
|
+
|
|
6
|
+
function isGlobalInstall() {
|
|
7
|
+
if (String(process.env.npm_config_global || "").toLowerCase() === "true") return true;
|
|
8
|
+
if (String(process.env.npm_config_location || "").toLowerCase() === "global") return true;
|
|
9
|
+
|
|
10
|
+
const argvRaw = String(process.env.npm_config_argv || "");
|
|
11
|
+
if (argvRaw.includes("--global") || argvRaw.includes(" -g ")) return true;
|
|
12
|
+
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function main() {
|
|
17
|
+
const cliPath = path.join(__dirname, "..", "src", "cli.js");
|
|
18
|
+
if (!fs.existsSync(cliPath)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const initCwd = String(process.env.INIT_CWD || "").trim();
|
|
23
|
+
const workspaceArgs = initCwd ? ["--workspace-root", path.resolve(initCwd)] : [];
|
|
24
|
+
const cliArgs = isGlobalInstall()
|
|
25
|
+
? [cliPath, "install", ...workspaceArgs]
|
|
26
|
+
: [cliPath, "init-config", ...workspaceArgs];
|
|
27
|
+
|
|
28
|
+
const result = spawnSync(process.execPath, cliArgs, {
|
|
29
|
+
cwd: path.join(__dirname, ".."),
|
|
30
|
+
stdio: "inherit",
|
|
31
|
+
windowsHide: true,
|
|
32
|
+
shell: false
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (result.error) {
|
|
36
|
+
console.warn(`[boss-recommend-mcp] postinstall warning: ${result.error.message}`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (typeof result.status === "number" && result.status !== 0) {
|
|
40
|
+
console.warn(`[boss-recommend-mcp] postinstall warning: install exited with code ${result.status}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main();
|