agentweaver 0.1.12 → 0.1.13
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/LICENSE +21 -0
- package/README.md +6 -0
- package/dist/doctor/checks/agentweaver-home.js +57 -0
- package/dist/doctor/checks/category.js +9 -0
- package/dist/doctor/checks/cwd-context.js +69 -0
- package/dist/doctor/checks/env-diagnostics.js +171 -0
- package/dist/doctor/checks/executors.js +106 -0
- package/dist/doctor/checks/flow-readiness.js +305 -0
- package/dist/doctor/checks/node-version.js +79 -0
- package/dist/doctor/checks/register.js +18 -0
- package/dist/doctor/checks/system.js +91 -0
- package/dist/doctor/index.js +4 -0
- package/dist/doctor/orchestrator.js +78 -0
- package/dist/doctor/registry.js +50 -0
- package/dist/doctor/runner.js +89 -0
- package/dist/doctor/types.js +12 -0
- package/dist/index.js +17 -1
- package/package.json +4 -2
- package/dist/pipeline/flow-model-settings.js +0 -77
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { DoctorStatus, ReadinessStatus } from "./types.js";
|
|
2
|
+
import { REGISTRY } from "./registry.js";
|
|
3
|
+
import { DoctorOrchestrator } from "./orchestrator.js";
|
|
4
|
+
import { CATEGORY } from "./checks/category.js";
|
|
5
|
+
import "./checks/register.js";
|
|
6
|
+
const STATUS_ICONS = {
|
|
7
|
+
[DoctorStatus.Ok]: "✓",
|
|
8
|
+
[DoctorStatus.Warn]: "⚠",
|
|
9
|
+
[DoctorStatus.Fail]: "✗",
|
|
10
|
+
};
|
|
11
|
+
const READINESS_LABELS = {
|
|
12
|
+
[ReadinessStatus.Ready]: "Ready",
|
|
13
|
+
[ReadinessStatus.ReadyWithWarnings]: "Ready with warnings",
|
|
14
|
+
[ReadinessStatus.NotReady]: "Not ready",
|
|
15
|
+
};
|
|
16
|
+
const CATEGORY_LABELS = {
|
|
17
|
+
[CATEGORY.SYSTEM]: "System",
|
|
18
|
+
[CATEGORY.EXECUTORS]: "Executors",
|
|
19
|
+
[CATEGORY.ENV_DIAGNOSTICS]: "Environment",
|
|
20
|
+
[CATEGORY.FLOW_READINESS]: "Flow Readiness",
|
|
21
|
+
};
|
|
22
|
+
async function runDoctorCommand(args) {
|
|
23
|
+
const jsonMode = args.includes("--json");
|
|
24
|
+
const filter = args.find((arg) => arg !== "--json");
|
|
25
|
+
const orchestrator = new DoctorOrchestrator();
|
|
26
|
+
const report = await orchestrator.run(undefined, filter);
|
|
27
|
+
if (jsonMode) {
|
|
28
|
+
process.stdout.write(JSON.stringify(report, null, 2));
|
|
29
|
+
return report.overall === ReadinessStatus.NotReady ? 1 : 0;
|
|
30
|
+
}
|
|
31
|
+
const grouped = new Map();
|
|
32
|
+
for (const result of report.checks) {
|
|
33
|
+
const check = REGISTRY.getById(result.id);
|
|
34
|
+
const cat = check?.category ?? "unknown";
|
|
35
|
+
if (!grouped.has(cat)) {
|
|
36
|
+
grouped.set(cat, []);
|
|
37
|
+
}
|
|
38
|
+
grouped.get(cat).push(result);
|
|
39
|
+
}
|
|
40
|
+
const categoryOrder = [
|
|
41
|
+
CATEGORY.SYSTEM,
|
|
42
|
+
CATEGORY.EXECUTORS,
|
|
43
|
+
CATEGORY.ENV_DIAGNOSTICS,
|
|
44
|
+
CATEGORY.FLOW_READINESS,
|
|
45
|
+
];
|
|
46
|
+
for (const cat of categoryOrder) {
|
|
47
|
+
const items = grouped.get(cat);
|
|
48
|
+
if (!items || items.length === 0)
|
|
49
|
+
continue;
|
|
50
|
+
const label = CATEGORY_LABELS[cat] ?? cat;
|
|
51
|
+
console.log(`## ${label}`);
|
|
52
|
+
console.log();
|
|
53
|
+
for (const result of items) {
|
|
54
|
+
const icon = STATUS_ICONS[result.status];
|
|
55
|
+
const line = `[${icon}] ${result.title} - ${result.message}`;
|
|
56
|
+
console.log(line);
|
|
57
|
+
if (result.hint) {
|
|
58
|
+
console.log(` Hint: ${result.hint}`);
|
|
59
|
+
}
|
|
60
|
+
if (result.details) {
|
|
61
|
+
console.log(` Details: ${result.details}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
console.log();
|
|
65
|
+
}
|
|
66
|
+
for (const [cat, items] of grouped) {
|
|
67
|
+
if (categoryOrder.includes(cat))
|
|
68
|
+
continue;
|
|
69
|
+
const label = CATEGORY_LABELS[cat] ?? cat;
|
|
70
|
+
console.log(`## ${label}`);
|
|
71
|
+
console.log();
|
|
72
|
+
for (const result of items) {
|
|
73
|
+
const icon = STATUS_ICONS[result.status];
|
|
74
|
+
const line = `[${icon}] ${result.title} - ${result.message}`;
|
|
75
|
+
console.log(line);
|
|
76
|
+
if (result.hint) {
|
|
77
|
+
console.log(` Hint: ${result.hint}`);
|
|
78
|
+
}
|
|
79
|
+
if (result.details) {
|
|
80
|
+
console.log(` Details: ${result.details}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
console.log();
|
|
84
|
+
}
|
|
85
|
+
console.log(`Overall: ${READINESS_LABELS[report.overall]}`);
|
|
86
|
+
console.log(`Timestamp: ${report.timestamp}`);
|
|
87
|
+
return report.overall === ReadinessStatus.NotReady ? 1 : 0;
|
|
88
|
+
}
|
|
89
|
+
export { runDoctorCommand };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export var DoctorStatus;
|
|
2
|
+
(function (DoctorStatus) {
|
|
3
|
+
DoctorStatus["Ok"] = "ok";
|
|
4
|
+
DoctorStatus["Warn"] = "warn";
|
|
5
|
+
DoctorStatus["Fail"] = "fail";
|
|
6
|
+
})(DoctorStatus || (DoctorStatus = {}));
|
|
7
|
+
export var ReadinessStatus;
|
|
8
|
+
(function (ReadinessStatus) {
|
|
9
|
+
ReadinessStatus["Ready"] = "ready";
|
|
10
|
+
ReadinessStatus["ReadyWithWarnings"] = "ready_with_warnings";
|
|
11
|
+
ReadinessStatus["NotReady"] = "not_ready";
|
|
12
|
+
})(ReadinessStatus || (ReadinessStatus = {}));
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import { runCommand } from "./runtime/process-runner.js";
|
|
|
23
23
|
import { InteractiveUi } from "./interactive-ui.js";
|
|
24
24
|
import { bye, printError, printInfo, printPanel, printSummary, setFlowExecutionState, stripAnsi, } from "./tui.js";
|
|
25
25
|
import { requestUserInputInTerminal } from "./user-input.js";
|
|
26
|
+
import { runDoctorCommand } from "./doctor/index.js";
|
|
26
27
|
import { attachJiraContext, detectGitBranchName, requestJiraContext, resolveProjectScope, } from "./scope.js";
|
|
27
28
|
const COMMANDS = [
|
|
28
29
|
"auto-golang",
|
|
@@ -31,6 +32,7 @@ const COMMANDS = [
|
|
|
31
32
|
"auto-reset",
|
|
32
33
|
"bug-analyze",
|
|
33
34
|
"bug-fix",
|
|
35
|
+
"doctor",
|
|
34
36
|
"git-commit",
|
|
35
37
|
"gitlab-diff-review",
|
|
36
38
|
"gitlab-review",
|
|
@@ -97,6 +99,7 @@ function usage() {
|
|
|
97
99
|
agentweaver gitlab-review [--dry] [--verbose] [--prompt <text>] [--scope <name>]
|
|
98
100
|
agentweaver bug-analyze [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
99
101
|
agentweaver bug-fix [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
102
|
+
agentweaver doctor [<category>|<check-id>] [--json]
|
|
100
103
|
agentweaver mr-description [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
101
104
|
agentweaver plan [--dry] [--verbose] [--prompt <text>] [--md-lang <en|ru>] [<jira-browse-url|jira-issue-key>]
|
|
102
105
|
agentweaver task-describe [--dry] [--verbose] [--prompt <text>] [<jira-browse-url|jira-issue-key>]
|
|
@@ -434,6 +437,7 @@ function buildBaseConfig(command, options = {}) {
|
|
|
434
437
|
mdLang: options.mdLang ?? null,
|
|
435
438
|
dryRun: options.dryRun ?? false,
|
|
436
439
|
verbose: options.verbose ?? false,
|
|
440
|
+
...(options.doctorArgs !== undefined ? { doctorArgs: options.doctorArgs } : {}),
|
|
437
441
|
};
|
|
438
442
|
}
|
|
439
443
|
function commandRequiresTask(command) {
|
|
@@ -755,6 +759,10 @@ function requireJiraConfig(config) {
|
|
|
755
759
|
}
|
|
756
760
|
}
|
|
757
761
|
async function executeCommand(baseConfig, runFollowupVerify = true, requestUserInput = requestUserInputInTerminal, resolvedScope, setSummary, forceRefreshSummary = false, launchMode = "restart", launchProfile, runtime = runtimeServices) {
|
|
762
|
+
if (baseConfig.command === "doctor") {
|
|
763
|
+
const exitCode = await runDoctorCommand(baseConfig.doctorArgs ?? []);
|
|
764
|
+
return exitCode === 0;
|
|
765
|
+
}
|
|
758
766
|
const config = buildRuntimeConfig(baseConfig, resolvedScope ?? (await resolveScopeForCommand(baseConfig, requestUserInput)));
|
|
759
767
|
if (config.command === "auto-golang") {
|
|
760
768
|
requireJiraConfig(config);
|
|
@@ -1058,6 +1066,7 @@ function parseCliArgs(argv) {
|
|
|
1058
1066
|
let helpPhases = false;
|
|
1059
1067
|
let jiraRef;
|
|
1060
1068
|
let mdLang;
|
|
1069
|
+
const doctorArgs = [];
|
|
1061
1070
|
for (let index = 1; index < argv.length; index += 1) {
|
|
1062
1071
|
const token = argv[index] ?? "";
|
|
1063
1072
|
if (token === "--dry") {
|
|
@@ -1110,7 +1119,12 @@ function parseCliArgs(argv) {
|
|
|
1110
1119
|
}
|
|
1111
1120
|
continue;
|
|
1112
1121
|
}
|
|
1113
|
-
|
|
1122
|
+
if (command === "doctor") {
|
|
1123
|
+
doctorArgs.push(token);
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
jiraRef = token;
|
|
1127
|
+
}
|
|
1114
1128
|
}
|
|
1115
1129
|
if (command === "auto-golang" && helpPhases) {
|
|
1116
1130
|
printAutoPhasesHelp();
|
|
@@ -1130,6 +1144,7 @@ function parseCliArgs(argv) {
|
|
|
1130
1144
|
...(prompt !== undefined ? { prompt } : {}),
|
|
1131
1145
|
...(autoFromPhase !== undefined ? { autoFromPhase } : {}),
|
|
1132
1146
|
...(mdLang !== undefined ? { mdLang } : {}),
|
|
1147
|
+
...(doctorArgs.length > 0 ? { doctorArgs } : {}),
|
|
1133
1148
|
};
|
|
1134
1149
|
}
|
|
1135
1150
|
function buildConfigFromArgs(args) {
|
|
@@ -1141,6 +1156,7 @@ function buildConfigFromArgs(args) {
|
|
|
1141
1156
|
...(args.mdLang !== undefined ? { mdLang: args.mdLang } : {}),
|
|
1142
1157
|
dryRun: args.dry,
|
|
1143
1158
|
verbose: args.verbose,
|
|
1159
|
+
...(args.doctorArgs !== undefined ? { doctorArgs: args.doctorArgs } : {}),
|
|
1144
1160
|
});
|
|
1145
1161
|
}
|
|
1146
1162
|
async function runInteractive(jiraRef, forceRefresh = false, scopeName) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentweaver",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "CLI orchestrator for Jira/Codex engineering workflows",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -50,11 +50,13 @@
|
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^20.17.30",
|
|
53
|
+
"@types/semver": "^7.7.1",
|
|
53
54
|
"ts-node": "^10.9.2",
|
|
54
55
|
"typescript": "^5.8.3"
|
|
55
56
|
},
|
|
56
57
|
"dependencies": {
|
|
57
58
|
"markdown-it": "^14.1.1",
|
|
58
|
-
"neo-blessed": "^0.2.0"
|
|
59
|
+
"neo-blessed": "^0.2.0",
|
|
60
|
+
"semver": "^7.7.4"
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { DEFAULT_MODEL_BY_EXECUTOR, defaultModelForExecutor } from "./launch-profile-config.js";
|
|
4
|
-
import { scopeArtifactsDir } from "../artifacts.js";
|
|
5
|
-
const FLOW_MODEL_SETTINGS_FILE = "agentweaver-flow-model-settings.json";
|
|
6
|
-
function flowModelSettingsPath(scopeKey) {
|
|
7
|
-
return path.join(scopeArtifactsDir(scopeKey), FLOW_MODEL_SETTINGS_FILE);
|
|
8
|
-
}
|
|
9
|
-
function ensureArtifactsDir(scopeKey) {
|
|
10
|
-
const artifactsDir = scopeArtifactsDir(scopeKey);
|
|
11
|
-
if (!existsSync(artifactsDir)) {
|
|
12
|
-
mkdirSync(artifactsDir, { recursive: true });
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export function loadFlowModelSettings(scopeKey) {
|
|
16
|
-
const filePath = flowModelSettingsPath(scopeKey);
|
|
17
|
-
if (!existsSync(filePath)) {
|
|
18
|
-
return {};
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
const content = readFileSync(filePath, "utf8");
|
|
22
|
-
const parsed = JSON.parse(content);
|
|
23
|
-
if (typeof parsed !== "object" || parsed === null) {
|
|
24
|
-
return {};
|
|
25
|
-
}
|
|
26
|
-
return parsed;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export function saveFlowModelSettings(scopeKey, store) {
|
|
33
|
-
ensureArtifactsDir(scopeKey);
|
|
34
|
-
const filePath = flowModelSettingsPath(scopeKey);
|
|
35
|
-
const tempPath = `${filePath}.tmp`;
|
|
36
|
-
const content = JSON.stringify(store, null, 2);
|
|
37
|
-
writeFileSync(tempPath, content, "utf8");
|
|
38
|
-
renameSync(tempPath, filePath);
|
|
39
|
-
}
|
|
40
|
-
export function getEffectiveModelForFlow(flowId, scopeKey, executor) {
|
|
41
|
-
const store = loadFlowModelSettings(scopeKey);
|
|
42
|
-
const flowSettings = store[flowId];
|
|
43
|
-
if (!flowSettings) {
|
|
44
|
-
return defaultModelForExecutor(executor);
|
|
45
|
-
}
|
|
46
|
-
if (flowSettings.lastSelectedModel && flowSettings.lastSelectedModel !== "default") {
|
|
47
|
-
return flowSettings.lastSelectedModel;
|
|
48
|
-
}
|
|
49
|
-
if (flowSettings.defaultModel && flowSettings.defaultModel !== "default") {
|
|
50
|
-
return flowSettings.defaultModel;
|
|
51
|
-
}
|
|
52
|
-
return defaultModelForExecutor(executor);
|
|
53
|
-
}
|
|
54
|
-
export function updateLastSelectedModel(flowId, scopeKey, executor, model) {
|
|
55
|
-
const store = loadFlowModelSettings(scopeKey);
|
|
56
|
-
const existingSettings = store[flowId];
|
|
57
|
-
if (existingSettings) {
|
|
58
|
-
store[flowId] = {
|
|
59
|
-
...existingSettings,
|
|
60
|
-
executor,
|
|
61
|
-
defaultModel: model,
|
|
62
|
-
lastSelectedModel: model,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
store[flowId] = {
|
|
67
|
-
executor,
|
|
68
|
-
defaultModel: DEFAULT_MODEL_BY_EXECUTOR[executor],
|
|
69
|
-
lastSelectedModel: model,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
saveFlowModelSettings(scopeKey, store);
|
|
73
|
-
}
|
|
74
|
-
export function getFlowModelSettings(flowId, scopeKey) {
|
|
75
|
-
const store = loadFlowModelSettings(scopeKey);
|
|
76
|
-
return store[flowId] ?? null;
|
|
77
|
-
}
|