project-logbook 0.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 +34 -0
- package/dist/commands/build.d.ts +1 -0
- package/dist/commands/build.js +174 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +83 -0
- package/dist/commands/lint.d.ts +1 -0
- package/dist/commands/lint.js +78 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.js +127 -0
- package/dist/commands/log.d.ts +3 -0
- package/dist/commands/log.js +31 -0
- package/dist/commands/new.d.ts +1 -0
- package/dist/commands/new.js +135 -0
- package/dist/commands/preview.d.ts +1 -0
- package/dist/commands/preview.js +19 -0
- package/dist/commands/release.d.ts +3 -0
- package/dist/commands/release.js +66 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/commands/start.js +87 -0
- package/dist/commands/steer.d.ts +1 -0
- package/dist/commands/steer.js +22 -0
- package/dist/commands/upgrade.d.ts +1 -0
- package/dist/commands/upgrade.js +23 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +92 -0
- package/dist/lib/about-content.d.ts +1 -0
- package/dist/lib/about-content.js +7 -0
- package/dist/lib/build-helpers.d.ts +15 -0
- package/dist/lib/build-helpers.js +171 -0
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.js +41 -0
- package/dist/lib/git-helpers.d.ts +16 -0
- package/dist/lib/git-helpers.js +93 -0
- package/dist/lib/image-helpers.d.ts +19 -0
- package/dist/lib/image-helpers.js +121 -0
- package/dist/lib/jira-helpers.d.ts +5 -0
- package/dist/lib/jira-helpers.js +5 -0
- package/dist/lib/lint-runner.d.ts +2 -0
- package/dist/lib/lint-runner.js +31 -0
- package/dist/lib/lint-types.d.ts +24 -0
- package/dist/lib/lint-types.js +1 -0
- package/dist/lib/lockfile.d.ts +6 -0
- package/dist/lib/lockfile.js +1 -0
- package/dist/lib/logbook-client.d.ts +5 -0
- package/dist/lib/logbook-client.js +11 -0
- package/dist/lib/migrations.d.ts +11 -0
- package/dist/lib/migrations.js +34 -0
- package/dist/lib/session.d.ts +16 -0
- package/dist/lib/session.js +74 -0
- package/dist/lib/styles.d.ts +1 -0
- package/dist/lib/styles.js +21 -0
- package/dist/lib/template-types.d.ts +118 -0
- package/dist/lib/template-types.js +1 -0
- package/dist/lib/templates.d.ts +14 -0
- package/dist/lib/templates.js +158 -0
- package/dist/linters/frontmatter.d.ts +3 -0
- package/dist/linters/frontmatter.js +68 -0
- package/dist/linters/index.d.ts +1 -0
- package/dist/linters/index.js +18 -0
- package/dist/linters/jira-prefix.d.ts +3 -0
- package/dist/linters/jira-prefix.js +34 -0
- package/dist/linters/links.d.ts +3 -0
- package/dist/linters/links.js +28 -0
- package/dist/linters/lockfile.d.ts +3 -0
- package/dist/linters/lockfile.js +20 -0
- package/dist/linters/placeholders.d.ts +3 -0
- package/dist/linters/placeholders.js +62 -0
- package/dist/linters/project-integrity.d.ts +3 -0
- package/dist/linters/project-integrity.js +29 -0
- package/dist/linters/readability.d.ts +3 -0
- package/dist/linters/readability.js +41 -0
- package/dist/linters/workspaces.d.ts +3 -0
- package/dist/linters/workspaces.js +26 -0
- package/dist/templates/ABOUT.md +23 -0
- package/dist/templates/CONTRIBUTING.md +78 -0
- package/dist/templates/favicon.svg +21 -0
- package/dist/templates/index.md +30 -0
- package/dist/templates/log.md +4 -0
- package/dist/templates/logbook-client.js +162 -0
- package/dist/templates/steer.txt +25 -0
- package/dist/templates/styles.css +641 -0
- package/dist/templates/ticket.md +4 -0
- package/dist/utils/date.d.ts +8 -0
- package/dist/utils/date.js +47 -0
- package/dist/utils/fs.d.ts +13 -0
- package/dist/utils/fs.js +38 -0
- package/dist/utils/id.d.ts +7 -0
- package/dist/utils/id.js +36 -0
- package/dist/utils/slug.d.ts +2 -0
- package/dist/utils/slug.js +9 -0
- package/dist/utils/string.d.ts +2 -0
- package/dist/utils/string.js +4 -0
- package/package.json +69 -0
- package/src/templates/ABOUT.md +23 -0
- package/src/templates/CONTRIBUTING.md +78 -0
- package/src/templates/favicon.svg +21 -0
- package/src/templates/index.md +30 -0
- package/src/templates/log.md +4 -0
- package/src/templates/logbook-client.js +162 -0
- package/src/templates/steer.txt +25 -0
- package/src/templates/styles.css +641 -0
- package/src/templates/ticket.md +4 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getWorkspaces } from '../lib/config.js';
|
|
2
|
+
const linter = {
|
|
3
|
+
name: 'workspaces',
|
|
4
|
+
description: 'Validates workspaces field against package.json',
|
|
5
|
+
async check(context) {
|
|
6
|
+
if (!context.entryName || !context.frontmatter)
|
|
7
|
+
return [];
|
|
8
|
+
const { frontmatter } = context;
|
|
9
|
+
if (frontmatter.workspaces === undefined)
|
|
10
|
+
return [];
|
|
11
|
+
const issues = [];
|
|
12
|
+
const availableWorkspaces = getWorkspaces();
|
|
13
|
+
const entryWorkspaces = Array.isArray(frontmatter.workspaces) ? frontmatter.workspaces : [];
|
|
14
|
+
for (const ws of entryWorkspaces) {
|
|
15
|
+
if (!availableWorkspaces.includes(ws)) {
|
|
16
|
+
issues.push({
|
|
17
|
+
level: 'error',
|
|
18
|
+
category: 'workspace',
|
|
19
|
+
message: `Invalid workspace '${ws}'. Available workspaces: ${availableWorkspaces.join(', ')}`,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return issues;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export default linter;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# About this Logbook
|
|
2
|
+
|
|
3
|
+
This is a **Project Logbook** — a living documentation approach that tracks project evolution through ticket-based entries.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
Traditional project documentation often becomes stale quickly. Decisions get lost, the rationale behind changes remains undocumented, and onboarding new team members becomes challenging.
|
|
8
|
+
|
|
9
|
+
## The Solution
|
|
10
|
+
|
|
11
|
+
The Project Logbook captures every significant change as a structured entry containing:
|
|
12
|
+
|
|
13
|
+
- **Ticket**: Requirements and acceptance criteria
|
|
14
|
+
- **Technical Log**: Real-time implementation notes and decisions
|
|
15
|
+
- **Narrative**: A polished story explaining the why and how
|
|
16
|
+
|
|
17
|
+
## How It Works
|
|
18
|
+
|
|
19
|
+
Each entry in this logbook represents a discrete piece of work, documented using the same tool that generated this website. The timeline presents these entries as "news items", creating a narrative history of the project.
|
|
20
|
+
|
|
21
|
+
## Dogfooding
|
|
22
|
+
|
|
23
|
+
This website itself is built using the logbook tool it documents. Every feature added to this CLI is first documented as a logbook entry, demonstrating the tool's capabilities in real-time.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Contributing to Project Logbook
|
|
2
|
+
|
|
3
|
+
This project follows a strict **Agentic Documentation Workflow**. Whether you are a human or an AI agent, please adhere to the following protocol to ensure the history of this project remains professional, readable, and technically traceable.
|
|
4
|
+
|
|
5
|
+
## The Three-File Standard
|
|
6
|
+
Every change must be documented in a dedicated folder within `logbook/` using three files:
|
|
7
|
+
|
|
8
|
+
1. **`ticket.md`**: The source of truth. Contains the requirements, background, and acceptance criteria.
|
|
9
|
+
2. **`log.md`**: The chronological scratchpad. A real-time trace of technical decisions, pivots, and obstacles.
|
|
10
|
+
3. **`index.md`**: The narrative. A polished, high-level "story" of the change for stakeholders and future developers.
|
|
11
|
+
|
|
12
|
+
## Working Protocol
|
|
13
|
+
|
|
14
|
+
### 1. Inception
|
|
15
|
+
Always start by creating and activating a new entry:
|
|
16
|
+
```bash
|
|
17
|
+
logbook new [ID] [Slug]
|
|
18
|
+
logbook start [ID]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The `new` command accepts optional parameters. When invoked without arguments, it enters interactive mode:
|
|
22
|
+
- If `jiraPrefix` is configured, suggests the next ID with that prefix (e.g., LB-14)
|
|
23
|
+
- Prompts for title, auto-converts to slug
|
|
24
|
+
|
|
25
|
+
`logbook start` looks up the entry folder by ID prefix, so `logbook start LB-5` resolves to `LB-5-jira-support` automatically.
|
|
26
|
+
|
|
27
|
+
`logbook start` writes a `.logbook-active` JSON lockfile to ensure only one entry is worked on at a time. It also automatically records the current git user as the `prompter` in the `index.md` frontmatter — useful for tracking which human directed or reviewed an AI-assisted session.
|
|
28
|
+
|
|
29
|
+
Fill the `ticket.md` immediately so the context is anchored before you start coding. Optionally run:
|
|
30
|
+
```bash
|
|
31
|
+
logbook steer
|
|
32
|
+
```
|
|
33
|
+
to receive strategic guidance for the active entry based on the ticket content.
|
|
34
|
+
|
|
35
|
+
### 2. Execution
|
|
36
|
+
As you code, keep the `log.md` updated in real-time using the `logbook log` command. Do not wait until the end.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
logbook log "Investigated root cause — found issue in src/lib/config.ts"
|
|
40
|
+
logbook log "Fixed the bug" "Added tests" "All passing"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Each message is automatically prefixed with an ISO timestamp and appended as a bullet to the active `log.md`. You may pass multiple quoted strings in one call. If you encounter a bug or change your design, log it immediately. This is the most valuable file for future debugging.
|
|
44
|
+
|
|
45
|
+
Only update the currently active logbook entry. Do not edit other existing entries while working.
|
|
46
|
+
|
|
47
|
+
When you finish writing `index.md`, **remove the boilerplate link line** that the template inserts:
|
|
48
|
+
|
|
49
|
+
### 3. Quality Assurance
|
|
50
|
+
Before submitting your work, you MUST release the active entry and run the linter:
|
|
51
|
+
```bash
|
|
52
|
+
logbook release
|
|
53
|
+
logbook lint
|
|
54
|
+
```
|
|
55
|
+
`logbook release` removes the `.logbook-active` lockfile. The linter will fail if the lockfile is still present, enforcing that no entry is left dangling in a committed state.
|
|
56
|
+
|
|
57
|
+
The linter enforces rules to be followed.
|
|
58
|
+
|
|
59
|
+
### 4. Final Review
|
|
60
|
+
Use the preview command to see how your entry looks in the context of the whole project:
|
|
61
|
+
```bash
|
|
62
|
+
logbook preview
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## The `prompter` Field
|
|
66
|
+
|
|
67
|
+
The optional `prompter` frontmatter field in `index.md` records the human who directed, reviewed, or collaborated on a session — distinct from the AI `author`. It is set automatically by `logbook start` from the git `user.name` and injected into `index.md`. In fully automated pipelines without a human prompter, it may be omitted.
|
|
68
|
+
|
|
69
|
+
## Jira Integration
|
|
70
|
+
|
|
71
|
+
If the project has a `jiraBaseUrl` set in `.project-logbook`, the `ticket` field in `index.md` frontmatter is used to generate a direct link to the Jira issue in the built website. Ensure `ticket` is set correctly (e.g. `LB-5`) for every entry.
|
|
72
|
+
|
|
73
|
+
If `jiraPrefix` is configured, entry folder names and ticket references must match the prefix pattern.
|
|
74
|
+
|
|
75
|
+
## Tone & Style
|
|
76
|
+
- **Narrative over Lists**: In `index.md`, tell a story. Why did we make this change? What were the challenges?
|
|
77
|
+
- **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.
|
|
78
|
+
- **No Boilerplate in Commits**: All template placeholders must be replaced or removed before `logbook release`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<style>
|
|
3
|
+
.logo-path {
|
|
4
|
+
fill: white;
|
|
5
|
+
stroke: black;
|
|
6
|
+
stroke-width: 3;
|
|
7
|
+
stroke-linejoin: round;
|
|
8
|
+
stroke-linecap: round;
|
|
9
|
+
}
|
|
10
|
+
</style>
|
|
11
|
+
|
|
12
|
+
<!-- Letter 'L' -->
|
|
13
|
+
<path class="logo-path" d="M 5 20 v 60 h 22 v -10 h -12 v -50 z" />
|
|
14
|
+
|
|
15
|
+
<!-- Letter 'O' -->
|
|
16
|
+
<path class="logo-path" fill-rule="evenodd" d="M 33 20 v 60 h 28 v -60 z M 43 30 v 40 h 8 v -40 z" />
|
|
17
|
+
|
|
18
|
+
<!-- Letter 'G' -->
|
|
19
|
+
<path class="logo-path"
|
|
20
|
+
d="M 67 20 v 60 h 28 v -30 h -12 v 10 h 2 v 10 h -8 v -40 h 8 v 5 h 10 v -15 z" />
|
|
21
|
+
</svg>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
# The ticket field should match the ID portion (e.g., LB-34)
|
|
3
|
+
ticket: {{id}}
|
|
4
|
+
# The title should be a human-readable description of the work
|
|
5
|
+
title: {{title}}
|
|
6
|
+
prompter: [PROMPTER]
|
|
7
|
+
harness: [HARNESS]
|
|
8
|
+
llm: [LLM]
|
|
9
|
+
summary: [WRITE_SUMMARY_HERE]
|
|
10
|
+
# Tags for categorizing the change (must be from allowed list in .project-logbook)
|
|
11
|
+
tags: []
|
|
12
|
+
# Workspace(s) this change affects (must match package.json workspaces; leave empty for single-project)
|
|
13
|
+
# Example: workspaces: ["frontend", "shared"]
|
|
14
|
+
workspaces: []
|
|
15
|
+
# Set automatically by `logbook start`
|
|
16
|
+
dateStart: [DATE_START]
|
|
17
|
+
# Set automatically by `logbook release`
|
|
18
|
+
dateEnd: [DATE_END]
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Summary
|
|
22
|
+
TODO: Write a polished, highly readable ticket summary that reads like an engaging technical narrative (similar to a well-written dev blog post).
|
|
23
|
+
|
|
24
|
+
### Formatting & Style Rules:
|
|
25
|
+
- **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.
|
|
26
|
+
- **Add thematic headings:** TODO: Break the narrative down into logical chapters using Markdown headings (e.g., ### The Friction Points, ### The Fix, ### Closing the Gap).
|
|
27
|
+
- **Use bullet points:** TODO: Whenever listing multiple items (like friction points, test scenarios, or rewritten paths), use a bulleted list instead of a dense paragraph to make it scannable.
|
|
28
|
+
- **Use bold emphasis:** TODO: Bold key concepts, problems, and solutions to guide the reader's eye.
|
|
29
|
+
- **Format code:** TODO: Use inline backticks for files, plugins, HTML elements, and code snippets (e.g., `src/lib/build-helpers.ts`).
|
|
30
|
+
- **Keep paragraphs short:** TODO: Ensure no paragraph is longer than 3-4 sentences. Keep the pacing quick and engaging.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/* ── 1. Real-time relative dates ──────────────────────────────────────── */
|
|
5
|
+
function relativeDate(isoString) {
|
|
6
|
+
var d = new Date(isoString);
|
|
7
|
+
var now = new Date();
|
|
8
|
+
// Normalise both to midnight local time for day-diff calculation
|
|
9
|
+
var dDay = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
10
|
+
var nDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
11
|
+
var diffDays = Math.round((nDay - dDay) / 86400000);
|
|
12
|
+
|
|
13
|
+
var relative;
|
|
14
|
+
if (diffDays === 0) relative = 'today';
|
|
15
|
+
else if (diffDays === 1) relative = 'yesterday';
|
|
16
|
+
else if (diffDays < 7) relative = diffDays + ' days ago';
|
|
17
|
+
else if (diffDays < 14) relative = '1 week ago';
|
|
18
|
+
else if (diffDays < 30) relative = Math.floor(diffDays / 7) + ' weeks ago';
|
|
19
|
+
else if (diffDays < 60) relative = '1 month ago';
|
|
20
|
+
else if (diffDays < 365) relative = Math.floor(diffDays / 30) + ' months ago';
|
|
21
|
+
else if (diffDays < 730) relative = '1 year ago';
|
|
22
|
+
else relative = Math.floor(diffDays / 365) + ' years ago';
|
|
23
|
+
|
|
24
|
+
var absolute = d.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
|
|
25
|
+
return relative + ', ' + absolute;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function updateRelativeDates() {
|
|
29
|
+
var els = document.querySelectorAll('[data-date]');
|
|
30
|
+
for (var i = 0; i < els.length; i++) {
|
|
31
|
+
var el = els[i];
|
|
32
|
+
var iso = el.getAttribute('data-date');
|
|
33
|
+
if (iso) el.textContent = relativeDate(iso);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ── 2. localStorage-based "NEW" indicator ─────────────────────────────── */
|
|
38
|
+
var STORAGE_KEY = 'logbook_visited';
|
|
39
|
+
|
|
40
|
+
function getVisited() {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function markVisited(slug) {
|
|
49
|
+
try {
|
|
50
|
+
var visited = getVisited();
|
|
51
|
+
if (visited.indexOf(slug) === -1) {
|
|
52
|
+
visited.push(slug);
|
|
53
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(visited));
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
/* localStorage unavailable */
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function applyNewBadges() {
|
|
61
|
+
var visited = getVisited();
|
|
62
|
+
var items = document.querySelectorAll('[data-entry-slug]');
|
|
63
|
+
for (var i = 0; i < items.length; i++) {
|
|
64
|
+
var item = items[i];
|
|
65
|
+
var slug = item.getAttribute('data-entry-slug');
|
|
66
|
+
if (slug && visited.indexOf(slug) === -1) {
|
|
67
|
+
var badge = item.querySelector('.new-badge');
|
|
68
|
+
if (badge) badge.style.display = 'inline-block';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* ── 3. Tab switching functionality ────────────────────────────────────── */
|
|
74
|
+
function showTab(event, id) {
|
|
75
|
+
var eventTarget = event.currentTarget;
|
|
76
|
+
if (!eventTarget) return;
|
|
77
|
+
|
|
78
|
+
// Find the tabs-wrapper container that scopes this tab group
|
|
79
|
+
var wrapper = eventTarget.closest('.tabs-wrapper');
|
|
80
|
+
if (!wrapper) return;
|
|
81
|
+
|
|
82
|
+
// Hide all content sections within this wrapper only
|
|
83
|
+
var contentSections = wrapper.querySelectorAll('.content-section');
|
|
84
|
+
for (var i = 0; i < contentSections.length; i++) {
|
|
85
|
+
contentSections[i].style.display = 'none';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Deactivate all tabs within this wrapper only
|
|
89
|
+
var tabs = wrapper.querySelectorAll('.tab');
|
|
90
|
+
for (var i = 0; i < tabs.length; i++) {
|
|
91
|
+
tabs[i].classList.remove('active');
|
|
92
|
+
tabs[i].setAttribute('aria-selected', 'false');
|
|
93
|
+
tabs[i].setAttribute('tabindex', '-1');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Activate selected tab and content
|
|
97
|
+
var targetContent = document.getElementById(id);
|
|
98
|
+
if (targetContent) {
|
|
99
|
+
targetContent.style.display = 'block';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Find and activate the clicked tab
|
|
103
|
+
var clickedTab = null;
|
|
104
|
+
for (var i = 0; i < tabs.length; i++) {
|
|
105
|
+
if (tabs[i].getAttribute('aria-controls') === id) {
|
|
106
|
+
clickedTab = tabs[i];
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (clickedTab) {
|
|
111
|
+
clickedTab.classList.add('active');
|
|
112
|
+
clickedTab.setAttribute('aria-selected', 'true');
|
|
113
|
+
clickedTab.setAttribute('tabindex', '0');
|
|
114
|
+
clickedTab.focus();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function initTabs() {
|
|
119
|
+
var tabLists = document.querySelectorAll('[role="tablist"]');
|
|
120
|
+
for (var i = 0; i < tabLists.length; i++) {
|
|
121
|
+
var tabList = tabLists[i];
|
|
122
|
+
|
|
123
|
+
// Add keyboard navigation
|
|
124
|
+
tabList.addEventListener('keydown', function (event) {
|
|
125
|
+
var tabs = Array.from(this.querySelectorAll('.tab'));
|
|
126
|
+
var current = tabs.findIndex(function (t) {
|
|
127
|
+
return t.getAttribute('aria-selected') === 'true';
|
|
128
|
+
});
|
|
129
|
+
var next = -1;
|
|
130
|
+
|
|
131
|
+
if (event.key === 'ArrowRight') {
|
|
132
|
+
next = (current + 1) % tabs.length;
|
|
133
|
+
} else if (event.key === 'ArrowLeft') {
|
|
134
|
+
next = (current - 1 + tabs.length) % tabs.length;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (next !== -1) {
|
|
138
|
+
event.preventDefault();
|
|
139
|
+
tabs[next].click();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* ── Bootstrap ─────────────────────────────────────────────────────────── */
|
|
146
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
147
|
+
updateRelativeDates();
|
|
148
|
+
|
|
149
|
+
// On post pages: mark this entry as visited
|
|
150
|
+
var pageSlug = document.body.getAttribute('data-page-slug');
|
|
151
|
+
if (pageSlug) markVisited(pageSlug);
|
|
152
|
+
|
|
153
|
+
// On the timeline: apply NEW badges
|
|
154
|
+
applyNewBadges();
|
|
155
|
+
|
|
156
|
+
// Initialize tab functionality
|
|
157
|
+
initTabs();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Expose showTab globally for onclick handlers
|
|
161
|
+
window.showTab = showTab;
|
|
162
|
+
})();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
PROJECT LOGBOOK: AI AGENT STEERING PROTOCOL
|
|
2
|
+
|
|
3
|
+
The human prompter has already initialized and activated the current logbook entry.
|
|
4
|
+
Do NOT run `logbook new` or `logbook release` — these are prompter responsibilities.
|
|
5
|
+
|
|
6
|
+
Phase 1: Understand
|
|
7
|
+
1. Read `ticket.md` in the active entry. This is your source of truth for requirements.
|
|
8
|
+
2. Review `AGENTS.md` and `CONTRIBUTING.md` if you need architectural or workflow context.
|
|
9
|
+
|
|
10
|
+
Phase 2: Execute & Trace
|
|
11
|
+
1. Use `log.md` as a live technical scratchpad.
|
|
12
|
+
2. Log your work in real-time using the `logbook log "<message>"` command. Record every major decision, error, and pivot. Do not reconstruct this at the end.
|
|
13
|
+
Example: logbook log "Investigated root cause — found issue in src/lib/config.ts"
|
|
14
|
+
3. You may pass multiple messages in one call: logbook log "Msg A" "Msg B"
|
|
15
|
+
4. Stick to the active entry; never modify past entries in the logbook folder.
|
|
16
|
+
|
|
17
|
+
Phase 3: Synthesize
|
|
18
|
+
1. When implementation is finished, write the narrative in `index.md`.
|
|
19
|
+
2. Storytelling Mode: Explain the "Why" and the "Journey." Avoid simple technical bullet points.
|
|
20
|
+
3. Clean up all template placeholders and complete the frontmatter (author, summary, dates).
|
|
21
|
+
|
|
22
|
+
Phase 4: Verify
|
|
23
|
+
1. Run `npm run pre` (which includes `logbook lint` and other quality gates).
|
|
24
|
+
2. Ensure there are no linter errors, unreplaced placeholders, or architectural violations before concluding your work.
|
|
25
|
+
3. Hand back to the prompter, who will review and run `logbook release`.
|