@geneverse/workctl 0.2.5

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/dist/packages/capabilities/assistant/src/commands.d.ts +10 -0
  4. package/dist/packages/capabilities/assistant/src/commands.js +33 -0
  5. package/dist/packages/capabilities/assistant/src/commands.js.map +1 -0
  6. package/dist/packages/capabilities/assistant/src/index.d.ts +2 -0
  7. package/dist/packages/capabilities/assistant/src/index.js +3 -0
  8. package/dist/packages/capabilities/assistant/src/index.js.map +1 -0
  9. package/dist/packages/capabilities/assistant/src/status.d.ts +18 -0
  10. package/dist/packages/capabilities/assistant/src/status.js +48 -0
  11. package/dist/packages/capabilities/assistant/src/status.js.map +1 -0
  12. package/dist/packages/capabilities/jenkins/src/commands.d.ts +9 -0
  13. package/dist/packages/capabilities/jenkins/src/commands.js +43 -0
  14. package/dist/packages/capabilities/jenkins/src/commands.js.map +1 -0
  15. package/dist/packages/capabilities/jenkins/src/definition.d.ts +10 -0
  16. package/dist/packages/capabilities/jenkins/src/definition.js +59 -0
  17. package/dist/packages/capabilities/jenkins/src/definition.js.map +1 -0
  18. package/dist/packages/capabilities/jenkins/src/index.d.ts +2 -0
  19. package/dist/packages/capabilities/jenkins/src/index.js +3 -0
  20. package/dist/packages/capabilities/jenkins/src/index.js.map +1 -0
  21. package/dist/packages/capabilities/jira/src/adapters/filesystem/config.store.d.ts +2 -0
  22. package/dist/packages/capabilities/jira/src/adapters/filesystem/config.store.js +43 -0
  23. package/dist/packages/capabilities/jira/src/adapters/filesystem/config.store.js.map +1 -0
  24. package/dist/packages/capabilities/jira/src/adapters/filesystem/local.paths.d.ts +16 -0
  25. package/dist/packages/capabilities/jira/src/adapters/filesystem/local.paths.js +46 -0
  26. package/dist/packages/capabilities/jira/src/adapters/filesystem/local.paths.js.map +1 -0
  27. package/dist/packages/capabilities/jira/src/adapters/filesystem/sync-lock.d.ts +2 -0
  28. package/dist/packages/capabilities/jira/src/adapters/filesystem/sync-lock.js +120 -0
  29. package/dist/packages/capabilities/jira/src/adapters/filesystem/sync-lock.js.map +1 -0
  30. package/dist/packages/capabilities/jira/src/adapters/jira/jira.client.d.ts +31 -0
  31. package/dist/packages/capabilities/jira/src/adapters/jira/jira.client.js +344 -0
  32. package/dist/packages/capabilities/jira/src/adapters/jira/jira.client.js.map +1 -0
  33. package/dist/packages/capabilities/jira/src/adapters/kawari/catalog.d.ts +9 -0
  34. package/dist/packages/capabilities/jira/src/adapters/kawari/catalog.js +17 -0
  35. package/dist/packages/capabilities/jira/src/adapters/kawari/catalog.js.map +1 -0
  36. package/dist/packages/capabilities/jira/src/adapters/kawari/orchestrator.d.ts +14 -0
  37. package/dist/packages/capabilities/jira/src/adapters/kawari/orchestrator.js +116 -0
  38. package/dist/packages/capabilities/jira/src/adapters/kawari/orchestrator.js.map +1 -0
  39. package/dist/packages/capabilities/jira/src/adapters/kawari/scraper.d.ts +32 -0
  40. package/dist/packages/capabilities/jira/src/adapters/kawari/scraper.js +2 -0
  41. package/dist/packages/capabilities/jira/src/adapters/kawari/scraper.js.map +1 -0
  42. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/detect.d.ts +2 -0
  43. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/detect.js +45 -0
  44. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/detect.js.map +1 -0
  45. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/extract.d.ts +3 -0
  46. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/extract.js +115 -0
  47. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/extract.js.map +1 -0
  48. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/index.d.ts +2 -0
  49. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/index.js +27 -0
  50. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/index.js.map +1 -0
  51. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/navigation.d.ts +3 -0
  52. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/navigation.js +104 -0
  53. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/navigation.js.map +1 -0
  54. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/ready.d.ts +2 -0
  55. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/ready.js +47 -0
  56. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/ready.js.map +1 -0
  57. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/shared.d.ts +4 -0
  58. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/shared.js +5 -0
  59. package/dist/packages/capabilities/jira/src/adapters/kawari/v1/shared.js.map +1 -0
  60. package/dist/packages/capabilities/jira/src/adapters/terminal/node-cli.io.d.ts +2 -0
  61. package/dist/packages/capabilities/jira/src/adapters/terminal/node-cli.io.js +40 -0
  62. package/dist/packages/capabilities/jira/src/adapters/terminal/node-cli.io.js.map +1 -0
  63. package/dist/packages/capabilities/jira/src/batch-interaction.d.ts +53 -0
  64. package/dist/packages/capabilities/jira/src/batch-interaction.js +201 -0
  65. package/dist/packages/capabilities/jira/src/batch-interaction.js.map +1 -0
  66. package/dist/packages/capabilities/jira/src/capability.d.ts +16 -0
  67. package/dist/packages/capabilities/jira/src/capability.js +56 -0
  68. package/dist/packages/capabilities/jira/src/capability.js.map +1 -0
  69. package/dist/packages/capabilities/jira/src/cli/contracts.d.ts +42 -0
  70. package/dist/packages/capabilities/jira/src/cli/contracts.js +2 -0
  71. package/dist/packages/capabilities/jira/src/cli/contracts.js.map +1 -0
  72. package/dist/packages/capabilities/jira/src/cli/errors.d.ts +3 -0
  73. package/dist/packages/capabilities/jira/src/cli/errors.js +7 -0
  74. package/dist/packages/capabilities/jira/src/cli/errors.js.map +1 -0
  75. package/dist/packages/capabilities/jira/src/cli/program.d.ts +6 -0
  76. package/dist/packages/capabilities/jira/src/cli/program.js +48 -0
  77. package/dist/packages/capabilities/jira/src/cli/program.js.map +1 -0
  78. package/dist/packages/capabilities/jira/src/cli/run-cli.d.ts +2 -0
  79. package/dist/packages/capabilities/jira/src/cli/run-cli.js +72 -0
  80. package/dist/packages/capabilities/jira/src/cli/run-cli.js.map +1 -0
  81. package/dist/packages/capabilities/jira/src/commands/audit-links/audit-links.command.d.ts +2 -0
  82. package/dist/packages/capabilities/jira/src/commands/audit-links/audit-links.command.js +165 -0
  83. package/dist/packages/capabilities/jira/src/commands/audit-links/audit-links.command.js.map +1 -0
  84. package/dist/packages/capabilities/jira/src/commands/audit-links/audit-links.service.d.ts +30 -0
  85. package/dist/packages/capabilities/jira/src/commands/audit-links/audit-links.service.js +174 -0
  86. package/dist/packages/capabilities/jira/src/commands/audit-links/audit-links.service.js.map +1 -0
  87. package/dist/packages/capabilities/jira/src/commands/command-context.d.ts +10 -0
  88. package/dist/packages/capabilities/jira/src/commands/command-context.js +2 -0
  89. package/dist/packages/capabilities/jira/src/commands/command-context.js.map +1 -0
  90. package/dist/packages/capabilities/jira/src/commands/config-show/config-show.command.d.ts +2 -0
  91. package/dist/packages/capabilities/jira/src/commands/config-show/config-show.command.js +26 -0
  92. package/dist/packages/capabilities/jira/src/commands/config-show/config-show.command.js.map +1 -0
  93. package/dist/packages/capabilities/jira/src/commands/configure/configure.command.d.ts +2 -0
  94. package/dist/packages/capabilities/jira/src/commands/configure/configure.command.js +26 -0
  95. package/dist/packages/capabilities/jira/src/commands/configure/configure.command.js.map +1 -0
  96. package/dist/packages/capabilities/jira/src/commands/configure/configure.service.d.ts +42 -0
  97. package/dist/packages/capabilities/jira/src/commands/configure/configure.service.js +205 -0
  98. package/dist/packages/capabilities/jira/src/commands/configure/configure.service.js.map +1 -0
  99. package/dist/packages/capabilities/jira/src/commands/doctor/doctor.command.d.ts +2 -0
  100. package/dist/packages/capabilities/jira/src/commands/doctor/doctor.command.js +17 -0
  101. package/dist/packages/capabilities/jira/src/commands/doctor/doctor.command.js.map +1 -0
  102. package/dist/packages/capabilities/jira/src/commands/doctor/doctor.service.d.ts +18 -0
  103. package/dist/packages/capabilities/jira/src/commands/doctor/doctor.service.js +84 -0
  104. package/dist/packages/capabilities/jira/src/commands/doctor/doctor.service.js.map +1 -0
  105. package/dist/packages/capabilities/jira/src/commands/rollback/rollback.command.d.ts +2 -0
  106. package/dist/packages/capabilities/jira/src/commands/rollback/rollback.command.js +198 -0
  107. package/dist/packages/capabilities/jira/src/commands/rollback/rollback.command.js.map +1 -0
  108. package/dist/packages/capabilities/jira/src/commands/rollback/rollback.service.d.ts +37 -0
  109. package/dist/packages/capabilities/jira/src/commands/rollback/rollback.service.js +112 -0
  110. package/dist/packages/capabilities/jira/src/commands/rollback/rollback.service.js.map +1 -0
  111. package/dist/packages/capabilities/jira/src/commands/sync/audit-export.service.d.ts +18 -0
  112. package/dist/packages/capabilities/jira/src/commands/sync/audit-export.service.js +96 -0
  113. package/dist/packages/capabilities/jira/src/commands/sync/audit-export.service.js.map +1 -0
  114. package/dist/packages/capabilities/jira/src/commands/sync/preview.service.d.ts +23 -0
  115. package/dist/packages/capabilities/jira/src/commands/sync/preview.service.js +201 -0
  116. package/dist/packages/capabilities/jira/src/commands/sync/preview.service.js.map +1 -0
  117. package/dist/packages/capabilities/jira/src/commands/sync/sync.command.d.ts +2 -0
  118. package/dist/packages/capabilities/jira/src/commands/sync/sync.command.js +537 -0
  119. package/dist/packages/capabilities/jira/src/commands/sync/sync.command.js.map +1 -0
  120. package/dist/packages/capabilities/jira/src/commands/sync/verification.service.d.ts +34 -0
  121. package/dist/packages/capabilities/jira/src/commands/sync/verification.service.js +164 -0
  122. package/dist/packages/capabilities/jira/src/commands/sync/verification.service.js.map +1 -0
  123. package/dist/packages/capabilities/jira/src/config.d.ts +37 -0
  124. package/dist/packages/capabilities/jira/src/config.js +217 -0
  125. package/dist/packages/capabilities/jira/src/config.js.map +1 -0
  126. package/dist/packages/capabilities/jira/src/dependencies.d.ts +2 -0
  127. package/dist/packages/capabilities/jira/src/dependencies.js +92 -0
  128. package/dist/packages/capabilities/jira/src/dependencies.js.map +1 -0
  129. package/dist/packages/capabilities/jira/src/domain/date-range.d.ts +10 -0
  130. package/dist/packages/capabilities/jira/src/domain/date-range.js +63 -0
  131. package/dist/packages/capabilities/jira/src/domain/date-range.js.map +1 -0
  132. package/dist/packages/capabilities/jira/src/domain/marker.d.ts +20 -0
  133. package/dist/packages/capabilities/jira/src/domain/marker.js +100 -0
  134. package/dist/packages/capabilities/jira/src/domain/marker.js.map +1 -0
  135. package/dist/packages/capabilities/jira/src/domain/timesheet-entry.d.ts +45 -0
  136. package/dist/packages/capabilities/jira/src/domain/timesheet-entry.js +117 -0
  137. package/dist/packages/capabilities/jira/src/domain/timesheet-entry.js.map +1 -0
  138. package/dist/packages/capabilities/jira/src/index.d.ts +5 -0
  139. package/dist/packages/capabilities/jira/src/index.js +4 -0
  140. package/dist/packages/capabilities/jira/src/index.js.map +1 -0
  141. package/dist/packages/capabilities/jira/src/ports/jira.d.ts +49 -0
  142. package/dist/packages/capabilities/jira/src/ports/jira.js +11 -0
  143. package/dist/packages/capabilities/jira/src/ports/jira.js.map +1 -0
  144. package/dist/packages/capabilities/jira/src/ports/sync-lock.d.ts +6 -0
  145. package/dist/packages/capabilities/jira/src/ports/sync-lock.js +7 -0
  146. package/dist/packages/capabilities/jira/src/ports/sync-lock.js.map +1 -0
  147. package/dist/packages/capabilities/jira/src/ports/timesheet.d.ts +11 -0
  148. package/dist/packages/capabilities/jira/src/ports/timesheet.js +7 -0
  149. package/dist/packages/capabilities/jira/src/ports/timesheet.js.map +1 -0
  150. package/dist/packages/capabilities/jira/src/presentation.d.ts +37 -0
  151. package/dist/packages/capabilities/jira/src/presentation.js +111 -0
  152. package/dist/packages/capabilities/jira/src/presentation.js.map +1 -0
  153. package/dist/packages/cli/src/bin.d.ts +2 -0
  154. package/dist/packages/cli/src/bin.js +4 -0
  155. package/dist/packages/cli/src/bin.js.map +1 -0
  156. package/dist/packages/cli/src/commands/browsers/browsers.command.d.ts +7 -0
  157. package/dist/packages/cli/src/commands/browsers/browsers.command.js +22 -0
  158. package/dist/packages/cli/src/commands/browsers/browsers.command.js.map +1 -0
  159. package/dist/packages/cli/src/commands/browsers/browsers.service.d.ts +16 -0
  160. package/dist/packages/cli/src/commands/browsers/browsers.service.js +37 -0
  161. package/dist/packages/cli/src/commands/browsers/browsers.service.js.map +1 -0
  162. package/dist/packages/cli/src/commands/setup/setup.command.d.ts +4 -0
  163. package/dist/packages/cli/src/commands/setup/setup.command.js +41 -0
  164. package/dist/packages/cli/src/commands/setup/setup.command.js.map +1 -0
  165. package/dist/packages/cli/src/commands/setup/setup.service.d.ts +23 -0
  166. package/dist/packages/cli/src/commands/setup/setup.service.js +32 -0
  167. package/dist/packages/cli/src/commands/setup/setup.service.js.map +1 -0
  168. package/dist/packages/cli/src/commands/update/update.command.d.ts +7 -0
  169. package/dist/packages/cli/src/commands/update/update.command.js +34 -0
  170. package/dist/packages/cli/src/commands/update/update.command.js.map +1 -0
  171. package/dist/packages/cli/src/commands/update/update.service.d.ts +35 -0
  172. package/dist/packages/cli/src/commands/update/update.service.js +134 -0
  173. package/dist/packages/cli/src/commands/update/update.service.js.map +1 -0
  174. package/dist/packages/cli/src/index.d.ts +1 -0
  175. package/dist/packages/cli/src/index.js +2 -0
  176. package/dist/packages/cli/src/index.js.map +1 -0
  177. package/dist/packages/cli/src/program.d.ts +21 -0
  178. package/dist/packages/cli/src/program.js +74 -0
  179. package/dist/packages/cli/src/program.js.map +1 -0
  180. package/dist/packages/cli/src/release-version.d.ts +1 -0
  181. package/dist/packages/cli/src/release-version.js +2 -0
  182. package/package.json +57 -0
