tuyoo-devflow 0.1.12 → 0.1.15
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/CHANGELOG.md +19 -0
- package/README.md +3 -1
- package/dist/commands/agent/doctor.js +44 -13
- package/dist/commands/agent/doctor.js.map +1 -1
- package/dist/core/store/doctorJenkinsUrlCache.d.ts +8 -0
- package/dist/core/store/doctorJenkinsUrlCache.js +60 -0
- package/dist/core/store/doctorJenkinsUrlCache.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.15] - 2026-04-22
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- GitLab shell runner 在宿主机未预装 Node/npm 时,CI 现在会自动下载并缓存 Node 20,避免在 `npm ci` 前直接失败。
|
|
14
|
+
|
|
15
|
+
## [0.1.14] - 2026-04-22
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- GitLab CI 现在默认绑定 runner tag `pytuyoo_pipeline`,确保 tag 发布任务能被对应 runner 正常接单执行。
|
|
20
|
+
|
|
21
|
+
## [0.1.13] - 2026-04-22
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- `agent doctor` 现在会缓存上次输入的 Jenkins URL;再次执行时会提示是否复用,交互方式与 `agent install` 的命令缓存保持一致。
|
|
26
|
+
- GitHub npm 发布流程更新为在 `self-hosted` + `pytuyoo_pipeline` runner 上执行,并在发布前显式校验 `NPM_TOKEN` 是否已配置。
|
|
27
|
+
|
|
9
28
|
## [0.1.12] - 2026-04-22
|
|
10
29
|
|
|
11
30
|
### Changed
|
package/README.md
CHANGED
|
@@ -175,11 +175,13 @@ npm run pack:dry
|
|
|
175
175
|
|
|
176
176
|
- GitHub Actions
|
|
177
177
|
- CI:`.github/workflows/ci.yml`
|
|
178
|
-
- 发布:`.github/workflows/publish.yml`(tag `v*` 或手动触发)
|
|
178
|
+
- 发布:`.github/workflows/publish.yml`(push tag `v*` 或手动触发)
|
|
179
|
+
- 发布 Runner:`self-hosted` + `pytuyoo_pipeline`
|
|
179
180
|
- Secret:`NPM_TOKEN`
|
|
180
181
|
- GitLab CI
|
|
181
182
|
- CI + 发布:`.gitlab-ci.yml`
|
|
182
183
|
- 规则:tag 命中 `vX.Y.Z` 时执行 `npm publish`
|
|
184
|
+
- Runner tag:`pytuyoo_pipeline`
|
|
183
185
|
- Variable:`NPM_TOKEN`
|
|
184
186
|
|
|
185
187
|
详细发布步骤见 `RELEASING.md`。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { input } from "@inquirer/prompts";
|
|
2
|
+
import { confirm, input } from "@inquirer/prompts";
|
|
3
3
|
import { getCurrentUsername, getSupportedPlatform } from "../../core/platform.js";
|
|
4
4
|
import { safeErrorMessage } from "../../core/log/redact.js";
|
|
5
5
|
import { summarizeDoctorCheckProfile, } from "../../core/precheck/checkProfile.js";
|
|
@@ -7,10 +7,21 @@ import { guideAndInstallMissingTools } from "../../core/precheck/autoInstall.js"
|
|
|
7
7
|
import { checkRequiredTools } from "../../core/precheck/tools.js";
|
|
8
8
|
import { collectSystemInfoResults } from "../../core/precheck/systemInfo.js";
|
|
9
9
|
import { readDoctorCheckProfile, writeDoctorCheckProfile, } from "../../core/store/doctorCheckProfileStore.js";
|
|
10
|
+
import { loadDoctorJenkinsUrlCache, saveDoctorJenkinsUrlCache, shouldPersistDoctorJenkinsUrlCache, } from "../../core/store/doctorJenkinsUrlCache.js";
|
|
10
11
|
import { CheckReport } from "../../ui/CheckReport.js";
|
|
11
12
|
import { renderOnce } from "../../ui/renderOnce.js";
|
|
12
13
|
import { getFailedToolChecks, hasLinuxOrNetworkFailure, printCheckSummary, printFailedWhitelistReport, runDoctorChecks, } from "./shared.js";
|
|
13
14
|
import { promptDoctorCheckProfile } from "./checkProfilePrompt.js";
|
|
15
|
+
function formatCacheTime(isoTime) {
|
|
16
|
+
if (!isoTime) {
|
|
17
|
+
return "未知时间";
|
|
18
|
+
}
|
|
19
|
+
const date = new Date(isoTime);
|
|
20
|
+
if (Number.isNaN(date.getTime())) {
|
|
21
|
+
return isoTime;
|
|
22
|
+
}
|
|
23
|
+
return date.toLocaleString();
|
|
24
|
+
}
|
|
14
25
|
export function registerDoctorCommand(agentCommand) {
|
|
15
26
|
agentCommand
|
|
16
27
|
.command("doctor")
|
|
@@ -21,18 +32,38 @@ export function registerDoctorCommand(agentCommand) {
|
|
|
21
32
|
const username = getCurrentUsername();
|
|
22
33
|
const systemInfo = collectSystemInfoResults(platform, username);
|
|
23
34
|
await renderOnce(_jsx(CheckReport, { title: "\u5F53\u524D\u7CFB\u7EDF\u4FE1\u606F", results: systemInfo }));
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
const cachedJenkinsUrl = await loadDoctorJenkinsUrlCache();
|
|
36
|
+
let jenkinsUrl;
|
|
37
|
+
if (cachedJenkinsUrl) {
|
|
38
|
+
console.log(`检测到本地缓存的 Jenkins URL(更新时间: ${formatCacheTime(cachedJenkinsUrl.updatedAt)})。`);
|
|
39
|
+
console.log(`缓存内容: ${cachedJenkinsUrl.jenkinsUrl}`);
|
|
40
|
+
const shouldModifyCachedUrl = await confirm({
|
|
41
|
+
message: "是否需要修改 Jenkins URL?(默认不修改,直接继续下一步)",
|
|
42
|
+
default: false,
|
|
43
|
+
});
|
|
44
|
+
if (!shouldModifyCachedUrl) {
|
|
45
|
+
jenkinsUrl = cachedJenkinsUrl.jenkinsUrl;
|
|
46
|
+
console.log("已使用本地缓存的 Jenkins URL,继续执行。");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
jenkinsUrl =
|
|
50
|
+
jenkinsUrl ??
|
|
51
|
+
(await input({
|
|
52
|
+
message: "请输入 Jenkins URL(例如 http://jenkins.example.com/)",
|
|
53
|
+
default: cachedJenkinsUrl?.jenkinsUrl,
|
|
54
|
+
validate(value) {
|
|
55
|
+
try {
|
|
56
|
+
new URL(value);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return "URL 格式不正确";
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
}));
|
|
64
|
+
if (shouldPersistDoctorJenkinsUrlCache(jenkinsUrl)) {
|
|
65
|
+
await saveDoctorJenkinsUrlCache(jenkinsUrl);
|
|
66
|
+
}
|
|
36
67
|
const previousProfile = await readDoctorCheckProfile();
|
|
37
68
|
const checkProfile = await promptDoctorCheckProfile(jenkinsUrl, previousProfile);
|
|
38
69
|
await writeDoctorCheckProfile(checkProfile);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/commands/agent/doctor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/commands/agent/doctor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface DoctorJenkinsUrlCache {
|
|
2
|
+
jenkinsUrl: string;
|
|
3
|
+
updatedAt: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function shouldPersistDoctorJenkinsUrlCache(jenkinsUrl: string): boolean;
|
|
6
|
+
export declare function clearDoctorJenkinsUrlCache(): Promise<void>;
|
|
7
|
+
export declare function loadDoctorJenkinsUrlCache(): Promise<DoctorJenkinsUrlCache | null>;
|
|
8
|
+
export declare function saveDoctorJenkinsUrlCache(jenkinsUrl: string): Promise<void>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getConfigDir } from "../platform.js";
|
|
4
|
+
function getCacheFilePath() {
|
|
5
|
+
return path.join(getConfigDir(), "tmp", "agent-doctor-jenkins-url-cache.json");
|
|
6
|
+
}
|
|
7
|
+
function isPlaceholderValue(jenkinsUrl) {
|
|
8
|
+
const normalized = jenkinsUrl.trim().toLowerCase();
|
|
9
|
+
const placeholderKeywords = ["jenkins.example.com", "example.com", "<jenkins-host>", "http://<"];
|
|
10
|
+
return placeholderKeywords.some((keyword) => normalized.includes(keyword));
|
|
11
|
+
}
|
|
12
|
+
export function shouldPersistDoctorJenkinsUrlCache(jenkinsUrl) {
|
|
13
|
+
if (!jenkinsUrl.trim()) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
new URL(jenkinsUrl);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (isPlaceholderValue(jenkinsUrl)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
export async function clearDoctorJenkinsUrlCache() {
|
|
28
|
+
const filePath = getCacheFilePath();
|
|
29
|
+
if (await fs.pathExists(filePath)) {
|
|
30
|
+
await fs.remove(filePath);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export async function loadDoctorJenkinsUrlCache() {
|
|
34
|
+
const filePath = getCacheFilePath();
|
|
35
|
+
const exists = await fs.pathExists(filePath);
|
|
36
|
+
if (!exists) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const data = (await fs.readJson(filePath));
|
|
40
|
+
if (!data.jenkinsUrl || !shouldPersistDoctorJenkinsUrlCache(data.jenkinsUrl)) {
|
|
41
|
+
await clearDoctorJenkinsUrlCache();
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
jenkinsUrl: data.jenkinsUrl,
|
|
46
|
+
updatedAt: data.updatedAt ?? "",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export async function saveDoctorJenkinsUrlCache(jenkinsUrl) {
|
|
50
|
+
const filePath = getCacheFilePath();
|
|
51
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
52
|
+
await fs.writeJson(filePath, {
|
|
53
|
+
jenkinsUrl,
|
|
54
|
+
updatedAt: new Date().toISOString(),
|
|
55
|
+
}, { spaces: 2 });
|
|
56
|
+
if (process.platform !== "win32") {
|
|
57
|
+
await fs.chmod(filePath, 0o600);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=doctorJenkinsUrlCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctorJenkinsUrlCache.js","sourceRoot":"","sources":["../../../src/core/store/doctorJenkinsUrlCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9C,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,qCAAqC,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,mBAAmB,GAAG,CAAC,qBAAqB,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;IACjG,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,UAAkB;IACnE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAmC,CAAC;IAC7E,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7E,MAAM,0BAA0B,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,UAAkB;IAChE,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,MAAM,EAAE,CAAC,SAAS,CAChB,QAAQ,EACR;QACE,UAAU;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,EACD,EAAE,MAAM,EAAE,CAAC,EAAE,CACd,CAAC;IACF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
|