agentweaver 0.1.12 → 0.1.14

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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -18
  3. package/dist/doctor/checks/agentweaver-home.js +57 -0
  4. package/dist/doctor/checks/category.js +9 -0
  5. package/dist/doctor/checks/cwd-context.js +69 -0
  6. package/dist/doctor/checks/env-diagnostics.js +171 -0
  7. package/dist/doctor/checks/executors.js +106 -0
  8. package/dist/doctor/checks/flow-readiness.js +305 -0
  9. package/dist/doctor/checks/node-version.js +79 -0
  10. package/dist/doctor/checks/register.js +18 -0
  11. package/dist/doctor/checks/system.js +91 -0
  12. package/dist/doctor/index.js +4 -0
  13. package/dist/doctor/orchestrator.js +78 -0
  14. package/dist/doctor/registry.js +50 -0
  15. package/dist/doctor/runner.js +89 -0
  16. package/dist/doctor/types.js +12 -0
  17. package/dist/index.js +23 -27
  18. package/dist/interactive-ui.js +25 -25
  19. package/dist/pipeline/declarative-flows.js +1 -0
  20. package/dist/pipeline/flow-specs/auto-common.json +1 -0
  21. package/dist/pipeline/flow-specs/auto-golang.json +2 -1
  22. package/dist/pipeline/flow-specs/bugz/bug-analyze.json +1 -0
  23. package/dist/pipeline/flow-specs/bugz/bug-fix.json +1 -0
  24. package/dist/pipeline/flow-specs/git-commit.json +1 -0
  25. package/dist/pipeline/flow-specs/gitlab/gitlab-diff-review.json +3 -2
  26. package/dist/pipeline/flow-specs/gitlab/gitlab-review.json +3 -2
  27. package/dist/pipeline/flow-specs/gitlab/mr-description.json +1 -0
  28. package/dist/pipeline/flow-specs/go/run-go-linter-loop.json +3 -2
  29. package/dist/pipeline/flow-specs/go/run-go-tests-loop.json +3 -2
  30. package/dist/pipeline/flow-specs/implement.json +1 -0
  31. package/dist/pipeline/flow-specs/plan.json +2 -1
  32. package/dist/pipeline/flow-specs/review/review-fix.json +1 -0
  33. package/dist/pipeline/flow-specs/review/review-loop.json +1 -0
  34. package/dist/pipeline/flow-specs/review/review-project.json +1 -0
  35. package/dist/pipeline/flow-specs/review/review.json +2 -1
  36. package/dist/pipeline/flow-specs/task-describe.json +7 -6
  37. package/dist/pipeline/nodes/git-commit-node.js +1 -1
  38. package/dist/pipeline/nodes/git-status-node.js +1 -1
  39. package/dist/pipeline/nodes/review-findings-form-node.js +8 -8
  40. package/dist/pipeline/nodes/user-input-node.js +2 -2
  41. package/dist/runtime/process-runner.js +2 -2
  42. package/dist/scope.js +2 -2
  43. package/package.json +6 -3
  44. package/dist/pipeline/flow-model-settings.js +0 -77
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "kind": "task-describe-flow",
3
3
  "version": 1,
4
+ "description": "Generates a brief task description from a Jira issue or from manual input. When Jira is provided, fetches the issue and summarizes it; otherwise accepts free-form text and analyzes the codebase to produce a richer description.",
4
5
  "phases": [
5
6
  {
6
7
  "id": "task_describe",
@@ -12,7 +13,7 @@
12
13
  "formId": { "const": "task-describe-source-input" },
13
14
  "title": { "const": "Task Describe Source" },
14
15
  "description": {
15
- "const": "Укажи либо Jira issue key / browse URL, либо кратко опиши задачу вручную."
16
+ "const": "Provide a Jira issue key / browse URL, or describe the task manually."
16
17
  },
17
18
  "submitLabel": { "const": "Generate description" },
18
19
  "fields": {
@@ -22,7 +23,7 @@
22
23
  "id": "jira_ref",
23
24
  "type": "text",
24
25
  "label": "Jira issue key or browse URL",
25
- "help": "Например: DEMO-3288 или https://jira.example.ru/browse/DEMO-3288. Оставь пустым, если опишешь задачу вручную.",
26
+ "help": "Example: DEMO-3288 or https://jira.example.com/browse/DEMO-3288. Leave empty to describe the task manually.",
26
27
  "required": false
27
28
  }
28
29
  },
@@ -31,11 +32,11 @@
31
32
  "id": "additional_instructions",
32
33
  "type": "text",
33
34
  "label": "Additional instructions",
34
- "help": "Необязательные указания для генерации описания. Например: ссылка на другой локальный репозиторий, связанный проект, ограничения или полезный контекст.",
35
+ "help": "Optional instructions for description generation. Example: link to another local repo, related project, constraints, or useful context.",
35
36
  "required": false,
36
37
  "multiline": true,
37
38
  "rows": 4,
38
- "placeholder": "Например: смотри также ../billing-service, описание API есть в docs/task-templates.md"
39
+ "placeholder": "e.g. see also ../billing-service, API docs in docs/task-templates.md"
39
40
  }
