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,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP utilities for the logbook watcher.
|
|
3
|
+
*
|
|
4
|
+
* Provides the hub communication helper and terminal logging timestamp.
|
|
5
|
+
*/
|
|
6
|
+
import { request } from 'node:http';
|
|
7
|
+
/**
|
|
8
|
+
* Send a JSON POST request to the hub.
|
|
9
|
+
*
|
|
10
|
+
* @param port - Hub port number.
|
|
11
|
+
* @param path - URL path (e.g., '/_logbook/status').
|
|
12
|
+
* @param data - JSON-serializable payload.
|
|
13
|
+
*/
|
|
14
|
+
export function postToHub(port, path, data) {
|
|
15
|
+
const body = JSON.stringify(data);
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const req = request({
|
|
18
|
+
hostname: '127.0.0.1',
|
|
19
|
+
port,
|
|
20
|
+
path,
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
'Content-Length': Buffer.byteLength(body),
|
|
25
|
+
},
|
|
26
|
+
}, (res) => {
|
|
27
|
+
res.resume();
|
|
28
|
+
res.on('end', resolve);
|
|
29
|
+
});
|
|
30
|
+
req.on('error', reject);
|
|
31
|
+
req.write(body);
|
|
32
|
+
req.end();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Format a short timestamp for terminal logging (HH:MM:SS).
|
|
37
|
+
*
|
|
38
|
+
* @returns Formatted time string.
|
|
39
|
+
*/
|
|
40
|
+
export function logTime() {
|
|
41
|
+
const now = new Date();
|
|
42
|
+
const h = String(now.getHours()).padStart(2, '0');
|
|
43
|
+
const m = String(now.getMinutes()).padStart(2, '0');
|
|
44
|
+
const s = String(now.getSeconds()).padStart(2, '0');
|
|
45
|
+
return `${h}:${m}:${s}`;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=watcher-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher-http.js","sourceRoot":"","sources":["../../src/watch/watcher-http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAY,EAAE,IAAa;IACjE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,OAAO,CACjB;YACE,QAAQ,EAAE,WAAW;YACrB,IAAI;YACJ,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;aAC1C;SACF,EACD,CAAC,GAAG,EAAE,EAAE;YACN,GAAG,CAAC,MAAM,EAAE,CAAC;YACb,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzB,CAAC,CACF,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/** Local project watcher — pushes status snapshots to the hub. */
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import matter from 'gray-matter';
|
|
5
|
+
import { getConfig, getLogbookDirPath } from '../lib/config.js';
|
|
6
|
+
import { getEntryFilePaths } from '../lib/entry-paths.js';
|
|
7
|
+
import { mdToHtml } from '../lib/build-helpers.js';
|
|
8
|
+
import { transformLogToTimeline } from '../utils/log-timeline.js';
|
|
9
|
+
import { info, success } from '../lib/theme.js';
|
|
10
|
+
import { ALL_COLLECTORS } from './collectors/index.js';
|
|
11
|
+
import { createEmptyState } from './state.js';
|
|
12
|
+
import { evaluateStatuses } from './strategies/index.js';
|
|
13
|
+
import { collectDetails } from './collector.js';
|
|
14
|
+
import { postToHub, logTime } from './watcher-http.js';
|
|
15
|
+
import { setupFileWatchers } from './watcher-fs.js';
|
|
16
|
+
const LOCKFILE_NAME = '.logbook-active';
|
|
17
|
+
/**
|
|
18
|
+
* Build and push a full status snapshot to the hub.
|
|
19
|
+
*/
|
|
20
|
+
async function pushStatus(cwd, port, projectName, state, reason, jiraBaseUrl, repositoryUrl, primaryColor, agentName) {
|
|
21
|
+
const statuses = evaluateStatuses(state);
|
|
22
|
+
const details = await collectDetails(cwd);
|
|
23
|
+
// Render previews: read entry files, strip frontmatter, render to HTML.
|
|
24
|
+
let renderedStory;
|
|
25
|
+
let renderedLog;
|
|
26
|
+
let renderedTicket;
|
|
27
|
+
if (state.hasActiveTicket && state.activeTicketSlug) {
|
|
28
|
+
const config = getConfig(cwd);
|
|
29
|
+
const entriesDir = getLogbookDirPath(config, cwd);
|
|
30
|
+
const paths = getEntryFilePaths(entriesDir, state.activeTicketSlug);
|
|
31
|
+
if (existsSync(paths.index)) {
|
|
32
|
+
try {
|
|
33
|
+
const raw = readFileSync(paths.index, 'utf8');
|
|
34
|
+
renderedStory = await mdToHtml(matter(raw).content);
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
37
|
+
}
|
|
38
|
+
if (existsSync(paths.log)) {
|
|
39
|
+
try {
|
|
40
|
+
const raw = readFileSync(paths.log, 'utf8');
|
|
41
|
+
renderedLog = await transformLogToTimeline(raw);
|
|
42
|
+
}
|
|
43
|
+
catch { }
|
|
44
|
+
}
|
|
45
|
+
if (existsSync(paths.ticket)) {
|
|
46
|
+
try {
|
|
47
|
+
const raw = readFileSync(paths.ticket, 'utf8');
|
|
48
|
+
renderedTicket = await mdToHtml(raw);
|
|
49
|
+
}
|
|
50
|
+
catch { }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const status = {
|
|
54
|
+
projectPath: cwd,
|
|
55
|
+
projectName,
|
|
56
|
+
branch: state.branch,
|
|
57
|
+
activeTicket: state.activeTicketId ?? undefined,
|
|
58
|
+
latestLog: state.latestLog ?? undefined,
|
|
59
|
+
statuses,
|
|
60
|
+
lastActivity: state.lastActivityTimestamp,
|
|
61
|
+
details,
|
|
62
|
+
renderedStory,
|
|
63
|
+
renderedLog,
|
|
64
|
+
renderedTicket,
|
|
65
|
+
mrUrl: state.mrUrl,
|
|
66
|
+
jiraStatus: state.jiraStatus,
|
|
67
|
+
jiraBaseUrl,
|
|
68
|
+
repositoryUrl,
|
|
69
|
+
primaryColor,
|
|
70
|
+
agentName,
|
|
71
|
+
glabLastUpdated: state.glabLastUpdated,
|
|
72
|
+
jiraLastUpdated: state.jiraLastUpdated,
|
|
73
|
+
};
|
|
74
|
+
await postToHub(port, '/_logbook/status', status);
|
|
75
|
+
if (state.jiraAssignedIssues) {
|
|
76
|
+
await postToHub(port, '/_logbook/jira-issues', {
|
|
77
|
+
projectPath: cwd,
|
|
78
|
+
issues: state.jiraAssignedIssues,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (state.glabOpenMrs) {
|
|
82
|
+
await postToHub(port, '/_logbook/gitlab-mrs', {
|
|
83
|
+
projectPath: cwd,
|
|
84
|
+
mrs: state.glabOpenMrs,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
console.log(info(`[${logTime()}] ${reason}`));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Start the watcher loop for the given project.
|
|
91
|
+
*/
|
|
92
|
+
export async function startWatcher(cwd, port) {
|
|
93
|
+
const config = getConfig(cwd);
|
|
94
|
+
const projectName = config.projectName;
|
|
95
|
+
const entriesDir = getLogbookDirPath(config, cwd);
|
|
96
|
+
const lockfilePath = join(cwd, LOCKFILE_NAME);
|
|
97
|
+
// --- Check availability once at startup ---
|
|
98
|
+
const activeCollectors = [];
|
|
99
|
+
for (const collector of ALL_COLLECTORS) {
|
|
100
|
+
const isAvailable = await collector.available(cwd);
|
|
101
|
+
if (isAvailable) {
|
|
102
|
+
activeCollectors.push(collector);
|
|
103
|
+
console.log(info(`[${logTime()}] Collector '${collector.name}' active`));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.log(info(`[${logTime()}] Collector '${collector.name}' skipped (not available)`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// --- Initialize shared state ---
|
|
110
|
+
const state = createEmptyState();
|
|
111
|
+
for (const collector of activeCollectors) {
|
|
112
|
+
await collector.collect(cwd, state);
|
|
113
|
+
}
|
|
114
|
+
const payload = { projectPath: cwd, projectName };
|
|
115
|
+
await postToHub(port, '/_logbook/register', payload);
|
|
116
|
+
const agentName = undefined;
|
|
117
|
+
const pushCfg = {
|
|
118
|
+
jiraBaseUrl: config.jiraBaseUrl ?? '',
|
|
119
|
+
repositoryUrl: config.repositoryUrl,
|
|
120
|
+
primaryColor: config.primaryColor,
|
|
121
|
+
agentName,
|
|
122
|
+
};
|
|
123
|
+
const ps = (reason) => pushStatus(cwd, port, projectName, state, reason, pushCfg.jiraBaseUrl, pushCfg.repositoryUrl, pushCfg.primaryColor, pushCfg.agentName);
|
|
124
|
+
await ps('Initial status collected');
|
|
125
|
+
const runAndPush = async (collector, reason) => {
|
|
126
|
+
try {
|
|
127
|
+
const prevBranch = state.branch;
|
|
128
|
+
await collector.collect(cwd, state);
|
|
129
|
+
if (collector.name === 'git' && state.branch !== prevBranch) {
|
|
130
|
+
for (const c of activeCollectors) {
|
|
131
|
+
if (c.name === 'entries' || c.name === 'glab' || c.name === 'jira')
|
|
132
|
+
await c.collect(cwd, state);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
await ps(reason);
|
|
136
|
+
}
|
|
137
|
+
catch { }
|
|
138
|
+
};
|
|
139
|
+
const fsHandles = setupFileWatchers({ cwd, port, entriesDir, lockfilePath, activeCollectors, state, pushStatus: ps });
|
|
140
|
+
// --- Interval timers for interval-triggered collectors ---
|
|
141
|
+
const intervals = [];
|
|
142
|
+
for (const collector of activeCollectors) {
|
|
143
|
+
const schedule = collector.schedule;
|
|
144
|
+
if (schedule.type !== 'interval')
|
|
145
|
+
continue;
|
|
146
|
+
const timer = setInterval(() => {
|
|
147
|
+
void runAndPush(collector, `${collector.name} collector (periodic)`);
|
|
148
|
+
}, schedule.ms);
|
|
149
|
+
intervals.push(timer);
|
|
150
|
+
}
|
|
151
|
+
// --- Graceful shutdown ---
|
|
152
|
+
const cleanup = async () => {
|
|
153
|
+
for (const timer of intervals)
|
|
154
|
+
clearInterval(timer);
|
|
155
|
+
fsHandles.clearDebounce();
|
|
156
|
+
for (const w of fsHandles.watchers)
|
|
157
|
+
w.close();
|
|
158
|
+
try {
|
|
159
|
+
await Promise.race([
|
|
160
|
+
postToHub(port, '/_logbook/deregister', { projectPath: cwd }),
|
|
161
|
+
new Promise((resolve) => setTimeout(resolve, 1000)),
|
|
162
|
+
]);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Hub already gone.
|
|
166
|
+
}
|
|
167
|
+
console.log(info(`[${logTime()}] Watcher stopped. Goodbye.`));
|
|
168
|
+
process.exit(0);
|
|
169
|
+
};
|
|
170
|
+
process.on('SIGINT', () => void cleanup());
|
|
171
|
+
process.on('SIGTERM', () => void cleanup());
|
|
172
|
+
console.log(success(`[${logTime()}] Watching with ${activeCollectors.length} collector(s): ${activeCollectors.map((c) => c.name).join(', ')}`));
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/watch/watcher.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAExC;;GAEG;AACH,KAAK,UAAU,UAAU,CACvB,GAAW,EACX,IAAY,EACZ,WAAmB,EACnB,KAAmB,EACnB,MAAc,EACd,WAAmB,EACnB,aAAiC,EACjC,YAAgC,EAChC,SAA6B;IAE7B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAE1C,wEAAwE;IACxE,IAAI,aAAiC,CAAC;IACtC,IAAI,WAA+B,CAAC;IACpC,IAAI,cAAkC,CAAC;IACvC,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,iBAAiB,CAAC,UAAU,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpE,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC9C,aAAa,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC5C,WAAW,GAAG,MAAM,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC/C,cAAc,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAkB;QAC5B,WAAW,EAAE,GAAG;QAChB,WAAW;QACX,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,YAAY,EAAE,KAAK,CAAC,cAAc,IAAI,SAAS;QAC/C,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,SAAS;QACvC,QAAQ;QACR,YAAY,EAAE,KAAK,CAAC,qBAAqB;QACzC,OAAO;QACP,aAAa;QACb,WAAW;QACX,cAAc;QACd,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,WAAW;QACX,aAAa;QACb,YAAY;QACZ,SAAS;QACT,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,eAAe,EAAE,KAAK,CAAC,eAAe;KACvC,CAAC;IAEF,MAAM,SAAS,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,CAAC,CAAC;IAElD,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC7B,MAAM,SAAS,CAAC,IAAI,EAAE,uBAAuB,EAAE;YAC7C,WAAW,EAAE,GAAG;YAChB,MAAM,EAAE,KAAK,CAAC,kBAAkB;SACjC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,SAAS,CAAC,IAAI,EAAE,sBAAsB,EAAE;YAC5C,WAAW,EAAE,GAAG;YAChB,GAAG,EAAE,KAAK,CAAC,WAAW;SACvB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY;IAC1D,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACvC,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAE9C,6CAA6C;IAC7C,MAAM,gBAAgB,GAAgB,EAAE,CAAC;IACzC,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnD,IAAI,WAAW,EAAE,CAAC;YAChB,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,gBAAgB,SAAS,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC;QAC3E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,gBAAgB,SAAS,CAAC,IAAI,2BAA2B,CAAC,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IAEjC,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,OAAO,GAAoB,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACnE,MAAM,SAAS,CAAC,IAAI,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;IAErD,MAAM,SAAS,GAAuB,SAAS,CAAC;IAChD,MAAM,OAAO,GAAG;QACd,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;QACrC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS;KACV,CAAC;IACF,MAAM,EAAE,GAAG,CAAC,MAAc,EAAE,EAAE,CAC5B,UAAU,CACR,GAAG,EACH,IAAI,EACJ,WAAW,EACX,KAAK,EACL,MAAM,EACN,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,SAAS,CAClB,CAAC;IACJ,MAAM,EAAE,CAAC,0BAA0B,CAAC,CAAC;IAErC,MAAM,UAAU,GAAG,KAAK,EAAE,SAAoB,EAAE,MAAc,EAAE,EAAE;QAChE,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;YAChC,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACpC,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC5D,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;oBACjC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;wBAAE,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBAClG,CAAC;YACH,CAAC;YACD,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IAEtH,4DAA4D;IAC5D,MAAM,SAAS,GAAqC,EAAE,CAAC;IAEvD,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;QACpC,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,KAAK,UAAU,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,IAAI,uBAAuB,CAAC,CAAC;QACvE,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAChB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,4BAA4B;IAC5B,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,KAAK,MAAM,KAAK,IAAI,SAAS;YAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QACpD,SAAS,CAAC,aAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,QAAQ;YAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,SAAS,CAAC,IAAI,EAAE,sBAAsB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;gBAC7D,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;aACpD,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,6BAA6B,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IAE5C,OAAO,CAAC,GAAG,CACT,OAAO,CACL,IAAI,OAAO,EAAE,mBAAmB,gBAAgB,CAAC,MAAM,kBAAkB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1H,CACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-logbook",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A command-line tool for project logbooks.",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"demo-app"
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"dev": "tsx src/index.ts",
|
|
22
22
|
"build": "rimraf dist && tsc && mkdir -p dist/templates && cp src/templates/*.* dist/templates/ && chmod +x dist/index.js",
|
|
23
|
+
"crawl": "node scripts/crawl.js",
|
|
23
24
|
"prepublishOnly": "npm run build",
|
|
24
25
|
"lint": "eslint src --ext .ts --fix",
|
|
25
26
|
"format": "prettier --write --list-different .",
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# logbook Hub
|
|
2
|
+
|
|
3
|
+
The **logbook Hub** is a real-time dashboard for monitoring multiple project-logbook instances on your machine.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
- The first `logbook watch` invocation binds **port 4201** and becomes the Hub server.
|
|
8
|
+
- Subsequent invocations detect the Hub, register as a Watcher, and push status updates.
|
|
9
|
+
- Each project appears as a card on the dashboard with status badges.
|
|
10
|
+
- The dashboard updates in real time via **Server-Sent Events (SSE)**.
|
|
11
|
+
|
|
12
|
+
## What you see
|
|
13
|
+
|
|
14
|
+
| Element | Description |
|
|
15
|
+
|---------|-------------|
|
|
16
|
+
| **Badges** | Color-coded status indicators (green = good, yellow = warning, blue = info) |
|
|
17
|
+
| **Branch** | Current git branch, click to open in the repository |
|
|
18
|
+
| **Ticket** | Active logbook ticket, click to open in Jira (if configured) |
|
|
19
|
+
| **Activity** | Recent events: log entries, starts, releases |
|
|
20
|
+
| **Previews** | Story, Log, and Ticket content rendered as HTML (click buttons) |
|
|
21
|
+
| **Details** | LOC stats, staged/unstaged files, commit counts (click card to expand) |
|
|
22
|
+
|
|
23
|
+
## Status badges
|
|
24
|
+
|
|
25
|
+
The Help tab lists every status strategy with its severity and which badges it blocks.
|
|
26
|
+
|
|
27
|
+
## Jira & GitLab tabs
|
|
28
|
+
|
|
29
|
+
When a project has `jiraBaseUrl` configured and `JIRA_API_TOKEN` set, assigned issues appear in the Jira tab. When `glab` CLI is installed and authenticated, open merge requests appear in the GitLab tab.
|