@sireai/optimus 0.1.6 → 0.1.8

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 (28) hide show
  1. package/README.md +8 -1
  2. package/dist/cli/optimus.js +44 -66
  3. package/dist/cli/optimus.js.map +1 -1
  4. package/dist/cli/self-update.js +19 -4
  5. package/dist/cli/self-update.js.map +1 -1
  6. package/dist/config/load-config.js +9 -46
  7. package/dist/config/load-config.js.map +1 -1
  8. package/dist/integrations/jira/jira-auth-refresh.d.ts +15 -0
  9. package/dist/integrations/jira/jira-auth-refresh.js +131 -0
  10. package/dist/integrations/jira/jira-auth-refresh.js.map +1 -0
  11. package/dist/integrations/jira/jira-cli.js +107 -19
  12. package/dist/integrations/jira/jira-cli.js.map +1 -1
  13. package/dist/integrations/jira/jira-client.d.ts +6 -11
  14. package/dist/integrations/jira/jira-client.js +105 -279
  15. package/dist/integrations/jira/jira-client.js.map +1 -1
  16. package/dist/task-environment/delivery/feishu-card-renderer.js +8 -6
  17. package/dist/task-environment/delivery/feishu-card-renderer.js.map +1 -1
  18. package/dist/task-environment/delivery/sentry-feishu-card-renderer.js +6 -4
  19. package/dist/task-environment/delivery/sentry-feishu-card-renderer.js.map +1 -1
  20. package/dist/task-environment/delivery/task-publication-service.d.ts +8 -7
  21. package/dist/task-environment/delivery/task-publication-service.js +97 -8
  22. package/dist/task-environment/delivery/task-publication-service.js.map +1 -1
  23. package/dist/task-environment/observability/execution-metrics.js +1 -1
  24. package/dist/task-environment/observability/execution-metrics.js.map +1 -1
  25. package/dist/task-environment/storage/sqlite-task-store.js +1 -0
  26. package/dist/task-environment/storage/sqlite-task-store.js.map +1 -1
  27. package/dist/types.d.ts +3 -7
  28. 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:
