heyiam 0.1.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.
Files changed (60) hide show
  1. package/app/dist/assets/index-BGQkmy7q.css +1 -0
  2. package/app/dist/assets/index-CbLHxerW.js +14 -0
  3. package/app/dist/favicon.svg +1 -0
  4. package/app/dist/icons.svg +24 -0
  5. package/app/dist/index.html +20 -0
  6. package/dist/analyzer.d.ts +96 -0
  7. package/dist/analyzer.js +249 -0
  8. package/dist/analyzer.js.map +1 -0
  9. package/dist/auth.d.ts +34 -0
  10. package/dist/auth.js +99 -0
  11. package/dist/auth.js.map +1 -0
  12. package/dist/bridge.d.ts +32 -0
  13. package/dist/bridge.js +211 -0
  14. package/dist/bridge.js.map +1 -0
  15. package/dist/config.d.ts +4 -0
  16. package/dist/config.js +5 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/index.d.ts +4 -0
  19. package/dist/index.js +129 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/llm/anthropic-provider.d.ts +11 -0
  22. package/dist/llm/anthropic-provider.js +16 -0
  23. package/dist/llm/anthropic-provider.js.map +1 -0
  24. package/dist/llm/index.d.ts +16 -0
  25. package/dist/llm/index.js +25 -0
  26. package/dist/llm/index.js.map +1 -0
  27. package/dist/llm/project-enhance.d.ts +71 -0
  28. package/dist/llm/project-enhance.js +236 -0
  29. package/dist/llm/project-enhance.js.map +1 -0
  30. package/dist/llm/proxy-provider.d.ts +16 -0
  31. package/dist/llm/proxy-provider.js +60 -0
  32. package/dist/llm/proxy-provider.js.map +1 -0
  33. package/dist/llm/triage.d.ts +66 -0
  34. package/dist/llm/triage.js +283 -0
  35. package/dist/llm/triage.js.map +1 -0
  36. package/dist/llm/types.d.ts +19 -0
  37. package/dist/llm/types.js +2 -0
  38. package/dist/llm/types.js.map +1 -0
  39. package/dist/machine-key.d.ts +10 -0
  40. package/dist/machine-key.js +51 -0
  41. package/dist/machine-key.js.map +1 -0
  42. package/dist/parsers/claude.d.ts +18 -0
  43. package/dist/parsers/claude.js +265 -0
  44. package/dist/parsers/claude.js.map +1 -0
  45. package/dist/parsers/index.d.ts +28 -0
  46. package/dist/parsers/index.js +124 -0
  47. package/dist/parsers/index.js.map +1 -0
  48. package/dist/parsers/types.d.ts +81 -0
  49. package/dist/parsers/types.js +2 -0
  50. package/dist/parsers/types.js.map +1 -0
  51. package/dist/server.d.ts +3 -0
  52. package/dist/server.js +857 -0
  53. package/dist/server.js.map +1 -0
  54. package/dist/settings.d.ts +92 -0
  55. package/dist/settings.js +160 -0
  56. package/dist/settings.js.map +1 -0
  57. package/dist/summarize.d.ts +72 -0
  58. package/dist/summarize.js +312 -0
  59. package/dist/summarize.js.map +1 -0
  60. package/package.json +47 -0