@@ -0,0 +1,537 @@
1
+ import { CommanderError } from "commander";
2
+ import { resolveDateRange } from "../../domain/date-range.js";
3
+ import { classifyGrid, } from "../../domain/timesheet-entry.js";
4
+ import { JiraClientError } from "../../ports/jira.js";
5
+ import { createBatch4Preview, createBatch5Preview, formatPreview, ownershipConflictReason, } from "./preview.service.js";
6
+ import { createAuditRecords, } from "./audit-export.service.js";
7
+ import { formatVerification, verifyEntries } from "./verification.service.js";
8
+ import { formatBatchHeader, formatHours, formatWorklogFailureDetail, formatWorklogProgressTable, } from "../../presentation.js";
9
+ import { CliInteractionError } from "../../cli/errors.js";
10
+ const JIRA_KEY = /^[A-Z][A-Z0-9]*-\d+$/;
11
+ function replaceJiraKey(classified, oldKey, newKey) {
12
+ return {
13
+ ...classified,
14
+ eligible: classified.eligible.map((entry) => entry.jiraKey === oldKey
15
+ ? {
16
+ ...entry,
17
+ jiraKey: newKey,
18
+ description: entry.description.replace(new RegExp(`(?<![A-Z0-9])${oldKey}(?![A-Z0-9])`, "g"), newKey),
19
+ }
20
+ : entry),
21
+ };
22
+ }
23
+ async function readIssuesWithRepair(config, initial, dependencies, interaction, writeStatus) {
24
+ let classified = initial;
25
+ const excluded = [];
26
+ const issuesByKey = new Map();
27
+ const pending = [
28
+ ...new Set(classified.eligible.flatMap((entry) => entry.jiraKey ? [entry.jiraKey] : [])),
29
+ ];
30
+ let completed = 0;
31
+ let total = pending.length;
32
+ let loadingActive = false;
33
+ const loadingMessage = (jiraKey) => `Loading Jira issues and worklogs · ${jiraKey} · ${completed + 1}/${total}`;
34
+ if (pending[0]) {
35
+ const message = loadingMessage(pending[0]);
36
+ if (interaction) {
37
+ interaction.startLoading(message);
38
+ loadingActive = true;
39
+ }
40
+ else
41
+ writeStatus(`${message}\n`);
42
+ }
43
+ try {
44
+ while (pending.length > 0) {
45
+ const jiraKey = pending.shift();
46
+ if (issuesByKey.has(jiraKey))
47
+ continue;
48
+ const message = loadingMessage(jiraKey);
49
+ if (interaction)
50
+ interaction.updateLoading(message);
51
+ else if (completed > 0)
52
+ writeStatus(`${message}\n`);
53
+ try {
54
+ issuesByKey.set(jiraKey, await dependencies.readJiraIssue(config, jiraKey));
55
+ completed += 1;
56
+ }
57
+ catch (error) {
58
+ if (!(error instanceof JiraClientError) || error.status !== 404)
59
+ throw error;
60
+ if (!interaction) {
61
+ throw new CliInteractionError(`${error.message} Run this command in an interactive terminal to correct the Jira key, ` +
62
+ "or fix the description in Kawari.");
63
+ }
64
+ interaction.stopLoading(`Jira issue ${jiraKey} was not found`);
65
+ loadingActive = false;
66
+ const affected = classified.eligible.filter((entry) => entry.jiraKey === jiraKey);
67
+ let replacement;
68
+ for (;;) {
69
+ const resolution = await interaction.resolveMissingJiraIssue({
70
+ jiraKey,
71
+ entries: affected.map(({ date, description, duration }) => ({
72
+ date,
73
+ description,
74
+ duration,
75
+ })),
76
+ });
77
+ if (resolution.action === "cancel") {
78
+ throw new CommanderError(0, "batch.cancelled", "Sync batch cancelled.");
79
+ }
80
+ if (resolution.action === "exclude") {
81
+ excluded.push(...affected.map((entry) => ({
82
+ ...entry,
83
+ jiraKey,
84
+ exclusionKind: "Missing Jira Issue",
85
+ exclusionReason: "Excluded by user for this batch.",
86
+ })));
87
+ classified = {
88
+ ...classified,
89
+ eligible: classified.eligible.filter((entry) => entry.jiraKey !== jiraKey),
90
+ };
91
+ break;
92
+ }
93
+ replacement = resolution.jiraKey;
94
+ replacement = replacement.trim().toUpperCase();
95
+ if (JIRA_KEY.test(replacement))
96
+ break;
97
+ }
98
+ if (replacement !== undefined) {
99
+ classified = replaceJiraKey(classified, jiraKey, replacement);
100
+ pending.unshift(replacement);
101
+ total += 1;
102
+ }
103
+ if (pending[0]) {
104
+ interaction.startLoading(loadingMessage(pending[0]));
105
+ loadingActive = true;
106
+ }
107
+ }
108
+ }
109
+ if (interaction && loadingActive) {
110
+ interaction.stopLoading(`Loaded ${completed} Jira issue${completed === 1 ? "" : "s"}`);
111
+ loadingActive = false;
112
+ }
113
+ }
114
+ catch (error) {
115
+ if (interaction && loadingActive) {
116
+ interaction.failLoading("Could not load Jira issues and worklogs");
117
+ }
118
+ throw error;
119
+ }
120
+ const jiraKeys = [
121
+ ...new Set(classified.eligible.flatMap((entry) => entry.jiraKey ? [entry.jiraKey] : [])),
122
+ ];
123
+ return {
124
+ classified,
125
+ excluded,
126
+ jiraKeys,
127
+ issues: jiraKeys.map((key) => issuesByKey.get(key)),
128
+ };
129
+ }
130
+ async function reloadIssuesForVerification(config, jiraKeys, dependencies, interaction, writeStatus) {
131
+ const issues = [];
132
+ if (jiraKeys.length === 0)
133
+ return issues;
134
+ const message = (jiraKey, index) => `Verifying Jira worklogs · ${jiraKey} · ${index + 1}/${jiraKeys.length}`;
135
+ if (interaction)
136
+ interaction.startLoading(message(jiraKeys[0], 0));
137
+ else
138
+ writeStatus(`${message(jiraKeys[0], 0)}\n`);
139
+ try {
140
+ for (const [index, jiraKey] of jiraKeys.entries()) {
141
+ if (index > 0) {
142
+ if (interaction)
143
+ interaction.updateLoading(message(jiraKey, index));
144
+ else
145
+ writeStatus(`${message(jiraKey, index)}\n`);
146
+ }
147
+ issues.push(await dependencies.readJiraIssue(config, jiraKey));
148
+ }
149
+ interaction?.stopLoading("Verified Jira worklogs");
150
+ return issues;
151
+ }
152
+ catch (error) {
153
+ interaction?.failLoading("Could not verify Jira worklogs");
154
+ throw error;
155
+ }
156
+ }
157
+ export function registerSyncCommands({ program, io, dependencies, effectiveConfig }) {
158
+ const interaction = io.interaction ?? io.batchInteraction;
159
+ const info = (message) => {
160
+ if (interaction)
161
+ interaction.info(message.trimEnd());
162
+ else
163
+ io.stdout(message);
164
+ };
165
+ for (const name of ["sync", "preview", "verify"]) {
166
+ program
167
+ .command(name)
168
+ .description(`${name} a Jira time synchronization batch`)
169
+ .option("--from <date>", "start date in YYYY-MM-DD format")
170
+ .option("--to <date>", "end date in YYYY-MM-DD format")
171
+ .option("--scraper-version <version>", "use a bundled Kawari scraper version")
172
+ .option("--export <format>", "write an audit export (csv or json)")
173
+ .action(async (options) => {
174
+ if (options.export !== undefined && options.export !== "csv" && options.export !== "json") {
175
+ throw new CommanderError(2, "batch7.invalidExportFormat", "--export must be either csv or json.");
176
+ }
177
+ const syncLock = name === "sync"
178
+ ? await dependencies.acquireSyncLock()
179
+ : undefined;
180
+ try {
181
+ const exportFormat = options.export;
182
+ const config = effectiveConfig().config;
183
+ let range = resolveDateRange(options.from, options.to);
184
+ if (name === "sync" &&
185
+ options.from === undefined &&
186
+ options.to === undefined &&
187
+ interaction) {
188
+ const selectedRange = await interaction.requestDateRange("sync", range);
189
+ if (!selectedRange)
190
+ return;
191
+ range = selectedRange;
192
+ }
193
+ interaction?.begin(name, range.from, range.to);
194
+ interaction?.startLoading("Opening Kawari timesheet");
195
+ let inspection;
196
+ try {
197
+ inspection = await dependencies.inspect(config.timesheetUrl, range.from.slice(0, 7), options.scraperVersion);
198
+ }
199
+ catch (error) {
200
+ interaction?.failLoading("Failed to load Kawari timesheet");
201
+ throw error;
202
+ }
203
+ let classified = classifyGrid(inspection.grid, range);
204
+ let excluded = [];
205
+ const presentation = {
206
+ color: io.color === true,
207
+ ...(io.terminalWidth
208
+ ? {
209
+ terminalWidth: interaction
210
+ ? Math.max(20, io.terminalWidth - 6)
211
+ : io.terminalWidth,
212
+ }
213
+ : {}),
214
+ };
215
+ const present = (title, content) => {
216
+ if (interaction)
217
+ interaction.note(title, content.trimEnd());
218
+ else
219
+ io.stdout(content);
220
+ };
221
+ const batchEntries = [
222
+ ...classified.eligible,
223
+ ...classified.unmapped,
224
+ ];
225
+ const entryCount = batchEntries.length + classified.invalid.length;
226
+ const displayedEntryCount = entryCount +
227
+ (name === "verify" ? 0 : classified.zeroDuration.length);
228
+ const batchHours = batchEntries.reduce((total, entry) => total + entry.duration, 0);
229
+ if (interaction) {
230
+ interaction.stopLoading(`Loaded ${displayedEntryCount} ${displayedEntryCount === 1 ? "entry" : "entries"} · ${formatHours(batchHours)}`);
231
+ }
232
+ else {
233
+ io.stdout(formatBatchHeader(name, range.from, range.to, displayedEntryCount, batchHours, presentation));
234
+ }
235
+ const exportAudit = async (report, verification) => {
236
+ if (!exportFormat)
237
+ return;
238
+ try {
239
+ const destination = await dependencies.writeAuditExport(name, range.from, range.to, exportFormat, createAuditRecords(classified, report, verification, excluded));
240
+ info(`Audit export: ${destination}\n`);
241
+ }
242
+ catch {
243
+ throw new CliInteractionError("Could not write the audit export.");
244
+ }
245
+ };
246
+ if (classified.invalid.length > 0) {
247
+ const invalidReport = createBatch4Preview(classified.eligible, classified.unmapped, classified.invalid, name === "verify" ? [] : classified.zeroDuration);
248
+ present("Preview", formatPreview(invalidReport, presentation, Boolean(interaction)));
249
+ await exportAudit(invalidReport);
250
+ throw new CommanderError(1, "batch4.invalidEntries", "Invalid entries block the read-only Jira preview.");
251
+ }
252
+ const repaired = await readIssuesWithRepair(config, classified, dependencies, interaction, io.stdout);
253
+ classified = repaired.classified;
254
+ excluded = repaired.excluded;
255
+ const { jiraKeys } = repaired;
256
+ let { issues } = repaired;
257
+ const currentAccountId = name === "verify"
258
+ ? undefined
259
+ : (await dependencies.readCurrentJiraAccount?.(config))?.accountId;
260
+ if (name !== "verify" && !currentAccountId) {
261
+ throw new CliInteractionError("Could not verify the current Jira account.");
262
+ }
263
+ let report = createBatch5Preview(classified.eligible, classified.unmapped, classified.invalid, issues, excluded, currentAccountId, new Set(), name === "verify" ? [] : classified.zeroDuration);
264
+ present("Preview", formatPreview(report, presentation, Boolean(interaction)));
265
+ if (report.items.some(({ action }) => action === "Conflict") && name !== "verify") {
266
+ await exportAudit(report);
267
+ throw new CommanderError(1, "batch5.syncConflict", "Sync conflicts block the read-only batch.");
268
+ }
269
+ if (name === "preview") {
270
+ await exportAudit(report);
271
+ interaction?.complete("Preview complete. No Jira worklogs were changed.");
272
+ return;
273
+ }
274
+ if (name === "verify") {
275
+ const verification = verifyEntries(classified.eligible, classified.unmapped, issues, excluded);
276
+ present("Verification", formatVerification(verification, presentation, {
277
+ command: "verify",
278
+ embedded: Boolean(interaction),
279
+ }));
280
+ await exportAudit(report, verification);
281
+ if (verification.unresolvedHours > 0) {
282
+ throw new CommanderError(1, "batch7.verificationFailed", "Verification found unresolved eligible hours.");
283
+ }
284
+ interaction?.complete("Verification complete.");
285
+ return;
286
+ }
287
+ const ownershipReviewItems = report.items.filter(({ action, jiraKey }) => action === "OwnershipReview" && jiraKey);
288
+ const approvedForeignOwners = new Map();
289
+ if (ownershipReviewItems.length > 0) {
290
+ if (!interaction || !interaction.selectOwnershipOverrides) {
291
+ await exportAudit(report);
292
+ throw new CommanderError(1, "batch6.interactiveRequired", "Ownership review requires an interactive terminal.");
293
+ }
294
+ const issueByKey = new Map(issues.map((issue) => [issue.key, issue]));
295
+ const reviewsByKey = new Map();
296
+ for (const item of ownershipReviewItems) {
297
+ const jiraKey = item.jiraKey;
298
+ const issue = issueByKey.get(jiraKey);
299
+ const review = reviewsByKey.get(jiraKey) ?? {
300
+ jiraKey,
301
+ summary: issue.summary,
302
+ assignee: issue.assigneeDisplayName ?? issue.assigneeAccountId,
303
+ hours: 0,
304
+ };
305
+ review.hours += item.hours;
306
+ reviewsByKey.set(jiraKey, review);
307
+ }
308
+ const selection = await interaction.selectOwnershipOverrides([...reviewsByKey.values()].sort((left, right) => left.jiraKey.localeCompare(right.jiraKey)));
309
+ if (selection === undefined) {
310
+ throw new CommanderError(0, "batch.cancelled", "Sync batch cancelled.");
311
+ }
312
+ const selectedKeys = new Set(selection);
313
+ const reviewKeys = new Set(reviewsByKey.keys());
314
+ for (const jiraKey of selectedKeys) {
315
+ if (!reviewKeys.has(jiraKey)) {
316
+ throw new CliInteractionError(`Ownership review returned an unexpected Jira issue: ${jiraKey}.`);
317
+ }
318
+ approvedForeignOwners.set(jiraKey, issueByKey.get(jiraKey).assigneeAccountId);
319
+ }
320
+ const rejectedKeys = new Set([...reviewKeys].filter((jiraKey) => !selectedKeys.has(jiraKey)));
321
+ const ownershipExcluded = classified.eligible
322
+ .filter(({ jiraKey }) => jiraKey && rejectedKeys.has(jiraKey))
323
+ .map((entry) => ({
324
+ ...entry,
325
+ jiraKey: entry.jiraKey,
326
+ exclusionKind: "Ownership",
327
+ exclusionReason: `Excluded because ${entry.jiraKey} is assigned to another account and was not selected.`,
328
+ }));
329
+ excluded.push(...ownershipExcluded);
330
+ classified = {
331
+ ...classified,
332
+ eligible: classified.eligible.filter(({ jiraKey }) => !jiraKey || !rejectedKeys.has(jiraKey)),
333
+ };
334
+ report = createBatch5Preview(classified.eligible, classified.unmapped, classified.invalid, issues, excluded, currentAccountId, selectedKeys, classified.zeroDuration);
335
+ }
336
+ const createIdentities = new Set(report.items
337
+ .filter(({ action }) => action === "Create")
338
+ .flatMap(({ sourceIdentity }) => sourceIdentity ? [sourceIdentity] : []));
339
+ let entriesToCreate = classified.eligible.filter(({ sourceIdentity }) => createIdentities.has(sourceIdentity));
340
+ if (entriesToCreate.length === 0) {
341
+ const hasOwnershipExclusions = excluded.some(({ exclusionKind }) => exclusionKind === "Ownership");
342
+ const noWritesMessage = hasOwnershipExclusions
343
+ ? "No Jira worklogs were selected for creation"
344
+ : "No Jira worklogs need to be created";
345
+ if (interaction)
346
+ interaction.step(noWritesMessage);
347
+ else
348
+ io.stdout(`${noWritesMessage}.\n`);
349
+ const verification = verifyEntries(classified.eligible, classified.unmapped, issues, excluded);
350
+ present("Sync outcome", formatVerification(verification, presentation, {
351
+ command: "sync",
352
+ created: 0,
353
+ alreadySynced: report.items.filter(({ action }) => action === "Skip").length,
354
+ embedded: Boolean(interaction),
355
+ }));
356
+ await exportAudit(report, verification);
357
+ if (verification.unresolvedHours > 0) {
358
+ throw new CommanderError(1, "batch7.verificationFailed", "Verification found unresolved eligible hours.");
359
+ }
360
+ interaction?.complete(hasOwnershipExclusions
361
+ ? "Sync complete. Ownership exclusions were not created."
362
+ : "Sync complete. Jira is already up to date.");
363
+ return;
364
+ }
365
+ const hours = entriesToCreate.reduce((total, entry) => total + entry.duration, 0);
366
+ if (!interaction && !io.requestApproval) {
367
+ throw new CommanderError(1, "batch6.interactiveRequired", "Jira worklog creation requires an interactive terminal.");
368
+ }
369
+ const prompt = `Create ${entriesToCreate.length} Jira worklog(s) totaling ${hours}h?`;
370
+ const approved = interaction
371
+ ? await interaction.confirmWorklogCreation(prompt)
372
+ : (await io.requestApproval(`${prompt} Type yes to continue: `))
373
+ .trim().toLowerCase() === "yes";
374
+ if (!approved) {
375
+ if (interaction)
376
+ interaction.cancelled("Cancelled; no Jira worklogs were created.");
377
+ else
378
+ io.stdout("Cancelled; no Jira worklogs were created.\n");
379
+ await exportAudit(report);
380
+ return;
381
+ }
382
+ const candidateKeys = [
383
+ ...new Set(entriesToCreate.flatMap((entry) => entry.jiraKey ? [entry.jiraKey] : [])),
384
+ ];
385
+ const ownershipLoadingMessage = `Rechecking ownership · ${candidateKeys.length} Jira ${candidateKeys.length === 1 ? "issue" : "issues"}`;
386
+ if (interaction)
387
+ interaction.startLoading(ownershipLoadingMessage);
388
+ else
389
+ io.stdout(`${ownershipLoadingMessage}\n`);
390
+ let ownershipIssues;
391
+ try {
392
+ ownershipIssues = await Promise.all(candidateKeys.map((jiraKey) => dependencies.readJiraIssue(config, jiraKey)));
393
+ interaction?.stopLoading("Ownership rechecked");
394
+ }
395
+ catch (error) {
396
+ interaction?.failLoading("Could not recheck ownership");
397
+ throw error;
398
+ }
399
+ const ownershipConflicts = ownershipIssues.flatMap((issue) => {
400
+ if (issue.assigneeAccountId === currentAccountId)
401
+ return [];
402
+ const approvedOwner = approvedForeignOwners.get(issue.key);
403
+ if (approvedOwner &&
404
+ issue.assigneeStatus === "assigned" &&
405
+ issue.assigneeAccountId === approvedOwner) {
406
+ return [];
407
+ }
408
+ const reason = ownershipConflictReason(issue, currentAccountId);
409
+ return [`${issue.key}: ${reason ?? "Ownership changed after approval."}`];
410
+ });
411
+ if (ownershipConflicts.length > 0) {
412
+ throw new CommanderError(1, "batch6.ownershipChanged", `Jira issue ownership changed after approval; no worklogs were created.\n${ownershipConflicts.map((conflict) => `- ${conflict}`).join("\n")}`);
413
+ }
414
+ const refreshedByKey = new Map(ownershipIssues.map((issue) => [issue.key, issue]));
415
+ issues = issues.map((issue) => refreshedByKey.get(issue.key) ?? issue);
416
+ const reconciledReport = createBatch5Preview(classified.eligible, classified.unmapped, classified.invalid, issues, excluded, currentAccountId, new Set(approvedForeignOwners.keys()), classified.zeroDuration);
417
+ if (reconciledReport.items.some(({ action }) => action === "Conflict")) {
418
+ report = reconciledReport;
419
+ await exportAudit(report);
420
+ throw new CommanderError(1, "batch5.syncConflict", "Jira worklogs changed after approval; no worklogs were created.");
421
+ }
422
+ report = reconciledReport;
423
+ const reconciledCreateIdentities = new Set(report.items
424
+ .filter(({ action, sourceIdentity }) => action === "Create" && sourceIdentity && createIdentities.has(sourceIdentity))
425
+ .flatMap(({ sourceIdentity }) => sourceIdentity ? [sourceIdentity] : []));
426
+ entriesToCreate = entriesToCreate.filter(({ sourceIdentity }) => reconciledCreateIdentities.has(sourceIdentity));
427
+ if (entriesToCreate.length === 0) {
428
+ if (interaction)
429
+ interaction.step("No Jira worklogs need to be created");
430
+ else
431
+ io.stdout("No Jira worklogs need to be created.\n");
432
+ const verification = verifyEntries(classified.eligible, classified.unmapped, issues, excluded);
433
+ present("Sync outcome", formatVerification(verification, presentation, {
434
+ command: "sync",
435
+ created: 0,
436
+ alreadySynced: report.items.filter(({ action }) => action === "Skip").length,
437
+ embedded: Boolean(interaction),
438
+ }));
439
+ await exportAudit(report, verification);
440
+ if (verification.unresolvedHours > 0) {
441
+ throw new CommanderError(1, "batch7.verificationFailed", "Verification found unresolved eligible hours.");
442
+ }
443
+ interaction?.complete("Sync complete. Jira is already up to date.");
444
+ return;
445
+ }
446
+ const writeResults = [];
447
+ const progressTable = formatWorklogProgressTable(entriesToCreate.map((entry) => ({
448
+ date: entry.date,
449
+ jiraKey: entry.jiraKey,
450
+ hours: entry.duration,
451
+ })));
452
+ const tableHeader = [
453
+ progressTable.topBorder,
454
+ progressTable.header,
455
+ progressTable.separator,
456
+ ].join("\n");
457
+ if (interaction)
458
+ interaction.message(tableHeader);
459
+ else
460
+ io.stdout(`${tableHeader}\n`);
461
+ for (const [index, entry] of entriesToCreate.entries()) {
462
+ try {
463
+ const created = await dependencies.createJiraWorklog(config, entry);
464
+ writeResults.push({
465
+ status: "Succeeded",
466
+ date: entry.date,
467
+ jiraKey: entry.jiraKey,
468
+ hours: entry.duration,
469
+ detail: `worklog ${created.id}`,
470
+ });
471
+ const row = progressTable.createdRows[index];
472
+ if (interaction)
473
+ interaction.success(row);
474
+ else
475
+ io.stdout(`✓ ${row}\n`);
476
+ }
477
+ catch (error) {
478
+ const detail = error instanceof JiraClientError
479
+ ? error.message
480
+ : `Could not create the Jira worklog for ${entry.jiraKey}.`;
481
+ writeResults.push({
482
+ status: "Failed",
483
+ date: entry.date,
484
+ jiraKey: entry.jiraKey,
485
+ hours: entry.duration,
486
+ detail,
487
+ });
488
+ const row = progressTable.failedRows[index];
489
+ const detailRows = formatWorklogFailureDetail(detail, progressTable.contentWidth);
490
+ const message = [row, ...detailRows].join("\n");
491
+ if (interaction)
492
+ interaction.failure(message);
493
+ else
494
+ io.stderr(`✗ ${message}\n`);
495
+ }
496
+ }
497
+ if (interaction)
498
+ interaction.message(progressTable.bottomBorder);
499
+ else
500
+ io.stdout(`${progressTable.bottomBorder}\n`);
501
+ const succeededResults = writeResults.filter(({ status }) => status === "Succeeded");
502
+ const failedResults = writeResults.filter(({ status }) => status === "Failed");
503
+ const succeededWrites = succeededResults.length;
504
+ const failedWrites = failedResults.length;
505
+ const succeededHours = succeededResults.reduce((total, result) => total + result.hours, 0);
506
+ const failedHours = failedResults.reduce((total, result) => total + result.hours, 0);
507
+ const writeSummary = `Created ${succeededWrites} (${formatHours(succeededHours)}) · ` +
508
+ `Failed ${failedWrites} (${formatHours(failedHours)})`;
509
+ if (interaction)
510
+ interaction.info(writeSummary);
511
+ else
512
+ io.stdout(`${writeSummary}\n`);
513
+ const failures = writeResults.filter(({ status }) => status === "Failed").length;
514
+ const verifiedIssues = await reloadIssuesForVerification(config, jiraKeys, dependencies, interaction, io.stdout);
515
+ const verification = verifyEntries(classified.eligible, classified.unmapped, verifiedIssues, excluded);
516
+ present("Sync outcome", formatVerification(verification, presentation, {
517
+ command: "sync",
518
+ created: writeResults.filter(({ status }) => status === "Succeeded").length,
519
+ alreadySynced: report.items.filter(({ action }) => action === "Skip").length,
520
+ embedded: Boolean(interaction),
521
+ }));
522
+ await exportAudit(report, verification);
523
+ if (failures > 0) {
524
+ throw new CommanderError(1, "batch6.partialFailure", "One or more Jira worklogs could not be created; rerun to safely retry.");
525
+ }
526
+ if (verification.unresolvedHours > 0) {
527
+ throw new CommanderError(1, "batch7.verificationFailed", "Verification found unresolved eligible hours.");
528
+ }
529
+ interaction?.complete("Sync complete and verified.");
530
+ }
531
+ finally {
532
+ await syncLock?.release();
533
+ }
534
+ });
535
+ }
536
+ }
537
+ //# sourceMappingURL=sync.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.command.js","sourceRoot":"","sources":["../../../../../../../packages/capabilities/jira/src/commands/sync/sync.command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { JiraIssueSnapshot } from "../../ports/jira.js";
2
+ import type { BatchExcludedEntry, TimesheetEntry } from "../../domain/timesheet-entry.js";
3
+ import { type PresentationOptions } from "../../presentation.js";
4
+ export type VerificationStatus = "Matched" | "Missing" | "Mismatch";
5
+ export interface VerificationItem {
6
+ status: VerificationStatus;
7
+ entry: TimesheetEntry;
8
+ expectedHours: number;
9
+ actualHours: number;
10
+ reason?: string;
11
+ }
12
+ export interface VerificationGroup {
13
+ date: string;
14
+ jiraKey: string;
15
+ expectedHours: number;
16
+ actualHours: number;
17
+ unresolvedHours: number;
18
+ }
19
+ export interface VerificationReport {
20
+ items: VerificationItem[];
21
+ groups: VerificationGroup[];
22
+ expectedHours: number;
23
+ actualHours: number;
24
+ unresolvedHours: number;
25
+ excludedHours: number;
26
+ }
27
+ export interface VerificationPresentation {
28
+ command?: "sync" | "verify";
29
+ created?: number;
30
+ alreadySynced?: number;
31
+ embedded?: boolean;
32
+ }
33
+ export declare function verifyEntries(eligible: readonly TimesheetEntry[], unmapped: readonly TimesheetEntry[], issues: readonly JiraIssueSnapshot[], excluded?: readonly BatchExcludedEntry[]): VerificationReport;
34
+ export declare function formatVerification(report: VerificationReport, options?: PresentationOptions, presentationOptions?: VerificationPresentation): string;