ithos 0.1.3 → 0.1.4
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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +89 -2
- package/package.json +1 -1
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,SAAS,IAAI,OAAO,CAkInC"}
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { doctorRepository, exportMemory, initRepository, isArtifactType, recordArtifact, searchMemory, validateRepository } from "ithos-core";
|
|
2
|
+
import { doctorRepository, exportMemory, generateTimeline, initRepository, isArtifactType, recordArtifact, searchMemory, validateRepository } from "ithos-core";
|
|
3
3
|
export function createCli() {
|
|
4
4
|
const program = new Command();
|
|
5
5
|
program
|
|
6
6
|
.name("ithos")
|
|
7
7
|
.description("Local-first engineering memory")
|
|
8
|
-
.version("0.1.
|
|
8
|
+
.version("0.1.4");
|
|
9
9
|
program
|
|
10
10
|
.command("init")
|
|
11
11
|
.description("Initialize Ithos memory in the current repository")
|
|
@@ -92,6 +92,13 @@ export function createCli() {
|
|
|
92
92
|
const result = await exportMemory();
|
|
93
93
|
process.stdout.write(result.markdown);
|
|
94
94
|
});
|
|
95
|
+
program
|
|
96
|
+
.command("timeline")
|
|
97
|
+
.description("Show a chronological timeline of engineering memory")
|
|
98
|
+
.action(async () => {
|
|
99
|
+
const result = await generateTimeline();
|
|
100
|
+
renderTimeline(result);
|
|
101
|
+
});
|
|
95
102
|
return program;
|
|
96
103
|
}
|
|
97
104
|
function printList(label, values) {
|
|
@@ -108,3 +115,83 @@ async function readStdin() {
|
|
|
108
115
|
}
|
|
109
116
|
return Buffer.concat(chunks).toString("utf8");
|
|
110
117
|
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Timeline renderer
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Raw ANSI codes — no runtime dependency needed.
|
|
122
|
+
const ANSI = {
|
|
123
|
+
reset: "\x1b[0m",
|
|
124
|
+
bold: "\x1b[1m",
|
|
125
|
+
dim: "\x1b[2m",
|
|
126
|
+
cyan: "\x1b[36m",
|
|
127
|
+
blue: "\x1b[34m",
|
|
128
|
+
yellow: "\x1b[33m",
|
|
129
|
+
red: "\x1b[31m",
|
|
130
|
+
green: "\x1b[32m",
|
|
131
|
+
magenta: "\x1b[35m",
|
|
132
|
+
white: "\x1b[37m"
|
|
133
|
+
};
|
|
134
|
+
const TYPE_META = {
|
|
135
|
+
decisions: { icon: "\uD83D\uDCCC", color: "cyan", label: "Decision" },
|
|
136
|
+
sessions: { icon: "\uD83E\uDDE0", color: "blue", label: "Session" },
|
|
137
|
+
lessons: { icon: "\uD83D\uDCA1", color: "yellow", label: "Lesson" },
|
|
138
|
+
regressions: { icon: "\u26A0\uFE0F", color: "red", label: "Regression" },
|
|
139
|
+
defects: { icon: "\uD83D\uDC1B", color: "red", label: "Defect" },
|
|
140
|
+
architecture: { icon: "\uD83C\uDFDB\uFE0F", color: "magenta", label: "Architecture" },
|
|
141
|
+
features: { icon: "\u2728", color: "green", label: "Feature" },
|
|
142
|
+
patterns: { icon: "\uD83D\uDD01", color: "white", label: "Pattern" },
|
|
143
|
+
releases: { icon: "\uD83D\uDE80", color: "green", label: "Release" },
|
|
144
|
+
gaps: { icon: "\uD83D\uDD73\uFE0F", color: "yellow", label: "Gap" }
|
|
145
|
+
};
|
|
146
|
+
const SEPARATOR = ANSI.dim + "\u2500".repeat(52) + ANSI.reset;
|
|
147
|
+
function c(color, text) {
|
|
148
|
+
return `${ANSI[color]}${text}${ANSI.reset}`;
|
|
149
|
+
}
|
|
150
|
+
function renderEntry(entry) {
|
|
151
|
+
const meta = TYPE_META[entry.type] ?? {
|
|
152
|
+
icon: "\uD83D\uDCCB",
|
|
153
|
+
color: "white",
|
|
154
|
+
label: entry.type
|
|
155
|
+
};
|
|
156
|
+
const label = meta.label.padEnd(13);
|
|
157
|
+
const header = ` ${meta.icon} ${c(meta.color, ANSI.bold + label + ANSI.reset + ANSI[meta.color])}${entry.title}${ANSI.reset}`;
|
|
158
|
+
console.log(header);
|
|
159
|
+
for (const line of entry.summary) {
|
|
160
|
+
console.log(` ${ANSI.dim}\u2192 ${line}${ANSI.reset}`);
|
|
161
|
+
}
|
|
162
|
+
console.log(` ${ANSI.dim}\u21B3 ${entry.file}${ANSI.reset}`);
|
|
163
|
+
}
|
|
164
|
+
function renderTimeline(result) {
|
|
165
|
+
if (result.totalCount === 0) {
|
|
166
|
+
console.log(c("dim", "No engineering memory found. Run \`ithos record\` to capture your first artifact."));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const dates = [...result.groupedByDate.keys()];
|
|
170
|
+
console.log("");
|
|
171
|
+
dates.forEach((date, dateIndex) => {
|
|
172
|
+
const entries = result.groupedByDate.get(date);
|
|
173
|
+
// Date header
|
|
174
|
+
console.log(ANSI.bold + date + ANSI.reset);
|
|
175
|
+
console.log("");
|
|
176
|
+
entries.forEach((entry, entryIndex) => {
|
|
177
|
+
renderEntry(entry);
|
|
178
|
+
// Blank line between entries on the same date
|
|
179
|
+
if (entryIndex < entries.length - 1)
|
|
180
|
+
console.log("");
|
|
181
|
+
});
|
|
182
|
+
console.log("");
|
|
183
|
+
// Separator between date groups (not after the last one)
|
|
184
|
+
if (dateIndex < dates.length - 1) {
|
|
185
|
+
console.log(SEPARATOR);
|
|
186
|
+
console.log("");
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// Footer
|
|
190
|
+
const dayCount = dates.length;
|
|
191
|
+
const entryWord = result.totalCount === 1 ? "entry" : "entries";
|
|
192
|
+
const dayWord = dayCount === 1 ? "day" : "days";
|
|
193
|
+
console.log(ANSI.dim +
|
|
194
|
+
` ${result.totalCount} ${entryWord} across ${dayCount} ${dayWord}` +
|
|
195
|
+
ANSI.reset);
|
|
196
|
+
console.log("");
|
|
197
|
+
}
|