@numa-tech/numa 1.11.14 → 1.12.2
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 +197 -25
- package/dist/ai-registry/client.d.ts +65 -0
- package/dist/ai-registry/client.js +260 -0
- package/dist/ai-registry/client.js.map +1 -0
- package/dist/ai-registry/commands.d.ts +2 -0
- package/dist/ai-registry/commands.js +438 -0
- package/dist/ai-registry/commands.js.map +1 -0
- package/dist/ai-registry/errors.d.ts +8 -0
- package/dist/ai-registry/errors.js +40 -0
- package/dist/ai-registry/errors.js.map +1 -0
- package/dist/ai-registry/mcp-installer.d.ts +37 -0
- package/dist/ai-registry/mcp-installer.js +273 -0
- package/dist/ai-registry/mcp-installer.js.map +1 -0
- package/dist/ai-registry/schemas.d.ts +86 -0
- package/dist/ai-registry/schemas.js +39 -0
- package/dist/ai-registry/schemas.js.map +1 -0
- package/dist/ai-registry/skill-installer.d.ts +21 -0
- package/dist/ai-registry/skill-installer.js +262 -0
- package/dist/ai-registry/skill-installer.js.map +1 -0
- package/dist/app-config.d.ts +4 -2
- package/dist/app-config.js +15 -3
- package/dist/app-config.js.map +1 -1
- package/dist/cli.js +40 -12
- package/dist/cli.js.map +1 -1
- package/dist/codex-module.d.ts +8 -0
- package/dist/codex-module.js +152 -0
- package/dist/codex-module.js.map +1 -0
- package/dist/command-catalog.js +170 -64
- package/dist/command-catalog.js.map +1 -1
- package/dist/config-page.js +17 -0
- package/dist/config-page.js.map +1 -1
- package/dist/config.d.ts +4 -1
- package/dist/config.js +26 -7
- package/dist/config.js.map +1 -1
- package/dist/media/commands.js +12 -11
- package/dist/media/commands.js.map +1 -1
- package/dist/oauth.d.ts +2 -30
- package/dist/oauth.js +1 -294
- package/dist/oauth.js.map +1 -1
- package/dist/pipeline/client.d.ts +126 -0
- package/dist/pipeline/client.js +105 -0
- package/dist/pipeline/client.js.map +1 -0
- package/dist/pipeline/commands.d.ts +17 -0
- package/dist/pipeline/commands.js +283 -0
- package/dist/pipeline/commands.js.map +1 -0
- package/dist/pipeline/errors.d.ts +8 -0
- package/dist/pipeline/errors.js +37 -0
- package/dist/pipeline/errors.js.map +1 -0
- package/dist/pipeline/schemas.d.ts +243 -0
- package/dist/pipeline/schemas.js +60 -0
- package/dist/pipeline/schemas.js.map +1 -0
- package/dist/platform-profile.d.ts +75 -0
- package/dist/platform-profile.js +169 -0
- package/dist/platform-profile.js.map +1 -0
- package/dist/types.d.ts +1 -40
- package/dist/web-console-page.d.ts +2 -2
- package/dist/web-console-page.js +21 -7
- package/dist/web-console-page.js.map +1 -1
- package/dist/web-console.d.ts +17 -3
- package/dist/web-console.js +70 -5
- package/dist/web-console.js.map +1 -1
- package/examples/claude-desktop-npx.json +1 -1
- package/examples/codex-npx.json +1 -1
- package/package.json +30 -14
- package/skills/numa-ai-registry/SKILL.md +47 -0
- package/skills/numa-ai-registry/evals/evals.json +35 -0
- package/skills/numa-ai-registry/references/command-contract.md +53 -0
- package/assets/codex-shortcut-icon.icns +0 -0
- package/assets/codex-shortcut-icon.ico +0 -0
- package/dist/chatgpt-console.d.ts +0 -53
- package/dist/chatgpt-console.js +0 -105
- package/dist/chatgpt-console.js.map +0 -1
- package/dist/codex-auth-agent.d.ts +0 -60
- package/dist/codex-auth-agent.js +0 -331
- package/dist/codex-auth-agent.js.map +0 -1
- package/dist/codex-commands.d.ts +0 -13
- package/dist/codex-commands.js +0 -571
- package/dist/codex-commands.js.map +0 -1
- package/dist/codex-legacy-cleanup.d.ts +0 -5
- package/dist/codex-legacy-cleanup.js +0 -77
- package/dist/codex-legacy-cleanup.js.map +0 -1
- package/dist/codex-process.d.ts +0 -13
- package/dist/codex-process.js +0 -193
- package/dist/codex-process.js.map +0 -1
- package/dist/codex-protocol.d.ts +0 -352
- package/dist/codex-protocol.js +0 -116
- package/dist/codex-protocol.js.map +0 -1
- package/dist/codex-quota-cache.d.ts +0 -20
- package/dist/codex-quota-cache.js +0 -82
- package/dist/codex-quota-cache.js.map +0 -1
- package/dist/codex-selection.d.ts +0 -18
- package/dist/codex-selection.js +0 -47
- package/dist/codex-selection.js.map +0 -1
- package/dist/codex-service-client.d.ts +0 -11
- package/dist/codex-service-client.js +0 -91
- package/dist/codex-service-client.js.map +0 -1
- package/dist/codex-shortcuts.d.ts +0 -43
- package/dist/codex-shortcuts.js +0 -429
- package/dist/codex-shortcuts.js.map +0 -1
- package/dist/codex-tui.d.ts +0 -15
- package/dist/codex-tui.js +0 -235
- package/dist/codex-tui.js.map +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { resolveBackendUrl } from "../backend.js";
|
|
2
|
+
import { ensureAccessToken, fetchWithKeycloakIdentity } from "../oauth.js";
|
|
3
|
+
import { ApiErrorSchema, BuildListSchema, BuildLogSchema, BuildSchema, PipelineDetailSchema, PipelineListSchema } from "./schemas.js";
|
|
4
|
+
import { PipelineError, redactPipelineText } from "./errors.js";
|
|
5
|
+
function requestIdFrom(response, body) {
|
|
6
|
+
if (body && typeof body === "object" && "requestId" in body && typeof body.requestId === "string")
|
|
7
|
+
return body.requestId;
|
|
8
|
+
return response.headers.get("x-request-id") ?? undefined;
|
|
9
|
+
}
|
|
10
|
+
async function responseBody(response) {
|
|
11
|
+
const text = await response.text();
|
|
12
|
+
if (!text)
|
|
13
|
+
return {};
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(text);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return text;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function apiFailure(response, body) {
|
|
22
|
+
const parsed = ApiErrorSchema.safeParse(body);
|
|
23
|
+
const message = parsed.success
|
|
24
|
+
? parsed.data.message ?? response.statusText ?? "Jenkins pipeline API request failed."
|
|
25
|
+
: typeof body === "string" ? body : response.statusText || "Jenkins pipeline API request failed.";
|
|
26
|
+
return new PipelineError(`Jenkins pipeline API HTTP ${response.status}: ${redactPipelineText(message)}`, parsed.success ? parsed.data.code ?? "JENKINS_API_ERROR" : "JENKINS_API_ERROR", response.status, requestIdFrom(response, body));
|
|
27
|
+
}
|
|
28
|
+
function queryPath(path, entries) {
|
|
29
|
+
const query = new URLSearchParams();
|
|
30
|
+
for (const [key, value] of Object.entries(entries))
|
|
31
|
+
if (value != null && value !== "")
|
|
32
|
+
query.set(key, String(value));
|
|
33
|
+
return query.size ? `${path}?${query.toString()}` : path;
|
|
34
|
+
}
|
|
35
|
+
export class PipelineClient {
|
|
36
|
+
config;
|
|
37
|
+
fetchImpl;
|
|
38
|
+
tokenProvider;
|
|
39
|
+
constructor(config, dependencies = {}) {
|
|
40
|
+
this.config = config;
|
|
41
|
+
this.fetchImpl = dependencies.fetch ?? fetch;
|
|
42
|
+
this.tokenProvider = dependencies.tokenProvider ?? ensureAccessToken;
|
|
43
|
+
}
|
|
44
|
+
async authenticatedFetch(path, init = {}) {
|
|
45
|
+
const url = resolveBackendUrl(this.config, { method: "GET", path });
|
|
46
|
+
const headers = new Headers(init.headers);
|
|
47
|
+
headers.set("Accept", "application/json");
|
|
48
|
+
if (init.body != null)
|
|
49
|
+
headers.set("Content-Type", "application/json");
|
|
50
|
+
return fetchWithKeycloakIdentity(this.config, url, () => ({ ...init, headers }), {
|
|
51
|
+
fetch: this.fetchImpl,
|
|
52
|
+
tokenProvider: this.tokenProvider
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async json(path, schema, init = {}, expectedStatuses) {
|
|
56
|
+
const response = await this.authenticatedFetch(path, init);
|
|
57
|
+
const body = await responseBody(response);
|
|
58
|
+
if (!response.ok)
|
|
59
|
+
throw apiFailure(response, body);
|
|
60
|
+
if (expectedStatuses && !expectedStatuses.includes(response.status)) {
|
|
61
|
+
throw new PipelineError(`Jenkins pipeline API returned HTTP ${response.status}; expected ${expectedStatuses.join(" or ")}.`, "JENKINS_INVALID_RESPONSE", response.status, requestIdFrom(response, body));
|
|
62
|
+
}
|
|
63
|
+
const parsed = schema.safeParse(body);
|
|
64
|
+
if (!parsed.success) {
|
|
65
|
+
throw new PipelineError(`Jenkins pipeline API returned an invalid response: ${parsed.error.message}`, "JENKINS_INVALID_RESPONSE", response.status, requestIdFrom(response, body));
|
|
66
|
+
}
|
|
67
|
+
return parsed.data;
|
|
68
|
+
}
|
|
69
|
+
listPipelines(options = {}) {
|
|
70
|
+
return this.json(queryPath("/api/v1/jenkins/pipelines", {
|
|
71
|
+
application: options.application, tier: options.tier, branch: options.branch
|
|
72
|
+
}), PipelineListSchema);
|
|
73
|
+
}
|
|
74
|
+
inspectPipeline(applicationCode) {
|
|
75
|
+
return this.json(`/api/v1/jenkins/pipelines/${encodeURIComponent(applicationCode)}`, PipelineDetailSchema);
|
|
76
|
+
}
|
|
77
|
+
listBuilds(options = {}) {
|
|
78
|
+
return this.json(queryPath("/api/v1/jenkins/builds", {
|
|
79
|
+
application: options.application, tier: options.tier, branch: options.branch,
|
|
80
|
+
state: options.state, cursor: options.cursor, limit: options.limit
|
|
81
|
+
}), BuildListSchema);
|
|
82
|
+
}
|
|
83
|
+
triggerBuild(input) {
|
|
84
|
+
return this.json("/api/v1/jenkins/builds", BuildSchema, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: { "Idempotency-Key": input.idempotencyKey },
|
|
87
|
+
body: JSON.stringify(input)
|
|
88
|
+
}, [200, 202]);
|
|
89
|
+
}
|
|
90
|
+
getBuild(identifier) {
|
|
91
|
+
return this.json(`/api/v1/jenkins/builds/${encodeURIComponent(identifier)}`, BuildSchema);
|
|
92
|
+
}
|
|
93
|
+
stopBuild(identifier) {
|
|
94
|
+
return this.json(`/api/v1/jenkins/builds/${encodeURIComponent(identifier)}/stop`, BuildSchema, { method: "POST" }, [200, 202]);
|
|
95
|
+
}
|
|
96
|
+
retryBuild(identifier, parameters) {
|
|
97
|
+
return this.json(`/api/v1/jenkins/builds/${encodeURIComponent(identifier)}/retry`, BuildSchema, {
|
|
98
|
+
method: "POST", body: JSON.stringify({ parameters })
|
|
99
|
+
}, [200, 202]);
|
|
100
|
+
}
|
|
101
|
+
getLog(identifier, offset = 0, limit) {
|
|
102
|
+
return this.json(queryPath(`/api/v1/jenkins/builds/${encodeURIComponent(identifier)}/log`, { offset, limit }), BuildLogSchema);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/pipeline/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { PipelineClient } from "./client.js";
|
|
3
|
+
import { type PipelineBuild, type PipelineTier } from "./schemas.js";
|
|
4
|
+
export interface PipelineCommandDependencies {
|
|
5
|
+
clientFactory?: () => PipelineClient;
|
|
6
|
+
sleep?: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
|
|
7
|
+
random?: () => number;
|
|
8
|
+
}
|
|
9
|
+
export declare function parsePipelineTier(value: string): PipelineTier;
|
|
10
|
+
export declare function parseBuildParameters(expressions?: string[]): Record<string, string>;
|
|
11
|
+
export declare function waitForBuild(client: Pick<PipelineClient, "getBuild">, initial: PipelineBuild, options?: {
|
|
12
|
+
sleep?: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
|
|
13
|
+
random?: () => number;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
onUpdate?: (build: PipelineBuild) => void;
|
|
16
|
+
}): Promise<PipelineBuild>;
|
|
17
|
+
export declare function registerPipelineCommands(program: Command, dependencies?: PipelineCommandDependencies): void;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { loadAppConfig } from "../app-config.js";
|
|
4
|
+
import { loadConfig } from "../config.js";
|
|
5
|
+
import { PipelineClient } from "./client.js";
|
|
6
|
+
import { PipelineError, sanitizePipelineOutput } from "./errors.js";
|
|
7
|
+
import { BuildStateSchema, PipelineTierSchema } from "./schemas.js";
|
|
8
|
+
const TERMINAL_STATES = new Set(["SUCCESS", "FAILED", "ABORTED", "CANCELLED", "NOT_BUILT"]);
|
|
9
|
+
const SUCCESS_STATE = "SUCCESS";
|
|
10
|
+
function addExamples(command, examples) {
|
|
11
|
+
return command.addHelpText("after", `\nExamples:\n${examples.map((item) => ` ${item}`).join("\n")}\n`);
|
|
12
|
+
}
|
|
13
|
+
function snakeCase(key) {
|
|
14
|
+
return key.replace(/([a-z0-9])([A-Z])/gu, "$1_$2").toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
function stableOutput(value) {
|
|
17
|
+
const safe = sanitizePipelineOutput(value);
|
|
18
|
+
if (Array.isArray(safe))
|
|
19
|
+
return safe.map(stableOutput);
|
|
20
|
+
if (safe && typeof safe === "object") {
|
|
21
|
+
return Object.fromEntries(Object.entries(safe).map(([key, item]) => [snakeCase(key), stableOutput(item)]));
|
|
22
|
+
}
|
|
23
|
+
return safe;
|
|
24
|
+
}
|
|
25
|
+
async function jsonEnabled(command) {
|
|
26
|
+
const configured = await loadAppConfig();
|
|
27
|
+
return Boolean(command.optsWithGlobals().json || configured.output === "json");
|
|
28
|
+
}
|
|
29
|
+
async function output(command, payload, textValue) {
|
|
30
|
+
if (await jsonEnabled(command)) {
|
|
31
|
+
process.stdout.write(`${JSON.stringify(stableOutput(payload), null, 2)}\n`);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
process.stdout.write(`${sanitizePipelineOutput(textValue)}\n`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function identifier(value, label) {
|
|
38
|
+
const trimmed = value.trim();
|
|
39
|
+
if (!trimmed || trimmed.length > 512 || /[\u0000-\u001f\u007f]/u.test(trimmed)) {
|
|
40
|
+
throw new PipelineError(`${label} must be a non-empty identifier of at most 512 characters.`, "JENKINS_CLI_INPUT_INVALID");
|
|
41
|
+
}
|
|
42
|
+
return trimmed;
|
|
43
|
+
}
|
|
44
|
+
export function parsePipelineTier(value) {
|
|
45
|
+
const parsed = PipelineTierSchema.safeParse(value.trim().toUpperCase());
|
|
46
|
+
if (!parsed.success) {
|
|
47
|
+
throw new PipelineError("tier must be develop, staging, or production.", "JENKINS_CLI_INPUT_INVALID");
|
|
48
|
+
}
|
|
49
|
+
return parsed.data;
|
|
50
|
+
}
|
|
51
|
+
function parseBuildState(value) {
|
|
52
|
+
if (value == null)
|
|
53
|
+
return undefined;
|
|
54
|
+
const parsed = BuildStateSchema.safeParse(value.trim().toUpperCase());
|
|
55
|
+
if (!parsed.success)
|
|
56
|
+
throw new PipelineError("state is not a supported Jenkins build state.", "JENKINS_CLI_INPUT_INVALID");
|
|
57
|
+
return parsed.data;
|
|
58
|
+
}
|
|
59
|
+
function positiveInteger(value, label, fallback, maximum) {
|
|
60
|
+
if (value == null)
|
|
61
|
+
return fallback;
|
|
62
|
+
const parsed = Number(value);
|
|
63
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > maximum) {
|
|
64
|
+
throw new PipelineError(`${label} must be an integer between 1 and ${maximum}.`, "JENKINS_CLI_INPUT_INVALID");
|
|
65
|
+
}
|
|
66
|
+
return parsed;
|
|
67
|
+
}
|
|
68
|
+
function collect(value, previous) {
|
|
69
|
+
return [...previous, value];
|
|
70
|
+
}
|
|
71
|
+
export function parseBuildParameters(expressions = []) {
|
|
72
|
+
const parameters = {};
|
|
73
|
+
for (const expression of expressions) {
|
|
74
|
+
const separator = expression.indexOf("=");
|
|
75
|
+
const key = separator < 0 ? "" : expression.slice(0, separator).trim();
|
|
76
|
+
if (!/^[A-Za-z_][A-Za-z0-9_.-]{0,127}$/u.test(key)) {
|
|
77
|
+
throw new PipelineError(`Build parameter must use KEY=VALUE syntax with a valid key: ${expression}`, "JENKINS_PARAMETER_INVALID");
|
|
78
|
+
}
|
|
79
|
+
if (Object.hasOwn(parameters, key)) {
|
|
80
|
+
throw new PipelineError(`Duplicate build parameter: ${key}`, "JENKINS_PARAMETER_INVALID");
|
|
81
|
+
}
|
|
82
|
+
parameters[key] = expression.slice(separator + 1);
|
|
83
|
+
}
|
|
84
|
+
return parameters;
|
|
85
|
+
}
|
|
86
|
+
function defaultSleep(milliseconds, signal) {
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
if (signal?.aborted) {
|
|
89
|
+
reject(new PipelineError("Pipeline polling was cancelled.", "JENKINS_POLL_CANCELLED"));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const timeout = setTimeout(resolve, milliseconds);
|
|
93
|
+
signal?.addEventListener("abort", () => {
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
reject(new PipelineError("Pipeline polling was cancelled.", "JENKINS_POLL_CANCELLED"));
|
|
96
|
+
}, { once: true });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function jitteredDelay(random) {
|
|
100
|
+
return Math.round(2_000 * (0.85 + random() * 0.3));
|
|
101
|
+
}
|
|
102
|
+
export async function waitForBuild(client, initial, options = {}) {
|
|
103
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
104
|
+
const random = options.random ?? Math.random;
|
|
105
|
+
let build = initial;
|
|
106
|
+
options.onUpdate?.(build);
|
|
107
|
+
while (!TERMINAL_STATES.has(build.state)) {
|
|
108
|
+
await sleep(jitteredDelay(random), options.signal);
|
|
109
|
+
const buildId = build.requestId ?? (build.buildNumber == null ? undefined : String(build.buildNumber));
|
|
110
|
+
if (!buildId)
|
|
111
|
+
throw new PipelineError("Build response has no pollable identifier.", "JENKINS_INVALID_RESPONSE");
|
|
112
|
+
build = await client.getBuild(buildId);
|
|
113
|
+
options.onUpdate?.(build);
|
|
114
|
+
}
|
|
115
|
+
return build;
|
|
116
|
+
}
|
|
117
|
+
async function withInterrupt(run) {
|
|
118
|
+
const controller = new AbortController();
|
|
119
|
+
const stop = () => controller.abort();
|
|
120
|
+
process.once("SIGINT", stop);
|
|
121
|
+
try {
|
|
122
|
+
return await run(controller.signal);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
process.removeListener("SIGINT", stop);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function buildLine(build) {
|
|
129
|
+
return `${build.requestId ?? build.buildNumber ?? "-"}\t${build.state}\t${build.applicationCode ?? "-"}\t${build.tier ?? "-"}\t${build.branch ?? "-"}`;
|
|
130
|
+
}
|
|
131
|
+
function pipelineLine(pipeline) {
|
|
132
|
+
return `${String(pipeline.applicationCode ?? "-")}\t${String(pipeline.tier ?? "-")}\t${String(pipeline.branch ?? "-")}\t${pipeline.buildable === false ? "read-only" : "buildable"}`;
|
|
133
|
+
}
|
|
134
|
+
export function registerPipelineCommands(program, dependencies = {}) {
|
|
135
|
+
const client = () => dependencies.clientFactory?.() ?? new PipelineClient(loadConfig("pipeline"));
|
|
136
|
+
const sleep = dependencies.sleep ?? defaultSleep;
|
|
137
|
+
const random = dependencies.random ?? Math.random;
|
|
138
|
+
const pipeline = program.command("pipeline").description("通过平台 Keycloak 权限查询和操作 Jenkins 流水线");
|
|
139
|
+
addExamples(pipeline.command("list")
|
|
140
|
+
.description("列出当前用户可见的应用流水线")
|
|
141
|
+
.option("--app <code>", "按 Application code 过滤")
|
|
142
|
+
.option("--tier <tier>", "develop|staging|production")
|
|
143
|
+
.option("--branch <name>", "按分支过滤")
|
|
144
|
+
.action(async (options, command) => {
|
|
145
|
+
const result = await client().listPipelines({
|
|
146
|
+
application: options.app && identifier(options.app, "application"),
|
|
147
|
+
tier: options.tier ? parsePipelineTier(options.tier) : undefined,
|
|
148
|
+
branch: options.branch
|
|
149
|
+
});
|
|
150
|
+
await output(command, { ok: true, pipelines: result }, result.items.map((item) => pipelineLine(item)).join("\n") || "没有找到流水线");
|
|
151
|
+
}), ["numa pipeline list --app mci-devops-platform --tier develop --json"]);
|
|
152
|
+
addExamples(pipeline.command("inspect <application>")
|
|
153
|
+
.description("查看应用的流水线绑定、参数和最近构建")
|
|
154
|
+
.action(async (application, _options, command) => {
|
|
155
|
+
const result = await client().inspectPipeline(identifier(application, "application"));
|
|
156
|
+
await output(command, { ok: true, pipeline: result }, JSON.stringify(stableOutput(result), null, 2));
|
|
157
|
+
}), ["numa pipeline inspect mci-devops-platform --json"]);
|
|
158
|
+
addExamples(pipeline.command("builds")
|
|
159
|
+
.description("检索当前用户可见的构建记录")
|
|
160
|
+
.option("--app <code>", "按 Application code 过滤")
|
|
161
|
+
.option("--tier <tier>", "develop|staging|production")
|
|
162
|
+
.option("--branch <name>", "按分支过滤")
|
|
163
|
+
.option("--state <state>", "按构建状态过滤")
|
|
164
|
+
.option("--cursor <cursor>", "分页游标")
|
|
165
|
+
.option("--limit <number>", "返回条数,1-100", "20")
|
|
166
|
+
.action(async (options, command) => {
|
|
167
|
+
const result = await client().listBuilds({
|
|
168
|
+
application: options.app && identifier(options.app, "application"),
|
|
169
|
+
tier: options.tier ? parsePipelineTier(options.tier) : undefined,
|
|
170
|
+
branch: options.branch,
|
|
171
|
+
state: parseBuildState(options.state),
|
|
172
|
+
cursor: options.cursor,
|
|
173
|
+
limit: positiveInteger(options.limit, "limit", 20, 100)
|
|
174
|
+
});
|
|
175
|
+
await output(command, { ok: true, builds: result }, result.items.map(buildLine).join("\n") || "没有找到构建记录");
|
|
176
|
+
}), ["numa pipeline builds --app mci-devops-platform --state running --json"]);
|
|
177
|
+
addExamples(pipeline.command("build <application>")
|
|
178
|
+
.description("触发非生产流水线构建")
|
|
179
|
+
.requiredOption("--tier <tier>", "develop|staging|production")
|
|
180
|
+
.option("--branch <name>", "分支名称")
|
|
181
|
+
.option("-p, --param <KEY=VALUE>", "构建参数,可重复", collect, [])
|
|
182
|
+
.option("--idempotency-key <key>", "重试同一请求时必须复用的幂等键")
|
|
183
|
+
.option("--wait", "等待构建进入终态")
|
|
184
|
+
.action(async (application, options, command) => {
|
|
185
|
+
const idempotencyKey = options.idempotencyKey ? identifier(options.idempotencyKey, "idempotency-key") : randomUUID();
|
|
186
|
+
const request = {
|
|
187
|
+
applicationCode: identifier(application, "application"),
|
|
188
|
+
tier: parsePipelineTier(options.tier),
|
|
189
|
+
branch: options.branch,
|
|
190
|
+
parameters: parseBuildParameters(options.param),
|
|
191
|
+
idempotencyKey
|
|
192
|
+
};
|
|
193
|
+
const pipelineClient = client();
|
|
194
|
+
let result = await pipelineClient.triggerBuild(request);
|
|
195
|
+
if (options.wait)
|
|
196
|
+
result = await withInterrupt((signal) => waitForBuild(pipelineClient, result, { sleep, random, signal }));
|
|
197
|
+
await output(command, { ok: result.state === SUCCESS_STATE || !options.wait, build: result, idempotency_key: idempotencyKey }, buildLine(result));
|
|
198
|
+
if (options.wait && result.state !== SUCCESS_STATE)
|
|
199
|
+
process.exitCode = 1;
|
|
200
|
+
}), [
|
|
201
|
+
"numa pipeline build mci-devops-platform --tier develop --branch develop --param SONAR_SCAN=false --json",
|
|
202
|
+
"numa pipeline build mci-devops-platform --tier develop --wait"
|
|
203
|
+
]);
|
|
204
|
+
addExamples(pipeline.command("status <request-or-build-id>")
|
|
205
|
+
.description("查询构建状态,可持续观察至终态")
|
|
206
|
+
.option("--watch", "持续轮询至终态")
|
|
207
|
+
.action(async (value, options, command) => {
|
|
208
|
+
const pipelineClient = client();
|
|
209
|
+
const useJson = await jsonEnabled(command);
|
|
210
|
+
let result = await pipelineClient.getBuild(identifier(value, "request-or-build-id"));
|
|
211
|
+
if (options.watch)
|
|
212
|
+
result = await withInterrupt((signal) => waitForBuild(pipelineClient, result, {
|
|
213
|
+
sleep, random, signal,
|
|
214
|
+
onUpdate: (item) => { if (!useJson)
|
|
215
|
+
process.stderr.write(`${sanitizePipelineOutput(buildLine(item))}\n`); }
|
|
216
|
+
}));
|
|
217
|
+
await output(command, { ok: true, build: result }, buildLine(result));
|
|
218
|
+
}), ["numa pipeline status req_01ABC --watch --json"]);
|
|
219
|
+
addExamples(pipeline.command("log <request-or-build-id>")
|
|
220
|
+
.description("读取构建日志,follow 模式持续读取 progressiveText 游标")
|
|
221
|
+
.option("--follow", "持续读取直到构建终止且日志耗尽")
|
|
222
|
+
.option("--offset <number>", "起始日志游标", "0")
|
|
223
|
+
.option("--limit <number>", "单次读取上限")
|
|
224
|
+
.action(async (value, options, command) => {
|
|
225
|
+
const pipelineClient = client();
|
|
226
|
+
const buildId = identifier(value, "request-or-build-id");
|
|
227
|
+
let offset = options.offset == null ? 0 : Number(options.offset);
|
|
228
|
+
if (!Number.isInteger(offset) || offset < 0)
|
|
229
|
+
throw new PipelineError("offset must be a non-negative integer.", "JENKINS_CLI_INPUT_INVALID");
|
|
230
|
+
const limit = options.limit == null ? undefined : positiveInteger(options.limit, "limit", 1, 10_000_000);
|
|
231
|
+
const chunks = [];
|
|
232
|
+
const useJson = await jsonEnabled(command);
|
|
233
|
+
let latest = await pipelineClient.getLog(buildId, offset, limit);
|
|
234
|
+
chunks.push(String(sanitizePipelineOutput(latest.text)));
|
|
235
|
+
if (!useJson && latest.text)
|
|
236
|
+
process.stdout.write(String(sanitizePipelineOutput(latest.text)));
|
|
237
|
+
if (options.follow) {
|
|
238
|
+
latest = await withInterrupt(async (signal) => {
|
|
239
|
+
while (true) {
|
|
240
|
+
offset = latest.nextOffset;
|
|
241
|
+
if (!latest.moreData) {
|
|
242
|
+
const status = await pipelineClient.getBuild(buildId);
|
|
243
|
+
if (TERMINAL_STATES.has(status.state))
|
|
244
|
+
return latest;
|
|
245
|
+
await sleep(jitteredDelay(random), signal);
|
|
246
|
+
}
|
|
247
|
+
const next = await pipelineClient.getLog(buildId, offset, limit);
|
|
248
|
+
if (next.text) {
|
|
249
|
+
const safeText = String(sanitizePipelineOutput(next.text));
|
|
250
|
+
chunks.push(safeText);
|
|
251
|
+
if (!useJson)
|
|
252
|
+
process.stdout.write(safeText);
|
|
253
|
+
}
|
|
254
|
+
latest = next;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (useJson)
|
|
259
|
+
await output(command, { ok: true, log: { ...latest, text: chunks.join("") } }, "");
|
|
260
|
+
else if (!latest.text && chunks.length === 1)
|
|
261
|
+
process.stdout.write("\n");
|
|
262
|
+
}), ["numa pipeline log req_01ABC --follow", "numa pipeline log 1842 --offset 4096 --json"]);
|
|
263
|
+
addExamples(pipeline.command("stop <request-or-build-id>")
|
|
264
|
+
.description("停止排队中或运行中的非生产构建")
|
|
265
|
+
.option("--yes", "确认停止")
|
|
266
|
+
.action(async (value, options, command) => {
|
|
267
|
+
if (!options.yes)
|
|
268
|
+
throw new PipelineError("Stopping a build requires --yes.", "JENKINS_CONFIRMATION_REQUIRED");
|
|
269
|
+
const result = await client().stopBuild(identifier(value, "request-or-build-id"));
|
|
270
|
+
await output(command, { ok: true, build: result }, buildLine(result));
|
|
271
|
+
}), ["numa pipeline stop req_01ABC --yes --json"]);
|
|
272
|
+
addExamples(pipeline.command("retry <request-or-build-id>")
|
|
273
|
+
.description("重试非生产构建;敏感参数必须重新提供")
|
|
274
|
+
.option("--yes", "确认重试")
|
|
275
|
+
.option("-p, --param <KEY=VALUE>", "重新提供或覆盖构建参数,可重复", collect, [])
|
|
276
|
+
.action(async (value, options, command) => {
|
|
277
|
+
if (!options.yes)
|
|
278
|
+
throw new PipelineError("Retrying a build requires --yes.", "JENKINS_CONFIRMATION_REQUIRED");
|
|
279
|
+
const result = await client().retryBuild(identifier(value, "request-or-build-id"), parseBuildParameters(options.param));
|
|
280
|
+
await output(command, { ok: true, build: result }, buildLine(result));
|
|
281
|
+
}), ["numa pipeline retry req_01ABC --yes --param DEPLOY_TOKEN=secret --json"]);
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/pipeline/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function redactPipelineText(value: string): string;
|
|
2
|
+
export declare function sanitizePipelineOutput(value: unknown, key?: string): unknown;
|
|
3
|
+
export declare class PipelineError extends Error {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly status?: number | undefined;
|
|
6
|
+
readonly requestId?: string | undefined;
|
|
7
|
+
constructor(message: string, code: string, status?: number | undefined, requestId?: string | undefined);
|
|
8
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const JENKINS_URL_KEYS = /^(?:jenkinsUrl|upstreamUrl|jobUrl)$/iu;
|
|
2
|
+
const SENSITIVE_KEYS = /(?:authorization|accessToken|refreshToken|apiToken|clientSecret|password|passwd|secret|token)$/iu;
|
|
3
|
+
export function redactPipelineText(value) {
|
|
4
|
+
return value
|
|
5
|
+
.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu, "Bearer [REDACTED]")
|
|
6
|
+
.replace(/([?&](?:access_token|refresh_token|token|signature|credential)=)[^&#\s]+/giu, "$1[REDACTED]")
|
|
7
|
+
.replace(/\b((?:password|passwd|token|api[_-]?token|access[_-]?token|refresh[_-]?token|secret)\s*[=:]\s*)[^\s,;]+/giu, "$1[REDACTED]")
|
|
8
|
+
.replace(/https?:\/\/build\.mcisaas\.com(?:\/[^\s"']*)?/giu, "[REDACTED_JENKINS_URL]")
|
|
9
|
+
.replace(/("(?:accessToken|refreshToken|apiToken|clientSecret|password|secret|token)"\s*:\s*")[^"]*(")/giu, "$1[REDACTED]$2");
|
|
10
|
+
}
|
|
11
|
+
export function sanitizePipelineOutput(value, key = "") {
|
|
12
|
+
if (SENSITIVE_KEYS.test(key))
|
|
13
|
+
return "[REDACTED]";
|
|
14
|
+
if (JENKINS_URL_KEYS.test(key))
|
|
15
|
+
return "[REDACTED_JENKINS_URL]";
|
|
16
|
+
if (typeof value === "string")
|
|
17
|
+
return redactPipelineText(value);
|
|
18
|
+
if (Array.isArray(value))
|
|
19
|
+
return value.map((item) => sanitizePipelineOutput(item));
|
|
20
|
+
if (value && typeof value === "object") {
|
|
21
|
+
return Object.fromEntries(Object.entries(value).map(([name, item]) => [name, sanitizePipelineOutput(item, name)]));
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
export class PipelineError extends Error {
|
|
26
|
+
code;
|
|
27
|
+
status;
|
|
28
|
+
requestId;
|
|
29
|
+
constructor(message, code, status, requestId) {
|
|
30
|
+
super(redactPipelineText(message));
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.status = status;
|
|
33
|
+
this.requestId = requestId;
|
|
34
|
+
this.name = "PipelineError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/pipeline/errors.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,uCAAuC,CAAC;AACjE,MAAM,cAAc,GAAG,kGAAkG,CAAC;AAE1H,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,KAAK;SACT,OAAO,CAAC,mCAAmC,EAAE,mBAAmB,CAAC;SACjE,OAAO,CAAC,6EAA6E,EAAE,cAAc,CAAC;SACtG,OAAO,CAAC,4GAA4G,EAAE,cAAc,CAAC;SACrI,OAAO,CAAC,kDAAkD,EAAE,wBAAwB,CAAC;SACrF,OAAO,CAAC,iGAAiG,EAAE,gBAAgB,CAAC,CAAC;AAClI,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAc,EAAE,GAAG,GAAG,EAAE;IAC7D,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IAClD,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,wBAAwB,CAAC;IAChE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGpB,IAAI;IACJ,MAAM;IACN,SAAS;IAJ3B,YACE,OAAe,EACC,IAAY,EACZ,MAAe,EACf,SAAkB;QAElC,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;oBAJnB,IAAI;sBACJ,MAAM;yBACN,SAAS;QAGzB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
|