@sireai/optimus 0.1.5 → 0.1.7
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 +8 -1
- package/dist/cli/optimus.js +98 -86
- package/dist/cli/optimus.js.map +1 -1
- package/dist/cli/self-update.js +19 -4
- package/dist/cli/self-update.js.map +1 -1
- package/dist/config/load-config.js +9 -46
- package/dist/config/load-config.js.map +1 -1
- package/dist/integrations/jira/jira-auth-refresh.d.ts +15 -0
- package/dist/integrations/jira/jira-auth-refresh.js +131 -0
- package/dist/integrations/jira/jira-auth-refresh.js.map +1 -0
- package/dist/integrations/jira/jira-cli.js +102 -19
- package/dist/integrations/jira/jira-cli.js.map +1 -1
- package/dist/integrations/jira/jira-client.d.ts +6 -11
- package/dist/integrations/jira/jira-client.js +105 -271
- package/dist/integrations/jira/jira-client.js.map +1 -1
- package/dist/problem-solving-core/codex/codex-runner.d.ts +4 -0
- package/dist/problem-solving-core/codex/codex-runner.js +49 -3
- package/dist/problem-solving-core/codex/codex-runner.js.map +1 -1
- package/dist/task-environment/delivery/feishu-card-renderer.js +9 -0
- package/dist/task-environment/delivery/feishu-card-renderer.js.map +1 -1
- package/dist/task-environment/delivery/feishu-content/feishu-content-renderer.d.ts +1 -0
- package/dist/task-environment/delivery/feishu-content/feishu-content-renderer.js +5 -0
- package/dist/task-environment/delivery/feishu-content/feishu-content-renderer.js.map +1 -1
- package/dist/task-environment/delivery/feishu-notifier.js +1 -0
- package/dist/task-environment/delivery/feishu-notifier.js.map +1 -1
- package/dist/task-environment/delivery/feishu-templates/analysis-message-template.js +4 -0
- package/dist/task-environment/delivery/feishu-templates/analysis-message-template.js.map +1 -1
- package/dist/task-environment/delivery/feishu-templates/bugfix-message-template.js +4 -0
- package/dist/task-environment/delivery/feishu-templates/bugfix-message-template.js.map +1 -1
- package/dist/task-environment/delivery/feishu-templates/default-message-template.js +4 -0
- package/dist/task-environment/delivery/feishu-templates/default-message-template.js.map +1 -1
- package/dist/task-environment/delivery/feishu-templates/patch-message-template.js +4 -0
- package/dist/task-environment/delivery/feishu-templates/patch-message-template.js.map +1 -1
- package/dist/task-environment/delivery/feishu-templates/sentry-bugfix-message-template.js +4 -0
- package/dist/task-environment/delivery/feishu-templates/sentry-bugfix-message-template.js.map +1 -1
- package/dist/task-environment/delivery/feishu-templates/template-types.d.ts +1 -0
- package/dist/task-environment/delivery/sentry-feishu-card-renderer.js +5 -0
- package/dist/task-environment/delivery/sentry-feishu-card-renderer.js.map +1 -1
- package/dist/task-environment/delivery/task-delivery-service.js +4 -1
- package/dist/task-environment/delivery/task-delivery-service.js.map +1 -1
- package/dist/task-environment/delivery/task-publication-service.d.ts +3 -8
- package/dist/task-environment/delivery/task-publication-service.js +0 -43
- package/dist/task-environment/delivery/task-publication-service.js.map +1 -1
- package/dist/task-environment/execution-addresses.d.ts +1 -0
- package/dist/task-environment/execution-addresses.js +82 -1
- package/dist/task-environment/execution-addresses.js.map +1 -1
- package/dist/task-environment/observability/execution-metrics.d.ts +11 -0
- package/dist/task-environment/observability/execution-metrics.js +110 -0
- package/dist/task-environment/observability/execution-metrics.js.map +1 -0
- package/dist/task-environment/observability/runtime-panel.d.ts +1 -0
- package/dist/task-environment/observability/runtime-panel.js +32 -2
- package/dist/task-environment/observability/runtime-panel.js.map +1 -1
- package/dist/task-environment/storage/sqlite-task-store.d.ts +5 -1
- package/dist/task-environment/storage/sqlite-task-store.js +65 -6
- package/dist/task-environment/storage/sqlite-task-store.js.map +1 -1
- package/dist/types.d.ts +17 -7
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -20,7 +20,13 @@ From a user view, the flow is simple: submit a problem, let Optimus run inside t
|
|
|
20
20
|
### 1. Install
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm install -g @sireai/optimus
|
|
23
|
+
npm install -g @sireai/optimus --registry=https://registry.npmjs.org
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If Jira CAS refresh reports a missing Playwright browser, install Chromium once:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx playwright install chromium
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
### 2. Run setup
|
|
@@ -95,6 +101,7 @@ Jira intake:
|
|
|
95
101
|
|
|
96
102
|
```bash
|
|
97
103
|
optimus jira-submit-issue --issue-key MICARAPPI-13178 --repo mobile-app
|
|
104
|
+
optimus jira-refresh-auth --issue-key MICARAPPI-13178
|
|
98
105
|
```
|
|
99
106
|
|
|
100
107
|
Sentry intake:
|
package/dist/cli/optimus.js
CHANGED
|
@@ -23,6 +23,7 @@ import { TriageRunner } from "../task-environment/orchestration/triage-runner.js
|
|
|
23
23
|
import { OptimusRuntime } from "../task-environment/runtime/optimus-runtime.js";
|
|
24
24
|
import { SQLiteTaskStore } from "../task-environment/storage/sqlite-task-store.js";
|
|
25
25
|
import { SQLiteEventStore } from "../task-environment/storage/sqlite-event-store.js";
|
|
26
|
+
import { buildTaskExecutionMetrics, formatExecutionMetricsCompact } from "../task-environment/observability/execution-metrics.js";
|
|
26
27
|
import { FeishuNotifier } from "../task-environment/delivery/feishu-notifier.js";
|
|
27
28
|
import { TaskDeliveryDispatcher } from "../task-environment/delivery/task-delivery-dispatcher.js";
|
|
28
29
|
import { TaskDeliveryService } from "../task-environment/delivery/task-delivery-service.js";
|
|
@@ -164,7 +165,7 @@ function renderCliHelp() {
|
|
|
164
165
|
" postrun-retry Rebuild postrun artifacts and optionally replay publication",
|
|
165
166
|
"",
|
|
166
167
|
"Integration commands:",
|
|
167
|
-
" jira-search|jira-get-issue|jira-search-assigned-open|jira-submit-issue|jira-submit-assigned-open|jira-add-comment|jira-poll-once|jira-poll-daemon",
|
|
168
|
+
" jira-search|jira-get-issue|jira-search-assigned-open|jira-submit-issue|jira-submit-assigned-open|jira-add-comment|jira-refresh-auth|jira-poll-once|jira-poll-daemon",
|
|
168
169
|
" sentry-get-event|sentry-submit-event",
|
|
169
170
|
" Example: optimus help jira-submit-issue",
|
|
170
171
|
"",
|
|
@@ -362,7 +363,8 @@ function renderCommandHelp(command) {
|
|
|
362
363
|
" --expand <csv> Jira expand parameters",
|
|
363
364
|
" --properties <csv> Jira properties",
|
|
364
365
|
" --comment-limit <n> Comment limit, default 3",
|
|
365
|
-
" --update-history true|false Include update history"
|
|
366
|
+
" --update-history true|false Include update history",
|
|
367
|
+
" --raw Include raw Jira REST response"
|
|
366
368
|
].join("\n"),
|
|
367
369
|
"jira-search": [
|
|
368
370
|
"optimus jira-search",
|
|
@@ -402,6 +404,19 @@ function renderCommandHelp(command) {
|
|
|
402
404
|
" --issue-key <key> Jira issue key",
|
|
403
405
|
" --body <text> Comment body"
|
|
404
406
|
].join("\n"),
|
|
407
|
+
"jira-refresh-auth": [
|
|
408
|
+
"optimus jira-refresh-auth",
|
|
409
|
+
"",
|
|
410
|
+
"Usage:",
|
|
411
|
+
" optimus jira-refresh-auth [options]",
|
|
412
|
+
"",
|
|
413
|
+
"Optional:",
|
|
414
|
+
" --verify Verify current Jira REST auth without refreshing",
|
|
415
|
+
" --issue-key <key> Verify by reading a specific Jira issue",
|
|
416
|
+
"",
|
|
417
|
+
"Example:",
|
|
418
|
+
" optimus jira-refresh-auth --issue-key MICARAPPI-13178"
|
|
419
|
+
].join("\n"),
|
|
405
420
|
"jira-poll-once": [
|
|
406
421
|
"optimus jira-poll-once",
|
|
407
422
|
"",
|
|
@@ -475,6 +490,8 @@ function mapJiraCommand(command) {
|
|
|
475
490
|
return "submit-assigned-open";
|
|
476
491
|
case "jira-add-comment":
|
|
477
492
|
return "add-comment";
|
|
493
|
+
case "jira-refresh-auth":
|
|
494
|
+
return "refresh-auth";
|
|
478
495
|
case "jira-poll-once":
|
|
479
496
|
return "poll-once";
|
|
480
497
|
case "jira-poll-daemon":
|
|
@@ -502,44 +519,18 @@ function resolveJiraQuickDoctorIssues(config, options) {
|
|
|
502
519
|
fix: "Rerun `optimus setup` and provide a real Jira base URL."
|
|
503
520
|
});
|
|
504
521
|
}
|
|
505
|
-
if (config.
|
|
506
|
-
if (!config.bearerToken?.trim()) {
|
|
507
|
-
issues.push({
|
|
508
|
-
code: "jira_token_missing",
|
|
509
|
-
message: "Jira integration is enabled, but Jira bearer token is missing.",
|
|
510
|
-
fix: "Rerun `optimus setup` and provide a Jira token."
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
return issues;
|
|
514
|
-
}
|
|
515
|
-
if (config.authType === "basic") {
|
|
516
|
-
if (!config.username?.trim() || !(config.apiToken?.trim() || config.password?.trim())) {
|
|
517
|
-
issues.push({
|
|
518
|
-
code: "jira_basic_auth_missing",
|
|
519
|
-
message: "Jira integration is enabled, but Jira basic auth credentials are incomplete.",
|
|
520
|
-
fix: "Provide Jira username plus api token or password, then rerun `optimus doctor --quick`."
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
return issues;
|
|
524
|
-
}
|
|
525
|
-
if (!config.mcpUrl?.trim() || /jira-mcp\.example\.com/i.test(config.mcpUrl)) {
|
|
522
|
+
if (!config.personalToken?.trim()) {
|
|
526
523
|
issues.push({
|
|
527
|
-
code: "
|
|
528
|
-
message: "Jira integration is enabled, but Jira
|
|
529
|
-
fix: "
|
|
524
|
+
code: "jira_token_missing",
|
|
525
|
+
message: "Jira integration is enabled, but Jira personal token is missing.",
|
|
526
|
+
fix: "Rerun `optimus setup` and provide a Jira personal token."
|
|
530
527
|
});
|
|
531
528
|
}
|
|
532
|
-
|
|
533
|
-
"X-Atlassian-Jira-Url",
|
|
534
|
-
"X-Atlassian-Username",
|
|
535
|
-
"X-Atlassian-Jira-Personal-Token"
|
|
536
|
-
];
|
|
537
|
-
const missingHeaders = requiredHeaders.filter((name) => !config.httpHeaders[name]?.trim());
|
|
538
|
-
if (missingHeaders.length > 0) {
|
|
529
|
+
if (!config.casCookieName?.trim()) {
|
|
539
530
|
issues.push({
|
|
540
|
-
code: "
|
|
541
|
-
message:
|
|
542
|
-
fix: "
|
|
531
|
+
code: "jira_cas_cookie_name_missing",
|
|
532
|
+
message: "Jira integration is enabled, but Jira CAS cookie name is missing.",
|
|
533
|
+
fix: "Rerun `optimus setup` and provide the Jira CAS cookie name."
|
|
543
534
|
});
|
|
544
535
|
}
|
|
545
536
|
return issues;
|
|
@@ -924,12 +915,24 @@ async function promptSetupAnswers(defaults) {
|
|
|
924
915
|
}
|
|
925
916
|
return rl.question(prompt);
|
|
926
917
|
};
|
|
918
|
+
const printSetupSection = (title, detail) => {
|
|
919
|
+
console.log(`\n[${title}]`);
|
|
920
|
+
if (detail) {
|
|
921
|
+
console.log(detail);
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
const renderSetupPrompt = (label, promptLabel, defaultValue) => {
|
|
925
|
+
const suffix = defaultValue !== undefined ? ` [${defaultValue}]` : "";
|
|
926
|
+
return `[${label}] ${promptLabel}${suffix}: `;
|
|
927
|
+
};
|
|
927
928
|
try {
|
|
928
929
|
if (await pathExists(configPath)) {
|
|
929
930
|
console.log(`Existing config found at ${configPath}. Press Enter to keep current values.`);
|
|
930
931
|
}
|
|
931
|
-
|
|
932
|
-
const
|
|
932
|
+
printSetupSection("Repository", "Register the primary local repository used by Optimus.");
|
|
933
|
+
const repoPath = (await ask(renderSetupPrompt("Required", "Repository path", defaults.repoPath))).trim() || defaults.repoPath;
|
|
934
|
+
const repoAlias = (await ask(renderSetupPrompt("Required", "Repository alias", defaults.repoAlias))).trim() || defaults.repoAlias;
|
|
935
|
+
printSetupSection("Codex", "Choose one authentication mode, then fill the fields that follow.");
|
|
933
936
|
const codexAuthMode = await askSetupCodexAuthMode({ ask, defaultMode: defaults.codexAuthMode });
|
|
934
937
|
let codexApiKey;
|
|
935
938
|
let codexProviderId;
|
|
@@ -937,54 +940,54 @@ async function promptSetupAnswers(defaults) {
|
|
|
937
940
|
let codexProviderBaseUrl;
|
|
938
941
|
let codexProviderApiKeyEnvName;
|
|
939
942
|
if (codexAuthMode === "openai_api_key") {
|
|
940
|
-
codexApiKey = (await ask("OpenAI API key for OPENAI_API_KEY
|
|
943
|
+
codexApiKey = (await ask(renderSetupPrompt("Optional", "OpenAI API key for OPENAI_API_KEY", "leave blank to keep existing"))).trim() || undefined;
|
|
941
944
|
}
|
|
942
945
|
else if (codexAuthMode === "model_provider") {
|
|
943
|
-
codexProviderId = (await ask(
|
|
944
|
-
codexProviderDisplayName = (await ask(
|
|
945
|
-
codexProviderBaseUrl = (await ask(
|
|
946
|
-
codexProviderApiKeyEnvName = (await ask(
|
|
946
|
+
codexProviderId = (await ask(renderSetupPrompt("Required", "Provider id", defaults.codexProviderId ?? ""))).trim() || defaults.codexProviderId;
|
|
947
|
+
codexProviderDisplayName = (await ask(renderSetupPrompt("Required", "Provider display name", defaults.codexProviderDisplayName ?? ""))).trim() || defaults.codexProviderDisplayName;
|
|
948
|
+
codexProviderBaseUrl = (await ask(renderSetupPrompt("Required", "Provider base URL", defaults.codexProviderBaseUrl ?? ""))).trim() || defaults.codexProviderBaseUrl;
|
|
949
|
+
codexProviderApiKeyEnvName = (await ask(renderSetupPrompt("Required", "Provider API key env name", defaults.codexProviderApiKeyEnvName ?? ""))).trim() || defaults.codexProviderApiKeyEnvName;
|
|
947
950
|
const providerKeyLabel = codexProviderApiKeyEnvName || defaults.codexProviderApiKeyEnvName || "the configured provider env";
|
|
948
|
-
codexApiKey = (await ask(`Provider API key value for ${providerKeyLabel}
|
|
951
|
+
codexApiKey = (await ask(renderSetupPrompt("Optional", `Provider API key value for ${providerKeyLabel}`, "leave blank to keep existing"))).trim() || undefined;
|
|
949
952
|
}
|
|
950
|
-
|
|
953
|
+
printSetupSection("Feishu", "Enable this module when task notifications should be sent to Feishu.");
|
|
954
|
+
const enableFeishuInput = (await ask(renderSetupPrompt("Optional module", "Enable Feishu delivery", defaults.enableFeishu ? "Y/n" : "y/N"))).trim().toLowerCase();
|
|
951
955
|
const enableFeishu = enableFeishuInput.length === 0
|
|
952
956
|
? defaults.enableFeishu
|
|
953
957
|
: ["y", "yes"].includes(enableFeishuInput);
|
|
954
958
|
const feishuWebhook = enableFeishu
|
|
955
|
-
? (await ask(
|
|
959
|
+
? (await ask(renderSetupPrompt("Required", "Feishu webhook", defaults.feishuWebhook ? "configured" : ""))).trim() || defaults.feishuWebhook
|
|
956
960
|
: undefined;
|
|
957
961
|
const feishuSecret = enableFeishu
|
|
958
|
-
? (await ask(
|
|
962
|
+
? (await ask(renderSetupPrompt("Optional", "Feishu secret", defaults.feishuSecret ? "configured" : ""))).trim() || defaults.feishuSecret
|
|
959
963
|
: undefined;
|
|
960
|
-
|
|
964
|
+
printSetupSection("Jira", "Enable this module when Optimus should read issues or comment back to Jira.");
|
|
965
|
+
const enableJiraInput = (await ask(renderSetupPrompt("Optional module", "Enable Jira integration", defaults.enableJira ? "Y/n" : "y/N"))).trim().toLowerCase();
|
|
961
966
|
const enableJira = enableJiraInput.length === 0
|
|
962
967
|
? defaults.enableJira
|
|
963
968
|
: ["y", "yes"].includes(enableJiraInput);
|
|
964
969
|
const jiraBaseUrl = enableJira
|
|
965
|
-
? (await ask(
|
|
966
|
-
: undefined;
|
|
967
|
-
const jiraMcpUrl = enableJira
|
|
968
|
-
? (await ask(`Jira MCP URL [${defaults.jiraMcpUrl ?? ""}]: `)).trim() || defaults.jiraMcpUrl
|
|
969
|
-
: undefined;
|
|
970
|
-
const jiraUsername = enableJira
|
|
971
|
-
? (await ask(`Jira username [${defaults.jiraUsername ?? ""}]: `)).trim() || defaults.jiraUsername
|
|
970
|
+
? (await ask(renderSetupPrompt("Required", "Jira base URL", defaults.jiraBaseUrl ?? ""))).trim() || defaults.jiraBaseUrl
|
|
972
971
|
: undefined;
|
|
973
972
|
const jiraPersonalToken = enableJira
|
|
974
|
-
? (await ask(
|
|
973
|
+
? (await ask(renderSetupPrompt("Required", "Jira personal token", defaults.jiraPersonalToken ? "configured" : ""))).trim() || defaults.jiraPersonalToken
|
|
974
|
+
: undefined;
|
|
975
|
+
const jiraCasCookieName = enableJira
|
|
976
|
+
? (await ask(renderSetupPrompt("Optional", "Jira CAS cookie name", defaults.jiraCasCookieName ?? "_aegis_cas_p"))).trim() || defaults.jiraCasCookieName || "_aegis_cas_p"
|
|
975
977
|
: undefined;
|
|
976
|
-
|
|
978
|
+
printSetupSection("Sentry", "Enable this module when tasks can be created from Sentry events.");
|
|
979
|
+
const enableSentryInput = (await ask(renderSetupPrompt("Optional module", "Enable Sentry integration", defaults.enableSentry ? "Y/n" : "y/N"))).trim().toLowerCase();
|
|
977
980
|
const enableSentry = enableSentryInput.length === 0
|
|
978
981
|
? defaults.enableSentry
|
|
979
982
|
: ["y", "yes"].includes(enableSentryInput);
|
|
980
983
|
const sentryBaseUrl = enableSentry
|
|
981
|
-
? (await ask(
|
|
984
|
+
? (await ask(renderSetupPrompt("Required", "Sentry base URL", defaults.sentryBaseUrl ?? ""))).trim() || defaults.sentryBaseUrl
|
|
982
985
|
: undefined;
|
|
983
986
|
const sentryOrg = enableSentry
|
|
984
|
-
? (await ask(
|
|
987
|
+
? (await ask(renderSetupPrompt("Required", "Sentry org", defaults.sentryOrg ?? ""))).trim() || defaults.sentryOrg
|
|
985
988
|
: undefined;
|
|
986
989
|
const sentryAuthToken = enableSentry
|
|
987
|
-
? (await ask(
|
|
990
|
+
? (await ask(renderSetupPrompt("Required", "Sentry auth token", defaults.sentryAuthToken ? "configured" : ""))).trim() || defaults.sentryAuthToken
|
|
988
991
|
: undefined;
|
|
989
992
|
return {
|
|
990
993
|
repoPath,
|
|
@@ -1000,9 +1003,9 @@ async function promptSetupAnswers(defaults) {
|
|
|
1000
1003
|
...(feishuSecret ? { feishuSecret } : {}),
|
|
1001
1004
|
enableJira,
|
|
1002
1005
|
...(jiraBaseUrl ? { jiraBaseUrl } : {}),
|
|
1003
|
-
...(jiraMcpUrl ? { jiraMcpUrl } : {}),
|
|
1004
|
-
...(jiraUsername ? { jiraUsername } : {}),
|
|
1005
1006
|
...(jiraPersonalToken ? { jiraPersonalToken } : {}),
|
|
1007
|
+
...(jiraCasCookieName ? { jiraCasCookieName } : {}),
|
|
1008
|
+
...(defaults.jiraCustomHeaders ? { jiraCustomHeaders: defaults.jiraCustomHeaders } : {}),
|
|
1006
1009
|
enableSentry,
|
|
1007
1010
|
...(sentryBaseUrl ? { sentryBaseUrl } : {}),
|
|
1008
1011
|
...(sentryOrg ? { sentryOrg } : {}),
|
|
@@ -1052,9 +1055,9 @@ async function resolveDefaultSetupAnswers() {
|
|
|
1052
1055
|
...(config.delivery.feishu.secret ? { feishuSecret: config.delivery.feishu.secret } : {}),
|
|
1053
1056
|
enableJira: config.jira.enabled,
|
|
1054
1057
|
...(config.jira.baseUrl ? { jiraBaseUrl: config.jira.baseUrl } : {}),
|
|
1055
|
-
...(config.jira.
|
|
1056
|
-
...(config.jira.
|
|
1057
|
-
...(config.jira.
|
|
1058
|
+
...(config.jira.personalToken ? { jiraPersonalToken: config.jira.personalToken } : {}),
|
|
1059
|
+
...(config.jira.casCookieName ? { jiraCasCookieName: config.jira.casCookieName } : {}),
|
|
1060
|
+
...(config.jira.customHeaders ? { jiraCustomHeaders: config.jira.customHeaders } : {}),
|
|
1058
1061
|
enableSentry: config.sentry.enabled,
|
|
1059
1062
|
...(config.sentry.baseUrl ? { sentryBaseUrl: config.sentry.baseUrl } : {}),
|
|
1060
1063
|
...(config.sentry.org ? { sentryOrg: config.sentry.org } : {}),
|
|
@@ -1079,7 +1082,7 @@ function normalizeSetupCodexAuthMode(value) {
|
|
|
1079
1082
|
}
|
|
1080
1083
|
function renderSetupCodexAuthModePrompt(defaultMode) {
|
|
1081
1084
|
const defaultIndex = SETUP_CODEX_AUTH_MODE_OPTIONS.find((option) => option.mode === defaultMode)?.index ?? "1";
|
|
1082
|
-
const lines = ["Codex auth mode:"];
|
|
1085
|
+
const lines = ["[Required] Codex auth mode:"];
|
|
1083
1086
|
for (const option of SETUP_CODEX_AUTH_MODE_OPTIONS) {
|
|
1084
1087
|
const defaultSuffix = option.index === defaultIndex ? " (default)" : "";
|
|
1085
1088
|
lines.push(`${option.index}. ${option.label} [${option.mode}]${defaultSuffix}`);
|
|
@@ -1125,12 +1128,6 @@ function validateSetupAnswers(answers) {
|
|
|
1125
1128
|
if (answers.enableJira && !answers.jiraBaseUrl?.trim()) {
|
|
1126
1129
|
return "setup requires a Jira base URL when Jira integration is enabled.";
|
|
1127
1130
|
}
|
|
1128
|
-
if (answers.enableJira && !answers.jiraMcpUrl?.trim()) {
|
|
1129
|
-
return "setup requires a Jira MCP URL when Jira integration is enabled.";
|
|
1130
|
-
}
|
|
1131
|
-
if (answers.enableJira && !answers.jiraUsername?.trim()) {
|
|
1132
|
-
return "setup requires a Jira username when Jira integration is enabled.";
|
|
1133
|
-
}
|
|
1134
1131
|
if (answers.enableJira && !answers.jiraPersonalToken?.trim()) {
|
|
1135
1132
|
return "setup requires a Jira personal token when Jira integration is enabled.";
|
|
1136
1133
|
}
|
|
@@ -1207,19 +1204,16 @@ function buildSetupConfig(answers) {
|
|
|
1207
1204
|
config.jira.enabled = answers.enableJira;
|
|
1208
1205
|
if (answers.enableJira) {
|
|
1209
1206
|
config.jira.baseUrl = answers.jiraBaseUrl ?? config.jira.baseUrl;
|
|
1210
|
-
if (answers.
|
|
1211
|
-
config.jira.
|
|
1212
|
-
}
|
|
1213
|
-
config.jira.
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
delete config.jira.username;
|
|
1221
|
-
delete config.jira.apiToken;
|
|
1222
|
-
delete config.jira.password;
|
|
1207
|
+
if (answers.jiraPersonalToken) {
|
|
1208
|
+
config.jira.personalToken = answers.jiraPersonalToken;
|
|
1209
|
+
}
|
|
1210
|
+
config.jira.casCookieName = answers.jiraCasCookieName?.trim() || "_aegis_cas_p";
|
|
1211
|
+
if (answers.jiraCustomHeaders?.trim()) {
|
|
1212
|
+
config.jira.customHeaders = answers.jiraCustomHeaders.trim();
|
|
1213
|
+
}
|
|
1214
|
+
else {
|
|
1215
|
+
delete config.jira.customHeaders;
|
|
1216
|
+
}
|
|
1223
1217
|
}
|
|
1224
1218
|
config.sentry.enabled = answers.enableSentry;
|
|
1225
1219
|
if (answers.enableSentry) {
|
|
@@ -2389,6 +2383,7 @@ async function main() {
|
|
|
2389
2383
|
const taskRuns = runs.filter((run) => run.taskId === task.taskId);
|
|
2390
2384
|
const activeRun = runs.find((run) => run.runId === task.activeRunId) ?? taskRuns.slice(-1)[0];
|
|
2391
2385
|
const timing = activeRun ? buildRunTimingSnapshot(activeRun, config) : { elapsedMs: 0, idleMs: 0, timeoutKind: null };
|
|
2386
|
+
const activeMetrics = activeRun ? buildTaskExecutionMetrics(activeRun) : undefined;
|
|
2392
2387
|
return {
|
|
2393
2388
|
taskId: task.taskId,
|
|
2394
2389
|
taskPackageId: task.taskPackageId,
|
|
@@ -2415,9 +2410,14 @@ async function main() {
|
|
|
2415
2410
|
elapsedMs: activeRun ? timing.elapsedMs : null,
|
|
2416
2411
|
idleMs: activeRun ? timing.idleMs : null,
|
|
2417
2412
|
timeoutKind: activeRun ? timing.timeoutKind : null,
|
|
2413
|
+
metrics: activeMetrics ? {
|
|
2414
|
+
...activeMetrics,
|
|
2415
|
+
display: formatExecutionMetricsCompact(activeMetrics)
|
|
2416
|
+
} : null,
|
|
2418
2417
|
nextAction: buildTaskNextAction(task.status, activeRun?.failureCategory),
|
|
2419
2418
|
runs: taskRuns.slice(-3).map((run) => {
|
|
2420
2419
|
const timing = buildRunTimingSnapshot(run, config);
|
|
2420
|
+
const metrics = buildTaskExecutionMetrics(run);
|
|
2421
2421
|
return {
|
|
2422
2422
|
runId: run.runId,
|
|
2423
2423
|
status: run.status,
|
|
@@ -2444,7 +2444,11 @@ async function main() {
|
|
|
2444
2444
|
cancelRequestedAt: run.cancelRequestedAt ?? null,
|
|
2445
2445
|
elapsedMs: timing.elapsedMs,
|
|
2446
2446
|
idleMs: timing.idleMs,
|
|
2447
|
-
timeoutKind: timing.timeoutKind
|
|
2447
|
+
timeoutKind: timing.timeoutKind,
|
|
2448
|
+
metrics: metrics ? {
|
|
2449
|
+
...metrics,
|
|
2450
|
+
display: formatExecutionMetricsCompact(metrics)
|
|
2451
|
+
} : null
|
|
2448
2452
|
};
|
|
2449
2453
|
})
|
|
2450
2454
|
};
|
|
@@ -3119,6 +3123,10 @@ function renderTaskResultReport(input) {
|
|
|
3119
3123
|
if (latestRun.endedAt) {
|
|
3120
3124
|
lines.push(`Ended At: ${latestRun.endedAt}`);
|
|
3121
3125
|
}
|
|
3126
|
+
const metrics = formatExecutionMetricsCompact(buildTaskExecutionMetrics(latestRun));
|
|
3127
|
+
if (metrics) {
|
|
3128
|
+
lines.push(`Metrics: ${metrics}`);
|
|
3129
|
+
}
|
|
3122
3130
|
}
|
|
3123
3131
|
lines.push("");
|
|
3124
3132
|
lines.push("Summary");
|
|
@@ -3142,6 +3150,10 @@ function renderTaskResultReport(input) {
|
|
|
3142
3150
|
lines.push("Delivery");
|
|
3143
3151
|
lines.push(`Outcome: ${input.deliveryBundle.outcome}`);
|
|
3144
3152
|
lines.push(`Decision: ${input.deliveryBundle.summary.decision}`);
|
|
3153
|
+
const metrics = formatExecutionMetricsCompact(input.deliveryBundle.metrics);
|
|
3154
|
+
if (metrics) {
|
|
3155
|
+
lines.push(`Metrics: ${metrics}`);
|
|
3156
|
+
}
|
|
3145
3157
|
if (input.deliveryBundle.warnings?.length) {
|
|
3146
3158
|
lines.push(`Warnings: ${input.deliveryBundle.warnings.join(", ")}`);
|
|
3147
3159
|
}
|