package/dist/bridge.js ADDED
@@ -0,0 +1,211 @@
1
+ // Bridge — converts parser output (SessionAnalysis from parsers/types.ts)
2
+ // into the analyzer's input format (SessionAnalysis from analyzer.ts)
3
+ import { analyzeSession } from "./analyzer.js";
4
+ import { parseSession } from "./parsers/index.js";
5
+ export function bridgeToAnalyzer(parsed, opts) {
6
+ const turns = entriesToTurns(parsed.raw_entries);
7
+ const filesChanged = computePerFileChanges(parsed.tool_calls);
8
+ const title = extractTitle(parsed.raw_entries);
9
+ const rawLog = extractRawLog(parsed.raw_entries);
10
+ const wallClockMinutes = parsed.wall_clock_ms > 0
11
+ ? Math.max(1, Math.round(parsed.wall_clock_ms / 60_000))
12
+ : undefined;
13
+ return {
14
+ id: opts.sessionId,
15
+ title,
16
+ date: parsed.start_time ?? new Date().toISOString(),
17
+ ...(parsed.end_time ? { endTime: parsed.end_time } : {}),
18
+ durationMinutes: parsed.duration_ms > 0
19
+ ? Math.max(1, Math.round(parsed.duration_ms / 60_000))
20
+ : 0,
21
+ ...(wallClockMinutes != null ? { wallClockMinutes } : {}),
22
+ projectName: opts.projectName,
23
+ turns,
24
+ filesChanged,
25
+ rawLog,
26
+ ...(parsed.cwd ? { cwd: parsed.cwd } : {}),
27
+ ...(opts.agentRole ? { agentRole: opts.agentRole } : {}),
28
+ ...(opts.parentSessionId ? { parentSessionId: opts.parentSessionId } : {}),
29
+ };
30
+ }
31
+ function isToolUseBlock(block) {
32
+ return block.type === "tool_use";
33
+ }
34
+ function getContentBlocks(entry) {
35
+ const content = entry.message?.content;
36
+ if (!content || typeof content === "string")
37
+ return [];
38
+ return content;
39
+ }
40
+ function entriesToTurns(entries) {
41
+ const turns = [];
42
+ for (const entry of entries) {
43
+ if (entry.type === "user") {
44
+ const content = entry.message?.content;
45
+ if (typeof content === "string") {
46
+ turns.push({
47
+ timestamp: entry.timestamp,
48
+ type: "prompt",
49
+ content,
50
+ });
51
+ }
52
+ // tool_result user entries are skipped — they're plumbing, not meaningful turns
53
+ }
54
+ else if (entry.type === "assistant") {
55
+ const blocks = getContentBlocks(entry);
56
+ for (const block of blocks) {
57
+ if (block.type === "text") {
58
+ turns.push({
59
+ timestamp: entry.timestamp,
60
+ type: "response",
61
+ content: block.text,
62
+ });
63
+ }
64
+ else if (isToolUseBlock(block)) {
65
+ const toolInput = extractToolInput(block);
66
+ turns.push({
67
+ timestamp: entry.timestamp,
68
+ type: "tool",
69
+ content: `${block.name} ${toolInput ?? ""}`.trim(),
70
+ toolName: block.name,
71
+ toolInput,
72
+ });
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return turns;
78
+ }
79
+ function extractToolInput(block) {
80
+ const input = block.input;
81
+ if (typeof input.file_path === "string")
82
+ return input.file_path;
83
+ if (typeof input.command === "string")
84
+ return input.command;
85
+ if (typeof input.pattern === "string")
86
+ return input.pattern;
87
+ if (typeof input.path === "string")
88
+ return input.path;
89
+ return undefined;
90
+ }
91
+ function computePerFileChanges(toolCalls) {
92
+ const files = new Map();
93
+ // Track writes for dedup (last write wins)
94
+ const writeLineCounts = new Map();
95
+ for (const call of toolCalls) {
96
+ if (call.name === "Write") {
97
+ const filePath = call.input.file_path;
98
+ const content = call.input.content;
99
+ if (typeof filePath !== "string" || typeof content !== "string")
100
+ continue;
101
+ const lines = content.split("\n").length;
102
+ const prev = writeLineCounts.get(filePath) ?? 0;
103
+ const existing = files.get(filePath) ?? { additions: 0, deletions: 0 };
104
+ if (writeLineCounts.has(filePath)) {
105
+ existing.additions = existing.additions - prev + lines;
106
+ }
107
+ else {
108
+ existing.additions += lines;
109
+ }
110
+ writeLineCounts.set(filePath, lines);
111
+ files.set(filePath, existing);
112
+ }
113
+ else if (call.name === "Edit") {
114
+ const filePath = call.input.file_path;
115
+ const oldStr = call.input.old_string;
116
+ const newStr = call.input.new_string;
117
+ if (typeof filePath !== "string")
118
+ continue;
119
+ const existing = files.get(filePath) ?? { additions: 0, deletions: 0 };
120
+ existing.additions += typeof newStr === "string" ? newStr.split("\n").length : 0;
121
+ existing.deletions += typeof oldStr === "string" ? oldStr.split("\n").length : 0;
122
+ files.set(filePath, existing);
123
+ }
124
+ }
125
+ return [...files.entries()]
126
+ .map(([path, stats]) => ({ path, ...stats }))
127
+ .sort((a, b) => a.path.localeCompare(b.path));
128
+ }
129
+ function extractTitle(entries) {
130
+ // Use the first user prompt as the title
131
+ for (const entry of entries) {
132
+ if (entry.type === "user") {
133
+ const content = entry.message?.content;
134
+ if (typeof content === "string" && content.trim().length > 0) {
135
+ const title = content.trim();
136
+ return title.length > 120 ? title.slice(0, 117) + "..." : title;
137
+ }
138
+ }
139
+ }
140
+ return "Untitled session";
141
+ }
142
+ function extractRawLog(entries) {
143
+ const log = [];
144
+ for (const entry of entries) {
145
+ if (entry.type === "user") {
146
+ const content = entry.message?.content;
147
+ if (typeof content === "string") {
148
+ log.push(`> ${content}`);
149
+ }
150
+ }
151
+ else if (entry.type === "assistant") {
152
+ const blocks = getContentBlocks(entry);
153
+ for (const block of blocks) {
154
+ if (block.type === "text") {
155
+ log.push(block.text);
156
+ }
157
+ else if (isToolUseBlock(block)) {
158
+ log.push(`[${block.name}] ${extractToolInput(block) ?? ""}`);
159
+ }
160
+ }
161
+ }
162
+ }
163
+ return log;
164
+ }
165
+ /**
166
+ * Deduplicate worktree clones: agents with same role and start time within
167
+ * 30 seconds are considered duplicates. Keep the one with more turns.
168
+ */
169
+ export function deduplicateChildren(children) {
170
+ const seen = new Map();
171
+ for (const child of children) {
172
+ const startBucket = Math.floor(new Date(child.date).getTime() / 30_000);
173
+ const key = `${child.agentRole ?? 'agent'}::${startBucket}`;
174
+ const existing = seen.get(key);
175
+ if (!existing || child.turns > existing.turns) {
176
+ seen.set(key, child);
177
+ }
178
+ }
179
+ return [...seen.values()];
180
+ }
181
+ /** Parse, bridge, and analyze each child session. Attaches results to parent. */
182
+ export async function bridgeChildSessions(parentMeta, projectName) {
183
+ if (!parentMeta.children || parentMeta.children.length === 0)
184
+ return [];
185
+ const results = [];
186
+ for (const child of parentMeta.children) {
187
+ try {
188
+ const parsed = await parseSession(child.path);
189
+ const input = bridgeToAnalyzer(parsed, {
190
+ sessionId: child.sessionId,
191
+ projectName,
192
+ agentRole: parsed.agent_role ?? child.agentRole,
193
+ parentSessionId: parentMeta.sessionId,
194
+ });
195
+ results.push(analyzeSession(input));
196
+ }
197
+ catch {
198
+ // Skip children that fail to parse
199
+ }
200
+ }
201
+ return deduplicateChildren(results);
202
+ }
203
+ /** Compute aggregated stats from fully-parsed child sessions. */
204
+ export function aggregateChildStats(children) {
205
+ return {
206
+ totalLoc: children.reduce((sum, c) => sum + c.linesOfCode, 0),
207
+ totalDurationMinutes: children.reduce((sum, c) => sum + c.durationMinutes, 0),
208
+ agentCount: children.length,
209
+ };
210
+ }
211
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Base URL for the heyi.am Phoenix API. Set HEYIAM_API_URL in env for dev. */
2
+ export declare const API_URL: string;
3
+ /** Current enhancement mode: 'local' if ANTHROPIC_API_KEY is set, 'proxy' otherwise. */
4
+ export declare const ENHANCE_MODE: 'local' | 'proxy';
package/dist/config.js ADDED
@@ -0,0 +1,5 @@
1
+ /** Base URL for the heyi.am Phoenix API. Set HEYIAM_API_URL in env for dev. */
2
+ export const API_URL = process.env.HEYIAM_API_URL ?? 'https://heyi.am';
3
+ /** Current enhancement mode: 'local' if ANTHROPIC_API_KEY is set, 'proxy' otherwise. */
4
+ export const ENHANCE_MODE = process.env.ANTHROPIC_API_KEY ? 'local' : 'proxy';
5
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,iBAAiB,CAAC;AAEvE,wFAAwF;AACxF,MAAM,CAAC,MAAM,YAAY,GAAsB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC"}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ declare const program: Command;
4
+ export { program };
package/dist/index.js ADDED
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { startServer } from './server.js';
4
+ import open from 'open';
5
+ import { checkAuthStatus, deviceAuthFlow, getAuthToken, deleteAuthToken, buildPublishPayload } from './auth.js';
6
+ import { loadOrCreateKeyPair, signPayload, getFingerprint } from './machine-key.js';
7
+ const program = new Command();
8
+ program
9
+ .name('heyiam')
10
+ .description('Turn AI coding sessions into portfolio case studies')
11
+ .version('0.1.0');
12
+ program
13
+ .command('open')
14
+ .description('Start the local server and open the browser')
15
+ .option('-p, --port <number>', 'Port to run on', '17845')
16
+ .option('--no-open', 'Start server without opening browser')
17
+ .action(async (opts) => {
18
+ const port = parseInt(opts.port, 10);
19
+ const server = await startServer(port);
20
+ const url = `http://localhost:${port}`;
21
+ console.log(`\nheyiam running at ${url}`);
22
+ console.log('Press Ctrl+C to stop\n');
23
+ if (opts.open) {
24
+ await open(url);
25
+ }
26
+ // Keep the process alive until Ctrl+C
27
+ const shutdown = () => {
28
+ console.log('\nShutting down...');
29
+ server.close(() => process.exit(0));
30
+ // Force exit after 3s if connections hang
31
+ setTimeout(() => process.exit(0), 3000);
32
+ };
33
+ process.on('SIGINT', shutdown);
34
+ process.on('SIGTERM', shutdown);
35
+ // Block forever — the event loop stays alive because the server is listening
36
+ await new Promise(() => { });
37
+ });
38
+ import { API_URL } from './config.js';
39
+ const API_BASE = API_URL;
40
+ program
41
+ .command('login')
42
+ .description('Authenticate with heyi.am')
43
+ .option('--api-url <url>', 'API base URL', API_BASE)
44
+ .action(async (opts) => {
45
+ const status = await checkAuthStatus(opts.apiUrl);
46
+ if (status.authenticated) {
47
+ console.log(`Already logged in as ${status.username}`);
48
+ return;
49
+ }
50
+ console.log('Starting device authorization...');
51
+ try {
52
+ const auth = await deviceAuthFlow(opts.apiUrl, undefined, {
53
+ openBrowser: (url) => open(url).then(() => { }),
54
+ onUserCode: (code, uri) => {
55
+ console.log(`\nOpen ${uri} and enter code: ${code}\n`);
56
+ },
57
+ });
58
+ console.log(`Logged in as ${auth.username}`);
59
+ }
60
+ catch (err) {
61
+ console.error(`Login failed: ${err.message}`);
62
+ process.exitCode = 1;
63
+ }
64
+ });
65
+ program
66
+ .command('logout')
67
+ .description('Remove saved authentication credentials')
68
+ .action(() => {
69
+ deleteAuthToken();
70
+ console.log('Logged out. Run `heyiam login` to re-authenticate.');
71
+ });
72
+ program
73
+ .command('publish')
74
+ .description('Publish a session to heyi.am')
75
+ .option('--api-url <url>', 'API base URL', API_BASE)
76
+ .action(async (opts) => {
77
+ const auth = getAuthToken();
78
+ if (!auth) {
79
+ console.error('Not logged in. Run `heyiam login` first.');
80
+ process.exitCode = 1;
81
+ return;
82
+ }
83
+ const keyPair = loadOrCreateKeyPair();
84
+ const fingerprint = getFingerprint(keyPair.publicKey);
85
+ console.log(`Using machine key: ${fingerprint}`);
86
+ // TODO: session data will come from the parser pipeline once Task 8.3+ are complete
87
+ const sessionData = { placeholder: true };
88
+ const payloadStr = JSON.stringify(sessionData);
89
+ const signature = signPayload(payloadStr, keyPair.privateKey);
90
+ const body = buildPublishPayload(sessionData, signature, keyPair.publicKey);
91
+ try {
92
+ const res = await fetch(`${opts.apiUrl}/api/shares`, {
93
+ method: 'POST',
94
+ headers: {
95
+ 'Content-Type': 'application/json',
96
+ Authorization: `Bearer ${auth.token}`,
97
+ },
98
+ body: JSON.stringify(body),
99
+ });
100
+ if (!res.ok) {
101
+ const err = await res.text();
102
+ console.error(`Publish failed (${res.status}): ${err}`);
103
+ process.exitCode = 1;
104
+ return;
105
+ }
106
+ const result = (await res.json());
107
+ console.log(`Published! ${result.url ?? ''}`);
108
+ }
109
+ catch (err) {
110
+ console.error(`Publish failed: ${err.message}`);
111
+ process.exitCode = 1;
112
+ }
113
+ });
114
+ // Default to 'open' when no command is given
115
+ program.action(async () => {
116
+ await program.parseAsync(['', '', 'open']);
117
+ });
118
+ export { program };
119
+ // Only run if this is the entry point (not imported for testing).
120
+ // When installed via npm link, process.argv[1] is the symlink path
121
+ // (e.g., ~/.nvm/.../bin/heyiam), so we resolve it to check the real path.
122
+ import { realpathSync } from 'node:fs';
123
+ const resolvedArgv = process.argv[1] ? realpathSync(process.argv[1]) : '';
124
+ const isDirectRun = resolvedArgv.endsWith('/dist/index.js') ||
125
+ resolvedArgv.endsWith('/src/index.ts');
126
+ if (isDirectRun) {
127
+ program.parseAsync(process.argv);
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Session } from '../analyzer.js';
2
+ import type { EnhancementResult } from '../summarize.js';
3
+ import type { LLMProvider } from './types.js';
4
+ /**
5
+ * BYOK provider — calls Anthropic SDK directly using the user's local API key.
6
+ * Reads from env var first, then falls back to ~/.config/heyiam/settings.json.
7
+ */
8
+ export declare class AnthropicProvider implements LLMProvider {
9
+ name: "local";
10
+ enhance(session: Session): Promise<EnhancementResult>;
11
+ }
@@ -0,0 +1,16 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { summarizeSession } from '../summarize.js';
3
+ import { getAnthropicApiKey } from '../settings.js';
4
+ /**
5
+ * BYOK provider — calls Anthropic SDK directly using the user's local API key.
6
+ * Reads from env var first, then falls back to ~/.config/heyiam/settings.json.
7
+ */
8
+ export class AnthropicProvider {
9
+ name = 'local';
10
+ async enhance(session) {
11
+ const apiKey = getAnthropicApiKey();
12
+ const client = apiKey ? new Anthropic({ apiKey }) : new Anthropic();
13
+ return summarizeSession(session, { client });
14
+ }
15
+ }
16
+ //# sourceMappingURL=anthropic-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-provider.js","sourceRoot":"","sources":["../../src/llm/anthropic-provider.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B,IAAI,GAAG,OAAgB,CAAC;IAExB,KAAK,CAAC,OAAO,CAAC,OAAgB;QAC5B,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;QACpE,OAAO,gBAAgB,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { LLMProvider } from './types.js';
2
+ export type { LLMProvider } from './types.js';
3
+ export { ProxyError } from './proxy-provider.js';
4
+ /**
5
+ * Returns the appropriate LLM provider based on environment.
6
+ *
7
+ * Resolution priority:
8
+ * 1. If ANTHROPIC_API_KEY env var is set → AnthropicProvider (BYOK)
9
+ * 2. If API key saved in ~/.config/heyiam/settings.json → AnthropicProvider (BYOK)
10
+ * 3. Otherwise → ProxyProvider (server-side, requires auth)
11
+ */
12
+ export declare function getProvider(): LLMProvider;
13
+ /**
14
+ * Returns the current enhancement mode for display purposes.
15
+ */
16
+ export declare function getEnhanceMode(): 'local' | 'proxy';
@@ -0,0 +1,25 @@
1
+ import { AnthropicProvider } from './anthropic-provider.js';
2
+ import { ProxyProvider } from './proxy-provider.js';
3
+ import { getAnthropicApiKey } from '../settings.js';
4
+ export { ProxyError } from './proxy-provider.js';
5
+ /**
6
+ * Returns the appropriate LLM provider based on environment.
7
+ *
8
+ * Resolution priority:
9
+ * 1. If ANTHROPIC_API_KEY env var is set → AnthropicProvider (BYOK)
10
+ * 2. If API key saved in ~/.config/heyiam/settings.json → AnthropicProvider (BYOK)
11
+ * 3. Otherwise → ProxyProvider (server-side, requires auth)
12
+ */
13
+ export function getProvider() {
14
+ if (getAnthropicApiKey()) {
15
+ return new AnthropicProvider();
16
+ }
17
+ return new ProxyProvider();
18
+ }
19
+ /**
20
+ * Returns the current enhancement mode for display purposes.
21
+ */
22
+ export function getEnhanceMode() {
23
+ return getAnthropicApiKey() ? 'local' : 'proxy';
24
+ }
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,kBAAkB,EAAE,EAAE,CAAC;QACzB,OAAO,IAAI,iBAAiB,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,aAAa,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,kBAAkB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AAClD,CAAC"}
@@ -0,0 +1,71 @@
1
+ export interface SessionSummary {
2
+ sessionId: string;
3
+ title: string;
4
+ developerTake?: string;
5
+ skills: string[];
6
+ executionSteps: Array<{
7
+ title: string;
8
+ body: string;
9
+ }>;
10
+ keyDecisions?: string[];
11
+ duration: number;
12
+ loc: number;
13
+ turns: number;
14
+ files: number;
15
+ date: string;
16
+ correctionCount?: number;
17
+ }
18
+ export interface SkippedSessionMeta {
19
+ title: string;
20
+ duration: number;
21
+ loc: number;
22
+ }
23
+ export interface ProjectQuestion {
24
+ id: string;
25
+ category: 'pattern' | 'architecture' | 'evolution';
26
+ question: string;
27
+ context: string;
28
+ }
29
+ export interface ProjectEnhanceResult {
30
+ narrative: string;
31
+ arc: Array<{
32
+ phase: number;
33
+ title: string;
34
+ description: string;
35
+ }>;
36
+ skills: string[];
37
+ timeline: Array<{
38
+ period: string;
39
+ label: string;
40
+ sessions: Array<{
41
+ sessionId: string;
42
+ title: string;
43
+ featured: boolean;
44
+ tag?: string;
45
+ }>;
46
+ }>;
47
+ questions: ProjectQuestion[];
48
+ }
49
+ export interface RefinedNarrative {
50
+ narrative: string;
51
+ timeline: ProjectEnhanceResult['timeline'];
52
+ }
53
+ export type EnhanceProjectProgress = {
54
+ type: 'narrative_chunk';
55
+ text: string;
56
+ };
57
+ /**
58
+ * Generate a project narrative, arc, timeline, and context-aware questions
59
+ * from enhanced session summaries. Streams narrative chunks via onProgress
60
+ * as the LLM generates the response.
61
+ */
62
+ export declare function enhanceProject(sessions: SessionSummary[], skippedSessions: SkippedSessionMeta[], onProgress?: (event: EnhanceProjectProgress) => void): Promise<ProjectEnhanceResult>;
63
+ /**
64
+ * Refine a project narrative by weaving in the developer's answers
65
+ * to context-aware questions.
66
+ */
67
+ export declare function refineNarrative(draftNarrative: string, draftTimeline: ProjectEnhanceResult['timeline'], answers: Array<{
68
+ questionId: string;
69
+ question: string;
70
+ answer: string;
71
+ }>): Promise<RefinedNarrative>;