project-logbook 1.0.0 → 1.2.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 +5 -1
- package/dist/commands/build.js +49 -15
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/lint.js +2 -1
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/list.js +10 -10
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/log.js +24 -1
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/new-helpers.d.ts +26 -0
- package/dist/commands/new-helpers.js +103 -0
- package/dist/commands/new-helpers.js.map +1 -0
- package/dist/commands/new.d.ts +4 -1
- package/dist/commands/new.js +115 -96
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/release.js +1 -1
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/start.d.ts +1 -1
- package/dist/commands/start.js +105 -43
- 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/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/autolink.d.ts +15 -0
- package/dist/lib/autolink.js +39 -0
- package/dist/lib/autolink.js.map +1 -0
- package/dist/lib/build-helpers.d.ts +3 -3
- package/dist/lib/build-helpers.js +54 -60
- package/dist/lib/build-helpers.js.map +1 -1
- package/dist/lib/build-steps.d.ts +2 -2
- package/dist/lib/build-steps.js +30 -3
- package/dist/lib/build-steps.js.map +1 -1
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.js +10 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/custom-card-renderer.d.ts +2 -0
- package/dist/lib/custom-card-renderer.js +58 -0
- package/dist/lib/custom-card-renderer.js.map +1 -0
- package/dist/lib/custom-types-builder.d.ts +4 -0
- package/dist/lib/custom-types-builder.js +37 -0
- package/dist/lib/custom-types-builder.js.map +1 -0
- package/dist/lib/git-helpers.js +10 -1
- package/dist/lib/git-helpers.js.map +1 -1
- package/dist/lib/image-dimension-parser.d.ts +11 -0
- package/dist/lib/image-dimension-parser.js +127 -0
- package/dist/lib/image-dimension-parser.js.map +1 -0
- package/dist/lib/image-helpers.d.ts +2 -0
- package/dist/lib/image-helpers.js +2 -0
- package/dist/lib/image-helpers.js.map +1 -1
- package/dist/lib/markdown-processors.d.ts +5 -2
- package/dist/lib/markdown-processors.js +9 -7
- package/dist/lib/markdown-processors.js.map +1 -1
- package/dist/lib/post-template.d.ts +5 -0
- package/dist/lib/post-template.js +48 -0
- package/dist/lib/post-template.js.map +1 -0
- package/dist/lib/session.d.ts +2 -2
- package/dist/lib/session.js +29 -1
- package/dist/lib/session.js.map +1 -1
- package/dist/lib/template-helpers.js +17 -1
- package/dist/lib/template-helpers.js.map +1 -1
- package/dist/lib/template-types.d.ts +16 -3
- package/dist/lib/templates.d.ts +5 -7
- package/dist/lib/templates.js +39 -53
- package/dist/lib/templates.js.map +1 -1
- package/dist/templates/CONTRIBUTING.md +43 -2
- package/dist/templates/adr.md +34 -0
- package/dist/templates/index.md +5 -4
- package/dist/templates/log.md +1 -1
- package/dist/templates/steer.txt +14 -1
- package/dist/templates/styles.css +32 -0
- package/dist/utils/prompt.d.ts +6 -0
- package/dist/utils/prompt.js +59 -0
- package/dist/utils/prompt.js.map +1 -0
- package/package.json +4 -4
- package/src/templates/CONTRIBUTING.md +43 -2
- package/src/templates/adr.md +34 -0
- package/src/templates/index.md +5 -4
- package/src/templates/log.md +1 -1
- package/src/templates/steer.txt +14 -1
- package/src/templates/styles.css +32 -0
|
@@ -22,10 +22,18 @@ export interface TimelineTemplateProps {
|
|
|
22
22
|
repositoryUrl?: string;
|
|
23
23
|
currentPage?: number;
|
|
24
24
|
totalPages?: number;
|
|
25
|
+
researchEntries?: TimelineResearchItem[];
|
|
26
|
+
adrItems?: TimelineAdrItem[];
|
|
27
|
+
customTabs?: {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
items: TimelineResearchItem[];
|
|
31
|
+
}[];
|
|
32
|
+
}
|
|
33
|
+
export interface TimelineResearchItem extends TimelineEntry {
|
|
34
|
+
status: string;
|
|
35
|
+
updated: string;
|
|
25
36
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Configuration for a month group in the timeline
|
|
28
|
-
*/
|
|
29
37
|
export interface TimelineGroup {
|
|
30
38
|
month: string;
|
|
31
39
|
items: TimelineItem[];
|
|
@@ -72,6 +80,10 @@ export interface TimelineEntry {
|
|
|
72
80
|
summary: string;
|
|
73
81
|
tags?: string[];
|
|
74
82
|
workspaces?: string[];
|
|
83
|
+
teaserImage?: {
|
|
84
|
+
src: string;
|
|
85
|
+
ratio: number;
|
|
86
|
+
};
|
|
75
87
|
}
|
|
76
88
|
/**
|
|
77
89
|
* A standalone git commit shown as a non-clickable info item in the timeline.
|
|
@@ -128,6 +140,7 @@ export interface PostTemplateProps {
|
|
|
128
140
|
slug?: string;
|
|
129
141
|
tags?: string[];
|
|
130
142
|
workspaces?: string[];
|
|
143
|
+
backLink?: string;
|
|
131
144
|
}
|
|
132
145
|
/**
|
|
133
146
|
* Configuration for navigation between entries
|
package/dist/lib/templates.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { TabConfig, TimelineTemplateProps
|
|
1
|
+
import type { TabConfig, TimelineTemplateProps } from './template-types.js';
|
|
2
|
+
export { postTemplate } from './post-template.js';
|
|
2
3
|
export declare const tabsComponent: (tabs: TabConfig[], defaultActive?: number) => {
|
|
3
4
|
tabsHtml: string;
|
|
4
5
|
sectionsHtml: string;
|
|
5
6
|
};
|
|
6
|
-
|
|
7
|
+
interface LayoutProps {
|
|
7
8
|
title: string;
|
|
8
9
|
header: string;
|
|
9
10
|
content: string;
|
|
@@ -15,14 +16,11 @@ export declare const layout: ({ title, header, content, projectName, basePath, d
|
|
|
15
16
|
includeRssLink?: boolean;
|
|
16
17
|
prevUrl?: string;
|
|
17
18
|
nextUrl?: string;
|
|
18
|
-
}
|
|
19
|
+
}
|
|
20
|
+
export declare const layout: ({ title, header, content, projectName, basePath, description, bodySlug, buildMeta, includeRssLink, prevUrl, nextUrl, }: LayoutProps) => string;
|
|
19
21
|
export declare const timelineTemplate: (props: TimelineTemplateProps & {
|
|
20
22
|
includeRssLink?: boolean;
|
|
21
23
|
}) => {
|
|
22
24
|
header: string;
|
|
23
25
|
content: string;
|
|
24
26
|
};
|
|
25
|
-
export declare const postTemplate: (props: PostTemplateProps) => {
|
|
26
|
-
header: string;
|
|
27
|
-
content: string;
|
|
28
|
-
};
|
package/dist/lib/templates.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { ATTR_PAGE_SLUG
|
|
2
|
-
import { escapeHtml
|
|
3
|
-
import { html,
|
|
1
|
+
import { ATTR_PAGE_SLUG } from './html-attributes.js';
|
|
2
|
+
import { escapeHtml } from './html-escape.js';
|
|
3
|
+
import { html, renderTimelineEntryItem, renderTimelineCommitItem, renderTimelineTagItem, renderTimelineAdrItem, paginationLinks, } from './template-helpers.js';
|
|
4
|
+
import { renderCustomCard } from './custom-card-renderer.js';
|
|
5
|
+
import { autolinkReferences, getRegisteredResearchEntries } from './autolink.js';
|
|
6
|
+
export { postTemplate } from './post-template.js';
|
|
4
7
|
export const tabsComponent = (tabs, defaultActive = 0) => {
|
|
5
8
|
const tabsHtml = tabs
|
|
6
9
|
.map((tab, index) => `<div class="tab ${index === defaultActive ? 'active' : ''}" role="tab" aria-selected="${index === defaultActive}" aria-controls="${escapeHtml(tab.id)}" tabindex="${index === defaultActive ? '0' : '-1'}" onclick="showTab(event, '${escapeHtml(tab.id)}')">${escapeHtml(tab.title)}</div>`)
|
|
@@ -13,6 +16,9 @@ export const tabsComponent = (tabs, defaultActive = 0) => {
|
|
|
13
16
|
export const layout = ({ title, header, content, projectName, basePath = './', description, bodySlug, buildMeta, includeRssLink = false, prevUrl, nextUrl, }) => {
|
|
14
17
|
const metaDescription = description ||
|
|
15
18
|
`A chronological timeline of recent development changes, narrative updates, and commits for ${projectName}.`;
|
|
19
|
+
const registeredResearchEntries = getRegisteredResearchEntries();
|
|
20
|
+
const processedHeader = registeredResearchEntries.length > 0 ? autolinkReferences(header, registeredResearchEntries, basePath) : header;
|
|
21
|
+
const processedContent = registeredResearchEntries.length > 0 ? autolinkReferences(content, registeredResearchEntries, basePath) : content;
|
|
16
22
|
return html `<!DOCTYPE html>
|
|
17
23
|
<html lang="en">
|
|
18
24
|
<head>
|
|
@@ -26,7 +32,7 @@ export const layout = ({ title, header, content, projectName, basePath = './', d
|
|
|
26
32
|
<link rel="stylesheet" href="${basePath}style.css">
|
|
27
33
|
</head>
|
|
28
34
|
<body${bodySlug ? ` ${ATTR_PAGE_SLUG}="${bodySlug}"` : ''} class="tabs-wrapper">
|
|
29
|
-
${
|
|
35
|
+
${processedHeader}<main>${processedContent}</main>
|
|
30
36
|
<footer>
|
|
31
37
|
${buildMeta ? `<p class="build-time">${buildMeta}${includeRssLink ? ` • <a href="${basePath}rss.xml">RSS Feed</a>` : ''}</p>` : ''}
|
|
32
38
|
</footer>
|
|
@@ -61,11 +67,35 @@ export const timelineTemplate = (props) => {
|
|
|
61
67
|
.join('')}
|
|
62
68
|
${paginationLinks(currentPage, totalPages)}
|
|
63
69
|
</div>`;
|
|
64
|
-
const {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
const tabs = [{ id: 'timeline', title: 'Timeline', content: timelineTab }];
|
|
71
|
+
if (props.adrItems && props.adrItems.length > 0) {
|
|
72
|
+
const adrTabHtml = html `
|
|
73
|
+
<div class="timeline">${props.adrItems.map((item) => renderTimelineAdrItem(item)).join('')}</div>
|
|
74
|
+
`;
|
|
75
|
+
tabs.push({ id: 'adrs', title: 'ADRs', content: adrTabHtml });
|
|
76
|
+
}
|
|
77
|
+
if (props.researchEntries && props.researchEntries.length > 0) {
|
|
78
|
+
const researchHtml = html `
|
|
79
|
+
<div class="timeline">
|
|
80
|
+
${props.researchEntries.map((e) => renderCustomCard(e, 'research', 'RESEARCH')).join('')}
|
|
81
|
+
</div>
|
|
82
|
+
`;
|
|
83
|
+
tabs.push({ id: 'research', title: 'Research', content: researchHtml });
|
|
84
|
+
}
|
|
85
|
+
if (props.customTabs) {
|
|
86
|
+
for (const tab of props.customTabs) {
|
|
87
|
+
if (tab.items && tab.items.length > 0) {
|
|
88
|
+
const tabHtml = html `
|
|
89
|
+
<div class="timeline">
|
|
90
|
+
${tab.items.map((e) => renderCustomCard(e, tab.id, tab.title.toUpperCase())).join('')}
|
|
91
|
+
</div>
|
|
92
|
+
`;
|
|
93
|
+
tabs.push({ id: tab.id, title: tab.title, content: tabHtml });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
tabs.push({ id: 'readme', title: 'Project Readme', content: readmeHtml || '<p>No README available.</p>' }, { id: 'about', title: 'About this Logbook', content: aboutHtml || '<p>No information available.</p>' });
|
|
98
|
+
const { tabsHtml, sectionsHtml } = tabsComponent(tabs, 0);
|
|
69
99
|
const header = html `<header>
|
|
70
100
|
<div class="header-inner">
|
|
71
101
|
<h1><a href="./index.html">${escapeHtml(projectName)}</a></h1>
|
|
@@ -77,48 +107,4 @@ export const timelineTemplate = (props) => {
|
|
|
77
107
|
</header>`;
|
|
78
108
|
return { header, content: sectionsHtml };
|
|
79
109
|
};
|
|
80
|
-
export const postTemplate = (props) => {
|
|
81
|
-
const { title, displayDate, dateStart, harness, llm, prompter, content, ticketHtml, logHtml, commits, version, jiraUrl, repositoryUrl, prevEntry, nextEntry, tags, workspaces } = props; // prettier-ignore
|
|
82
|
-
// Validate jiraUrl scheme to prevent javascript: URLs
|
|
83
|
-
const validatedJiraUrl = jiraUrl ? validateUrlScheme(jiraUrl) : undefined;
|
|
84
|
-
const jiraBtn = validatedJiraUrl
|
|
85
|
-
? `<a href="${escapeHtml(validatedJiraUrl)}" class="jira-link-btn" target="_blank" rel="noopener noreferrer">View in Jira ↗</a>`
|
|
86
|
-
: '';
|
|
87
|
-
const tabBtn = (id, label, active = false) => `<div class="tab${active ? ' active' : ''}" role="tab" aria-selected="${active}" aria-controls="${escapeHtml(id)}" tabindex="${active ? '0' : '-1'}" onclick="showTab(event, '${escapeHtml(id)}')">${escapeHtml(label)}</div>`;
|
|
88
|
-
const header = html `<header>
|
|
89
|
-
<div class="header-inner">
|
|
90
|
-
<h1>${escapeHtml(title)}</h1>
|
|
91
|
-
<div class="tagline">
|
|
92
|
-
<span ${ATTR_DATA_DATE}="${dateStart}">${displayDate}</span> •
|
|
93
|
-
${llm ? `${escapeHtml(llm)} via ` : ''}${escapeHtml(harness)}${prompter ? ` / ${escapeHtml(prompter)}` : ''} •
|
|
94
|
-
v${version}
|
|
95
|
-
</div>
|
|
96
|
-
<div class="header-nav">
|
|
97
|
-
<div class="header-nav-left">
|
|
98
|
-
<a href="../index.html" class="back-link">← Back to Timeline</a>
|
|
99
|
-
</div>
|
|
100
|
-
<div class="tabs" role="tablist" aria-label="Entry sections">
|
|
101
|
-
${tabBtn('story', 'Story', true)}${tabBtn('spec', 'Original Spec')}${tabBtn('log', 'Technical Log')}
|
|
102
|
-
</div>
|
|
103
|
-
<div class="header-nav-right">${jiraBtn ? `${jiraBtn}` : '<span></span>'}</div>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
|
-
</header>`;
|
|
107
|
-
const mainContent = html `<article>
|
|
108
|
-
<div class="content-sections">
|
|
109
|
-
<div id="story" class="content-section" role="tabpanel">
|
|
110
|
-
${renderTagsAndWorkspaces(tags, workspaces)}${content}
|
|
111
|
-
</div>
|
|
112
|
-
<div id="spec" class="content-section" role="tabpanel" style="display:none;">${ticketHtml}</div>
|
|
113
|
-
<div id="log" class="content-section" role="tabpanel" style="display:none;">
|
|
114
|
-
${logHtml}${renderCommits(commits, repositoryUrl)}
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
<nav class="post-nav">
|
|
118
|
-
<div class="post-nav-prev">${prevEntry ? navLink(prevEntry, 'prev') : '<span></span>'}</div>
|
|
119
|
-
<div class="post-nav-next">${nextEntry ? navLink(nextEntry, 'next') : '<span></span>'}</div>
|
|
120
|
-
</nav>
|
|
121
|
-
</article>`;
|
|
122
|
-
return { header, content: mainContent };
|
|
123
|
-
};
|
|
124
110
|
//# sourceMappingURL=templates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/lib/templates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/lib/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -65,7 +65,17 @@ Once the work is ready:
|
|
|
65
65
|
|
|
66
66
|
The linter enforces rules to be followed.
|
|
67
67
|
|
|
68
|
-
### 4.
|
|
68
|
+
### 4. Interactive Local QA Loop
|
|
69
|
+
Development is an iterative process. Expect to go through several feedback loops with the prompter before a ticket is finalized:
|
|
70
|
+
- **Test & Challenge**: The prompter will run and test your changes, challenge architectural patterns, and suggest revisions.
|
|
71
|
+
- **Cycle Routine**: During each feedback round:
|
|
72
|
+
1. Update code according to feedback.
|
|
73
|
+
2. Log key decisions, errors, and pivots in `log.md` (`logbook log "..."`).
|
|
74
|
+
3. Keep the story in `index.md` fully up-to-date with any design/code changes.
|
|
75
|
+
4. Run `npm run pre` to verify linting and tests pass.
|
|
76
|
+
- **Commit Optimization**: Once the implementation is solid, optimize the final git commit message to match project standards before releasing.
|
|
77
|
+
|
|
78
|
+
### 5. Final Review
|
|
69
79
|
Use the preview command to see how your entry looks in the context of the whole project:
|
|
70
80
|
```bash
|
|
71
81
|
logbook preview
|
|
@@ -84,4 +94,35 @@ If `jiraPrefix` is configured, entry folder names and ticket references must mat
|
|
|
84
94
|
## Tone & Style
|
|
85
95
|
- **Narrative over Lists**: In `index.md`, tell a story. Why did we make this change? What were the challenges?
|
|
86
96
|
- **Technical Precision**: In `log.md`, be specific. Mention file paths, error messages, and specific design patterns. Log in real time — do not reconstruct after the fact.
|
|
87
|
-
- **No Boilerplate in Commits**: All template placeholders must be replaced or removed before `logbook release`.
|
|
97
|
+
- **No Boilerplate in Commits**: All template placeholders must be replaced or removed before `logbook release`.
|
|
98
|
+
|
|
99
|
+
## Research Logs
|
|
100
|
+
For exploratory research, technical spike investigations, and architectural decision groundwork, we use **Research Logs**.
|
|
101
|
+
|
|
102
|
+
- **Required Setup**: Before creating your first research log, ensure that your configured research directory exists on your filesystem (for example, create it using `mkdir -p docs/research`).
|
|
103
|
+
- **Location**: Stored in `docs/research/` (configurable via `researchDir` in `.project-logbook`).
|
|
104
|
+
- **Scaffolding**: Run `logbook new [ID] [Slug] --research` or `logbook new -r` to scaffold. This automatically generates a numeric ID prefixed with `RES-` (e.g., `RES-1`).
|
|
105
|
+
- **Commands**: Commands like `logbook start RES-1`, `logbook log`, and `logbook release` work transparently.
|
|
106
|
+
- **Auto-Activity Tracking**: Writing a log message via `logbook log` automatically updates the `updated` frontmatter field inside the research log's `index.md`.
|
|
107
|
+
- **Status Lifecycle**: The frontmatter `status` field tracks progress: `active`, `paused`, `postponed`, or `completed`.
|
|
108
|
+
- **Visuals**: Research logs are compiled and displayed under a dedicated "Research" tab on the built logbook homepage, sorted by their latest `updated` date.
|
|
109
|
+
|
|
110
|
+
## Custom Storyline Types
|
|
111
|
+
Beyond standard logbook entries and Research Logs, you can define completely custom storyline types (e.g., "analyses", "spikes", "decisions") in `.project-logbook`.
|
|
112
|
+
|
|
113
|
+
- **Required Setup**: Define the custom types inside your `.project-logbook` configuration file under `customTypes` and ensure the directory exists on your filesystem:
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"customTypes": {
|
|
117
|
+
"analyses": {
|
|
118
|
+
"prefix": "ANA",
|
|
119
|
+
"dir": "docs/analyses",
|
|
120
|
+
"tabTitle": "Analyses",
|
|
121
|
+
"sortBy": "updated"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
- **Directory Setup**: Ensure the directory configured (e.g., `docs/analyses`) is created on your filesystem (for example, create it using `mkdir -p docs/analyses`).
|
|
127
|
+
- **Scaffolding**: Run `logbook new [ID] [Slug] --type analyses` or `logbook new -t analyses` to scaffold the entry.
|
|
128
|
+
- **Visuals**: Just like Research Logs, these custom types will automatically compile into dedicated tabs on the built logbook homepage using your specified `tabTitle`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: [ID_NUM]
|
|
3
|
+
title: [YAML_TITLE]
|
|
4
|
+
status: "proposed"
|
|
5
|
+
date: [DATE]
|
|
6
|
+
author: "[AUTHOR]"
|
|
7
|
+
superseded_by: null
|
|
8
|
+
tags: []
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR [ID]: [TITLE]
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
[Describe the issue motivating this decision and any context that influences it.]
|
|
15
|
+
|
|
16
|
+
## Considered Options
|
|
17
|
+
1. **[Option A]**: [Brief description.]
|
|
18
|
+
2. **[Option B]**: [Brief description.]
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
[State the decision and briefly explain what it means in practice.]
|
|
22
|
+
|
|
23
|
+
## Rationale
|
|
24
|
+
[Explain why this option was chosen over the alternatives.]
|
|
25
|
+
|
|
26
|
+
## Consequences
|
|
27
|
+
|
|
28
|
+
### Positive
|
|
29
|
+
* [Benefit 1]
|
|
30
|
+
* [Benefit 2]
|
|
31
|
+
|
|
32
|
+
### Negative
|
|
33
|
+
* [Drawback 1]
|
|
34
|
+
* [Drawback 2]
|
package/dist/templates/index.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# The ticket field should match the ID portion (e.g., LB-34)
|
|
3
3
|
ticket: {{id}}
|
|
4
4
|
# The title should be a human-readable description of the work
|
|
5
|
-
title: {{
|
|
5
|
+
title: {{yamlTitle}}
|
|
6
6
|
prompter: "[PROMPTER]"
|
|
7
7
|
harness: "[HARNESS]"
|
|
8
8
|
llm: "[LLM]"
|
|
@@ -27,9 +27,10 @@ TODO: Write a polished, highly readable ticket summary that reads like an engagi
|
|
|
27
27
|
|
|
28
28
|
### Formatting & Style Rules:
|
|
29
29
|
- **Maintain the narrative tone:** TODO: Keep the storytelling flair (e.g., describing how problems accumulated or how gaps surfaced), but stay strictly factual based on the provided changes.
|
|
30
|
-
- **Add thematic headings:** TODO: Break the narrative down into logical chapters using Markdown
|
|
31
|
-
- **
|
|
30
|
+
- **Add thematic headings:** TODO: Break the narrative down into logical chapters using action-oriented Markdown subheadings that describe what was improved/solved (e.g., ### Improving TabGroup Accessibility, ### Binding Dialog Colors to the Theme) rather than dry, generic headers like "Friction" or "The Fix".
|
|
31
|
+
- **Avoid forced bullet points:** TODO: Write in natural, flowing paragraphs (like in a dev blog post). Only use bullet points for actual, simple lists of items (e.g., list of modified files or configuration options), never to structure or split your main story thoughts.
|
|
32
32
|
- **Use bold emphasis:** TODO: Bold key concepts, problems, and solutions to guide the reader's eye.
|
|
33
33
|
- **Format code:** TODO: Use inline backticks for files, plugins, HTML elements, and code snippets (e.g., `src/lib/build-helpers.ts`).
|
|
34
|
-
- **Keep paragraphs short:** TODO: Ensure no paragraph is longer than
|
|
34
|
+
- **Keep paragraphs short:** TODO: Ensure no paragraph is longer than 4 sentences. Keep the pacing quick and engaging.
|
|
35
|
+
- **Weave the narrative:** TODO: Do not list all friction points in one massive block followed by all fixes/solutions in another. Instead, weave them together chronologically or by component/theme (e.g., describe the friction and its corresponding fix within the same chapter or paragraph).
|
|
35
36
|
- **Do not state the obvious**: TODO: Passed tests, lints, pre-commit suites are mandatory and no ticket is released without this. This does not need to be mentioned
|
package/dist/templates/log.md
CHANGED
package/dist/templates/steer.txt
CHANGED
|
@@ -33,9 +33,22 @@ You MUST log your work continuously using `logbook log "<message>"`. This is not
|
|
|
33
33
|
Phase 3: Synthesize
|
|
34
34
|
1. When implementation is finished, write the narrative in `index.md`.
|
|
35
35
|
2. Storytelling Mode: Explain the "Why" and the "Journey." Avoid simple technical bullet points.
|
|
36
|
+
- **Keep paragraphs short**: Max 4 sentences per paragraph to ensure fast-paced, readable prose.
|
|
37
|
+
- **Use bold & code formatting**: Use inline backticks for files/code, and bolding for key terms/problems.
|
|
38
|
+
- **Structure with H3 headings**: Use action-oriented subheadings describing the topic/component modified (e.g., ### Improving TabGroup Accessibility, ### Binding Dialog Colors to the Theme) instead of generic "Friction" or "Fix" headers.
|
|
39
|
+
- **Avoid forced lists**: Write in natural, flowing paragraphs. Only use bullet points for simple lists of items (e.g., files modified, options checked), never to split or structure your core narrative thoughts.
|
|
40
|
+
- **Weave friction & fix**: Do not separate all problems into one block and all solutions into another. Weave them together chronologically or group them by component/theme.
|
|
36
41
|
3. Clean up all template placeholders and complete the frontmatter (author, summary, dates).
|
|
37
42
|
|
|
38
43
|
Phase 4: Verify
|
|
39
44
|
1. Run `npm run pre` (which includes `logbook lint` and other quality gates).
|
|
40
45
|
2. Ensure there are no linter errors, unreplaced placeholders, or architectural violations before concluding your work.
|
|
41
|
-
3. Hand back to the prompter
|
|
46
|
+
3. Hand back to the prompter for local QA/review.
|
|
47
|
+
|
|
48
|
+
Phase 5: Local QA & Iterative Refinement
|
|
49
|
+
1. Expect feedback loops: The prompter will test your changes, challenge decisions, and request refinements.
|
|
50
|
+
2. In each iteration loop:
|
|
51
|
+
- Log decisions and pivots in `log.md` in real-time (`logbook log "<message>"`).
|
|
52
|
+
- Update the story in `index.md` to reflect any design/code changes.
|
|
53
|
+
- Run verification again (`npm run pre`).
|
|
54
|
+
3. Optimize the git commit message (conforming to project standards) before final release.
|
|
@@ -169,6 +169,38 @@ main {
|
|
|
169
169
|
transform: translateX(4px);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
.teaser-image-right {
|
|
173
|
+
flex-shrink: 0;
|
|
174
|
+
max-width: 200px;
|
|
175
|
+
max-height: 120px;
|
|
176
|
+
display: flex;
|
|
177
|
+
align-items: center;
|
|
178
|
+
justify-content: center;
|
|
179
|
+
overflow: hidden;
|
|
180
|
+
border-radius: 4px;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.teaser-image-right img {
|
|
184
|
+
max-width: 100%;
|
|
185
|
+
max-height: 100%;
|
|
186
|
+
object-fit: contain;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.teaser-image-bottom {
|
|
190
|
+
margin-top: 0.75rem;
|
|
191
|
+
display: flex;
|
|
192
|
+
justify-content: center;
|
|
193
|
+
align-items: center;
|
|
194
|
+
width: 100%;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.teaser-image-bottom img {
|
|
198
|
+
max-width: 100%;
|
|
199
|
+
max-height: 200px;
|
|
200
|
+
object-fit: contain;
|
|
201
|
+
border-radius: 4px;
|
|
202
|
+
}
|
|
203
|
+
|
|
172
204
|
/* Post Page */
|
|
173
205
|
.back-link {
|
|
174
206
|
display: inline-flex;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard-library CLI selection menu using Node's readline and raw mode.
|
|
3
|
+
* Moves cursor up/down, handles carriage return, Ctrl+C to abort, and hides the cursor.
|
|
4
|
+
* ponytail: simple raw-mode keyboard selection, no massive external prompt libraries.
|
|
5
|
+
*/
|
|
6
|
+
export declare function selectPrompt(message: string, choices: string[]): Promise<number>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import readline from 'node:readline';
|
|
2
|
+
/**
|
|
3
|
+
* Standard-library CLI selection menu using Node's readline and raw mode.
|
|
4
|
+
* Moves cursor up/down, handles carriage return, Ctrl+C to abort, and hides the cursor.
|
|
5
|
+
* ponytail: simple raw-mode keyboard selection, no massive external prompt libraries.
|
|
6
|
+
*/
|
|
7
|
+
export async function selectPrompt(message, choices) {
|
|
8
|
+
if (choices.length === 0) {
|
|
9
|
+
return -1;
|
|
10
|
+
}
|
|
11
|
+
const { stdin, stdout } = process;
|
|
12
|
+
// Non-interactive / non-TTY fallback to prevent hanging in CI/scripts
|
|
13
|
+
if (!stdin.isTTY) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
let index = 0;
|
|
18
|
+
const render = () => {
|
|
19
|
+
stdout.write('\r\x1B[K' + message + '\n');
|
|
20
|
+
choices.forEach((choice, i) => {
|
|
21
|
+
const prefix = i === index ? '> ' : ' ';
|
|
22
|
+
stdout.write('\x1B[K' + prefix + choice + '\n');
|
|
23
|
+
});
|
|
24
|
+
// Move cursor back up to the start of the list
|
|
25
|
+
stdout.write(`\x1B[${choices.length + 1}A`);
|
|
26
|
+
};
|
|
27
|
+
readline.emitKeypressEvents(stdin);
|
|
28
|
+
stdin.setRawMode(true);
|
|
29
|
+
stdout.write('\x1B[?25l'); // Hide cursor
|
|
30
|
+
render();
|
|
31
|
+
const onKey = (_str, key) => {
|
|
32
|
+
if (key.name === 'up') {
|
|
33
|
+
index = (index - 1 + choices.length) % choices.length;
|
|
34
|
+
render();
|
|
35
|
+
}
|
|
36
|
+
else if (key.name === 'down') {
|
|
37
|
+
index = (index + 1) % choices.length;
|
|
38
|
+
render();
|
|
39
|
+
}
|
|
40
|
+
else if (key.name === 'return') {
|
|
41
|
+
cleanup();
|
|
42
|
+
resolve(index);
|
|
43
|
+
}
|
|
44
|
+
else if (key.ctrl && key.name === 'c') {
|
|
45
|
+
cleanup();
|
|
46
|
+
process.exit(130); // 130 is standard SIGINT exit code
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const cleanup = () => {
|
|
50
|
+
// Move cursor down past choices and show cursor again
|
|
51
|
+
stdout.write(`\x1B[${choices.length + 1}B\x1B[?25h\r`);
|
|
52
|
+
stdin.removeListener('keypress', onKey);
|
|
53
|
+
stdin.setRawMode(false);
|
|
54
|
+
stdin.pause(); // ponytail: pause stdin so Node can exit instead of hanging
|
|
55
|
+
};
|
|
56
|
+
stdin.on('keypress', onKey);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,OAAiB;IACnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAElC,sEAAsE;IACtE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;YAC1C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBAC5B,MAAM,MAAM,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YACH,+CAA+C;YAC/C,MAAM,CAAC,KAAK,CAAC,QAAQ,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC;QAEF,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc;QACzC,MAAM,EAAE,CAAC;QAET,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,GAAsC,EAAE,EAAE;YACrE,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACtB,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;gBACtD,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC/B,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;gBACrC,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAmC;YACxD,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,sDAAsD;YACtD,MAAM,CAAC,KAAK,CAAC,QAAQ,OAAO,CAAC,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC;YACvD,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACxB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,4DAA4D;QAC7E,CAAC,CAAC;QAEF,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-logbook",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A command-line tool for project logbooks.",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"demo-app"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"madge": "madge --circular --extensions ts --ts-config ./tsconfig.json src/index.ts",
|
|
28
28
|
"jscpd": "jscpd src",
|
|
29
29
|
"test": "vitest run",
|
|
30
|
-
"pre": "npm run format && npm run lint && npm
|
|
30
|
+
"pre": "npm run format && npm run lint && npm run test && npm run build && npm run knip && npm run madge && npm run jscpd && npm run dev build && npm run dev lint && npm audit --audit-level=high",
|
|
31
31
|
"next": "node scripts/create-ticket-from-backlog.js",
|
|
32
32
|
"link": "npm run build && npm link",
|
|
33
33
|
"open": "npm run dev build && node scripts/open-and-view-dist.js"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@types/rss": "^0.0.32",
|
|
47
47
|
"@typescript-eslint/eslint-plugin": "^8.32.1",
|
|
48
48
|
"@typescript-eslint/parser": "^8.32.1",
|
|
49
|
-
"@vitest/coverage-v8": "^
|
|
49
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
50
50
|
"cross-env": "^7.0.3",
|
|
51
51
|
"eslint": "^9.27.0",
|
|
52
52
|
"jscpd": "^4.2.4",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"rimraf": "^6.1.3",
|
|
57
57
|
"tsx": "^4.21.0",
|
|
58
58
|
"typescript": "^6.0.3",
|
|
59
|
-
"vitest": "^
|
|
59
|
+
"vitest": "^4.1.8"
|
|
60
60
|
},
|
|
61
61
|
"overrides": {
|
|
62
62
|
"typescript": "^6.0.3"
|
|
@@ -65,7 +65,17 @@ Once the work is ready:
|
|
|
65
65
|
|
|
66
66
|
The linter enforces rules to be followed.
|
|
67
67
|
|
|
68
|
-
### 4.
|
|
68
|
+
### 4. Interactive Local QA Loop
|
|
69
|
+
Development is an iterative process. Expect to go through several feedback loops with the prompter before a ticket is finalized:
|
|
70
|
+
- **Test & Challenge**: The prompter will run and test your changes, challenge architectural patterns, and suggest revisions.
|
|
71
|
+
- **Cycle Routine**: During each feedback round:
|
|
72
|
+
1. Update code according to feedback.
|
|
73
|
+
2. Log key decisions, errors, and pivots in `log.md` (`logbook log "..."`).
|
|
74
|
+
3. Keep the story in `index.md` fully up-to-date with any design/code changes.
|
|
75
|
+
4. Run `npm run pre` to verify linting and tests pass.
|
|
76
|
+
- **Commit Optimization**: Once the implementation is solid, optimize the final git commit message to match project standards before releasing.
|
|
77
|
+
|
|
78
|
+
### 5. Final Review
|
|
69
79
|
Use the preview command to see how your entry looks in the context of the whole project:
|
|
70
80
|
```bash
|
|
71
81
|
logbook preview
|
|
@@ -84,4 +94,35 @@ If `jiraPrefix` is configured, entry folder names and ticket references must mat
|
|
|
84
94
|
## Tone & Style
|
|
85
95
|
- **Narrative over Lists**: In `index.md`, tell a story. Why did we make this change? What were the challenges?
|
|
86
96
|
- **Technical Precision**: In `log.md`, be specific. Mention file paths, error messages, and specific design patterns. Log in real time — do not reconstruct after the fact.
|
|
87
|
-
- **No Boilerplate in Commits**: All template placeholders must be replaced or removed before `logbook release`.
|
|
97
|
+
- **No Boilerplate in Commits**: All template placeholders must be replaced or removed before `logbook release`.
|
|
98
|
+
|
|
99
|
+
## Research Logs
|
|
100
|
+
For exploratory research, technical spike investigations, and architectural decision groundwork, we use **Research Logs**.
|
|
101
|
+
|
|
102
|
+
- **Required Setup**: Before creating your first research log, ensure that your configured research directory exists on your filesystem (for example, create it using `mkdir -p docs/research`).
|
|
103
|
+
- **Location**: Stored in `docs/research/` (configurable via `researchDir` in `.project-logbook`).
|
|
104
|
+
- **Scaffolding**: Run `logbook new [ID] [Slug] --research` or `logbook new -r` to scaffold. This automatically generates a numeric ID prefixed with `RES-` (e.g., `RES-1`).
|
|
105
|
+
- **Commands**: Commands like `logbook start RES-1`, `logbook log`, and `logbook release` work transparently.
|
|
106
|
+
- **Auto-Activity Tracking**: Writing a log message via `logbook log` automatically updates the `updated` frontmatter field inside the research log's `index.md`.
|
|
107
|
+
- **Status Lifecycle**: The frontmatter `status` field tracks progress: `active`, `paused`, `postponed`, or `completed`.
|
|
108
|
+
- **Visuals**: Research logs are compiled and displayed under a dedicated "Research" tab on the built logbook homepage, sorted by their latest `updated` date.
|
|
109
|
+
|
|
110
|
+
## Custom Storyline Types
|
|
111
|
+
Beyond standard logbook entries and Research Logs, you can define completely custom storyline types (e.g., "analyses", "spikes", "decisions") in `.project-logbook`.
|
|
112
|
+
|
|
113
|
+
- **Required Setup**: Define the custom types inside your `.project-logbook` configuration file under `customTypes` and ensure the directory exists on your filesystem:
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"customTypes": {
|
|
117
|
+
"analyses": {
|
|
118
|
+
"prefix": "ANA",
|
|
119
|
+
"dir": "docs/analyses",
|
|
120
|
+
"tabTitle": "Analyses",
|
|
121
|
+
"sortBy": "updated"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
- **Directory Setup**: Ensure the directory configured (e.g., `docs/analyses`) is created on your filesystem (for example, create it using `mkdir -p docs/analyses`).
|
|
127
|
+
- **Scaffolding**: Run `logbook new [ID] [Slug] --type analyses` or `logbook new -t analyses` to scaffold the entry.
|
|
128
|
+
- **Visuals**: Just like Research Logs, these custom types will automatically compile into dedicated tabs on the built logbook homepage using your specified `tabTitle`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: [ID_NUM]
|
|
3
|
+
title: [YAML_TITLE]
|
|
4
|
+
status: "proposed"
|
|
5
|
+
date: [DATE]
|
|
6
|
+
author: "[AUTHOR]"
|
|
7
|
+
superseded_by: null
|
|
8
|
+
tags: []
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ADR [ID]: [TITLE]
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
[Describe the issue motivating this decision and any context that influences it.]
|
|
15
|
+
|
|
16
|
+
## Considered Options
|
|
17
|
+
1. **[Option A]**: [Brief description.]
|
|
18
|
+
2. **[Option B]**: [Brief description.]
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
[State the decision and briefly explain what it means in practice.]
|
|
22
|
+
|
|
23
|
+
## Rationale
|
|
24
|
+
[Explain why this option was chosen over the alternatives.]
|
|
25
|
+
|
|
26
|
+
## Consequences
|
|
27
|
+
|
|
28
|
+
### Positive
|
|
29
|
+
* [Benefit 1]
|
|
30
|
+
* [Benefit 2]
|
|
31
|
+
|
|
32
|
+
### Negative
|
|
33
|
+
* [Drawback 1]
|
|
34
|
+
* [Drawback 2]
|