@springbrand/cli 0.1.0
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 +167 -0
- package/dist/commands/auth.d.ts +4 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +241 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/check-version.d.ts +3 -0
- package/dist/commands/check-version.d.ts.map +1 -0
- package/dist/commands/check-version.js +112 -0
- package/dist/commands/check-version.js.map +1 -0
- package/dist/commands/config-claude.d.ts +4 -0
- package/dist/commands/config-claude.d.ts.map +1 -0
- package/dist/commands/config-claude.js +78 -0
- package/dist/commands/config-claude.js.map +1 -0
- package/dist/commands/connect.d.ts +41 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +901 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/doctor.d.ts +6 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +124 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/upgrade.d.ts +9 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +133 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/agent-detect.d.ts +33 -0
- package/dist/lib/agent-detect.d.ts.map +1 -0
- package/dist/lib/agent-detect.js +81 -0
- package/dist/lib/agent-detect.js.map +1 -0
- package/dist/lib/agent-launcher.d.ts +22 -0
- package/dist/lib/agent-launcher.d.ts.map +1 -0
- package/dist/lib/agent-launcher.js +67 -0
- package/dist/lib/agent-launcher.js.map +1 -0
- package/dist/lib/auth.d.ts +90 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +327 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/bundled-skill.d.ts +5 -0
- package/dist/lib/bundled-skill.d.ts.map +1 -0
- package/dist/lib/bundled-skill.js +13 -0
- package/dist/lib/bundled-skill.js.map +1 -0
- package/dist/lib/claude-config.d.ts +19 -0
- package/dist/lib/claude-config.d.ts.map +1 -0
- package/dist/lib/claude-config.js +202 -0
- package/dist/lib/claude-config.js.map +1 -0
- package/dist/lib/cli-install.d.ts +40 -0
- package/dist/lib/cli-install.d.ts.map +1 -0
- package/dist/lib/cli-install.js +42 -0
- package/dist/lib/cli-install.js.map +1 -0
- package/dist/lib/command-code-config.d.ts +5 -0
- package/dist/lib/command-code-config.d.ts.map +1 -0
- package/dist/lib/command-code-config.js +16 -0
- package/dist/lib/command-code-config.js.map +1 -0
- package/dist/lib/connect-all-auth.d.ts +21 -0
- package/dist/lib/connect-all-auth.d.ts.map +1 -0
- package/dist/lib/connect-all-auth.js +113 -0
- package/dist/lib/connect-all-auth.js.map +1 -0
- package/dist/lib/connect-all-summary.d.ts +10 -0
- package/dist/lib/connect-all-summary.d.ts.map +1 -0
- package/dist/lib/connect-all-summary.js +153 -0
- package/dist/lib/connect-all-summary.js.map +1 -0
- package/dist/lib/connect-all-uninstall.d.ts +7 -0
- package/dist/lib/connect-all-uninstall.d.ts.map +1 -0
- package/dist/lib/connect-all-uninstall.js +249 -0
- package/dist/lib/connect-all-uninstall.js.map +1 -0
- package/dist/lib/connect-all.d.ts +42 -0
- package/dist/lib/connect-all.d.ts.map +1 -0
- package/dist/lib/connect-all.js +438 -0
- package/dist/lib/connect-all.js.map +1 -0
- package/dist/lib/connect-auth.d.ts +7 -0
- package/dist/lib/connect-auth.d.ts.map +1 -0
- package/dist/lib/connect-auth.js +50 -0
- package/dist/lib/connect-auth.js.map +1 -0
- package/dist/lib/connect-clients.d.ts +108 -0
- package/dist/lib/connect-clients.d.ts.map +1 -0
- package/dist/lib/connect-clients.js +358 -0
- package/dist/lib/connect-clients.js.map +1 -0
- package/dist/lib/connect-fallback.d.ts +27 -0
- package/dist/lib/connect-fallback.d.ts.map +1 -0
- package/dist/lib/connect-fallback.js +166 -0
- package/dist/lib/connect-fallback.js.map +1 -0
- package/dist/lib/connect-picker.d.ts +19 -0
- package/dist/lib/connect-picker.d.ts.map +1 -0
- package/dist/lib/connect-picker.js +155 -0
- package/dist/lib/connect-picker.js.map +1 -0
- package/dist/lib/connect-preflight.d.ts +17 -0
- package/dist/lib/connect-preflight.d.ts.map +1 -0
- package/dist/lib/connect-preflight.js +81 -0
- package/dist/lib/connect-preflight.js.map +1 -0
- package/dist/lib/connect-runtime.d.ts +109 -0
- package/dist/lib/connect-runtime.d.ts.map +1 -0
- package/dist/lib/connect-runtime.js +360 -0
- package/dist/lib/connect-runtime.js.map +1 -0
- package/dist/lib/constants.d.ts +23 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +87 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/cursor-config.d.ts +16 -0
- package/dist/lib/cursor-config.d.ts.map +1 -0
- package/dist/lib/cursor-config.js +34 -0
- package/dist/lib/cursor-config.js.map +1 -0
- package/dist/lib/doctor-checks.d.ts +21 -0
- package/dist/lib/doctor-checks.d.ts.map +1 -0
- package/dist/lib/doctor-checks.js +312 -0
- package/dist/lib/doctor-checks.js.map +1 -0
- package/dist/lib/doctor-repairs.d.ts +11 -0
- package/dist/lib/doctor-repairs.d.ts.map +1 -0
- package/dist/lib/doctor-repairs.js +130 -0
- package/dist/lib/doctor-repairs.js.map +1 -0
- package/dist/lib/doctor-report.d.ts +195 -0
- package/dist/lib/doctor-report.d.ts.map +1 -0
- package/dist/lib/doctor-report.js +102 -0
- package/dist/lib/doctor-report.js.map +1 -0
- package/dist/lib/doctor-telemetry.d.ts +9 -0
- package/dist/lib/doctor-telemetry.d.ts.map +1 -0
- package/dist/lib/doctor-telemetry.js +63 -0
- package/dist/lib/doctor-telemetry.js.map +1 -0
- package/dist/lib/harness-detect.d.ts +33 -0
- package/dist/lib/harness-detect.d.ts.map +1 -0
- package/dist/lib/harness-detect.js +70 -0
- package/dist/lib/harness-detect.js.map +1 -0
- package/dist/lib/harness-spec.d.ts +285 -0
- package/dist/lib/harness-spec.d.ts.map +1 -0
- package/dist/lib/harness-spec.js +268 -0
- package/dist/lib/harness-spec.js.map +1 -0
- package/dist/lib/harness.d.ts +27 -0
- package/dist/lib/harness.d.ts.map +1 -0
- package/dist/lib/harness.js +125 -0
- package/dist/lib/harness.js.map +1 -0
- package/dist/lib/hermes-config.d.ts +22 -0
- package/dist/lib/hermes-config.d.ts.map +1 -0
- package/dist/lib/hermes-config.js +76 -0
- package/dist/lib/hermes-config.js.map +1 -0
- package/dist/lib/hermes-env.d.ts +19 -0
- package/dist/lib/hermes-env.d.ts.map +1 -0
- package/dist/lib/hermes-env.js +169 -0
- package/dist/lib/hermes-env.js.map +1 -0
- package/dist/lib/hermes-plugin.d.ts +40 -0
- package/dist/lib/hermes-plugin.d.ts.map +1 -0
- package/dist/lib/hermes-plugin.js +168 -0
- package/dist/lib/hermes-plugin.js.map +1 -0
- package/dist/lib/install-root.d.ts +18 -0
- package/dist/lib/install-root.d.ts.map +1 -0
- package/dist/lib/install-root.js +55 -0
- package/dist/lib/install-root.js.map +1 -0
- package/dist/lib/mcp-config.d.ts +36 -0
- package/dist/lib/mcp-config.d.ts.map +1 -0
- package/dist/lib/mcp-config.js +90 -0
- package/dist/lib/mcp-config.js.map +1 -0
- package/dist/lib/mcp-endpoint.d.ts +16 -0
- package/dist/lib/mcp-endpoint.d.ts.map +1 -0
- package/dist/lib/mcp-endpoint.js +41 -0
- package/dist/lib/mcp-endpoint.js.map +1 -0
- package/dist/lib/mcp-json-config.d.ts +43 -0
- package/dist/lib/mcp-json-config.d.ts.map +1 -0
- package/dist/lib/mcp-json-config.js +164 -0
- package/dist/lib/mcp-json-config.js.map +1 -0
- package/dist/lib/notice.d.ts +13 -0
- package/dist/lib/notice.d.ts.map +1 -0
- package/dist/lib/notice.js +73 -0
- package/dist/lib/notice.js.map +1 -0
- package/dist/lib/omp-config.d.ts +18 -0
- package/dist/lib/omp-config.d.ts.map +1 -0
- package/dist/lib/omp-config.js +73 -0
- package/dist/lib/omp-config.js.map +1 -0
- package/dist/lib/output.d.ts +22 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +92 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/pi-config.d.ts +27 -0
- package/dist/lib/pi-config.d.ts.map +1 -0
- package/dist/lib/pi-config.js +113 -0
- package/dist/lib/pi-config.js.map +1 -0
- package/dist/lib/registration-detect.d.ts +28 -0
- package/dist/lib/registration-detect.d.ts.map +1 -0
- package/dist/lib/registration-detect.js +563 -0
- package/dist/lib/registration-detect.js.map +1 -0
- package/dist/lib/setup-telemetry.d.ts +273 -0
- package/dist/lib/setup-telemetry.d.ts.map +1 -0
- package/dist/lib/setup-telemetry.js +309 -0
- package/dist/lib/setup-telemetry.js.map +1 -0
- package/dist/lib/signals.d.ts +14 -0
- package/dist/lib/signals.d.ts.map +1 -0
- package/dist/lib/signals.js +29 -0
- package/dist/lib/signals.js.map +1 -0
- package/dist/lib/skill-install.d.ts +10 -0
- package/dist/lib/skill-install.d.ts.map +1 -0
- package/dist/lib/skill-install.js +94 -0
- package/dist/lib/skill-install.js.map +1 -0
- package/dist/lib/skill-paths.d.ts +7 -0
- package/dist/lib/skill-paths.d.ts.map +1 -0
- package/dist/lib/skill-paths.js +37 -0
- package/dist/lib/skill-paths.js.map +1 -0
- package/dist/lib/skill-vendor.d.ts +20 -0
- package/dist/lib/skill-vendor.d.ts.map +1 -0
- package/dist/lib/skill-vendor.js +215 -0
- package/dist/lib/skill-vendor.js.map +1 -0
- package/dist/lib/skill.d.ts +14 -0
- package/dist/lib/skill.d.ts.map +1 -0
- package/dist/lib/skill.js +87 -0
- package/dist/lib/skill.js.map +1 -0
- package/dist/lib/verify.d.ts +35 -0
- package/dist/lib/verify.d.ts.map +1 -0
- package/dist/lib/verify.js +169 -0
- package/dist/lib/verify.js.map +1 -0
- package/dist/program.d.ts +8 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +54 -0
- package/dist/program.js.map +1 -0
- package/package.json +55 -0
- package/skill/springbrand-action-api/SKILL.md +49 -0
- package/skill/springbrand-action-api/references/action-aliases.md +156 -0
- package/skill/springbrand-action-api/references/action-discovery.md +95 -0
- package/skill/springbrand-connector/SKILL.md +49 -0
- package/skill/springbrand-gtm/SKILL.md +34 -0
- package/skill/springbrand-platform/SKILL.md +55 -0
- package/skill/springbrand-platform/references/plugin-discovery.md +94 -0
- package/skill/use-springbrand/SKILL.md +70 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/** 复刻自 tiny-fish CLI 编译产物:connect-runtime.d.ts + connect-runtime.impl.js */
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import spawn from 'cross-spawn';
|
|
4
|
+
import { CONNECT_ATTEMPT_ENV, isAttemptId, takePendingConnectAttempt, } from './auth.js';
|
|
5
|
+
import { CLI_INVOCATION_ID, CLI_VERSION } from './constants.js';
|
|
6
|
+
import { detectHarness, detectHumanInitiated, detectRuntimeEnv } from './harness.js';
|
|
7
|
+
import { boundedVersion, errLine, sanitizeLine } from './output.js';
|
|
8
|
+
import { postConnectEvent, telemetryDisabled } from './setup-telemetry.js';
|
|
9
|
+
import { installSignalGuard } from './signals.js';
|
|
10
|
+
export const NON_INTERACTIVE_TIMEOUT_MS = 10_000;
|
|
11
|
+
// Mirrors the route's Zod enum; tests both sides pin it.
|
|
12
|
+
export const CONNECT_FAILURE_REASONS = [
|
|
13
|
+
'harness_not_installed',
|
|
14
|
+
'harness_command_unsupported',
|
|
15
|
+
'harness_too_old',
|
|
16
|
+
'key_auth_unsupported',
|
|
17
|
+
'command_not_found',
|
|
18
|
+
'timeout',
|
|
19
|
+
'spawn_error',
|
|
20
|
+
'nonzero_exit',
|
|
21
|
+
'invalid_config',
|
|
22
|
+
'user_abandoned',
|
|
23
|
+
'process_terminated',
|
|
24
|
+
'unexpected_error',
|
|
25
|
+
];
|
|
26
|
+
/** Ctrl+C killed a setup child — abandonment, not error. */
|
|
27
|
+
export class ConnectInterruptedError extends Error {
|
|
28
|
+
}
|
|
29
|
+
/** Carried hoisted-install failure an earlier harness already reported. */
|
|
30
|
+
export class HoistedFailureReportedError extends Error {
|
|
31
|
+
}
|
|
32
|
+
/** A classified step failure; runGuarded forwards the reason. */
|
|
33
|
+
export class ConnectStepError extends Error {
|
|
34
|
+
failureReason;
|
|
35
|
+
harnessVersion;
|
|
36
|
+
failureDetail;
|
|
37
|
+
constructor(message, failureReason, opts) {
|
|
38
|
+
super(message, { cause: opts?.cause });
|
|
39
|
+
this.failureReason = failureReason;
|
|
40
|
+
this.harnessVersion = opts?.harnessVersion;
|
|
41
|
+
this.failureDetail = opts?.failureDetail;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Hoisted install predates this attempt's telemetry; the gap reads ~0 ms. */
|
|
45
|
+
export function withStageDuration(error, stageDurationMs) {
|
|
46
|
+
error.stageDurationMs = stageDurationMs;
|
|
47
|
+
return error;
|
|
48
|
+
}
|
|
49
|
+
export function stageDurationOf(error) {
|
|
50
|
+
const value = error?.stageDurationMs;
|
|
51
|
+
return typeof value === 'number' ? value : undefined;
|
|
52
|
+
}
|
|
53
|
+
/** A bounded sign-in wait elapsed — unfinished, not broken. */
|
|
54
|
+
export class SignInTimeoutError extends ConnectStepError {
|
|
55
|
+
constructor(message, cause) {
|
|
56
|
+
super(message, 'timeout', { cause });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// A maxBuffer overflow is also killed with SIGTERM, and is a failure too.
|
|
60
|
+
const NOT_INTERRUPTIONS = new Set(['ETIMEDOUT', 'ENOBUFS']);
|
|
61
|
+
export function throwIfInterrupted(result) {
|
|
62
|
+
// spawn.sync kills a timed-out child with SIGTERM, so signal alone would misread a slow
|
|
63
|
+
// network as the user walking away. A timeout is a failure and must report as one.
|
|
64
|
+
const code = result.error?.code;
|
|
65
|
+
if (code && NOT_INTERRUPTIONS.has(code))
|
|
66
|
+
return;
|
|
67
|
+
if (result.signal === 'SIGINT') {
|
|
68
|
+
throw new ConnectInterruptedError('Setup interrupted');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Bounded removal spawn shared by install cleanup and --uninstall; Ctrl+C throws. */
|
|
72
|
+
export function spawnRemoval(command, args, timeoutMs) {
|
|
73
|
+
const result = spawn.sync(command, [...args], {
|
|
74
|
+
encoding: 'utf8',
|
|
75
|
+
timeout: timeoutMs,
|
|
76
|
+
});
|
|
77
|
+
throwIfInterrupted(result);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
// Sanitized before the cut so the count is not spent on invisible bytes.
|
|
81
|
+
const STDERR_TAIL_MAX_CHARS = 400;
|
|
82
|
+
/** Outcome plus a bounded stderr tail; the route sanitizes and caps the rest. */
|
|
83
|
+
export function spawnFailureDetail(result) {
|
|
84
|
+
const stderr = typeof result.stderr === 'string'
|
|
85
|
+
? sanitizeLine(result.stderr.trim()).slice(-STDERR_TAIL_MAX_CHARS)
|
|
86
|
+
: '';
|
|
87
|
+
// A signal kill leaves status null, where the signal is the diagnosis.
|
|
88
|
+
const outcome = result.signal ? `signal=${result.signal}` : `exit=${result.status}`;
|
|
89
|
+
return `${outcome}${stderr ? ` | ${stderr}` : ''}`;
|
|
90
|
+
}
|
|
91
|
+
/** Classifies a spawn failure; interrupts throw instead. */
|
|
92
|
+
export function spawnStepError(message, result, failureDetail) {
|
|
93
|
+
throwIfInterrupted(result);
|
|
94
|
+
const code = result.error?.code;
|
|
95
|
+
const reason = !result.error
|
|
96
|
+
? 'nonzero_exit'
|
|
97
|
+
: code === 'ENOENT'
|
|
98
|
+
? 'command_not_found'
|
|
99
|
+
: code === 'ETIMEDOUT'
|
|
100
|
+
? 'timeout'
|
|
101
|
+
: 'spawn_error';
|
|
102
|
+
const detail = failureDetail ?? (reason === 'nonzero_exit' ? spawnFailureDetail(result) : undefined);
|
|
103
|
+
return new ConnectStepError(message, reason, { cause: result.error, failureDetail: detail });
|
|
104
|
+
}
|
|
105
|
+
export function commandNotFound(error) {
|
|
106
|
+
return error?.code === 'ENOENT';
|
|
107
|
+
}
|
|
108
|
+
/** One command redoes every post-install step for a client. */
|
|
109
|
+
export function finishSetupCommand(client) {
|
|
110
|
+
return `npx -y @springbrand/cli@latest connect ${client}`;
|
|
111
|
+
}
|
|
112
|
+
/** Terminal events exactly once, whichever of flow or signal handler wins. */
|
|
113
|
+
export function settle(state, telemetry, stage, detail) {
|
|
114
|
+
if (state.settled)
|
|
115
|
+
return;
|
|
116
|
+
state.settled = true;
|
|
117
|
+
telemetry.track(stage, { harnessDegraded: state.harnessDegraded, ...detail });
|
|
118
|
+
}
|
|
119
|
+
// Raw-mode children still surface via throwIfInterrupted; cooked-mode stages
|
|
120
|
+
// (npm/npx/OAuth waits) land here.
|
|
121
|
+
function installConnectSignalGuard(state, telemetry) {
|
|
122
|
+
return installSignalGuard(async (signal) => {
|
|
123
|
+
if (!state.settled) {
|
|
124
|
+
settle(state, telemetry, 'aborted', {
|
|
125
|
+
failedStage: state.stage,
|
|
126
|
+
failureReason: signal === 'SIGINT' ? 'user_abandoned' : 'process_terminated',
|
|
127
|
+
});
|
|
128
|
+
errLine('Setup interrupted — run the command again to finish.');
|
|
129
|
+
}
|
|
130
|
+
// Settled spans the whole post-install phase; the `completed` POST may still be in flight.
|
|
131
|
+
await telemetry.flush();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/** Shared terminal handling: interrupted → aborted, else failed. */
|
|
135
|
+
export async function runGuarded(state, telemetry, body) {
|
|
136
|
+
const uninstallSignalGuard = installConnectSignalGuard(state, telemetry);
|
|
137
|
+
try {
|
|
138
|
+
await body();
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
if (error instanceof ConnectInterruptedError) {
|
|
142
|
+
settle(state, telemetry, 'aborted', {
|
|
143
|
+
failedStage: state.stage,
|
|
144
|
+
failureReason: 'user_abandoned',
|
|
145
|
+
});
|
|
146
|
+
errLine('Setup interrupted — run the command again to finish.');
|
|
147
|
+
process.exitCode = 130;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// An elapsed sign-in wait is abandonment, not breakage.
|
|
151
|
+
if (error instanceof SignInTimeoutError) {
|
|
152
|
+
settle(state, telemetry, 'aborted', {
|
|
153
|
+
failedStage: state.stage,
|
|
154
|
+
failureReason: 'timeout',
|
|
155
|
+
failureDetail: error.failureDetail ?? error.message,
|
|
156
|
+
});
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
// An earlier attempt owns the shared failure's terminal row.
|
|
160
|
+
if (error instanceof HoistedFailureReportedError)
|
|
161
|
+
throw error;
|
|
162
|
+
settle(state, telemetry, 'failed', {
|
|
163
|
+
failedStage: state.stage,
|
|
164
|
+
failureReason: error instanceof ConnectStepError ? error.failureReason : 'unexpected_error',
|
|
165
|
+
...(error instanceof ConnectStepError
|
|
166
|
+
? {
|
|
167
|
+
harnessVersion: error.harnessVersion,
|
|
168
|
+
failureDetail: error.failureDetail ?? error.message,
|
|
169
|
+
}
|
|
170
|
+
: {}),
|
|
171
|
+
stageDurationMs: stageDurationOf(error),
|
|
172
|
+
});
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
uninstallSignalGuard();
|
|
177
|
+
await telemetry.flush();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function probeTimeoutMs(client) {
|
|
181
|
+
return client.supportCheck.timeoutMs ?? NON_INTERACTIVE_TIMEOUT_MS;
|
|
182
|
+
}
|
|
183
|
+
function throwProbeFailure(client, result) {
|
|
184
|
+
throwIfInterrupted(result);
|
|
185
|
+
// A hung probe is a timeout, not a missing capability.
|
|
186
|
+
if (result.error?.code === 'ETIMEDOUT') {
|
|
187
|
+
const probe = `${client.command} ${client.supportCheck.args.join(' ')}`;
|
|
188
|
+
throw new ConnectStepError(`${client.displayName} did not respond to \`${probe}\` within ` +
|
|
189
|
+
`${probeTimeoutMs(client) / 1000}s. Retry.`, 'timeout', { cause: result.error });
|
|
190
|
+
}
|
|
191
|
+
// It ran and exited non-zero, so the version is still answerable.
|
|
192
|
+
throw new ConnectStepError(client.supportCheck.unavailableMessage, 'harness_command_unsupported', { cause: result.error, harnessVersion: probeHarnessVersion(client) });
|
|
193
|
+
}
|
|
194
|
+
function supportProbeOutput(client) {
|
|
195
|
+
const result = spawn.sync(client.command, client.supportCheck.args, {
|
|
196
|
+
encoding: 'utf8',
|
|
197
|
+
// Agent harnesses export FORCE_COLOR, which makes clients colourise even a piped --help.
|
|
198
|
+
env: { ...process.env, FORCE_COLOR: '0', NO_COLOR: '1' },
|
|
199
|
+
timeout: probeTimeoutMs(client),
|
|
200
|
+
});
|
|
201
|
+
// 127 is the shell's not-found code; a wrapper shim with no real binary behind it exits that.
|
|
202
|
+
if (commandNotFound(result.error) || result.status === 127) {
|
|
203
|
+
throw new ConnectStepError(`${client.displayName} is not installed or not available on PATH.`, 'harness_not_installed', { cause: result.error });
|
|
204
|
+
}
|
|
205
|
+
if (result.error || result.status !== 0) {
|
|
206
|
+
throwProbeFailure(client, result);
|
|
207
|
+
}
|
|
208
|
+
// Belt and braces with the colour env: a client that ignores NO_COLOR still has to match.
|
|
209
|
+
return sanitizeLine(`${result.stdout ?? ''}\n${result.stderr ?? ''}`);
|
|
210
|
+
}
|
|
211
|
+
function debugProbeOutput(client, output) {
|
|
212
|
+
if (!process.env['SPRINGBRAND_DEBUG'])
|
|
213
|
+
return;
|
|
214
|
+
errLine(`${client.command} ${client.supportCheck.args.join(' ')} printed:\n${output.trim()}`);
|
|
215
|
+
}
|
|
216
|
+
function requireEssential(client, output) {
|
|
217
|
+
if (client.supportCheck.patterns.every((pattern) => pattern.test(output)))
|
|
218
|
+
return;
|
|
219
|
+
debugProbeOutput(client, output);
|
|
220
|
+
throw new ConnectStepError(client.supportCheck.unavailableMessage, 'harness_too_old', {
|
|
221
|
+
harnessVersion: probeHarnessVersion(client),
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
/** Absence is a fact; an unknown flag means an upstream rename. */
|
|
225
|
+
function resolveVariant(client, output) {
|
|
226
|
+
const check = client.supportCheck;
|
|
227
|
+
// Token equality, not a built regex: exact on both edges, and no dynamic RegExp.
|
|
228
|
+
const listed = new Set(output.split(/[\s,=]+/));
|
|
229
|
+
const matched = check.variants?.find((flag) => listed.has(flag));
|
|
230
|
+
if (matched)
|
|
231
|
+
return matched;
|
|
232
|
+
const unknown = check.unknownVariant?.exec(output)?.[0];
|
|
233
|
+
if (unknown === undefined)
|
|
234
|
+
return undefined;
|
|
235
|
+
// Unacknowledged policy warnings can block the install; fail before it does.
|
|
236
|
+
debugProbeOutput(client, output);
|
|
237
|
+
throw new ConnectStepError(`${client.displayName} lists \`${unknown}\`, which this SpringBrand CLI does not recognise. ` +
|
|
238
|
+
'Upgrade the SpringBrand CLI with `sp upgrade` and retry.', 'harness_too_old', { harnessVersion: probeHarnessVersion(client) });
|
|
239
|
+
}
|
|
240
|
+
/** Refresh paths need the advertised alternative without connect's version probe. */
|
|
241
|
+
export function probeSupportVariant(client) {
|
|
242
|
+
const output = supportProbeOutput(client);
|
|
243
|
+
requireEssential(client, output);
|
|
244
|
+
return resolveVariant(client, output);
|
|
245
|
+
}
|
|
246
|
+
export function requireCommandSupport(client) {
|
|
247
|
+
const output = supportProbeOutput(client);
|
|
248
|
+
requireEssential(client, output);
|
|
249
|
+
const optionalSupported = (client.supportCheck.optionalPatterns ?? []).every((pattern) => pattern.test(output));
|
|
250
|
+
const keyAuthPattern = client.supportCheck.keyAuthPattern;
|
|
251
|
+
const keyAuthSupported = keyAuthPattern ? keyAuthPattern.test(output) : true;
|
|
252
|
+
if (!optionalSupported || !keyAuthSupported)
|
|
253
|
+
debugProbeOutput(client, output);
|
|
254
|
+
return {
|
|
255
|
+
optionalSupported,
|
|
256
|
+
keyAuthSupported,
|
|
257
|
+
matchedVariant: resolveVariant(client, output),
|
|
258
|
+
harnessVersion: probeHarnessVersion(client),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/** Best-effort; the server rejects non-printable characters and >32 chars. */
|
|
262
|
+
function probeHarnessVersion(client) {
|
|
263
|
+
const result = spawn.sync(client.command, ['--version'], {
|
|
264
|
+
encoding: 'utf8',
|
|
265
|
+
timeout: probeTimeoutMs(client),
|
|
266
|
+
});
|
|
267
|
+
if (result.error || result.status !== 0)
|
|
268
|
+
return undefined;
|
|
269
|
+
return boundedVersion(result.stdout ?? '');
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* One page-minted id seeds one install attempt, so `sp onboard` connecting three agents
|
|
273
|
+
* does not report three installs under it. Later connects in the run fall back to a random id.
|
|
274
|
+
*/
|
|
275
|
+
function takeSeedAttemptId() {
|
|
276
|
+
const fromEnv = process.env[CONNECT_ATTEMPT_ENV];
|
|
277
|
+
// Both sources are read-and-clear, and the delete lands before any subprocess inherits it.
|
|
278
|
+
delete process.env[CONNECT_ATTEMPT_ENV];
|
|
279
|
+
const parked = takePendingConnectAttempt();
|
|
280
|
+
return fromEnv && isAttemptId(fromEnv) ? fromEnv : parked;
|
|
281
|
+
}
|
|
282
|
+
// postConnectEvent is total, so this only fires on a bug inside deliver.
|
|
283
|
+
function reportDeliverBug(error) {
|
|
284
|
+
if (!process.env['SPRINGBRAND_DEBUG'])
|
|
285
|
+
return;
|
|
286
|
+
errLine(`connect telemetry failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
287
|
+
}
|
|
288
|
+
export function createConnectTelemetry(mcpUrl, client, opts) {
|
|
289
|
+
// Consumed even when --url already supplied an id: leaving it behind would let a stale
|
|
290
|
+
// seed reach the agent this connect launches, or the next connect on this machine.
|
|
291
|
+
const seeded = takeSeedAttemptId();
|
|
292
|
+
// A setup-page id (via --url, the env var, or one parked by login) joins "copied the
|
|
293
|
+
// command" to this install attempt.
|
|
294
|
+
const attemptId = opts?.attemptId ?? seeded ?? opts?.fallbackAttemptId ?? randomUUID();
|
|
295
|
+
const endpoint = new URL('/api/cli/connect-event', mcpUrl).toString();
|
|
296
|
+
const pending = [];
|
|
297
|
+
let lastTrackAt;
|
|
298
|
+
let harnessVersion;
|
|
299
|
+
let fallbackOutcome;
|
|
300
|
+
async function deliver(body) {
|
|
301
|
+
// postConnectEvent's own opt-out check is too late to skip the work above it.
|
|
302
|
+
if (telemetryDisabled())
|
|
303
|
+
return;
|
|
304
|
+
await postConnectEvent({ endpoint, body, attempts: 2, label: 'connect' });
|
|
305
|
+
}
|
|
306
|
+
function eventBody(stage, detail, stageDurationMs) {
|
|
307
|
+
return JSON.stringify({
|
|
308
|
+
attempt_id: attemptId,
|
|
309
|
+
client,
|
|
310
|
+
stage,
|
|
311
|
+
failed_stage: detail?.failedStage,
|
|
312
|
+
phase: detail?.phase,
|
|
313
|
+
failure_reason: detail?.failureReason,
|
|
314
|
+
// Only with failed_stage: the route refine 400s the event otherwise.
|
|
315
|
+
failure_detail: detail?.failedStage ? detail.failureDetail : undefined,
|
|
316
|
+
// Terminal rows only: rescue checkpoints stay wire-identical to normal ones.
|
|
317
|
+
fallback_outcome: stage === 'failed' || stage === 'aborted' ? fallbackOutcome : undefined,
|
|
318
|
+
harness_version: detail?.harnessVersion ?? harnessVersion,
|
|
319
|
+
plugin_version: detail?.pluginVersion,
|
|
320
|
+
auth_mode: detail?.authMode,
|
|
321
|
+
harness_degraded: detail?.harnessDegraded,
|
|
322
|
+
stage_duration_ms: stageDurationMs,
|
|
323
|
+
runtime_platform: process.platform,
|
|
324
|
+
node_version: process.version,
|
|
325
|
+
cli_version: CLI_VERSION,
|
|
326
|
+
// Same signal the usage events carry, so TTY and headless connects can be split.
|
|
327
|
+
is_human_initiated: detectHumanInitiated(),
|
|
328
|
+
// "none", not absent — absent has to keep meaning "CLI too old".
|
|
329
|
+
calling_harness: detectHarness() ?? 'none',
|
|
330
|
+
cli_invocation_id: CLI_INVOCATION_ID,
|
|
331
|
+
runtime_env: detectRuntimeEnv(),
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
attemptId,
|
|
336
|
+
// Fire-and-forget; awaiting each event stalls setup when telemetry down.
|
|
337
|
+
setHarnessVersion(version) {
|
|
338
|
+
harnessVersion = version;
|
|
339
|
+
},
|
|
340
|
+
setFallbackOutcome(outcome) {
|
|
341
|
+
fallbackOutcome = outcome;
|
|
342
|
+
},
|
|
343
|
+
track(stage, detail) {
|
|
344
|
+
const now = Date.now();
|
|
345
|
+
// Clamped: a backward clock step would send a route-rejected negative.
|
|
346
|
+
const stageDurationMs = detail?.stageDurationMs ??
|
|
347
|
+
(lastTrackAt === undefined ? undefined : Math.max(0, now - lastTrackAt));
|
|
348
|
+
lastTrackAt = now;
|
|
349
|
+
// Absorbed here, not in flush: flush runs in runGuarded's finally, so a rejection would
|
|
350
|
+
// replace the error the flow is already reporting.
|
|
351
|
+
pending.push(deliver(eventBody(stage, detail, stageDurationMs)).catch(reportDeliverBug));
|
|
352
|
+
},
|
|
353
|
+
// Awaited in finally so in-flight events land before exit. Drains, so the signal-guard
|
|
354
|
+
// flush and the finally flush do not re-await the same events.
|
|
355
|
+
async flush() {
|
|
356
|
+
await Promise.all(pending.splice(0));
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=connect-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-runtime.js","sourceRoot":"","sources":["../../src/lib/connect-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** 复刻自 tiny-fish CLI 编译产物:constants.d.ts + constants.impl.js */
|
|
2
|
+
export declare const CLI_VERSION: string;
|
|
3
|
+
/** One id per CLI process; joins events across commands (PF-3779). */
|
|
4
|
+
export declare const CLI_INVOCATION_ID: string;
|
|
5
|
+
/** Unversioned: the install site appends `@latest`, the version read must not. */
|
|
6
|
+
export declare const SPRINGBRAND_CLI_PACKAGE = "@springbrand/cli";
|
|
7
|
+
export declare const CLI_AGENT_IDENTITY = "springbrand-cli";
|
|
8
|
+
/** Names the bundled dir, every install target dir, and the lock entry. */
|
|
9
|
+
export declare const WEB_SKILL_NAME = "use-springbrand";
|
|
10
|
+
/** The CLI installs one common entry skill plus the domain guidance it references. */
|
|
11
|
+
export declare const BUNDLED_SKILL_NAMES: readonly ["use-springbrand", "springbrand-platform", "springbrand-action-api", "springbrand-connector", "springbrand-gtm"];
|
|
12
|
+
/** The descriptor hands this name to harnesses; the probes resolve it. */
|
|
13
|
+
export declare const SPRINGBRAND_API_KEY_VAR = "SPRINGBRAND_API_KEY";
|
|
14
|
+
export declare const BASE_URL: string;
|
|
15
|
+
export declare const API_URL_OVERRIDE: string | undefined;
|
|
16
|
+
export declare const WEB_APP_URL: string;
|
|
17
|
+
/** URL where users can create and manage API keys */
|
|
18
|
+
export declare function getDashboardUrl(source?: string): string;
|
|
19
|
+
export declare const DASHBOARD_URL: string;
|
|
20
|
+
export declare const HARNESS_PROBE_TIMEOUT_MS = 15000;
|
|
21
|
+
/** Hermes' own id for the SpringBrand web plugin. */
|
|
22
|
+
export declare const HERMES_PLUGIN_NAME = "springbrand";
|
|
23
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAMhE,eAAO,MAAM,WAAW,EAAE,MAAqB,CAAC;AAChD,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,EAAE,MAAqB,CAAC;AACtD,kFAAkF;AAClF,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AACpD,2EAA2E;AAC3E,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAChD,sFAAsF;AACtF,eAAO,MAAM,mBAAmB,4HAMtB,CAAC;AACX,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAkB7D,eAAO,MAAM,QAAQ,EAAE,MAA6D,CAAC;AAGrF,eAAO,MAAM,gBAAgB,EAAE,MAAM,GAAG,SAA0B,CAAC;AAUnE,eAAO,MAAM,WAAW,EAAE,MAAiE,CAAC;AAsB5F,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAIvD;AACD,eAAO,MAAM,aAAa,EAAE,MAA0B,CAAC;AACvD,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/** 复刻自 tiny-fish CLI 编译产物:constants.d.ts + constants.impl.js */
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { createRequire } from 'module';
|
|
4
|
+
const _require = createRequire(import.meta.url);
|
|
5
|
+
const _pkg = _require('../../package.json');
|
|
6
|
+
export const CLI_VERSION = _pkg.version;
|
|
7
|
+
/** One id per CLI process; joins events across commands (PF-3779). */
|
|
8
|
+
export const CLI_INVOCATION_ID = randomUUID();
|
|
9
|
+
/** Unversioned: the install site appends `@latest`, the version read must not. */
|
|
10
|
+
export const SPRINGBRAND_CLI_PACKAGE = '@springbrand/cli';
|
|
11
|
+
// How we identify ourselves to other tools; `skills` echoes it back.
|
|
12
|
+
export const CLI_AGENT_IDENTITY = 'springbrand-cli';
|
|
13
|
+
/** Names the bundled dir, every install target dir, and the lock entry. */
|
|
14
|
+
export const WEB_SKILL_NAME = 'use-springbrand';
|
|
15
|
+
/** The CLI installs one common entry skill plus the domain guidance it references. */
|
|
16
|
+
export const BUNDLED_SKILL_NAMES = [
|
|
17
|
+
WEB_SKILL_NAME,
|
|
18
|
+
'springbrand-platform',
|
|
19
|
+
'springbrand-action-api',
|
|
20
|
+
'springbrand-connector',
|
|
21
|
+
'springbrand-gtm',
|
|
22
|
+
];
|
|
23
|
+
/** The descriptor hands this name to harnesses; the probes resolve it. */
|
|
24
|
+
export const SPRINGBRAND_API_KEY_VAR = 'SPRINGBRAND_API_KEY';
|
|
25
|
+
/** Base URL for the SpringBrand API. Override with SPRINGBRAND_API_URL for staging/self-hosted. */
|
|
26
|
+
const apiUrlOverride = process.env['SPRINGBRAND_API_URL']?.trim() || undefined;
|
|
27
|
+
if (apiUrlOverride) {
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = new URL(apiUrlOverride);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
process.stderr.write('Error: SPRINGBRAND_API_URL must be a valid https URL\n');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const loopbackHttp = parsed.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(parsed.hostname);
|
|
37
|
+
if (parsed.protocol !== 'https:' && !loopbackHttp) {
|
|
38
|
+
process.stderr.write(`Error: SPRINGBRAND_API_URL must use https:// (got protocol "${parsed.protocol || 'unknown'}")\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export const BASE_URL = apiUrlOverride ?? 'https://connector.springbrand.ai';
|
|
43
|
+
// Left undefined, the SDK sends Search and Fetch to their own hosts, which are the ones
|
|
44
|
+
// behind the API gateway.
|
|
45
|
+
export const API_URL_OVERRIDE = apiUrlOverride;
|
|
46
|
+
/**
|
|
47
|
+
* Where a user creates and copies an MCP API key. Placeholder: the page belongs to the
|
|
48
|
+
* sp-platform web app and its path is not final yet, so `sp auth login` opens the settings area
|
|
49
|
+
* rather than a key page that may not exist.
|
|
50
|
+
*
|
|
51
|
+
* Deliberately independent of `SPRINGBRAND_API_URL`: pointing the MCP endpoint at a local
|
|
52
|
+
* worker must not move the browser page a human is told to visit.
|
|
53
|
+
*/
|
|
54
|
+
const webUrlOverride = process.env['SPRINGBRAND_WEB_URL']?.trim() || undefined;
|
|
55
|
+
export const WEB_APP_URL = parsedOrigin(webUrlOverride) ?? 'https://springbrand.ai';
|
|
56
|
+
const DASHBOARD_PATH = '/account-settings';
|
|
57
|
+
function parsedOrigin(value) {
|
|
58
|
+
if (!value)
|
|
59
|
+
return undefined;
|
|
60
|
+
try {
|
|
61
|
+
return new URL(value).origin;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
process.stderr.write('Warning: SPRINGBRAND_WEB_URL is not a valid URL; using the default.\n');
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const DEFAULT_DASHBOARD_SOURCE = 'cli';
|
|
69
|
+
const DASHBOARD_SOURCE_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
70
|
+
function normalizeDashboardSource(source) {
|
|
71
|
+
const normalized = source?.trim().toLowerCase();
|
|
72
|
+
if (!normalized || !DASHBOARD_SOURCE_PATTERN.test(normalized)) {
|
|
73
|
+
return DEFAULT_DASHBOARD_SOURCE;
|
|
74
|
+
}
|
|
75
|
+
return normalized;
|
|
76
|
+
}
|
|
77
|
+
/** URL where users can create and manage API keys */
|
|
78
|
+
export function getDashboardUrl(source) {
|
|
79
|
+
const url = new URL(`${WEB_APP_URL}${DASHBOARD_PATH}`);
|
|
80
|
+
url.searchParams.set('source', normalizeDashboardSource(source));
|
|
81
|
+
return url.toString();
|
|
82
|
+
}
|
|
83
|
+
export const DASHBOARD_URL = getDashboardUrl();
|
|
84
|
+
export const HARNESS_PROBE_TIMEOUT_MS = 15_000;
|
|
85
|
+
/** Hermes' own id for the SpringBrand web plugin. */
|
|
86
|
+
export const HERMES_PLUGIN_NAME = 'springbrand';
|
|
87
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** 复刻自 tiny-fish CLI 编译产物:cursor-config.d.ts + cursor-config.impl.js */
|
|
2
|
+
import type { McpJsonServerEntry, McpJsonWriteResult } from './mcp-json-config.js';
|
|
3
|
+
export declare function cursorMcpPath(): string;
|
|
4
|
+
/** Dry-run description of the pending write; touches nothing. */
|
|
5
|
+
export declare function planCursorWrite(mcpUrl: string, apiKey?: string): string;
|
|
6
|
+
/** Reports the header's shape, never its value. */
|
|
7
|
+
export declare function readCursorSpringbrandEntry(): CursorSpringbrandEntry;
|
|
8
|
+
/** Merges only the `springbrand` key; skips unreadable/corrupt files rather than clobber. */
|
|
9
|
+
export declare function writeCursorMcpConfig(mcpUrl: string, apiKey?: string): CursorMcpWriteResult;
|
|
10
|
+
/** Removes only the `springbrand` key. */
|
|
11
|
+
export declare function removeCursorMcpServer(): CursorMcpWriteResult;
|
|
12
|
+
/** Cursor deeplink format: cursor://anysphere.cursor-deeplink/mcp/install?name=$NAME&config=$BASE64 */
|
|
13
|
+
export declare function cursorInstallDeeplink(mcpUrl: string): string;
|
|
14
|
+
export type CursorMcpWriteResult = McpJsonWriteResult;
|
|
15
|
+
export type CursorSpringbrandEntry = McpJsonServerEntry;
|
|
16
|
+
//# sourceMappingURL=cursor-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-config.d.ts","sourceRoot":"","sources":["../../src/lib/cursor-config.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AASnF,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AACD,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvE;AACD,mDAAmD;AACnD,wBAAgB,0BAA0B,IAAI,sBAAsB,CAEnE;AACD,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAE1F;AACD,0CAA0C;AAC1C,wBAAgB,qBAAqB,IAAI,oBAAoB,CAE5D;AACD,uGAAuG;AACvG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG5D;AAGD,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEtD,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** 复刻自 tiny-fish CLI 编译产物:cursor-config.d.ts + cursor-config.impl.js */
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { buildSpringbrandServerEntry, planWrite, readSpringbrandEntry, removeServer, writeMcpConfig, } from './mcp-json-config.js';
|
|
5
|
+
const CURSOR_TARGET = {
|
|
6
|
+
serverKey: 'springbrand',
|
|
7
|
+
dir: () => path.join(os.homedir(), '.cursor'),
|
|
8
|
+
file: () => path.join(os.homedir(), '.cursor', 'mcp.json'),
|
|
9
|
+
};
|
|
10
|
+
export function cursorMcpPath() {
|
|
11
|
+
return CURSOR_TARGET.file();
|
|
12
|
+
}
|
|
13
|
+
/** Dry-run description of the pending write; touches nothing. */
|
|
14
|
+
export function planCursorWrite(mcpUrl, apiKey) {
|
|
15
|
+
return planWrite(CURSOR_TARGET, mcpUrl, apiKey);
|
|
16
|
+
}
|
|
17
|
+
/** Reports the header's shape, never its value. */
|
|
18
|
+
export function readCursorSpringbrandEntry() {
|
|
19
|
+
return readSpringbrandEntry(CURSOR_TARGET);
|
|
20
|
+
}
|
|
21
|
+
/** Merges only the `springbrand` key; skips unreadable/corrupt files rather than clobber. */
|
|
22
|
+
export function writeCursorMcpConfig(mcpUrl, apiKey) {
|
|
23
|
+
return writeMcpConfig(CURSOR_TARGET, mcpUrl, apiKey);
|
|
24
|
+
}
|
|
25
|
+
/** Removes only the `springbrand` key. */
|
|
26
|
+
export function removeCursorMcpServer() {
|
|
27
|
+
return removeServer(CURSOR_TARGET);
|
|
28
|
+
}
|
|
29
|
+
/** Cursor deeplink format: cursor://anysphere.cursor-deeplink/mcp/install?name=$NAME&config=$BASE64 */
|
|
30
|
+
export function cursorInstallDeeplink(mcpUrl) {
|
|
31
|
+
const config = Buffer.from(JSON.stringify(buildSpringbrandServerEntry(mcpUrl))).toString('base64');
|
|
32
|
+
return `cursor://anysphere.cursor-deeplink/mcp/install?name=${CURSOR_TARGET.serverKey}&config=${encodeURIComponent(config)}`;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=cursor-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-config.js","sourceRoot":"","sources":["../../src/lib/cursor-config.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,oBAAoB,EAAE,YAAY,EAAE,cAAc,GAAG,MAAM,sBAAsB,CAAC;AACnI,MAAM,aAAa,GAAG;IAClB,SAAS,EAAE,aAAa;IACxB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC;IAC7C,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;CAC7D,CAAC;AACF,MAAM,UAAU,aAAa;IACzB,OAAO,aAAa,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC;AACD,iEAAiE;AACjE,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,MAAe;IAC3D,OAAO,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AACD,mDAAmD;AACnD,MAAM,UAAU,0BAA0B;IACtC,OAAO,oBAAoB,CAAC,aAAa,CAAC,CAAC;AAC/C,CAAC;AACD,6FAA6F;AAC7F,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,MAAe;IAChE,OAAO,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AACD,0CAA0C;AAC1C,MAAM,UAAU,qBAAqB;IACjC,OAAO,YAAY,CAAC,aAAa,CAAC,CAAC;AACvC,CAAC;AACD,uGAAuG;AACvG,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnG,OAAO,uDAAuD,aAAa,CAAC,SAAS,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AACjI,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** 复刻自 tiny-fish CLI 编译产物:doctor-checks.d.ts + doctor-checks.impl.js */
|
|
2
|
+
import type { DoctorCheck } from './doctor-report.js';
|
|
3
|
+
import type { RegistrationStatus } from './registration-detect.js';
|
|
4
|
+
import type { VerifyResult } from './verify.js';
|
|
5
|
+
export declare function provesHarnessReach(status: RegistrationStatus, keyAuth: VerifyResult | undefined, healthOk: boolean, mcpUrl: string): boolean;
|
|
6
|
+
export declare function checkCliVersion(): DoctorCheck;
|
|
7
|
+
export declare function checkConnectivity(mcpUrl: string): Promise<DoctorCheck>;
|
|
8
|
+
export declare function checkRegistration(status: RegistrationStatus, mcpUrl: string, keyAuth: VerifyResult | undefined, cliKeyMissing: boolean): DoctorCheck;
|
|
9
|
+
export declare function checkCredential(): {
|
|
10
|
+
check: DoctorCheck;
|
|
11
|
+
key?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function checkAuthCall(auth: VerifyResult | undefined): DoctorCheck;
|
|
14
|
+
export declare function verifyHarnessKey(status: RegistrationStatus, cliAuth: Promise<VerifyResult> | undefined, mcpUrl: string): Promise<VerifyResult> | undefined;
|
|
15
|
+
export declare function checkPiAdapter(status: RegistrationStatus): DoctorCheck;
|
|
16
|
+
export declare function checkHermesPlugin(status: RegistrationStatus): HermesPluginResult;
|
|
17
|
+
export interface HermesPluginResult {
|
|
18
|
+
check: DoctorCheck;
|
|
19
|
+
observedVersion?: string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=doctor-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-checks.d.ts","sourceRoot":"","sources":["../../src/lib/doctor-checks.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,YAAY,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAe5I;AAED,wBAAgB,eAAe,IAAI,WAAW,CAS7C;AACD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAW5E;AA+FD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,SAAS,EAAE,aAAa,EAAE,OAAO,GAAG,WAAW,CAQpJ;AACD,wBAAgB,eAAe,IAAI;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB,CAWA;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,CAuBzE;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAQ1J;AA2DD,wBAAgB,cAAc,CAAC,MAAM,EAAE,kBAAkB,GAAG,WAAW,CAgCtE;AACD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAqBhF;AAGD,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B"}
|