ghcralph 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.
- package/LICENSE +21 -0
- package/README.md +327 -0
- package/bin/ghcralph.js +2 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +92 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +118 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/index.d.ts +11 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +11 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +116 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/rollback.d.ts +8 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +238 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/run.d.ts +28 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +407 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +399 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/action-executor.d.ts +96 -0
- package/dist/core/action-executor.d.ts.map +1 -0
- package/dist/core/action-executor.js +289 -0
- package/dist/core/action-executor.js.map +1 -0
- package/dist/core/checkpoint-manager.d.ts +94 -0
- package/dist/core/checkpoint-manager.d.ts.map +1 -0
- package/dist/core/checkpoint-manager.js +236 -0
- package/dist/core/checkpoint-manager.js.map +1 -0
- package/dist/core/config-manager.d.ts +62 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +184 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/config-schema.d.ts +74 -0
- package/dist/core/config-schema.d.ts.map +1 -0
- package/dist/core/config-schema.js +84 -0
- package/dist/core/config-schema.js.map +1 -0
- package/dist/core/context-builder.d.ts +116 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +388 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/feedback-builder.d.ts +94 -0
- package/dist/core/feedback-builder.d.ts.map +1 -0
- package/dist/core/feedback-builder.js +226 -0
- package/dist/core/feedback-builder.js.map +1 -0
- package/dist/core/file-safeguard.d.ts +109 -0
- package/dist/core/file-safeguard.d.ts.map +1 -0
- package/dist/core/file-safeguard.js +200 -0
- package/dist/core/file-safeguard.js.map +1 -0
- package/dist/core/git-branch-manager.d.ts +122 -0
- package/dist/core/git-branch-manager.d.ts.map +1 -0
- package/dist/core/git-branch-manager.js +302 -0
- package/dist/core/git-branch-manager.js.map +1 -0
- package/dist/core/github-plan.d.ts +86 -0
- package/dist/core/github-plan.d.ts.map +1 -0
- package/dist/core/github-plan.js +333 -0
- package/dist/core/github-plan.js.map +1 -0
- package/dist/core/index.d.ts +43 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +26 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/local-markdown-plan.d.ts +65 -0
- package/dist/core/local-markdown-plan.d.ts.map +1 -0
- package/dist/core/local-markdown-plan.js +154 -0
- package/dist/core/local-markdown-plan.js.map +1 -0
- package/dist/core/loop-engine.d.ts +133 -0
- package/dist/core/loop-engine.d.ts.map +1 -0
- package/dist/core/loop-engine.js +420 -0
- package/dist/core/loop-engine.js.map +1 -0
- package/dist/core/loop-events.d.ts +48 -0
- package/dist/core/loop-events.d.ts.map +1 -0
- package/dist/core/loop-events.js +24 -0
- package/dist/core/loop-events.js.map +1 -0
- package/dist/core/loop-state.d.ts +51 -0
- package/dist/core/loop-state.d.ts.map +1 -0
- package/dist/core/loop-state.js +48 -0
- package/dist/core/loop-state.js.map +1 -0
- package/dist/core/markdown-parser.d.ts +51 -0
- package/dist/core/markdown-parser.d.ts.map +1 -0
- package/dist/core/markdown-parser.js +122 -0
- package/dist/core/markdown-parser.js.map +1 -0
- package/dist/core/plan-manager.d.ts +61 -0
- package/dist/core/plan-manager.d.ts.map +1 -0
- package/dist/core/plan-manager.js +7 -0
- package/dist/core/plan-manager.js.map +1 -0
- package/dist/core/progress-tracker.d.ts +74 -0
- package/dist/core/progress-tracker.d.ts.map +1 -0
- package/dist/core/progress-tracker.js +198 -0
- package/dist/core/progress-tracker.js.map +1 -0
- package/dist/core/prompt-examples.d.ts +52 -0
- package/dist/core/prompt-examples.d.ts.map +1 -0
- package/dist/core/prompt-examples.js +194 -0
- package/dist/core/prompt-examples.js.map +1 -0
- package/dist/core/response-parser.d.ts +90 -0
- package/dist/core/response-parser.d.ts.map +1 -0
- package/dist/core/response-parser.js +209 -0
- package/dist/core/response-parser.js.map +1 -0
- package/dist/core/verification-hooks.d.ts +103 -0
- package/dist/core/verification-hooks.d.ts.map +1 -0
- package/dist/core/verification-hooks.js +268 -0
- package/dist/core/verification-hooks.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/auth.d.ts +28 -0
- package/dist/integrations/auth.d.ts.map +1 -0
- package/dist/integrations/auth.js +76 -0
- package/dist/integrations/auth.js.map +1 -0
- package/dist/integrations/copilot-agent.d.ts +104 -0
- package/dist/integrations/copilot-agent.d.ts.map +1 -0
- package/dist/integrations/copilot-agent.js +235 -0
- package/dist/integrations/copilot-agent.js.map +1 -0
- package/dist/integrations/index.d.ts +18 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +14 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/mcp-tools.d.ts +129 -0
- package/dist/integrations/mcp-tools.d.ts.map +1 -0
- package/dist/integrations/mcp-tools.js +272 -0
- package/dist/integrations/mcp-tools.js.map +1 -0
- package/dist/integrations/tokens.d.ts +45 -0
- package/dist/integrations/tokens.d.ts.map +1 -0
- package/dist/integrations/tokens.js +50 -0
- package/dist/integrations/tokens.js.map +1 -0
- package/dist/types/index.d.ts +53 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +37 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/output.d.ts +59 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +96 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/paths.d.ts +34 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +67 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/shell.d.ts +26 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +65 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/validation.d.ts +27 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +43 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop State
|
|
3
|
+
*
|
|
4
|
+
* Types and utilities for managing loop execution state
|
|
5
|
+
*/
|
|
6
|
+
import type { Task, LoopState } from '../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Iteration record for tracking loop progress
|
|
9
|
+
*/
|
|
10
|
+
export interface IterationRecord {
|
|
11
|
+
/** Iteration number (1-based) */
|
|
12
|
+
iteration: number;
|
|
13
|
+
/** When this iteration started */
|
|
14
|
+
startedAt: Date;
|
|
15
|
+
/** When this iteration ended */
|
|
16
|
+
endedAt?: Date;
|
|
17
|
+
/** Tokens used in this iteration */
|
|
18
|
+
tokensUsed: number;
|
|
19
|
+
/** Whether the iteration succeeded */
|
|
20
|
+
success: boolean;
|
|
21
|
+
/** Summary of what happened */
|
|
22
|
+
summary?: string;
|
|
23
|
+
/** Error if the iteration failed */
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Full loop execution state including history
|
|
28
|
+
*/
|
|
29
|
+
export interface FullLoopState extends LoopState {
|
|
30
|
+
/** The task being executed */
|
|
31
|
+
task: Task;
|
|
32
|
+
/** History of all iterations */
|
|
33
|
+
iterations: IterationRecord[];
|
|
34
|
+
/** When the loop ended (if completed) */
|
|
35
|
+
endedAt?: Date;
|
|
36
|
+
/** Final result message */
|
|
37
|
+
result?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create initial loop state for a task
|
|
41
|
+
*/
|
|
42
|
+
export declare function createInitialState(task: Task): FullLoopState;
|
|
43
|
+
/**
|
|
44
|
+
* Create an iteration record
|
|
45
|
+
*/
|
|
46
|
+
export declare function createIterationRecord(iteration: number): IterationRecord;
|
|
47
|
+
/**
|
|
48
|
+
* Mark an iteration as complete
|
|
49
|
+
*/
|
|
50
|
+
export declare function completeIteration(record: IterationRecord, success: boolean, tokensUsed: number, summary?: string, error?: string): IterationRecord;
|
|
51
|
+
//# sourceMappingURL=loop-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-state.d.ts","sourceRoot":"","sources":["../../src/core/loop-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,SAAS,EAAE,IAAI,CAAC;IAChB,gCAAgC;IAChC,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,8BAA8B;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,gCAAgC;IAChC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,yCAAyC;IACzC,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,CAS5D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAOxE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,eAAe,CAiBjB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop State
|
|
3
|
+
*
|
|
4
|
+
* Types and utilities for managing loop execution state
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Create initial loop state for a task
|
|
8
|
+
*/
|
|
9
|
+
export function createInitialState(task) {
|
|
10
|
+
return {
|
|
11
|
+
task,
|
|
12
|
+
iteration: 0,
|
|
13
|
+
tokensUsed: 0,
|
|
14
|
+
startedAt: new Date(),
|
|
15
|
+
status: 'running',
|
|
16
|
+
iterations: [],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create an iteration record
|
|
21
|
+
*/
|
|
22
|
+
export function createIterationRecord(iteration) {
|
|
23
|
+
return {
|
|
24
|
+
iteration,
|
|
25
|
+
startedAt: new Date(),
|
|
26
|
+
tokensUsed: 0,
|
|
27
|
+
success: false,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Mark an iteration as complete
|
|
32
|
+
*/
|
|
33
|
+
export function completeIteration(record, success, tokensUsed, summary, error) {
|
|
34
|
+
const result = {
|
|
35
|
+
...record,
|
|
36
|
+
endedAt: new Date(),
|
|
37
|
+
success,
|
|
38
|
+
tokensUsed,
|
|
39
|
+
};
|
|
40
|
+
if (summary !== undefined) {
|
|
41
|
+
result.summary = summary;
|
|
42
|
+
}
|
|
43
|
+
if (error !== undefined) {
|
|
44
|
+
result.error = error;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=loop-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-state.js","sourceRoot":"","sources":["../../src/core/loop-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsCH;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAU;IAC3C,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,OAAO;QACL,SAAS;QACT,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,KAAK;KACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAuB,EACvB,OAAgB,EAChB,UAAkB,EAClB,OAAgB,EAChB,KAAc;IAEd,MAAM,MAAM,GAAoB;QAC9B,GAAG,MAAM;QACT,OAAO,EAAE,IAAI,IAAI,EAAE;QACnB,OAAO;QACP,UAAU;KACX,CAAC;IAEF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown Parser
|
|
3
|
+
*
|
|
4
|
+
* Parse Markdown files with task lists and YAML frontmatter
|
|
5
|
+
*/
|
|
6
|
+
import type { Task } from '../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Parsed task from Markdown
|
|
9
|
+
*/
|
|
10
|
+
export interface ParsedMarkdownTask {
|
|
11
|
+
/** Task ID (generated from line number) */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Task title (checkbox text) */
|
|
14
|
+
title: string;
|
|
15
|
+
/** Full task content (multi-line if present) */
|
|
16
|
+
content: string;
|
|
17
|
+
/** Whether the task is completed (checkbox checked) */
|
|
18
|
+
completed: boolean;
|
|
19
|
+
/** Line number in the source file */
|
|
20
|
+
lineNumber: number;
|
|
21
|
+
/** Indentation level (for nested tasks) */
|
|
22
|
+
indentLevel: number;
|
|
23
|
+
/** Parent task ID if nested */
|
|
24
|
+
parentId?: string;
|
|
25
|
+
/** Metadata from frontmatter or inline */
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parsed Markdown document
|
|
30
|
+
*/
|
|
31
|
+
export interface ParsedMarkdownPlan {
|
|
32
|
+
/** Frontmatter metadata */
|
|
33
|
+
frontmatter?: Record<string, unknown>;
|
|
34
|
+
/** All parsed tasks */
|
|
35
|
+
tasks: ParsedMarkdownTask[];
|
|
36
|
+
/** Raw content */
|
|
37
|
+
rawContent: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parse a Markdown file content for tasks
|
|
41
|
+
*/
|
|
42
|
+
export declare function parseMarkdownPlan(content: string): ParsedMarkdownPlan;
|
|
43
|
+
/**
|
|
44
|
+
* Convert parsed Markdown task to Task type
|
|
45
|
+
*/
|
|
46
|
+
export declare function toTask(parsed: ParsedMarkdownTask, source?: 'local' | 'github'): Task;
|
|
47
|
+
/**
|
|
48
|
+
* Update a checkbox in Markdown content
|
|
49
|
+
*/
|
|
50
|
+
export declare function updateTaskCheckbox(content: string, lineNumber: number, completed: boolean): string;
|
|
51
|
+
//# sourceMappingURL=markdown-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-parser.d.ts","sourceRoot":"","sources":["../../src/core/markdown-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,uBAAuB;IACvB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAqCD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAiErE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAE,OAAO,GAAG,QAAkB,GAAG,IAAI,CAQ7F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GACjB,MAAM,CAaR"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown Parser
|
|
3
|
+
*
|
|
4
|
+
* Parse Markdown files with task lists and YAML frontmatter
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Regex for matching task list items
|
|
8
|
+
* Matches: "- [ ] Task" or "- [x] Task" with optional indentation
|
|
9
|
+
*/
|
|
10
|
+
const TASK_REGEX = /^(\s*)-\s*\[([ xX])\]\s*(.+)$/;
|
|
11
|
+
/**
|
|
12
|
+
* Regex for matching YAML frontmatter
|
|
13
|
+
*/
|
|
14
|
+
const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
15
|
+
/**
|
|
16
|
+
* Parse YAML frontmatter (simple key: value parsing)
|
|
17
|
+
*/
|
|
18
|
+
function parseFrontmatter(frontmatterStr) {
|
|
19
|
+
const result = {};
|
|
20
|
+
for (const line of frontmatterStr.split('\n')) {
|
|
21
|
+
const colonIndex = line.indexOf(':');
|
|
22
|
+
if (colonIndex > 0) {
|
|
23
|
+
const key = line.substring(0, colonIndex).trim();
|
|
24
|
+
let value = line.substring(colonIndex + 1).trim();
|
|
25
|
+
// Simple type coercion
|
|
26
|
+
if (value === 'true')
|
|
27
|
+
value = true;
|
|
28
|
+
else if (value === 'false')
|
|
29
|
+
value = false;
|
|
30
|
+
else if (!isNaN(Number(value)) && value !== '')
|
|
31
|
+
value = Number(value);
|
|
32
|
+
result[key] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parse a Markdown file content for tasks
|
|
39
|
+
*/
|
|
40
|
+
export function parseMarkdownPlan(content) {
|
|
41
|
+
const result = {
|
|
42
|
+
tasks: [],
|
|
43
|
+
rawContent: content,
|
|
44
|
+
};
|
|
45
|
+
// Extract frontmatter if present
|
|
46
|
+
const frontmatterMatch = content.match(FRONTMATTER_REGEX);
|
|
47
|
+
let contentStart = 0;
|
|
48
|
+
if (frontmatterMatch) {
|
|
49
|
+
result.frontmatter = parseFrontmatter(frontmatterMatch[1] ?? '');
|
|
50
|
+
contentStart = frontmatterMatch[0].length;
|
|
51
|
+
}
|
|
52
|
+
// Parse lines for tasks
|
|
53
|
+
const lines = content.substring(contentStart).split('\n');
|
|
54
|
+
const taskStack = []; // Stack for tracking parent tasks
|
|
55
|
+
for (let i = 0; i < lines.length; i++) {
|
|
56
|
+
const line = lines[i];
|
|
57
|
+
if (!line)
|
|
58
|
+
continue;
|
|
59
|
+
const match = line.match(TASK_REGEX);
|
|
60
|
+
if (match) {
|
|
61
|
+
const indentStr = match[1] ?? '';
|
|
62
|
+
const checkbox = match[2];
|
|
63
|
+
const title = match[3]?.trim() ?? '';
|
|
64
|
+
// Calculate indent level (assuming 2 spaces per level)
|
|
65
|
+
const indentLevel = Math.floor(indentStr.length / 2);
|
|
66
|
+
// Adjust task stack for current indent level
|
|
67
|
+
while (taskStack.length > indentLevel) {
|
|
68
|
+
taskStack.pop();
|
|
69
|
+
}
|
|
70
|
+
const taskId = `task-${i + 1}`;
|
|
71
|
+
const parentId = taskStack.length > 0 ? taskStack[taskStack.length - 1] : undefined;
|
|
72
|
+
const task = {
|
|
73
|
+
id: taskId,
|
|
74
|
+
title,
|
|
75
|
+
content: title, // Initial content is just the title
|
|
76
|
+
completed: checkbox?.toLowerCase() === 'x',
|
|
77
|
+
lineNumber: i + 1 + (frontmatterMatch ? frontmatterMatch[0].split('\n').length - 1 : 0),
|
|
78
|
+
indentLevel,
|
|
79
|
+
};
|
|
80
|
+
if (parentId !== undefined) {
|
|
81
|
+
task.parentId = parentId;
|
|
82
|
+
}
|
|
83
|
+
result.tasks.push(task);
|
|
84
|
+
// Update stack for potential child tasks
|
|
85
|
+
if (taskStack.length === indentLevel) {
|
|
86
|
+
taskStack.push(taskId);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
taskStack[indentLevel] = taskId;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Convert parsed Markdown task to Task type
|
|
97
|
+
*/
|
|
98
|
+
export function toTask(parsed, source = 'local') {
|
|
99
|
+
return {
|
|
100
|
+
id: parsed.id,
|
|
101
|
+
title: parsed.title,
|
|
102
|
+
content: parsed.content,
|
|
103
|
+
status: parsed.completed ? 'completed' : 'pending',
|
|
104
|
+
source,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Update a checkbox in Markdown content
|
|
109
|
+
*/
|
|
110
|
+
export function updateTaskCheckbox(content, lineNumber, completed) {
|
|
111
|
+
const lines = content.split('\n');
|
|
112
|
+
const lineIndex = lineNumber - 1;
|
|
113
|
+
if (lineIndex >= 0 && lineIndex < lines.length) {
|
|
114
|
+
const line = lines[lineIndex];
|
|
115
|
+
if (line) {
|
|
116
|
+
const newCheckbox = completed ? '[x]' : '[ ]';
|
|
117
|
+
lines[lineIndex] = line.replace(/\[([ xX])\]/, newCheckbox);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return lines.join('\n');
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=markdown-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-parser.js","sourceRoot":"","sources":["../../src/core/markdown-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Manager Interface
|
|
3
|
+
*
|
|
4
|
+
* Common interface for different plan sources (local Markdown, GitHub Issues)
|
|
5
|
+
*/
|
|
6
|
+
import type { Task } from '../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Plan source type
|
|
9
|
+
*/
|
|
10
|
+
export type PlanSourceType = 'local' | 'github';
|
|
11
|
+
/**
|
|
12
|
+
* Task filter options
|
|
13
|
+
*/
|
|
14
|
+
export interface TaskFilter {
|
|
15
|
+
/** Filter by status */
|
|
16
|
+
status?: 'pending' | 'in-progress' | 'completed' | 'all';
|
|
17
|
+
/** Filter by label/tag */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** Maximum number of tasks to return */
|
|
20
|
+
limit?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Plan manager interface
|
|
24
|
+
*/
|
|
25
|
+
export interface PlanManager {
|
|
26
|
+
/** The type of plan source */
|
|
27
|
+
readonly sourceType: PlanSourceType;
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the plan manager
|
|
30
|
+
*/
|
|
31
|
+
initialize(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Get all tasks from the plan
|
|
34
|
+
*/
|
|
35
|
+
getTasks(filter?: TaskFilter): Promise<Task[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Get the next pending task
|
|
38
|
+
*/
|
|
39
|
+
getNextTask(): Promise<Task | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Get a specific task by ID
|
|
42
|
+
*/
|
|
43
|
+
getTask(id: string): Promise<Task | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Mark a task as in-progress
|
|
46
|
+
*/
|
|
47
|
+
startTask(id: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Mark a task as completed
|
|
50
|
+
*/
|
|
51
|
+
completeTask(id: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Mark a task as failed
|
|
54
|
+
*/
|
|
55
|
+
failTask(id: string, error?: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Update task progress
|
|
58
|
+
*/
|
|
59
|
+
updateProgress(id: string, progress: string): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=plan-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-manager.d.ts","sourceRoot":"","sources":["../../src/core/plan-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,MAAM,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,KAAK,CAAC;IACzD,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IAEpC;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-manager.js","sourceRoot":"","sources":["../../src/core/plan-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Tracker
|
|
3
|
+
*
|
|
4
|
+
* Creates and maintains Markdown-based progress artifacts
|
|
5
|
+
*/
|
|
6
|
+
import type { FullLoopState } from './loop-state.js';
|
|
7
|
+
/**
|
|
8
|
+
* Session data for JSON output
|
|
9
|
+
*/
|
|
10
|
+
export interface SessionData {
|
|
11
|
+
startedAt: string;
|
|
12
|
+
taskId: string;
|
|
13
|
+
taskTitle: string;
|
|
14
|
+
status: string;
|
|
15
|
+
iteration: number;
|
|
16
|
+
maxIterations: number;
|
|
17
|
+
tokensUsed: number;
|
|
18
|
+
elapsedMs: number;
|
|
19
|
+
iterations: Array<{
|
|
20
|
+
number: number;
|
|
21
|
+
startedAt: string;
|
|
22
|
+
endedAt?: string;
|
|
23
|
+
tokensUsed: number;
|
|
24
|
+
success: boolean;
|
|
25
|
+
summary?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
}>;
|
|
28
|
+
lastCheckpoint?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Progress Tracker class
|
|
32
|
+
*/
|
|
33
|
+
export declare class ProgressTracker {
|
|
34
|
+
private projectRoot;
|
|
35
|
+
private maxIterations;
|
|
36
|
+
constructor(projectRoot?: string, maxIterations?: number);
|
|
37
|
+
/**
|
|
38
|
+
* Get the progress file path
|
|
39
|
+
*/
|
|
40
|
+
getProgressFilePath(): string;
|
|
41
|
+
/**
|
|
42
|
+
* Generate Markdown content for the progress file
|
|
43
|
+
*/
|
|
44
|
+
generateMarkdown(state: FullLoopState): string;
|
|
45
|
+
/**
|
|
46
|
+
* Format status for display
|
|
47
|
+
*/
|
|
48
|
+
private formatStatus;
|
|
49
|
+
/**
|
|
50
|
+
* Format an iteration for the log
|
|
51
|
+
*/
|
|
52
|
+
private formatIteration;
|
|
53
|
+
/**
|
|
54
|
+
* Save progress to file
|
|
55
|
+
*/
|
|
56
|
+
save(state: FullLoopState): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Load session data from progress file (if exists)
|
|
59
|
+
*/
|
|
60
|
+
load(): Promise<SessionData | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Get session data as JSON
|
|
63
|
+
*/
|
|
64
|
+
toJSON(state: FullLoopState): SessionData;
|
|
65
|
+
/**
|
|
66
|
+
* Check if a session exists
|
|
67
|
+
*/
|
|
68
|
+
hasSession(): Promise<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* Clear progress file
|
|
71
|
+
*/
|
|
72
|
+
clear(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=progress-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-tracker.d.ts","sourceRoot":"","sources":["../../src/core/progress-tracker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AAOtE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,KAAK,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAwBD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,aAAa,CAAS;gBAElB,WAAW,CAAC,EAAE,MAAM,EAAE,aAAa,GAAE,MAAW;IAK5D;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM;IA8B9C;;OAEG;IACH,OAAO,CAAC,YAAY;IAiBpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAwBvB;;OAEG;IACG,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAYzC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,WAAW;IAuCzC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IASpC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Tracker
|
|
3
|
+
*
|
|
4
|
+
* Creates and maintains Markdown-based progress artifacts
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { getLocalStateDir } from '../utils/paths.js';
|
|
9
|
+
import { debug } from '../utils/output.js';
|
|
10
|
+
/**
|
|
11
|
+
* Progress file name
|
|
12
|
+
*/
|
|
13
|
+
const PROGRESS_FILE = 'progress.md';
|
|
14
|
+
/**
|
|
15
|
+
* Format a date for display
|
|
16
|
+
*/
|
|
17
|
+
function formatDate(date) {
|
|
18
|
+
return date.toISOString();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Format elapsed time
|
|
22
|
+
*/
|
|
23
|
+
function formatElapsed(startDate, endDate) {
|
|
24
|
+
const end = endDate ?? new Date();
|
|
25
|
+
const ms = end.getTime() - startDate.getTime();
|
|
26
|
+
const seconds = Math.floor(ms / 1000);
|
|
27
|
+
const minutes = Math.floor(seconds / 60);
|
|
28
|
+
if (minutes > 0) {
|
|
29
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
30
|
+
}
|
|
31
|
+
return `${seconds}s`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Progress Tracker class
|
|
35
|
+
*/
|
|
36
|
+
export class ProgressTracker {
|
|
37
|
+
projectRoot;
|
|
38
|
+
maxIterations;
|
|
39
|
+
constructor(projectRoot, maxIterations = 10) {
|
|
40
|
+
this.projectRoot = projectRoot;
|
|
41
|
+
this.maxIterations = maxIterations;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get the progress file path
|
|
45
|
+
*/
|
|
46
|
+
getProgressFilePath() {
|
|
47
|
+
return path.join(getLocalStateDir(this.projectRoot), PROGRESS_FILE);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generate Markdown content for the progress file
|
|
51
|
+
*/
|
|
52
|
+
generateMarkdown(state) {
|
|
53
|
+
const { task, iteration, tokensUsed, startedAt, status, iterations, lastCheckpoint } = state;
|
|
54
|
+
let md = `# Ralph Progress Log\n\n`;
|
|
55
|
+
md += `## Current Session\n\n`;
|
|
56
|
+
md += `- **Started**: ${formatDate(startedAt)}\n`;
|
|
57
|
+
md += `- **Task**: ${task.title}\n`;
|
|
58
|
+
md += `- **Status**: ${this.formatStatus(status)}\n`;
|
|
59
|
+
md += `- **Iterations**: ${iteration}/${this.maxIterations}\n`;
|
|
60
|
+
md += `- **Tokens Used**: ${tokensUsed.toLocaleString()}\n`;
|
|
61
|
+
md += `- **Elapsed**: ${formatElapsed(startedAt)}\n`;
|
|
62
|
+
if (lastCheckpoint) {
|
|
63
|
+
md += `- **Last Checkpoint**: \`${lastCheckpoint}\`\n`;
|
|
64
|
+
}
|
|
65
|
+
md += `\n### Task Details\n\n`;
|
|
66
|
+
md += `\`\`\`\n${task.content}\n\`\`\`\n`;
|
|
67
|
+
if (iterations.length > 0) {
|
|
68
|
+
md += `\n### Iteration Log\n\n`;
|
|
69
|
+
for (const iter of iterations) {
|
|
70
|
+
md += this.formatIteration(iter);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return md;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Format status for display
|
|
77
|
+
*/
|
|
78
|
+
formatStatus(status) {
|
|
79
|
+
switch (status) {
|
|
80
|
+
case 'running':
|
|
81
|
+
return 'π In Progress';
|
|
82
|
+
case 'completed':
|
|
83
|
+
return 'β
Completed';
|
|
84
|
+
case 'failed':
|
|
85
|
+
return 'β Failed';
|
|
86
|
+
case 'stopped':
|
|
87
|
+
return 'βΉοΈ Stopped';
|
|
88
|
+
case 'paused':
|
|
89
|
+
return 'βΈοΈ Paused';
|
|
90
|
+
default:
|
|
91
|
+
return status;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Format an iteration for the log
|
|
96
|
+
*/
|
|
97
|
+
formatIteration(iter) {
|
|
98
|
+
const time = iter.startedAt.toLocaleTimeString();
|
|
99
|
+
const status = iter.success ? 'β' : 'β';
|
|
100
|
+
let md = `#### Iteration ${iter.iteration} (${time}) ${status}\n\n`;
|
|
101
|
+
md += `- **Tokens**: ${iter.tokensUsed.toLocaleString()}\n`;
|
|
102
|
+
if (iter.summary) {
|
|
103
|
+
md += `- **Summary**: ${iter.summary}\n`;
|
|
104
|
+
}
|
|
105
|
+
if (iter.error) {
|
|
106
|
+
md += `- **Error**: ${iter.error}\n`;
|
|
107
|
+
}
|
|
108
|
+
if (iter.endedAt) {
|
|
109
|
+
const duration = iter.endedAt.getTime() - iter.startedAt.getTime();
|
|
110
|
+
md += `- **Duration**: ${Math.floor(duration / 1000)}s\n`;
|
|
111
|
+
}
|
|
112
|
+
md += `\n`;
|
|
113
|
+
return md;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Save progress to file
|
|
117
|
+
*/
|
|
118
|
+
async save(state) {
|
|
119
|
+
const filePath = this.getProgressFilePath();
|
|
120
|
+
const dir = path.dirname(filePath);
|
|
121
|
+
await fs.mkdir(dir, { recursive: true });
|
|
122
|
+
const content = this.generateMarkdown(state);
|
|
123
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
124
|
+
debug(`Progress saved to ${filePath}`);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Load session data from progress file (if exists)
|
|
128
|
+
*/
|
|
129
|
+
async load() {
|
|
130
|
+
const filePath = this.getProgressFilePath();
|
|
131
|
+
try {
|
|
132
|
+
await fs.access(filePath);
|
|
133
|
+
// For now, return null - parsing would require more complex logic
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get session data as JSON
|
|
142
|
+
*/
|
|
143
|
+
toJSON(state) {
|
|
144
|
+
const result = {
|
|
145
|
+
startedAt: formatDate(state.startedAt),
|
|
146
|
+
taskId: state.task.id,
|
|
147
|
+
taskTitle: state.task.title,
|
|
148
|
+
status: state.status,
|
|
149
|
+
iteration: state.iteration,
|
|
150
|
+
maxIterations: this.maxIterations,
|
|
151
|
+
tokensUsed: state.tokensUsed,
|
|
152
|
+
elapsedMs: Date.now() - state.startedAt.getTime(),
|
|
153
|
+
iterations: state.iterations.map((iter) => {
|
|
154
|
+
const iterResult = {
|
|
155
|
+
number: iter.iteration,
|
|
156
|
+
startedAt: formatDate(iter.startedAt),
|
|
157
|
+
tokensUsed: iter.tokensUsed,
|
|
158
|
+
success: iter.success,
|
|
159
|
+
};
|
|
160
|
+
if (iter.endedAt)
|
|
161
|
+
iterResult.endedAt = formatDate(iter.endedAt);
|
|
162
|
+
if (iter.summary)
|
|
163
|
+
iterResult.summary = iter.summary;
|
|
164
|
+
if (iter.error)
|
|
165
|
+
iterResult.error = iter.error;
|
|
166
|
+
return iterResult;
|
|
167
|
+
}),
|
|
168
|
+
};
|
|
169
|
+
if (state.lastCheckpoint) {
|
|
170
|
+
result.lastCheckpoint = state.lastCheckpoint;
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Check if a session exists
|
|
176
|
+
*/
|
|
177
|
+
async hasSession() {
|
|
178
|
+
try {
|
|
179
|
+
await fs.access(this.getProgressFilePath());
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Clear progress file
|
|
188
|
+
*/
|
|
189
|
+
async clear() {
|
|
190
|
+
try {
|
|
191
|
+
await fs.unlink(this.getProgressFilePath());
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// File doesn't exist
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=progress-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-tracker.js","sourceRoot":"","sources":["../../src/core/progress-tracker.ts"],"names":[],"mappings":"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"}
|