@@ -165,7 +165,7 @@ function renderCliHelp() {
165
165
  " postrun-retry Rebuild postrun artifacts and optionally replay publication",
166
166
  "",
167
167
  "Integration commands:",
168
- " 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",
169
169
  " sentry-get-event|sentry-submit-event",
170
170
  " Example: optimus help jira-submit-issue",
171
171
  "",
@@ -363,7 +363,8 @@ function renderCommandHelp(command) {
363
363
  " --expand <csv> Jira expand parameters",
364
364
  " --properties <csv> Jira properties",
365
365
  " --comment-limit <n> Comment limit, default 3",
366
- " --update-history true|false Include update history"
366
+ " --update-history true|false Include update history",
367
+ " --raw Include raw Jira REST response"
367
368
  ].join("\n"),
368
369
  "jira-search": [
369
370
  "optimus jira-search",
@@ -403,6 +404,19 @@ function renderCommandHelp(command) {
403
404
  " --issue-key <key> Jira issue key",
404
405
  " --body <text> Comment body"
405
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"),
406
420
  "jira-poll-once": [
407
421
  "optimus jira-poll-once",
408
422
  "",
@@ -476,6 +490,8 @@ function mapJiraCommand(command) {
476
490
  return "submit-assigned-open";
477
491
  case "jira-add-comment":
478
492
  return "add-comment";
493
+ case "jira-refresh-auth":
494
+ return "refresh-auth";
479
495
  case "jira-poll-once":
480
496
  return "poll-once";
481
497
  case "jira-poll-daemon":
@@ -503,44 +519,18 @@ function resolveJiraQuickDoctorIssues(config, options) {
503
519
  fix: "Rerun `optimus setup` and provide a real Jira base URL."
504
520
  });
505
521
  }
506
- if (config.authType === "bearer") {
507
- if (!config.bearerToken?.trim()) {
508
- issues.push({
509
- code: "jira_token_missing",
510
- message: "Jira integration is enabled, but Jira bearer token is missing.",
511
- fix: "Rerun `optimus setup` and provide a Jira token."
512
- });
513
- }
514
- return issues;
515
- }
516
- if (config.authType === "basic") {
517
- if (!config.username?.trim() || !(config.apiToken?.trim() || config.password?.trim())) {
518
- issues.push({
519
- code: "jira_basic_auth_missing",
520
- message: "Jira integration is enabled, but Jira basic auth credentials are incomplete.",
521
- fix: "Provide Jira username plus api token or password, then rerun `optimus doctor --quick`."
522
- });
523
- }
524
- return issues;
525
- }
526
- if (!config.mcpUrl?.trim() || /jira-mcp\.example\.com/i.test(config.mcpUrl)) {
522
+ if (!config.personalToken?.trim()) {
527
523
  issues.push({
528
- code: "jira_mcp_url_missing",
529
- message: "Jira integration is enabled, but Jira MCP URL is missing or still using the placeholder value.",
530
- fix: "Provide a real Jira MCP URL, then rerun `optimus doctor --quick`."
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."
531
527
  });
532
528
  }
533
- const requiredHeaders = [
534
- "X-Atlassian-Jira-Url",
535
- "X-Atlassian-Username",
536
- "X-Atlassian-Jira-Personal-Token"
537
- ];
538
- const missingHeaders = requiredHeaders.filter((name) => !config.httpHeaders[name]?.trim());
539
- if (missingHeaders.length > 0) {
529
+ if (!config.casCookieName?.trim()) {
540
530
  issues.push({
541
- code: "jira_mcp_headers_missing",
542
- message: `Jira integration is enabled, but Jira MCP headers are incomplete: ${missingHeaders.join(", ")}.`,
543
- fix: "Provide the required Jira MCP headers, then rerun `optimus doctor --quick`."
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."
544
534
  });
545
535
  }
546
536
  return issues;
@@ -979,15 +969,12 @@ async function promptSetupAnswers(defaults) {
979
969
  const jiraBaseUrl = enableJira
980
970
  ? (await ask(renderSetupPrompt("Required", "Jira base URL", defaults.jiraBaseUrl ?? ""))).trim() || defaults.jiraBaseUrl
981
971
  : undefined;
982
- const jiraMcpUrl = enableJira
983
- ? (await ask(renderSetupPrompt("Required", "Jira MCP URL", defaults.jiraMcpUrl ?? ""))).trim() || defaults.jiraMcpUrl
984
- : undefined;
985
- const jiraUsername = enableJira
986
- ? (await ask(renderSetupPrompt("Required", "Jira username", defaults.jiraUsername ?? ""))).trim() || defaults.jiraUsername
987
- : undefined;
988
972
  const jiraPersonalToken = enableJira
989
973
  ? (await ask(renderSetupPrompt("Required", "Jira personal token", defaults.jiraPersonalToken ? "configured" : ""))).trim() || defaults.jiraPersonalToken
990
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"
977
+ : undefined;
991
978
  printSetupSection("Sentry", "Enable this module when tasks can be created from Sentry events.");
992
979
  const enableSentryInput = (await ask(renderSetupPrompt("Optional module", "Enable Sentry integration", defaults.enableSentry ? "Y/n" : "y/N"))).trim().toLowerCase();
993
980
  const enableSentry = enableSentryInput.length === 0
@@ -1016,9 +1003,9 @@ async function promptSetupAnswers(defaults) {
1016
1003
  ...(feishuSecret ? { feishuSecret } : {}),
1017
1004
  enableJira,
1018
1005
  ...(jiraBaseUrl ? { jiraBaseUrl } : {}),
1019
- ...(jiraMcpUrl ? { jiraMcpUrl } : {}),
1020
- ...(jiraUsername ? { jiraUsername } : {}),
1021
1006
  ...(jiraPersonalToken ? { jiraPersonalToken } : {}),
1007
+ ...(jiraCasCookieName ? { jiraCasCookieName } : {}),
1008
+ ...(defaults.jiraCustomHeaders ? { jiraCustomHeaders: defaults.jiraCustomHeaders } : {}),
1022
1009
  enableSentry,
1023
1010
  ...(sentryBaseUrl ? { sentryBaseUrl } : {}),
1024
1011
  ...(sentryOrg ? { sentryOrg } : {}),
@@ -1068,9 +1055,9 @@ async function resolveDefaultSetupAnswers() {
1068
1055
  ...(config.delivery.feishu.secret ? { feishuSecret: config.delivery.feishu.secret } : {}),
1069
1056
  enableJira: config.jira.enabled,
1070
1057
  ...(config.jira.baseUrl ? { jiraBaseUrl: config.jira.baseUrl } : {}),
1071
- ...(config.jira.mcpUrl ? { jiraMcpUrl: config.jira.mcpUrl } : {}),
1072
- ...(config.jira.httpHeaders["X-Atlassian-Username"] ? { jiraUsername: config.jira.httpHeaders["X-Atlassian-Username"] } : {}),
1073
- ...(config.jira.httpHeaders["X-Atlassian-Jira-Personal-Token"] ? { jiraPersonalToken: config.jira.httpHeaders["X-Atlassian-Jira-Personal-Token"] } : {}),
1058
+ ...(config.jira.personalToken ? { jiraPersonalToken: config.jira.personalToken } : {}),
1059
+ ...(config.jira.casCookieName ? { jiraCasCookieName: config.jira.casCookieName } : {}),
1060
+ ...(config.jira.customHeaders ? { jiraCustomHeaders: config.jira.customHeaders } : {}),
1074
1061
  enableSentry: config.sentry.enabled,
1075
1062
  ...(config.sentry.baseUrl ? { sentryBaseUrl: config.sentry.baseUrl } : {}),
1076
1063
  ...(config.sentry.org ? { sentryOrg: config.sentry.org } : {}),
@@ -1141,12 +1128,6 @@ function validateSetupAnswers(answers) {
1141
1128
  if (answers.enableJira && !answers.jiraBaseUrl?.trim()) {
1142
1129
  return "setup requires a Jira base URL when Jira integration is enabled.";
1143
1130
  }
1144
- if (answers.enableJira && !answers.jiraMcpUrl?.trim()) {
1145
- return "setup requires a Jira MCP URL when Jira integration is enabled.";
1146
- }
1147
- if (answers.enableJira && !answers.jiraUsername?.trim()) {
1148
- return "setup requires a Jira username when Jira integration is enabled.";
1149
- }
1150
1131
  if (answers.enableJira && !answers.jiraPersonalToken?.trim()) {
1151
1132
  return "setup requires a Jira personal token when Jira integration is enabled.";
1152
1133
  }
@@ -1223,19 +1204,16 @@ function buildSetupConfig(answers) {
1223
1204
  config.jira.enabled = answers.enableJira;
1224
1205
  if (answers.enableJira) {
1225
1206
  config.jira.baseUrl = answers.jiraBaseUrl ?? config.jira.baseUrl;
1226
- if (answers.jiraMcpUrl) {
1227
- config.jira.mcpUrl = answers.jiraMcpUrl;
1228
- }
1229
- config.jira.authType = "http_headers";
1230
- config.jira.httpHeaders = {
1231
- "X-Atlassian-Jira-Url": answers.jiraBaseUrl ?? config.jira.baseUrl,
1232
- "X-Atlassian-Username": answers.jiraUsername ?? "",
1233
- "X-Atlassian-Jira-Personal-Token": answers.jiraPersonalToken ?? ""
1234
- };
1235
- delete config.jira.bearerToken;
1236
- delete config.jira.username;
1237
- delete config.jira.apiToken;
1238
- 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
+ }
1239
1217
  }
1240
1218
  config.sentry.enabled = answers.enableSentry;
1241
1219
  if (answers.enableSentry) {