project-logbook 1.2.0 → 1.3.0
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 +2 -0
- package/dist/commands/build.js +7 -4
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/log.js +2 -0
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/new-helpers.d.ts +0 -1
- package/dist/commands/new-helpers.js +6 -3
- package/dist/commands/new-helpers.js.map +1 -1
- package/dist/commands/release.js +2 -0
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/start.js +90 -21
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.js +3 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/watch.d.ts +15 -0
- package/dist/commands/watch.js +153 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/autolink.d.ts +5 -0
- package/dist/lib/autolink.js +36 -2
- package/dist/lib/autolink.js.map +1 -1
- package/dist/lib/build-helpers.d.ts +10 -1
- package/dist/lib/build-helpers.js +27 -4
- package/dist/lib/build-helpers.js.map +1 -1
- package/dist/lib/build-steps.js +2 -1
- package/dist/lib/build-steps.js.map +1 -1
- package/dist/lib/config.d.ts +8 -0
- package/dist/lib/config.js +7 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/custom-card-renderer.js +2 -1
- package/dist/lib/custom-card-renderer.js.map +1 -1
- package/dist/lib/entry-href.d.ts +7 -0
- package/dist/lib/entry-href.js +8 -0
- package/dist/lib/entry-href.js.map +1 -0
- package/dist/lib/markdown-processors.d.ts +2 -1
- package/dist/lib/post-template.js +3 -3
- package/dist/lib/post-template.js.map +1 -1
- package/dist/lib/template-helpers.js +3 -2
- package/dist/lib/template-helpers.js.map +1 -1
- package/dist/lib/template-types.d.ts +2 -0
- package/dist/lib/templates.js +5 -3
- package/dist/lib/templates.js.map +1 -1
- package/dist/linters/jira-prefix.js +32 -16
- package/dist/linters/jira-prefix.js.map +1 -1
- package/dist/templates/about-watch.md +29 -0
- package/dist/templates/hub.css +677 -0
- package/dist/templates/hub.js +628 -0
- package/dist/utils/id.d.ts +1 -1
- package/dist/utils/id.js +4 -1
- package/dist/utils/id.js.map +1 -1
- package/dist/watch/collector.d.ts +14 -0
- package/dist/watch/collector.js +33 -0
- package/dist/watch/collector.js.map +1 -0
- package/dist/watch/collectors/acli.d.ts +15 -0
- package/dist/watch/collectors/acli.js +197 -0
- package/dist/watch/collectors/acli.js.map +1 -0
- package/dist/watch/collectors/entries.d.ts +9 -0
- package/dist/watch/collectors/entries.js +90 -0
- package/dist/watch/collectors/entries.js.map +1 -0
- package/dist/watch/collectors/git.d.ts +12 -0
- package/dist/watch/collectors/git.js +58 -0
- package/dist/watch/collectors/git.js.map +1 -0
- package/dist/watch/collectors/glab.d.ts +10 -0
- package/dist/watch/collectors/glab.js +184 -0
- package/dist/watch/collectors/glab.js.map +1 -0
- package/dist/watch/collectors/index.d.ts +10 -0
- package/dist/watch/collectors/index.js +21 -0
- package/dist/watch/collectors/index.js.map +1 -0
- package/dist/watch/collectors/jira.d.ts +3 -0
- package/dist/watch/collectors/jira.js +110 -0
- package/dist/watch/collectors/jira.js.map +1 -0
- package/dist/watch/collectors/type-guards.d.ts +17 -0
- package/dist/watch/collectors/type-guards.js +35 -0
- package/dist/watch/collectors/type-guards.js.map +1 -0
- package/dist/watch/collectors/types.d.ts +37 -0
- package/dist/watch/collectors/types.js +9 -0
- package/dist/watch/collectors/types.js.map +1 -0
- package/dist/watch/dashboard-html.d.ts +11 -0
- package/dist/watch/dashboard-html.js +73 -0
- package/dist/watch/dashboard-html.js.map +1 -0
- package/dist/watch/dashboard-script.d.ts +12 -0
- package/dist/watch/dashboard-script.js +20 -0
- package/dist/watch/dashboard-script.js.map +1 -0
- package/dist/watch/dashboard-styles.d.ts +12 -0
- package/dist/watch/dashboard-styles.js +20 -0
- package/dist/watch/dashboard-styles.js.map +1 -0
- package/dist/watch/dashboard.d.ts +12 -0
- package/dist/watch/dashboard.js +50 -0
- package/dist/watch/dashboard.js.map +1 -0
- package/dist/watch/git-utils.d.ts +30 -0
- package/dist/watch/git-utils.js +101 -0
- package/dist/watch/git-utils.js.map +1 -0
- package/dist/watch/hub-state.d.ts +37 -0
- package/dist/watch/hub-state.js +55 -0
- package/dist/watch/hub-state.js.map +1 -0
- package/dist/watch/hub.d.ts +2 -0
- package/dist/watch/hub.js +219 -0
- package/dist/watch/hub.js.map +1 -0
- package/dist/watch/log-utils.d.ts +13 -0
- package/dist/watch/log-utils.js +24 -0
- package/dist/watch/log-utils.js.map +1 -0
- package/dist/watch/notify.d.ts +18 -0
- package/dist/watch/notify.js +45 -0
- package/dist/watch/notify.js.map +1 -0
- package/dist/watch/state.d.ts +34 -0
- package/dist/watch/state.js +36 -0
- package/dist/watch/state.js.map +1 -0
- package/dist/watch/strategies/behind-default.d.ts +5 -0
- package/dist/watch/strategies/behind-default.js +21 -0
- package/dist/watch/strategies/behind-default.js.map +1 -0
- package/dist/watch/strategies/idle.d.ts +5 -0
- package/dist/watch/strategies/idle.js +21 -0
- package/dist/watch/strategies/idle.js.map +1 -0
- package/dist/watch/strategies/in-progress.d.ts +5 -0
- package/dist/watch/strategies/in-progress.js +21 -0
- package/dist/watch/strategies/in-progress.js.map +1 -0
- package/dist/watch/strategies/index.d.ts +34 -0
- package/dist/watch/strategies/index.js +148 -0
- package/dist/watch/strategies/index.js.map +1 -0
- package/dist/watch/strategies/jira-not-in-review.d.ts +2 -0
- package/dist/watch/strategies/jira-not-in-review.js +29 -0
- package/dist/watch/strategies/jira-not-in-review.js.map +1 -0
- package/dist/watch/strategies/jira-still-open.d.ts +2 -0
- package/dist/watch/strategies/jira-still-open.js +31 -0
- package/dist/watch/strategies/jira-still-open.js.map +1 -0
- package/dist/watch/strategies/mr-approval-optional.d.ts +5 -0
- package/dist/watch/strategies/mr-approval-optional.js +21 -0
- package/dist/watch/strategies/mr-approval-optional.js.map +1 -0
- package/dist/watch/strategies/mr-approved.d.ts +5 -0
- package/dist/watch/strategies/mr-approved.js +21 -0
- package/dist/watch/strategies/mr-approved.js.map +1 -0
- package/dist/watch/strategies/mr-conflicts.d.ts +5 -0
- package/dist/watch/strategies/mr-conflicts.js +21 -0
- package/dist/watch/strategies/mr-conflicts.js.map +1 -0
- package/dist/watch/strategies/mr-draft.d.ts +5 -0
- package/dist/watch/strategies/mr-draft.js +21 -0
- package/dist/watch/strategies/mr-draft.js.map +1 -0
- package/dist/watch/strategies/mr-open-comments.d.ts +5 -0
- package/dist/watch/strategies/mr-open-comments.js +21 -0
- package/dist/watch/strategies/mr-open-comments.js.map +1 -0
- package/dist/watch/strategies/narrative-missing.d.ts +5 -0
- package/dist/watch/strategies/narrative-missing.js +21 -0
- package/dist/watch/strategies/narrative-missing.js.map +1 -0
- package/dist/watch/strategies/no-mr.d.ts +5 -0
- package/dist/watch/strategies/no-mr.js +21 -0
- package/dist/watch/strategies/no-mr.js.map +1 -0
- package/dist/watch/strategies/pipeline-failed.d.ts +5 -0
- package/dist/watch/strategies/pipeline-failed.js +21 -0
- package/dist/watch/strategies/pipeline-failed.js.map +1 -0
- package/dist/watch/strategies/pipeline-running.d.ts +5 -0
- package/dist/watch/strategies/pipeline-running.js +21 -0
- package/dist/watch/strategies/pipeline-running.js.map +1 -0
- package/dist/watch/strategies/ready-for-release.d.ts +7 -0
- package/dist/watch/strategies/ready-for-release.js +35 -0
- package/dist/watch/strategies/ready-for-release.js.map +1 -0
- package/dist/watch/strategies/ready-to-commit.d.ts +5 -0
- package/dist/watch/strategies/ready-to-commit.js +21 -0
- package/dist/watch/strategies/ready-to-commit.js.map +1 -0
- package/dist/watch/strategies/ready-to-push.d.ts +5 -0
- package/dist/watch/strategies/ready-to-push.js +21 -0
- package/dist/watch/strategies/ready-to-push.js.map +1 -0
- package/dist/watch/strategies/released.d.ts +6 -0
- package/dist/watch/strategies/released.js +21 -0
- package/dist/watch/strategies/released.js.map +1 -0
- package/dist/watch/strategies/squash-merged.d.ts +6 -0
- package/dist/watch/strategies/squash-merged.js +21 -0
- package/dist/watch/strategies/squash-merged.js.map +1 -0
- package/dist/watch/strategies/types.d.ts +31 -0
- package/dist/watch/strategies/types.js +12 -0
- package/dist/watch/strategies/types.js.map +1 -0
- package/dist/watch/strategies/unstaged-changes.d.ts +5 -0
- package/dist/watch/strategies/unstaged-changes.js +21 -0
- package/dist/watch/strategies/unstaged-changes.js.map +1 -0
- package/dist/watch/strategies/wrong-branch.d.ts +6 -0
- package/dist/watch/strategies/wrong-branch.js +26 -0
- package/dist/watch/strategies/wrong-branch.js.map +1 -0
- package/dist/watch/types.d.ts +190 -0
- package/dist/watch/types.js +25 -0
- package/dist/watch/types.js.map +1 -0
- package/dist/watch/watcher-fs.d.ts +39 -0
- package/dist/watch/watcher-fs.js +105 -0
- package/dist/watch/watcher-fs.js.map +1 -0
- package/dist/watch/watcher-http.d.ts +19 -0
- package/dist/watch/watcher-http.js +47 -0
- package/dist/watch/watcher-http.js.map +1 -0
- package/dist/watch/watcher.d.ts +4 -0
- package/dist/watch/watcher.js +174 -0
- package/dist/watch/watcher.js.map +1 -0
- package/package.json +2 -1
- package/src/templates/about-watch.md +29 -0
- package/src/templates/hub.css +677 -0
- package/src/templates/hub.js +628 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../../src/watch/git-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub shared state and utilities for logbook watch.
|
|
3
|
+
*
|
|
4
|
+
* Contains the in-memory stores for projects, events, Jira issues, and GitLab
|
|
5
|
+
* MRs, plus HTTP helper functions used by the route handler.
|
|
6
|
+
*/
|
|
7
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
8
|
+
import type { ActivityEvent, GitLabMr, JiraIssue, ProjectStatus } from './types.js';
|
|
9
|
+
/** Connected SSE clients. */
|
|
10
|
+
export declare const sseClients: Set<ServerResponse>;
|
|
11
|
+
/** Current state of all registered projects. */
|
|
12
|
+
export declare const projectStates: Map<string, ProjectStatus>;
|
|
13
|
+
/** Activity timeline per project (keyed by projectPath). Max 50 events per project. */
|
|
14
|
+
export declare const projectEvents: Map<string, ActivityEvent[]>;
|
|
15
|
+
/** Jira assigned issues, deduplicated by key+jiraBaseUrl. */
|
|
16
|
+
export declare const jiraIssues: Map<string, JiraIssue>;
|
|
17
|
+
/** GitLab open MRs, deduplicated by projectUrl+iid. */
|
|
18
|
+
export declare const gitlabMrs: Map<string, GitLabMr>;
|
|
19
|
+
/** Maximum number of events to keep per project. */
|
|
20
|
+
export declare const MAX_EVENTS_PER_PROJECT = 50;
|
|
21
|
+
/**
|
|
22
|
+
* Broadcast an SSE event to all connected clients.
|
|
23
|
+
*
|
|
24
|
+
* @param data - The data object to send as JSON.
|
|
25
|
+
*/
|
|
26
|
+
export declare function broadcast(data: unknown): void;
|
|
27
|
+
/**
|
|
28
|
+
* Read the full request body as a string.
|
|
29
|
+
*
|
|
30
|
+
* @param req - The incoming HTTP request.
|
|
31
|
+
* @returns The request body string.
|
|
32
|
+
*/
|
|
33
|
+
export declare function readBody(req: IncomingMessage): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Send a JSON response.
|
|
36
|
+
*/
|
|
37
|
+
export declare function jsonResponse(res: ServerResponse, status: number, data: unknown): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub shared state and utilities for logbook watch.
|
|
3
|
+
*
|
|
4
|
+
* Contains the in-memory stores for projects, events, Jira issues, and GitLab
|
|
5
|
+
* MRs, plus HTTP helper functions used by the route handler.
|
|
6
|
+
*/
|
|
7
|
+
/** Connected SSE clients. */
|
|
8
|
+
export const sseClients = new Set();
|
|
9
|
+
/** Current state of all registered projects. */
|
|
10
|
+
export const projectStates = new Map();
|
|
11
|
+
/** Activity timeline per project (keyed by projectPath). Max 50 events per project. */
|
|
12
|
+
export const projectEvents = new Map();
|
|
13
|
+
/** Jira assigned issues, deduplicated by key+jiraBaseUrl. */
|
|
14
|
+
export const jiraIssues = new Map();
|
|
15
|
+
/** GitLab open MRs, deduplicated by projectUrl+iid. */
|
|
16
|
+
export const gitlabMrs = new Map();
|
|
17
|
+
/** Maximum number of events to keep per project. */
|
|
18
|
+
export const MAX_EVENTS_PER_PROJECT = 50;
|
|
19
|
+
/**
|
|
20
|
+
* Broadcast an SSE event to all connected clients.
|
|
21
|
+
*
|
|
22
|
+
* @param data - The data object to send as JSON.
|
|
23
|
+
*/
|
|
24
|
+
export function broadcast(data) {
|
|
25
|
+
const payload = `data: ${JSON.stringify(data)}\n\n`;
|
|
26
|
+
for (const client of sseClients) {
|
|
27
|
+
client.write(payload);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read the full request body as a string.
|
|
32
|
+
*
|
|
33
|
+
* @param req - The incoming HTTP request.
|
|
34
|
+
* @returns The request body string.
|
|
35
|
+
*/
|
|
36
|
+
export function readBody(req) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
const chunks = [];
|
|
39
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
40
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
41
|
+
req.on('error', reject);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Send a JSON response.
|
|
46
|
+
*/
|
|
47
|
+
export function jsonResponse(res, status, data) {
|
|
48
|
+
const body = JSON.stringify(data);
|
|
49
|
+
res.writeHead(status, {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
'Content-Length': Buffer.byteLength(body),
|
|
52
|
+
});
|
|
53
|
+
res.end(body);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=hub-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-state.js","sourceRoot":"","sources":["../../src/watch/hub-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,6BAA6B;AAC7B,MAAM,CAAC,MAAM,UAAU,GAAwB,IAAI,GAAG,EAAE,CAAC;AAEzD,gDAAgD;AAChD,MAAM,CAAC,MAAM,aAAa,GAA+B,IAAI,GAAG,EAAE,CAAC;AAEnE,uFAAuF;AACvF,MAAM,CAAC,MAAM,aAAa,GAAiC,IAAI,GAAG,EAAE,CAAC;AAErE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAA2B,IAAI,GAAG,EAAE,CAAC;AAE5D,uDAAuD;AACvD,MAAM,CAAC,MAAM,SAAS,GAA0B,IAAI,GAAG,EAAE,CAAC;AAE1D,oDAAoD;AACpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;IACpD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAoB;IAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAa;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE;QACpB,cAAc,EAAE,kBAAkB;QAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;KAC1C,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/** Hub server — serves the dashboard UI and bridges watchers ↔ SSE. */
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { getPackageVersion } from '../lib/package-version.js';
|
|
4
|
+
import { generateDashboardHtml } from './dashboard.js';
|
|
5
|
+
import { getStrategyMetadata } from './strategies/index.js';
|
|
6
|
+
import { broadcast, gitlabMrs, jiraIssues, jsonResponse, MAX_EVENTS_PER_PROJECT, projectEvents, projectStates, readBody, sseClients, } from './hub-state.js';
|
|
7
|
+
async function handleRequest(req, res) {
|
|
8
|
+
const url = req.url ?? '/';
|
|
9
|
+
const method = req.method ?? 'GET';
|
|
10
|
+
if (url === '/' && method === 'GET') {
|
|
11
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
12
|
+
res.end(await generateDashboardHtml());
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (url === '/_logbook/health' && method === 'GET') {
|
|
16
|
+
jsonResponse(res, 200, {
|
|
17
|
+
logbook: true,
|
|
18
|
+
version: getPackageVersion(),
|
|
19
|
+
projects: projectStates.size,
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (url === '/_logbook/strategies' && method === 'GET') {
|
|
24
|
+
jsonResponse(res, 200, getStrategyMetadata());
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (url === '/_logbook/jira-issues' && method === 'GET') {
|
|
28
|
+
jsonResponse(res, 200, [...jiraIssues.values()]);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (url === '/_logbook/jira-issues' && method === 'POST') {
|
|
32
|
+
const body = await readBody(req);
|
|
33
|
+
try {
|
|
34
|
+
const payload = JSON.parse(body);
|
|
35
|
+
if (Array.isArray(payload.issues)) {
|
|
36
|
+
const baseUrl = payload.issues[0]?.jiraBaseUrl;
|
|
37
|
+
if (baseUrl) {
|
|
38
|
+
for (const [key] of jiraIssues) {
|
|
39
|
+
if (key.startsWith(`${baseUrl}::`))
|
|
40
|
+
jiraIssues.delete(key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const issue of payload.issues)
|
|
44
|
+
jiraIssues.set(`${issue.jiraBaseUrl}::${issue.key}`, issue);
|
|
45
|
+
}
|
|
46
|
+
jsonResponse(res, 200, { ok: true });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
jsonResponse(res, 400, { error: 'Invalid JSON' });
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (url === '/_logbook/gitlab-mrs' && method === 'GET') {
|
|
54
|
+
jsonResponse(res, 200, [...gitlabMrs.values()]);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (url === '/_logbook/gitlab-mrs' && method === 'POST') {
|
|
58
|
+
const body = await readBody(req);
|
|
59
|
+
try {
|
|
60
|
+
const payload = JSON.parse(body);
|
|
61
|
+
if (Array.isArray(payload.mrs)) {
|
|
62
|
+
const projUrl = payload.mrs[0]?.projectUrl;
|
|
63
|
+
if (projUrl) {
|
|
64
|
+
for (const [key] of gitlabMrs) {
|
|
65
|
+
if (key.startsWith(`${projUrl}::`))
|
|
66
|
+
gitlabMrs.delete(key);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const mr of payload.mrs)
|
|
70
|
+
gitlabMrs.set(`${mr.projectUrl}::${mr.iid}`, mr);
|
|
71
|
+
}
|
|
72
|
+
jsonResponse(res, 200, { ok: true });
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
jsonResponse(res, 400, { error: 'Invalid JSON' });
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (url === '/_logbook/events' && method === 'GET') {
|
|
80
|
+
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' });
|
|
81
|
+
res.write('\n');
|
|
82
|
+
sseClients.add(res);
|
|
83
|
+
const eventsObj = {};
|
|
84
|
+
for (const [path, events] of projectEvents)
|
|
85
|
+
eventsObj[path] = events;
|
|
86
|
+
res.write(`data: ${JSON.stringify({ type: 'full-state', projects: [...projectStates.values()], events: eventsObj })}\n\n`);
|
|
87
|
+
req.on('close', () => sseClients.delete(res));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (url === '/_logbook/register' && method === 'POST') {
|
|
91
|
+
const body = await readBody(req);
|
|
92
|
+
try {
|
|
93
|
+
const payload = JSON.parse(body);
|
|
94
|
+
if (!payload.projectPath || !payload.projectName) {
|
|
95
|
+
jsonResponse(res, 400, { error: 'projectPath and projectName required' });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!projectStates.has(payload.projectPath)) {
|
|
99
|
+
projectStates.set(payload.projectPath, {
|
|
100
|
+
projectPath: payload.projectPath,
|
|
101
|
+
projectName: payload.projectName,
|
|
102
|
+
branch: undefined,
|
|
103
|
+
activeTicket: undefined,
|
|
104
|
+
latestLog: undefined,
|
|
105
|
+
statuses: [],
|
|
106
|
+
lastActivity: new Date().toISOString(),
|
|
107
|
+
details: undefined,
|
|
108
|
+
renderedStory: undefined,
|
|
109
|
+
renderedLog: undefined,
|
|
110
|
+
renderedTicket: undefined,
|
|
111
|
+
mrUrl: undefined,
|
|
112
|
+
jiraStatus: undefined,
|
|
113
|
+
jiraBaseUrl: undefined,
|
|
114
|
+
repositoryUrl: undefined,
|
|
115
|
+
primaryColor: undefined,
|
|
116
|
+
agentName: undefined,
|
|
117
|
+
glabLastUpdated: undefined,
|
|
118
|
+
jiraLastUpdated: undefined,
|
|
119
|
+
});
|
|
120
|
+
broadcast({ type: 'status-update', project: projectStates.get(payload.projectPath) });
|
|
121
|
+
}
|
|
122
|
+
jsonResponse(res, 200, { ok: true });
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
jsonResponse(res, 400, { error: 'Invalid JSON' });
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (url === '/_logbook/status' && method === 'POST') {
|
|
130
|
+
const body = await readBody(req);
|
|
131
|
+
try {
|
|
132
|
+
const status = JSON.parse(body);
|
|
133
|
+
if (!status.projectPath) {
|
|
134
|
+
jsonResponse(res, 400, { error: 'projectPath required' });
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
projectStates.set(status.projectPath, status);
|
|
138
|
+
broadcast({ type: 'status-update', project: status });
|
|
139
|
+
jsonResponse(res, 200, { ok: true });
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
jsonResponse(res, 400, { error: 'Invalid JSON' });
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (url === '/_logbook/deregister' && method === 'POST') {
|
|
147
|
+
const body = await readBody(req);
|
|
148
|
+
try {
|
|
149
|
+
const payload = JSON.parse(body);
|
|
150
|
+
if (payload.projectPath) {
|
|
151
|
+
projectStates.delete(payload.projectPath);
|
|
152
|
+
broadcast({ type: 'project-removed', projectPath: payload.projectPath });
|
|
153
|
+
}
|
|
154
|
+
jsonResponse(res, 200, { ok: true });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
jsonResponse(res, 400, { error: 'Invalid JSON' });
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (url === '/_logbook/event' && method === 'POST') {
|
|
162
|
+
const body = await readBody(req);
|
|
163
|
+
try {
|
|
164
|
+
const event = JSON.parse(body);
|
|
165
|
+
if (!event.projectPath || !event.description) {
|
|
166
|
+
jsonResponse(res, 400, { error: 'projectPath and description required' });
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const events = projectEvents.get(event.projectPath) ?? [];
|
|
170
|
+
const normalize = (d) => d.replace(/^Logged:\s*/, '');
|
|
171
|
+
if (events.length > 0 && normalize(events[0].description) === normalize(event.description)) {
|
|
172
|
+
jsonResponse(res, 200, { ok: true });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
events.unshift({
|
|
176
|
+
timestamp: event.timestamp || new Date().toISOString(),
|
|
177
|
+
description: event.description,
|
|
178
|
+
source: event.source || 'unknown',
|
|
179
|
+
});
|
|
180
|
+
if (events.length > MAX_EVENTS_PER_PROJECT)
|
|
181
|
+
events.length = MAX_EVENTS_PER_PROJECT;
|
|
182
|
+
projectEvents.set(event.projectPath, events);
|
|
183
|
+
broadcast({ type: 'activity-event', projectPath: event.projectPath, event: events[0] });
|
|
184
|
+
jsonResponse(res, 200, { ok: true });
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
jsonResponse(res, 400, { error: 'Invalid JSON' });
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
res.writeHead(404);
|
|
192
|
+
res.end('Not Found');
|
|
193
|
+
}
|
|
194
|
+
export function startHub(port) {
|
|
195
|
+
const server = createServer((req, res) => {
|
|
196
|
+
handleRequest(req, res).catch(() => {
|
|
197
|
+
if (!res.headersSent) {
|
|
198
|
+
res.writeHead(500);
|
|
199
|
+
res.end('Internal Server Error');
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
const shutdown = () => {
|
|
204
|
+
for (const client of sseClients)
|
|
205
|
+
client.end();
|
|
206
|
+
sseClients.clear();
|
|
207
|
+
server.close();
|
|
208
|
+
};
|
|
209
|
+
process.once('SIGINT', shutdown);
|
|
210
|
+
process.once('SIGTERM', shutdown);
|
|
211
|
+
return new Promise((resolve, reject) => {
|
|
212
|
+
server.on('error', reject);
|
|
213
|
+
server.listen(port, '127.0.0.1', () => {
|
|
214
|
+
const addr = server.address();
|
|
215
|
+
resolve(`http://127.0.0.1:${typeof addr === 'object' && addr ? addr.port : port}`);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/watch/hub.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,YAAY,EAA6C,MAAM,WAAW,CAAC;AAEpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,QAAQ,EACR,UAAU,GACX,MAAM,gBAAgB,CAAC;AAExB,KAAK,UAAU,aAAa,CAAC,GAAoB,EAAE,GAAmB;IACpE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC;IAEnC,IAAI,GAAG,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACpC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,MAAM,qBAAqB,EAAE,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,kBAAkB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACnD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;YACrB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,iBAAiB,EAAE;YAC5B,QAAQ,EAAE,aAAa,CAAC,IAAI;SACJ,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,sBAAsB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACvD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,uBAAuB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACxD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,uBAAuB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAiD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;gBAC/C,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;wBAC/B,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,IAAI,CAAC;4BAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;gBACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM;oBAAE,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;YAClG,CAAC;YACD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,sBAAsB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACvD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,sBAAsB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAA6C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;gBAC3C,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;wBAC9B,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,IAAI,CAAC;4BAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC5D,CAAC;gBACH,CAAC;gBACD,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,GAAG;oBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;YACjF,CAAC;YACD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,kBAAkB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACnD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;QACnH,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChB,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,MAAM,SAAS,GAAoC,EAAE,CAAC;QACtD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,aAAa;YAAE,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QACrE,GAAG,CAAC,KAAK,CACP,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,MAAM,CAChH,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,oBAAoB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAoB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;gBACjD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC,CAAC;gBAC1E,OAAO;YACT,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5C,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE;oBACrC,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,MAAM,EAAE,SAAS;oBACjB,YAAY,EAAE,SAAS;oBACvB,SAAS,EAAE,SAAS;oBACpB,QAAQ,EAAE,EAAE;oBACZ,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACtC,OAAO,EAAE,SAAS;oBAClB,aAAa,EAAE,SAAS;oBACxB,WAAW,EAAE,SAAS;oBACtB,cAAc,EAAE,SAAS;oBACzB,KAAK,EAAE,SAAS;oBAChB,UAAU,EAAE,SAAS;oBACrB,WAAW,EAAE,SAAS;oBACtB,aAAa,EAAE,SAAS;oBACxB,YAAY,EAAE,SAAS;oBACvB,SAAS,EAAE,SAAS;oBACpB,eAAe,EAAE,SAAS;oBAC1B,eAAe,EAAE,SAAS;iBAC3B,CAAC,CAAC;gBACH,SAAS,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;YACD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,kBAAkB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,GAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACxB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;gBAC1D,OAAO;YACT,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAC9C,SAAS,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACtD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,sBAAsB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAA4B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1D,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAC1C,SAAS,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;YAC3E,CAAC;YACD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,KAAK,iBAAiB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,KAAK,GAA4C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxE,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBAC7C,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC,CAAC;gBAC1E,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAC1D,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YAC9D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3F,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YACD,MAAM,CAAC,OAAO,CAAC;gBACb,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACtD,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,SAAS;aAClC,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,MAAM,GAAG,sBAAsB;gBAAE,MAAM,CAAC,MAAM,GAAG,sBAAsB,CAAC;YACnF,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAC7C,SAAS,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxF,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,KAAK,MAAM,MAAM,IAAI,UAAU;YAAE,MAAM,CAAC,GAAG,EAAE,CAAC;QAC9C,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YACpC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,CAAC,oBAAoB,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACrF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared log file utilities for logbook watch collectors.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract the last timestamped log entry from a log.md file.
|
|
6
|
+
*
|
|
7
|
+
* @param logPath - Absolute path to the log.md file.
|
|
8
|
+
* @returns The last entry's message and timestamp, or undefined if none found.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getLastLogEntry(logPath: string): {
|
|
11
|
+
message: string;
|
|
12
|
+
timestamp: string;
|
|
13
|
+
} | undefined;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared log file utilities for logbook watch collectors.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
5
|
+
/**
|
|
6
|
+
* Extract the last timestamped log entry from a log.md file.
|
|
7
|
+
*
|
|
8
|
+
* @param logPath - Absolute path to the log.md file.
|
|
9
|
+
* @returns The last entry's message and timestamp, or undefined if none found.
|
|
10
|
+
*/
|
|
11
|
+
export function getLastLogEntry(logPath) {
|
|
12
|
+
if (!existsSync(logPath))
|
|
13
|
+
return undefined;
|
|
14
|
+
const content = readFileSync(logPath, 'utf8');
|
|
15
|
+
const lines = content.split('\n').filter(Boolean).reverse();
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
const match = line.match(/^-\s+(\d{4}-\d{2}-\d{2}T[^:]+:[^:]+:[^:]+Z):\s+(.+)$/);
|
|
18
|
+
if (match) {
|
|
19
|
+
return { timestamp: match[1], message: match[2] };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=log-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-utils.js","sourceRoot":"","sources":["../../src/watch/log-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACjF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub notification helper for logbook commands.
|
|
3
|
+
*
|
|
4
|
+
* Provides a fire-and-forget function that commands (log, start, release, etc.)
|
|
5
|
+
* call to push activity events directly to the running hub. If no hub is
|
|
6
|
+
* running, the call silently no-ops — commands never fail because of watch.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Notify the logbook watch hub of a command activity event.
|
|
10
|
+
*
|
|
11
|
+
* This is fire-and-forget: if the hub is not running or the request fails,
|
|
12
|
+
* it resolves silently. Commands should never block or fail because of this.
|
|
13
|
+
*
|
|
14
|
+
* @param projectPath - Absolute path to the project root.
|
|
15
|
+
* @param description - Short description of what happened (e.g., "Logged: fixed auth bug").
|
|
16
|
+
* @param source - The command name that triggered this (e.g., "logbook log").
|
|
17
|
+
*/
|
|
18
|
+
export declare function notifyHub(projectPath: string, description: string, source: string): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub notification helper for logbook commands.
|
|
3
|
+
*
|
|
4
|
+
* Provides a fire-and-forget function that commands (log, start, release, etc.)
|
|
5
|
+
* call to push activity events directly to the running hub. If no hub is
|
|
6
|
+
* running, the call silently no-ops — commands never fail because of watch.
|
|
7
|
+
*/
|
|
8
|
+
import { request } from 'node:http';
|
|
9
|
+
import { resolveWatchPort } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Notify the logbook watch hub of a command activity event.
|
|
12
|
+
*
|
|
13
|
+
* This is fire-and-forget: if the hub is not running or the request fails,
|
|
14
|
+
* it resolves silently. Commands should never block or fail because of this.
|
|
15
|
+
*
|
|
16
|
+
* @param projectPath - Absolute path to the project root.
|
|
17
|
+
* @param description - Short description of what happened (e.g., "Logged: fixed auth bug").
|
|
18
|
+
* @param source - The command name that triggered this (e.g., "logbook log").
|
|
19
|
+
*/
|
|
20
|
+
export function notifyHub(projectPath, description, source) {
|
|
21
|
+
const body = JSON.stringify({
|
|
22
|
+
projectPath,
|
|
23
|
+
description,
|
|
24
|
+
source,
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
});
|
|
27
|
+
const req = request({
|
|
28
|
+
hostname: '127.0.0.1',
|
|
29
|
+
port: resolveWatchPort(),
|
|
30
|
+
path: '/_logbook/event',
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
'Content-Length': Buffer.byteLength(body),
|
|
35
|
+
},
|
|
36
|
+
timeout: 1000,
|
|
37
|
+
}, (res) => {
|
|
38
|
+
res.resume();
|
|
39
|
+
});
|
|
40
|
+
req.on('error', () => { });
|
|
41
|
+
req.on('timeout', () => req.destroy());
|
|
42
|
+
req.write(body);
|
|
43
|
+
req.end();
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/watch/notify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,WAAmB,EAAE,WAAmB,EAAE,MAAc;IAChF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,WAAW;QACX,WAAW;QACX,MAAM;QACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,OAAO,CACjB;QACE,QAAQ,EAAE,WAAW;QACrB,IAAI,EAAE,gBAAgB,EAAE;QACxB,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;SAC1C;QACD,OAAO,EAAE,IAAI;KACd,EACD,CAAC,GAAG,EAAE,EAAE;QACN,GAAG,CAAC,MAAM,EAAE,CAAC;IACf,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC1B,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChB,GAAG,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared watcher state for logbook watch.
|
|
3
|
+
*
|
|
4
|
+
* This is the single source of truth that collectors write to and strategies
|
|
5
|
+
* read from. Each field is optional — a collector populates its subset, and
|
|
6
|
+
* strategies handle missing data gracefully (undefined = not available).
|
|
7
|
+
*
|
|
8
|
+
* The state is mutable. Collectors update it in-place on their own schedule.
|
|
9
|
+
* After any collector runs, strategies are re-evaluated against the current
|
|
10
|
+
* snapshot.
|
|
11
|
+
*/
|
|
12
|
+
import type { GitLabMr, JiraIssue, WatcherMetrics } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* The mutable watcher state. Extends WatcherMetrics with fields for future
|
|
15
|
+
* collectors (glab, acli, etc.).
|
|
16
|
+
*/
|
|
17
|
+
export interface WatcherState extends WatcherMetrics {
|
|
18
|
+
/** MR title if one exists. */
|
|
19
|
+
mrTitle?: string;
|
|
20
|
+
/** All open MRs for the project (for GitLab tab). */
|
|
21
|
+
glabOpenMrs?: GitLabMr[];
|
|
22
|
+
/** Jira ticket assignee. */
|
|
23
|
+
jiraAssignee?: string;
|
|
24
|
+
/** All Jira issues assigned to the current user (for Jira tab). */
|
|
25
|
+
jiraAssignedIssues?: JiraIssue[];
|
|
26
|
+
/** ISO timestamp of last successful GitLab collector run. */
|
|
27
|
+
glabLastUpdated?: string;
|
|
28
|
+
/** ISO timestamp of last successful Jira collector run. */
|
|
29
|
+
jiraLastUpdated?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a fresh empty state with safe defaults.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createEmptyState(): WatcherState;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared watcher state for logbook watch.
|
|
3
|
+
*
|
|
4
|
+
* This is the single source of truth that collectors write to and strategies
|
|
5
|
+
* read from. Each field is optional — a collector populates its subset, and
|
|
6
|
+
* strategies handle missing data gracefully (undefined = not available).
|
|
7
|
+
*
|
|
8
|
+
* The state is mutable. Collectors update it in-place on their own schedule.
|
|
9
|
+
* After any collector runs, strategies are re-evaluated against the current
|
|
10
|
+
* snapshot.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Create a fresh empty state with safe defaults.
|
|
14
|
+
*/
|
|
15
|
+
export function createEmptyState() {
|
|
16
|
+
return {
|
|
17
|
+
branch: undefined,
|
|
18
|
+
defaultBranch: 'main',
|
|
19
|
+
hasActiveTicket: false,
|
|
20
|
+
activeTicketId: undefined,
|
|
21
|
+
activeTicketSlug: undefined,
|
|
22
|
+
latestLog: undefined,
|
|
23
|
+
latestLogTimestamp: undefined,
|
|
24
|
+
isDirty: false,
|
|
25
|
+
stagedFiles: 0,
|
|
26
|
+
unstagedFiles: 0,
|
|
27
|
+
isAheadOfRemote: false,
|
|
28
|
+
hasNarrativePlaceholders: false,
|
|
29
|
+
isReleased: false,
|
|
30
|
+
hasLockfile: false,
|
|
31
|
+
isSquashMerged: false,
|
|
32
|
+
commitsBehindDefault: 0,
|
|
33
|
+
lastActivityTimestamp: new Date().toISOString(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/watch/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4BH;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,aAAa,EAAE,MAAM;QACrB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,SAAS;QACzB,gBAAgB,EAAE,SAAS;QAC3B,SAAS,EAAE,SAAS;QACpB,kBAAkB,EAAE,SAAS;QAC7B,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,CAAC;QAChB,eAAe,EAAE,KAAK;QACtB,wBAAwB,EAAE,KAAK;QAC/B,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,KAAK;QACrB,oBAAoB,EAAE,CAAC;QACvB,qBAAqB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behind Default — the current branch is behind the default branch.
|
|
3
|
+
*/
|
|
4
|
+
export const behindDefaultCheck = {
|
|
5
|
+
id: 'behind-default',
|
|
6
|
+
source: 'Git',
|
|
7
|
+
description: 'The current branch is behind the default branch. Consider rebasing or merging.',
|
|
8
|
+
blockedBy: ['squash-merged', 'released'],
|
|
9
|
+
check(metrics) {
|
|
10
|
+
if (metrics.commitsBehindDefault > 0) {
|
|
11
|
+
return {
|
|
12
|
+
id: 'behind-default',
|
|
13
|
+
label: 'Behind Default',
|
|
14
|
+
severity: 'warning',
|
|
15
|
+
detail: `${metrics.commitsBehindDefault} commit${metrics.commitsBehindDefault !== 1 ? 's' : ''} behind ${metrics.defaultBranch}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=behind-default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behind-default.js","sourceRoot":"","sources":["../../../src/watch/strategies/behind-default.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,EAAE,EAAE,gBAAgB;IACpB,MAAM,EAAE,KAAK;IACb,WAAW,EAAE,gFAAgF;IAC7F,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,oBAAoB,GAAG,CAAC,EAAE,CAAC;YACrC,OAAO;gBACL,EAAE,EAAE,gBAAgB;gBACpB,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,UAAU,OAAO,CAAC,oBAAoB,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,OAAO,CAAC,aAAa,EAAE;aACjI,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idle — no active ticket and no dirty state.
|
|
3
|
+
*/
|
|
4
|
+
export const idleCheck = {
|
|
5
|
+
id: 'idle',
|
|
6
|
+
source: 'LOGBOOK',
|
|
7
|
+
description: 'No active ticket and no uncommitted changes.',
|
|
8
|
+
blockedBy: ['squash-merged', 'released'],
|
|
9
|
+
check(metrics) {
|
|
10
|
+
if (!metrics.hasActiveTicket && !metrics.isDirty) {
|
|
11
|
+
return {
|
|
12
|
+
id: 'idle',
|
|
13
|
+
label: 'Idle',
|
|
14
|
+
severity: 'info',
|
|
15
|
+
detail: 'No active ticket. All clean.',
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=idle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idle.js","sourceRoot":"","sources":["../../../src/watch/strategies/idle.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAmB;IACvC,EAAE,EAAE,MAAM;IACV,MAAM,EAAE,SAAS;IACjB,WAAW,EAAE,8CAA8C;IAC3D,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACjD,OAAO;gBACL,EAAE,EAAE,MAAM;gBACV,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,8BAA8B;aACvC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In Progress — an active ticket is present but no other blocking state.
|
|
3
|
+
*/
|
|
4
|
+
export const inProgressCheck = {
|
|
5
|
+
id: 'in-progress',
|
|
6
|
+
source: 'LOGBOOK',
|
|
7
|
+
description: 'An active ticket is present and work is in progress.',
|
|
8
|
+
blockedBy: ['squash-merged', 'released'],
|
|
9
|
+
check(metrics) {
|
|
10
|
+
if (metrics.hasActiveTicket) {
|
|
11
|
+
return {
|
|
12
|
+
id: 'in-progress',
|
|
13
|
+
label: 'In Progress',
|
|
14
|
+
severity: 'info',
|
|
15
|
+
detail: `Working on ${metrics.activeTicketId ?? metrics.activeTicketSlug ?? 'unknown'}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=in-progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-progress.js","sourceRoot":"","sources":["../../../src/watch/strategies/in-progress.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C,EAAE,EAAE,aAAa;IACjB,MAAM,EAAE,SAAS;IACjB,WAAW,EAAE,sDAAsD;IACnE,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5B,OAAO;gBACL,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,aAAa;gBACpB,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,cAAc,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,gBAAgB,IAAI,SAAS,EAAE;aACxF,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
|