40
41
  },
41
42
  {
@@ -43,11 +44,11 @@
43
44
  "id": "task_description",
44
45
  "type": "text",
45
46
  "label": "Task description",
46
- "help": "Кратко опиши задачу своими словами. Заполни это поле только если Jira нет.",
47
+ "help": "Briefly describe the task in your own words. Fill this field only if Jira is not used.",
47
48
  "required": false,
48
49
  "multiline": true,
49
50
  "rows": 3,
50
- "placeholder": "Например: добавить фильтр по статусу в список заказов и сохранить выбранное значение в URL"
51
+ "placeholder": "e.g. add a status filter to the order list and persist the selected value in the URL"
51
52
  }
52
53
  }
53
54
  ]
@@ -6,7 +6,7 @@ export const gitCommitNode = {
6
6
  async run(context, params) {
7
7
  printInfo(params.labelText ?? "Committing changes");
8
8
  if (context.dryRun) {
9
- printInfo("DRY RUN: git commit не выполнен");
9
+ printInfo("DRY RUN: git commit was not executed");
10
10
  return {
11
11
  value: {
12
12
  output: "",
@@ -187,7 +187,7 @@ export const gitStatusNode = {
187
187
  });
188
188
  const files = parsePorcelain(porcelainOutput);
189
189
  if (files.length === 0) {
190
- throw new TaskRunnerError("Нет изменённых файлов для коммита.");
190
+ throw new TaskRunnerError("No changed files to commit.");
191
191
  }
192
192
  const diff = await context.runtime.runCommand(["git", "diff"], {
193
193
  dryRun: context.dryRun,
@@ -48,8 +48,8 @@ export const reviewFindingsFormNode = {
48
48
  {
49
49
  id: "apply_all",
50
50
  type: "boolean",
51
- label: "Исправить все findings в этой итерации",
52
- help: "Если включено, выбор списка ниже не ограничивает scope исправлений.",
51
+ label: "Fix all findings in this iteration",
52
+ help: "If enabled, the selection list below does not limit the scope of fixes.",
53
53
  default: selectableFindings.length === 0,
54
54
  },
55
55
  ];
@@ -57,8 +57,8 @@ export const reviewFindingsFormNode = {
57
57
  fields.push({
58
58
  id: "selected_findings",
59
59
  type: "multi-select",
60
- label: "Какие findings исправить сейчас",
61
- help: "Space переключает пункт. Если apply_all=false, выберите хотя бы один finding.",
60
+ label: "Which findings to fix now",
61
+ help: "Space toggles an item. If apply_all is off, select at least one finding.",
62
62
  options: selectableFindings.map((finding) => ({
63
63
  value: finding.title,
64
64
  label: `${finding.title} | ${finding.severity || "-"}`,
@@ -80,17 +80,17 @@ export const reviewFindingsFormNode = {
80
80
  fields.push({
81
81
  id: "extra_notes",
82
82
  type: "text",
83
- label: "Дополнительные указания",
84
- help: "Короткий комментарий для этой итерации review-fix.",
83
+ label: "Additional instructions",
84
+ help: "Short comment for this review-fix iteration.",
85
85
  default: "",
86
- placeholder: "Например: исправить только блокеры",
86
+ placeholder: "e.g. fix only blockers",
87
87
  });
88
88
  return {
89
89
  value: {
90
90
  formId: params.formId,
91
91
  title: params.title,
92
92
  ...(params.description ? { description: params.description } : {}),
93
- submitLabel: "Запустить review-fix",
93
+ submitLabel: "Run review-fix",
94
94
  fields,
95
95
  findingCount: selectableFindings.length,
96
96
  },
@@ -46,8 +46,8 @@ function buildTaskDescribePromptSuffix(params, values) {
46
46
  ].join("\n\n")
47
47
  : "",
48
48
  summaryText: additionalInstructions
49
- ? `Источник задачи: Jira\nJira: ${jiraRef}\n\nДополнительные указания:\n${additionalInstructions}`
50
- : `Источник задачи: Jira\nJira: ${jiraRef}`,
49
+ ? `Task source: Jira\nJira: ${jiraRef}\n\nAdditional instructions:\n${additionalInstructions}`
50
+ : `Task source: Jira\nJira: ${jiraRef}`,
51
51
  };
52
52
  }
53
53
  return {
@@ -112,7 +112,7 @@ export async function runCommand(argv, options = {}) {
112
112
  }
113
113
  });
114
114
  if (outputAdapter.renderAuxiliaryOutput !== false) {
115
- printFramedBlock("Запуск", formatLaunchDetails(statusLabel), "cyan");
115
+ printFramedBlock("Launch", formatLaunchDetails(statusLabel), "cyan");
116
116
  }
117
117
  try {
118
118
  const exitCode = await new Promise((resolve, reject) => {
@@ -134,7 +134,7 @@ export async function runCommand(argv, options = {}) {
134
134
  });
135
135
  });
136
136
  if (outputAdapter.renderAuxiliaryOutput !== false) {
137
- printInfo(`Закончили работу: ${statusLabel} (${formatDuration(Date.now() - startedAt)})`);
137
+ printInfo(`Finished: ${statusLabel} (${formatDuration(Date.now() - startedAt)})`);
138
138
  }
139
139
  if (signal?.aborted) {
140
140
  throw Object.assign(new FlowInterruptedError(), {
package/dist/scope.js CHANGED
@@ -104,14 +104,14 @@ export function buildJiraTaskInputForm() {
104
104
  return {
105
105
  formId: "jira-task-input",
106
106
  title: "Jira Task",
107
- description: "Укажи Jira issue key или browse URL для task-driven flow.",
107
+ description: "Provide a Jira issue key or browse URL for a task-driven flow.",
108
108
  submitLabel: "Continue",
109
109
  fields: [
110
110
  {
111
111
  id: "jira_ref",
112
112
  type: "text",
113
113
  label: "Jira issue key or browse URL",
114
- help: "Например: DEMO-3288 или https://jira.example.ru/browse/DEMO-3288",
114
+ help: "Example: DEMO-3288 or https://jira.example.com/browse/DEMO-3288",
115
115
  required: true,
116
116
  },
117
117
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentweaver",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "CLI orchestrator for Jira/Codex engineering workflows",
5
5
  "keywords": [
6
6
  "agent",
@@ -18,7 +18,7 @@
18
18
  "type": "git",
19
19
  "url": "git+https://github.com/seko99/AgentWeaver.git"
20
20
  },
21
- "license": "UNLICENSED",
21
+ "license": "MIT",
22
22
  "type": "module",
23
23
  "main": "dist/index.js",
24
24
  "exports": "./dist/index.js",
@@ -28,6 +28,7 @@
28
28
  "files": [
29
29
  "dist",
30
30
  "README.md",
31
+ "LICENSE",
31
32
  "run_go_tests.py",
32
33
  "run_go_linter.py",
33
34
  "run_go_coverage.sh"
@@ -50,11 +51,13 @@
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/node": "^20.17.30",
54
+ "@types/semver": "^7.7.1",
53
55
  "ts-node": "^10.9.2",
54
56
  "typescript": "^5.8.3"
55
57
  },
56
58
  "dependencies": {
57
59
  "markdown-it": "^14.1.1",
58
- "neo-blessed": "^0.2.0"
60
+ "neo-blessed": "^0.2.0",
61
+ "semver": "^7.7.4"
59
62
  }
60
63
  }
@@ -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
- }