agent-trajectories 0.5.9 → 0.6.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 +16 -8
- package/dist/{chunk-JMH3Z5BB.js → chunk-ENWKFNUD.js} +28 -3
- package/dist/chunk-ENWKFNUD.js.map +1 -0
- package/dist/cli/index.js +35 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/{index-B4yIThRL.d.ts → index-DEr3Rs32.d.ts} +9 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/package.json +3 -1
- package/dist/chunk-JMH3Z5BB.js.map +0 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ A **trajectory** is the complete story of agent work on a task:
|
|
|
21
21
|
Works with any task system: Beads, Linear, Jira, GitHub Issues, or standalone. Trajectories are a universal format—like Markdown for documentation.
|
|
22
22
|
|
|
23
23
|
### Multiple Storage Backends
|
|
24
|
-
- **File system** (default) - `.trajectories/` directory, git-friendly
|
|
24
|
+
- **File system** (default) - `.agentworkforce/trajectories/` directory, git-friendly
|
|
25
25
|
- **SQLite** - Local indexing and search
|
|
26
26
|
- **PostgreSQL/S3** - For teams and archival
|
|
27
27
|
|
|
@@ -95,17 +95,25 @@ Over time, trajectories become a searchable knowledge base:
|
|
|
95
95
|
### CLI
|
|
96
96
|
|
|
97
97
|
```bash
|
|
98
|
-
#
|
|
98
|
+
# Run without installing globally
|
|
99
|
+
npx --yes agent-trajectories start "Implement auth module"
|
|
100
|
+
|
|
101
|
+
# Or install globally if you prefer the short trail command
|
|
99
102
|
npm install -g agent-trajectories
|
|
103
|
+
trail start "Implement auth module"
|
|
100
104
|
|
|
101
|
-
# Or install locally
|
|
105
|
+
# Or install locally in a project
|
|
102
106
|
npm install agent-trajectories
|
|
107
|
+
npx --no-install trail start "Implement auth module"
|
|
108
|
+
# or
|
|
109
|
+
npm exec -- trail start "Implement auth module"
|
|
103
110
|
```
|
|
104
111
|
|
|
105
112
|
```bash
|
|
106
113
|
# Start tracking a task
|
|
107
114
|
trail start "Implement auth module"
|
|
108
|
-
# (
|
|
115
|
+
# (for non-global installs, replace `trail` with
|
|
116
|
+
# `npx --yes agent-trajectories`, `npx --no-install trail`, or `npm exec -- trail`)
|
|
109
117
|
|
|
110
118
|
# View current status
|
|
111
119
|
trail status
|
|
@@ -145,7 +153,7 @@ Use `--discard-sources` when the compacted summary should replace the raw source
|
|
|
145
153
|
- name: Compact trajectories
|
|
146
154
|
run: |
|
|
147
155
|
PR_COMMITS=$(git log ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} --format=%H | paste -sd, -)
|
|
148
|
-
OUTPUT=".trajectories/compacted/pr-${{ github.event.pull_request.number }}.json"
|
|
156
|
+
OUTPUT=".agentworkforce/trajectories/compacted/pr-${{ github.event.pull_request.number }}.json"
|
|
149
157
|
if [ -n "$PR_COMMITS" ]; then
|
|
150
158
|
npx agent-trajectories compact --commits "$PR_COMMITS" --output "$OUTPUT" --discard-sources
|
|
151
159
|
else
|
|
@@ -153,7 +161,7 @@ Use `--discard-sources` when the compacted summary should replace the raw source
|
|
|
153
161
|
fi
|
|
154
162
|
- name: Commit compacted trajectories
|
|
155
163
|
run: |
|
|
156
|
-
git add .trajectories/ || true
|
|
164
|
+
git add .agentworkforce/trajectories/ || true
|
|
157
165
|
git diff --cached --quiet || \
|
|
158
166
|
(git commit -m "chore: compact trajectories for PR #${{ github.event.pull_request.number }}" && git push)
|
|
159
167
|
```
|
|
@@ -463,7 +471,7 @@ The client manages trajectories with persistent storage.
|
|
|
463
471
|
```typescript
|
|
464
472
|
const client = new TrajectoryClient({
|
|
465
473
|
defaultAgent: 'my-agent', // Default agent name
|
|
466
|
-
dataDir: '.
|
|
474
|
+
dataDir: '.', // Base directory; stores under .agentworkforce/trajectories
|
|
467
475
|
autoSave: true, // Auto-save after operations
|
|
468
476
|
});
|
|
469
477
|
|
|
@@ -542,7 +550,7 @@ const t = TrajectoryBuilder.create('Task')
|
|
|
542
550
|
This project is in early development. See [PROPOSAL-trajectories.md](./PROPOSAL-trajectories.md) for the full design document.
|
|
543
551
|
|
|
544
552
|
**v1.0 (current)**
|
|
545
|
-
- [x] File-based storage (`.trajectories/`)
|
|
553
|
+
- [x] File-based storage (`.agentworkforce/trajectories/`)
|
|
546
554
|
- [x] Core CLI commands (`start`, `decision`, `complete`, `list`, `show`, `export`)
|
|
547
555
|
- [x] Agent Trace spec compliance (`.trace.json` generation)
|
|
548
556
|
- [x] Multi-agent participation tracking
|
|
@@ -687,6 +687,14 @@ var TRAJECTORY_FILE = "trajectory.json";
|
|
|
687
687
|
var SUMMARY_FILE = "summary.md";
|
|
688
688
|
var COMPACTION_FILE = "compaction.json";
|
|
689
689
|
var LEGACY_COMPACTION_SUFFIX = ".compaction.json";
|
|
690
|
+
var DEFAULT_TRAJECTORY_DATA_DIR = join(
|
|
691
|
+
".agentworkforce",
|
|
692
|
+
"trajectories"
|
|
693
|
+
);
|
|
694
|
+
var LEGACY_TRAJECTORY_DATA_DIR = ".trajectories";
|
|
695
|
+
function getDefaultTrajectoryDataDir(baseDir = process.cwd()) {
|
|
696
|
+
return join(baseDir, DEFAULT_TRAJECTORY_DATA_DIR);
|
|
697
|
+
}
|
|
690
698
|
function expandPath(path) {
|
|
691
699
|
if (path.startsWith("~")) {
|
|
692
700
|
return join(process.env.HOME ?? "", path.slice(1));
|
|
@@ -713,13 +721,15 @@ var FileStorage = class {
|
|
|
713
721
|
activeDir;
|
|
714
722
|
completedDir;
|
|
715
723
|
lastReconcileSummary;
|
|
724
|
+
shouldMigrateLegacyDefault = false;
|
|
716
725
|
constructor(baseDir) {
|
|
717
726
|
this.baseDir = baseDir ?? process.cwd();
|
|
718
727
|
const dataDir = process.env.TRAJECTORIES_DATA_DIR;
|
|
719
728
|
if (dataDir) {
|
|
720
729
|
this.trajectoriesDir = expandPath(dataDir);
|
|
721
730
|
} else {
|
|
722
|
-
this.trajectoriesDir =
|
|
731
|
+
this.trajectoriesDir = getDefaultTrajectoryDataDir(this.baseDir);
|
|
732
|
+
this.shouldMigrateLegacyDefault = true;
|
|
723
733
|
}
|
|
724
734
|
this.activeDir = join(this.trajectoriesDir, "active");
|
|
725
735
|
this.completedDir = join(this.trajectoriesDir, "completed");
|
|
@@ -728,6 +738,7 @@ var FileStorage = class {
|
|
|
728
738
|
* Initialize storage directories
|
|
729
739
|
*/
|
|
730
740
|
async initialize() {
|
|
741
|
+
await this.migrateLegacyDefaultDir();
|
|
731
742
|
await mkdir(this.trajectoriesDir, { recursive: true });
|
|
732
743
|
await mkdir(this.activeDir, { recursive: true });
|
|
733
744
|
await mkdir(this.completedDir, { recursive: true });
|
|
@@ -735,6 +746,17 @@ var FileStorage = class {
|
|
|
735
746
|
await rm(join(this.trajectoriesDir, "index.json"), { force: true });
|
|
736
747
|
await this.reconcileIndex();
|
|
737
748
|
}
|
|
749
|
+
async migrateLegacyDefaultDir() {
|
|
750
|
+
if (!this.shouldMigrateLegacyDefault) {
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
const legacyDir = join(this.baseDir, LEGACY_TRAJECTORY_DATA_DIR);
|
|
754
|
+
if (!existsSync(legacyDir) || existsSync(this.trajectoriesDir)) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
await mkdir(dirname(this.trajectoriesDir), { recursive: true });
|
|
758
|
+
await rename(legacyDir, this.trajectoriesDir);
|
|
759
|
+
}
|
|
738
760
|
/**
|
|
739
761
|
* Scan active/ and completed/ recursively and report trajectory files
|
|
740
762
|
* that can be loaded plus files that should be surfaced by doctor.
|
|
@@ -805,7 +827,7 @@ var FileStorage = class {
|
|
|
805
827
|
return this.lastReconcileSummary;
|
|
806
828
|
}
|
|
807
829
|
/**
|
|
808
|
-
* Move trajectory files that fail to load into `.trajectories/invalid/`
|
|
830
|
+
* Move trajectory files that fail to load into `.agentworkforce/trajectories/invalid/`
|
|
809
831
|
* so reconcile no longer scans them. Only quarantines parse and schema
|
|
810
832
|
* failures — transient io_error failures are left in place because the
|
|
811
833
|
* file may load fine on the next attempt.
|
|
@@ -2407,6 +2429,9 @@ export {
|
|
|
2407
2429
|
exportToMarkdown,
|
|
2408
2430
|
exportToPRSummary,
|
|
2409
2431
|
exportToTimeline,
|
|
2432
|
+
DEFAULT_TRAJECTORY_DATA_DIR,
|
|
2433
|
+
LEGACY_TRAJECTORY_DATA_DIR,
|
|
2434
|
+
getDefaultTrajectoryDataDir,
|
|
2410
2435
|
FileStorage,
|
|
2411
2436
|
compactWorkflow,
|
|
2412
2437
|
TrajectorySession,
|
|
@@ -2420,4 +2445,4 @@ export {
|
|
|
2420
2445
|
getCommitsBetween,
|
|
2421
2446
|
getFilesChangedBetween
|
|
2422
2447
|
};
|
|
2423
|
-
//# sourceMappingURL=chunk-
|
|
2448
|
+
//# sourceMappingURL=chunk-ENWKFNUD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sdk/client.ts","../src/core/id.ts","../src/core/schema.ts","../src/core/trajectory.ts","../src/export/json.ts","../src/export/markdown.ts","../src/export/pr-summary.ts","../src/export/timeline.ts","../src/storage/file.ts","../src/sdk/builder.ts","../src/core/trailers.ts","../src/core/trace.ts"],"sourcesContent":["/**\n * Trajectory SDK Client\n *\n * High-level client for programmatically creating and managing trajectories.\n * Provides a clean, developer-friendly API with automatic storage management.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve as resolvePath } from \"node:path\";\nimport {\n TrajectoryError,\n abandonTrajectory,\n addChapter,\n addDecision,\n addEvent,\n completeTrajectory,\n createTrajectory,\n} from \"../core/trajectory.js\";\nimport type {\n CompleteTrajectoryInput,\n CreateTrajectoryInput,\n Decision,\n EventSignificance,\n Trajectory,\n TrajectoryEventType,\n TrajectoryQuery,\n TrajectorySummary,\n} from \"../core/types.js\";\nimport { exportToJSON } from \"../export/json.js\";\nimport { exportToMarkdown } from \"../export/markdown.js\";\nimport { exportToPRSummary } from \"../export/pr-summary.js\";\nimport { exportToTimeline } from \"../export/timeline.js\";\nimport { FileStorage } from \"../storage/file.js\";\nimport type { StorageAdapter } from \"../storage/interface.js\";\n\nconst require = createRequire(import.meta.url);\n\ninterface TrajectoryCliPackage {\n name?: string;\n bin?: string | Record<string, string>;\n}\n\ninterface TrajectoryCliInvocation {\n command: string;\n args: string[];\n}\n\nfunction normalizeOptionalString(value?: string): string | undefined {\n const normalized = value?.trim();\n return normalized ? normalized : undefined;\n}\n\nfunction normalizeAutoCompactOptions(\n autoCompact?:\n | boolean\n | { mechanical?: boolean; markdown?: boolean; discardSources?: boolean },\n): false | { mechanical: boolean; markdown: boolean; discardSources: boolean } {\n if (!autoCompact) {\n return false;\n }\n\n if (autoCompact === true) {\n return { mechanical: false, markdown: true, discardSources: false };\n }\n\n return {\n mechanical: autoCompact.mechanical ?? false,\n markdown: autoCompact.markdown ?? true,\n discardSources: autoCompact.discardSources ?? false,\n };\n}\n\nfunction resolveStartWorkflowId(\n options?: Omit<CreateTrajectoryInput, \"title\">,\n): string | undefined {\n if (\n options !== undefined &&\n Object.prototype.hasOwnProperty.call(options, \"workflowId\")\n ) {\n return normalizeOptionalString(options.workflowId);\n }\n\n return normalizeOptionalString(process.env.TRAJECTORIES_WORKFLOW_ID);\n}\n\nfunction resolveTrajectoryCliInvocation(): TrajectoryCliInvocation {\n const explicitCli = normalizeOptionalString(process.env.TRAJECTORIES_CLI);\n if (explicitCli) {\n if (/\\.(?:cjs|mjs|js)$/i.test(explicitCli)) {\n return { command: process.execPath, args: [explicitCli] };\n }\n return { command: explicitCli, args: [] };\n }\n\n try {\n const packageJsonPath = require.resolve(\"agent-trajectories/package.json\");\n const pkg = JSON.parse(\n readFileSync(packageJsonPath, \"utf-8\"),\n ) as TrajectoryCliPackage;\n const binEntry =\n typeof pkg.bin === \"string\"\n ? pkg.bin\n : (pkg.bin?.trail ?? (pkg.name ? pkg.bin?.[pkg.name] : undefined));\n\n if (binEntry) {\n const cliPath = resolvePath(dirname(packageJsonPath), binEntry);\n if (existsSync(cliPath)) {\n return { command: process.execPath, args: [cliPath] };\n }\n }\n } catch {\n // Fall back to the CLI on PATH when package resolution is unavailable.\n }\n\n return { command: \"trail\", args: [] };\n}\n\nfunction parseCompactWorkflowOutput(stdout: string): {\n compactedPath: string;\n markdownPath?: string;\n} {\n const compactedPath = stdout.match(\n /^\\s*Compacted trajectory saved to:\\s*(.+)$/m,\n )?.[1];\n const markdownPath = stdout.match(\n /^\\s*Markdown summary saved to:\\s*(.+)$/m,\n )?.[1];\n\n if (!compactedPath) {\n throw new Error(\"compactWorkflow failed: unable to parse compacted path\");\n }\n\n return {\n compactedPath: compactedPath.trim(),\n ...(markdownPath ? { markdownPath: markdownPath.trim() } : {}),\n };\n}\n\nexport async function compactWorkflow(\n workflowId: string,\n options?: {\n markdown?: boolean;\n mechanical?: boolean;\n discardSources?: boolean;\n cwd?: string;\n },\n): Promise<{ compactedPath: string; markdownPath?: string }> {\n const normalizedWorkflowId = normalizeOptionalString(workflowId);\n if (!normalizedWorkflowId) {\n throw new Error(\"compactWorkflow failed: workflowId is required\");\n }\n\n const cli = resolveTrajectoryCliInvocation();\n const args = [\n ...cli.args,\n \"compact\",\n \"--workflow\",\n normalizedWorkflowId,\n \"--all\",\n ];\n\n if (options?.markdown) {\n args.push(\"--markdown\");\n }\n if (options?.mechanical) {\n args.push(\"--mechanical\");\n }\n if (options?.discardSources) {\n args.push(\"--discard-sources\");\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(cli.command, args, {\n cwd: options?.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n const stdoutChunks: Buffer[] = [];\n let stderr = \"\";\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(Buffer.from(chunk));\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n process.stderr.write(chunk);\n });\n\n child.on(\"error\", (error) => {\n reject(new Error(`compactWorkflow failed: ${error.message}`));\n });\n\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(\n new Error(\n `compactWorkflow failed: ${stderr.trim() || `exit code ${code}`}`,\n ),\n );\n return;\n }\n\n try {\n const stdout = Buffer.concat(stdoutChunks).toString(\"utf-8\");\n resolve(parseCompactWorkflowOutput(stdout));\n } catch (error) {\n reject(\n error instanceof Error\n ? error\n : new Error(\"compactWorkflow failed: unable to parse CLI output\"),\n );\n }\n });\n });\n}\n\n/**\n * Options for configuring the TrajectoryClient\n */\nexport interface TrajectoryClientOptions {\n /** Storage adapter to use. Defaults to FileStorage. */\n storage?: StorageAdapter;\n /** Base directory for default file storage. Stores under .agentworkforce/trajectories. */\n dataDir?: string;\n /** Default agent name to use when not specified */\n defaultAgent?: string;\n /** Default project ID. Defaults to current working directory */\n projectId?: string;\n /** Whether to auto-save after each operation. Defaults to true */\n autoSave?: boolean;\n /**\n * When set, session.complete() and session.done() automatically run compactWorkflow() against the trajectory's workflowId. Default false. Pass an object to control the flags passed to the CLI — e.g. { mechanical: true } skips the LLM for deterministic compaction, { markdown: false } skips the .md companion, { discardSources: true } prunes raw source trajectories after compaction.\n */\n autoCompact?:\n | boolean\n | { mechanical?: boolean; markdown?: boolean; discardSources?: boolean };\n}\n\n/**\n * Active trajectory session for chainable operations\n */\nexport class TrajectorySession {\n private trajectory: Trajectory;\n private client: TrajectoryClient;\n private autoSave: boolean;\n\n constructor(\n trajectory: Trajectory,\n client: TrajectoryClient,\n autoSave: boolean,\n ) {\n this.trajectory = trajectory;\n this.client = client;\n this.autoSave = autoSave;\n }\n\n /**\n * Get the current trajectory data\n */\n get data(): Trajectory {\n return this.trajectory;\n }\n\n /**\n * Get the trajectory ID\n */\n get id(): string {\n return this.trajectory.id;\n }\n\n private async autoCompactIfConfigured(): Promise<void> {\n const autoCompact = this.client.getAutoCompactOptions();\n if (!autoCompact || !this.trajectory.workflowId) {\n return;\n }\n\n try {\n await compactWorkflow(this.trajectory.workflowId, {\n ...autoCompact,\n cwd: this.client.getAutoCompactCwd(),\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(\n `Warning: autoCompact failed for workflow ${this.trajectory.workflowId}: ${message}`,\n );\n }\n }\n\n /**\n * Start a new chapter\n * @param title - Chapter title\n * @param agentName - Agent name (uses default if not specified)\n */\n async chapter(title: string, agentName?: string): Promise<TrajectorySession> {\n const agent = agentName ?? this.client.defaultAgent ?? \"default\";\n this.trajectory = addChapter(this.trajectory, { title, agentName: agent });\n if (this.autoSave) {\n await this.client.save(this.trajectory);\n }\n return this;\n }\n\n /**\n * Record an event\n * @param type - Event type\n * @param content - Human-readable content\n * @param options - Additional event options\n */\n async event(\n type: TrajectoryEventType,\n content: string,\n options?: {\n raw?: unknown;\n significance?: EventSignificance;\n tags?: string[];\n },\n ): Promise<TrajectorySession> {\n this.trajectory = addEvent(this.trajectory, {\n type,\n content,\n ...options,\n });\n if (this.autoSave) {\n await this.client.save(this.trajectory);\n }\n return this;\n }\n\n /**\n * Record a note\n */\n async note(\n content: string,\n significance?: EventSignificance,\n ): Promise<TrajectorySession> {\n return this.event(\"note\", content, { significance });\n }\n\n /**\n * Record a finding\n */\n async finding(\n content: string,\n significance?: EventSignificance,\n ): Promise<TrajectorySession> {\n return this.event(\"finding\", content, {\n significance: significance ?? \"medium\",\n });\n }\n\n /**\n * Record a reflection — a higher-level synthesis of recent observations.\n * Used by workflow orchestrators and lead agents to periodically\n * synthesize worker progress and course-correct.\n */\n async reflect(\n content: string,\n confidence?: number,\n ): Promise<TrajectorySession> {\n return this.event(\"reflection\", content, {\n significance: \"high\",\n ...(confidence !== undefined\n ? { tags: [`confidence:${confidence}`] }\n : {}),\n });\n }\n\n /**\n * Record an error\n */\n async error(content: string): Promise<TrajectorySession> {\n return this.event(\"error\", content, { significance: \"high\" });\n }\n\n /**\n * Record a decision\n * @param decision - Structured decision record\n */\n async decision(decision: Decision): Promise<TrajectorySession> {\n this.trajectory = addDecision(this.trajectory, decision);\n if (this.autoSave) {\n await this.client.save(this.trajectory);\n }\n return this;\n }\n\n /**\n * Quick decision helper for simple choices\n * @param question - What was the question/choice?\n * @param chosen - What was chosen\n * @param reasoning - Why this choice was made\n * @param alternatives - Optional list of alternatives considered\n */\n async decide(\n question: string,\n chosen: string,\n reasoning: string,\n alternatives?: Array<{ option: string; reason?: string }>,\n ): Promise<TrajectorySession> {\n return this.decision({\n question,\n chosen,\n reasoning,\n alternatives: alternatives ?? [],\n });\n }\n\n /**\n * Add a tag to the trajectory\n */\n async tag(tag: string): Promise<TrajectorySession> {\n if (!this.trajectory.tags.includes(tag)) {\n this.trajectory = {\n ...this.trajectory,\n tags: [...this.trajectory.tags, tag],\n };\n if (this.autoSave) {\n await this.client.save(this.trajectory);\n }\n }\n return this;\n }\n\n /**\n * Complete the trajectory with a retrospective\n * @param input - Retrospective details\n */\n async complete(input: CompleteTrajectoryInput): Promise<Trajectory> {\n this.trajectory = completeTrajectory(this.trajectory, input);\n await this.client.save(this.trajectory);\n await this.autoCompactIfConfigured();\n return this.trajectory;\n }\n\n /**\n * Quick complete with minimal required fields\n * @param summary - What was accomplished\n * @param confidence - Confidence level (0-1)\n * @param options - Additional optional fields\n */\n async done(\n summary: string,\n confidence: number,\n options?: Partial<Omit<CompleteTrajectoryInput, \"summary\" | \"confidence\">>,\n ): Promise<Trajectory> {\n return this.complete({\n summary,\n confidence,\n approach: options?.approach ?? \"Standard approach\",\n decisions: options?.decisions,\n challenges: options?.challenges,\n learnings: options?.learnings,\n suggestions: options?.suggestions,\n });\n }\n\n /**\n * Abandon the trajectory\n * @param reason - Reason for abandonment\n */\n async abandon(reason?: string): Promise<Trajectory> {\n this.trajectory = abandonTrajectory(this.trajectory, reason);\n await this.client.save(this.trajectory);\n return this.trajectory;\n }\n\n /**\n * Force save the current state\n */\n async save(): Promise<void> {\n await this.client.save(this.trajectory);\n }\n\n /**\n * Export to markdown\n */\n toMarkdown(): string {\n return exportToMarkdown(this.trajectory);\n }\n\n /**\n * Export to JSON\n */\n toJSON(compact?: boolean): string {\n return exportToJSON(this.trajectory, { compact });\n }\n\n /**\n * Export to timeline format\n */\n toTimeline(): string {\n return exportToTimeline(this.trajectory);\n }\n\n /**\n * Export to PR summary format\n */\n toPRSummary(): string {\n return exportToPRSummary(this.trajectory);\n }\n}\n\n/**\n * Main SDK client for trajectory management\n *\n * @example\n * ```typescript\n * import { TrajectoryClient } from 'agent-trajectories/sdk';\n *\n * const client = new TrajectoryClient({ defaultAgent: 'my-agent' });\n * await client.init();\n *\n * // Start a new trajectory\n * const session = await client.start('Implement feature X');\n *\n * // Record work\n * await session\n * .chapter('Research')\n * .note('Found relevant documentation')\n * .decide('Use library A vs B', 'Library A', 'Better TypeScript support');\n *\n * // Complete with retrospective\n * await session.done('Successfully implemented feature X', 0.9);\n * ```\n */\nexport class TrajectoryClient {\n private storage: StorageAdapter;\n private initialized = false;\n readonly defaultAgent?: string;\n private projectId?: string;\n private autoSave: boolean;\n private readonly autoCompactCwd?: string;\n private readonly autoCompact:\n | false\n | { mechanical: boolean; markdown: boolean; discardSources: boolean };\n\n constructor(options: TrajectoryClientOptions = {}) {\n this.storage = options.storage ?? new FileStorage(options.dataDir);\n this.defaultAgent = options.defaultAgent ?? process.env.TRAJECTORIES_AGENT;\n this.projectId = options.projectId ?? process.env.TRAJECTORIES_PROJECT;\n this.autoSave = options.autoSave ?? true;\n this.autoCompact = normalizeAutoCompactOptions(options.autoCompact);\n this.autoCompactCwd = options.storage ? undefined : options.dataDir;\n }\n\n getAutoCompactOptions():\n | false\n | { mechanical: boolean; markdown: boolean; discardSources: boolean } {\n return this.autoCompact;\n }\n\n getAutoCompactCwd(): string | undefined {\n return this.autoCompactCwd;\n }\n\n /**\n * Initialize the client (creates storage directories, etc.)\n * Must be called before using other methods.\n */\n async init(): Promise<void> {\n if (!this.initialized) {\n await this.storage.initialize();\n this.initialized = true;\n }\n }\n\n /**\n * Ensure the client is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new TrajectoryError(\n \"Client not initialized. Call init() first.\",\n \"NOT_INITIALIZED\",\n \"Add 'await client.init()' before using the client\",\n );\n }\n }\n\n /**\n * Start a new trajectory\n * @param title - Task title\n * @param options - Additional creation options\n * @returns A session for the new trajectory\n */\n async start(\n title: string,\n options?: Omit<CreateTrajectoryInput, \"title\">,\n ): Promise<TrajectorySession> {\n this.ensureInitialized();\n\n // Check if there's already an active trajectory\n const active = await this.storage.getActive();\n if (active) {\n throw new TrajectoryError(\n `Active trajectory already exists: ${active.id}`,\n \"ACTIVE_TRAJECTORY_EXISTS\",\n \"Complete or abandon the active trajectory first\",\n );\n }\n\n const workflowId = resolveStartWorkflowId(options);\n const { workflowId: _workflowId, ...createOptions } = options ?? {};\n\n const trajectory = createTrajectory({\n title,\n projectId: this.projectId,\n ...createOptions,\n });\n\n const stampedTrajectory = workflowId\n ? { ...trajectory, workflowId }\n : trajectory;\n\n await this.storage.save(stampedTrajectory);\n return new TrajectorySession(stampedTrajectory, this, this.autoSave);\n }\n\n /**\n * Resume the currently active trajectory\n * @returns Session for active trajectory, or null if none active\n */\n async resume(): Promise<TrajectorySession | null> {\n this.ensureInitialized();\n const active = await this.storage.getActive();\n if (!active) {\n return null;\n }\n return new TrajectorySession(active, this, this.autoSave);\n }\n\n /**\n * Get the active trajectory (without creating a session)\n */\n async getActive(): Promise<Trajectory | null> {\n this.ensureInitialized();\n return this.storage.getActive();\n }\n\n /**\n * Get a trajectory by ID\n * @param id - Trajectory ID\n */\n async get(id: string): Promise<Trajectory | null> {\n this.ensureInitialized();\n return this.storage.get(id);\n }\n\n /**\n * Open a trajectory session by ID\n * @param id - Trajectory ID\n */\n async open(id: string): Promise<TrajectorySession | null> {\n this.ensureInitialized();\n const trajectory = await this.storage.get(id);\n if (!trajectory) {\n return null;\n }\n return new TrajectorySession(trajectory, this, this.autoSave);\n }\n\n /**\n * List trajectories with optional filtering\n * @param query - Query options\n */\n async list(query?: TrajectoryQuery): Promise<TrajectorySummary[]> {\n this.ensureInitialized();\n return this.storage.list(query ?? {});\n }\n\n /**\n * Search trajectories by text\n * @param text - Search text\n * @param limit - Maximum results\n */\n async search(text: string, limit?: number): Promise<TrajectorySummary[]> {\n this.ensureInitialized();\n return this.storage.search(\n text,\n limit !== undefined ? { limit } : undefined,\n );\n }\n\n /**\n * Delete a trajectory\n * @param id - Trajectory ID\n */\n async delete(id: string): Promise<void> {\n this.ensureInitialized();\n await this.storage.delete(id);\n }\n\n /**\n * Save a trajectory to storage\n * @param trajectory - Trajectory to save\n */\n async save(trajectory: Trajectory): Promise<void> {\n this.ensureInitialized();\n await this.storage.save(trajectory);\n }\n\n /**\n * Close the client and release resources\n */\n async close(): Promise<void> {\n if (this.initialized) {\n await this.storage.close();\n this.initialized = false;\n }\n }\n\n /**\n * Export a trajectory to markdown\n * @param id - Trajectory ID\n */\n async exportMarkdown(id: string): Promise<string | null> {\n const trajectory = await this.get(id);\n if (!trajectory) return null;\n return exportToMarkdown(trajectory);\n }\n\n /**\n * Export a trajectory to JSON\n * @param id - Trajectory ID\n * @param compact - Whether to use compact format\n */\n async exportJSON(id: string, compact?: boolean): Promise<string | null> {\n const trajectory = await this.get(id);\n if (!trajectory) return null;\n return exportToJSON(trajectory, { compact });\n }\n\n /**\n * Export a trajectory to timeline format\n * @param id - Trajectory ID\n */\n async exportTimeline(id: string): Promise<string | null> {\n const trajectory = await this.get(id);\n if (!trajectory) return null;\n return exportToTimeline(trajectory);\n }\n\n /**\n * Export a trajectory to PR summary format\n * @param id - Trajectory ID\n */\n async exportPRSummary(id: string): Promise<string | null> {\n const trajectory = await this.get(id);\n if (!trajectory) return null;\n return exportToPRSummary(trajectory);\n }\n}\n","/**\n * ID generation utilities for trajectories and chapters\n *\n * Uses a simple random ID generator to avoid external dependencies.\n * IDs are URL-safe and collision-resistant.\n */\n\nimport { webcrypto } from \"node:crypto\";\n\nconst ALPHABET = \"abcdefghijklmnopqrstuvwxyz0123456789\";\nconst ID_LENGTH = 12;\n\n/**\n * Generate a random ID string\n * @param length - Length of the ID (default: 12)\n * @returns Random alphanumeric string\n */\nexport function generateRandomId(length: number = ID_LENGTH): string {\n let id = \"\";\n const randomValues = new Uint8Array(length);\n webcrypto.getRandomValues(randomValues);\n\n for (let i = 0; i < length; i++) {\n id += ALPHABET[randomValues[i] % ALPHABET.length];\n }\n\n return id;\n}\n\n/**\n * Generate a trajectory ID\n * Format: traj_xxxxxxxxxxxx (traj_ prefix + 12 random chars)\n * @returns Unique trajectory ID\n */\nexport function generateTrajectoryId(): string {\n return `traj_${generateRandomId()}`;\n}\n\n/**\n * Generate a chapter ID\n * Format: chap_xxxxxxxxxxxx (chap_ prefix + 12 random chars)\n * @returns Unique chapter ID\n */\nexport function generateChapterId(): string {\n return `chap_${generateRandomId()}`;\n}\n\n/**\n * Validate a trajectory ID format\n * @param id - The ID to validate\n * @returns True if valid format\n */\nexport function isValidTrajectoryId(id: string): boolean {\n // Accept the canonical 12-char form generated by this library AND the\n // legacy `traj_<timestamp>_<hex>` form produced by external writers\n // like the workforce workflow runner.\n return /^traj_[a-z0-9_]+$/.test(id);\n}\n\n/**\n * Validate a chapter ID format\n * @param id - The ID to validate\n * @returns True if valid format\n */\nexport function isValidChapterId(id: string): boolean {\n return /^chap_[a-z0-9]{12}$/.test(id);\n}\n","/**\n * Zod schemas for runtime validation of trajectory data\n *\n * These schemas validate input at system boundaries and ensure\n * data integrity when reading from storage.\n */\n\nimport { z } from \"zod\";\n\n/**\n * Task source system schema\n */\nexport const TaskSourceSystemSchema = z.union([\n z.literal(\"beads\"),\n z.literal(\"github\"),\n z.literal(\"linear\"),\n z.literal(\"jira\"),\n z.literal(\"plain\"),\n z.string(), // Allow custom systems\n]);\n\n/**\n * Task source schema\n */\nexport const TaskSourceSchema = z.object({\n system: TaskSourceSystemSchema,\n id: z.string().min(1, \"Task ID is required\"),\n url: z.string().url().optional(),\n});\n\n/**\n * Task reference schema\n */\nexport const TaskReferenceSchema = z.object({\n title: z\n .string()\n .min(1, \"Trajectory title is required\")\n .max(500, \"Trajectory title must be 500 characters or less\"),\n description: z.string().optional(),\n source: TaskSourceSchema.optional(),\n});\n\n/**\n * Trajectory status schema\n */\nexport const TrajectoryStatusSchema = z.enum([\n \"active\",\n \"completed\",\n \"abandoned\",\n]);\n\n/** Permissive on read so trajectories from other tools can load even with unknown event types. */\nexport const TrajectoryEventTypeSchema = z.union([\n z.literal(\"prompt\"),\n z.literal(\"thinking\"),\n z.literal(\"tool_call\"),\n z.literal(\"tool_result\"),\n z.literal(\"message_sent\"),\n z.literal(\"message_received\"),\n z.literal(\"decision\"),\n z.literal(\"finding\"),\n z.literal(\"reflection\"),\n z.literal(\"note\"),\n z.literal(\"error\"),\n z.literal(\"completion-evidence\"),\n z.literal(\"completion-marker\"),\n z.string(), // Allow event types emitted by other tools. Downstream code filters to known types.\n]);\n\n/**\n * Event significance schema\n */\nexport const EventSignificanceSchema = z.enum([\n \"low\",\n \"medium\",\n \"high\",\n \"critical\",\n]);\n\n/**\n * Trajectory event schema\n */\nexport const TrajectoryEventSchema = z.object({\n ts: z.number().int().positive(),\n type: TrajectoryEventTypeSchema,\n content: z.string().min(1, \"Event content is required\"),\n raw: z.unknown().optional(),\n significance: EventSignificanceSchema.optional(),\n tags: z.array(z.string()).optional(),\n confidence: z\n .number()\n .min(0, \"Confidence must be between 0 and 1\")\n .max(1, \"Confidence must be between 0 and 1\")\n .optional(),\n});\n\n/**\n * Alternative schema for decision alternatives\n */\nexport const AlternativeSchema = z.object({\n option: z.string().min(1, \"Alternative option is required\"),\n reason: z.string().optional(),\n});\n\n/**\n * Decision schema\n * Note: alternatives supports both string[] (legacy) and Alternative[] (new)\n */\nexport const DecisionSchema = z.object({\n question: z.string().min(1, \"Decision question is required\"),\n chosen: z.string().min(1, \"Chosen option is required\"),\n alternatives: z.array(z.union([z.string(), AlternativeSchema])),\n reasoning: z.string().min(1, \"Decision reasoning is required\"),\n confidence: z\n .number()\n .min(0, \"Confidence must be between 0 and 1\")\n .max(1, \"Confidence must be between 0 and 1\")\n .optional(),\n});\n\n/**\n * Agent participation schema\n */\nexport const AgentParticipationSchema = z.object({\n name: z.string().min(1, \"Agent name is required\"),\n role: z.string().min(1, \"Agent role is required\"),\n joinedAt: z.string().datetime(),\n leftAt: z.string().datetime().optional(),\n});\n\n/**\n * Chapter schema\n */\nexport const ChapterSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1, \"Chapter title is required\"),\n agentName: z.string().min(1, \"Agent name is required\"),\n startedAt: z.string().datetime(),\n endedAt: z.string().datetime().optional(),\n events: z.array(TrajectoryEventSchema),\n});\n\n/**\n * Retrospective schema\n */\nexport const RetrospectiveSchema = z.object({\n summary: z.string().min(1, \"Retrospective summary is required\"),\n approach: z.string().min(1, \"Approach description is required\"),\n decisions: z.array(DecisionSchema).optional(),\n challenges: z.array(z.string()).optional(),\n learnings: z.array(z.string()).optional(),\n suggestions: z.array(z.string()).optional(),\n confidence: z\n .number()\n .min(0, \"Confidence must be between 0 and 1\")\n .max(1, \"Confidence must be between 0 and 1\"),\n timeSpent: z.string().optional(),\n});\n\n// ============================================================================\n// Agent Trace Schemas\n// ============================================================================\n\n/**\n * Trace range schema - represents a range of lines in a file\n */\nexport const TraceRangeSchema = z.object({\n start_line: z.number().int().positive(\"Start line must be positive\"),\n end_line: z.number().int().positive(\"End line must be positive\"),\n revision: z.string().optional(),\n content_hash: z.string().optional(),\n});\n\n/**\n * Contributor type schema\n * Follows agent-trace.dev specification\n */\nexport const ContributorTypeSchema = z.enum([\n \"human\",\n \"ai\",\n \"mixed\",\n \"unknown\",\n]);\n\n/**\n * Trace contributor schema\n * model_id follows models.dev convention (e.g., 'anthropic/claude-opus-4-5-20251101')\n */\nexport const TraceContributorSchema = z.object({\n type: ContributorTypeSchema,\n model_id: z.string().max(250).optional(),\n});\n\n/**\n * Trace conversation schema\n */\nexport const TraceConversationSchema = z.object({\n contributor: TraceContributorSchema,\n url: z.string().url().optional(),\n ranges: z.array(TraceRangeSchema),\n});\n\n/**\n * Trace file schema\n */\nexport const TraceFileSchema = z.object({\n path: z.string().min(1, \"File path is required\"),\n conversations: z.array(TraceConversationSchema),\n});\n\n/**\n * Trace record schema - the main trace type\n * Follows agent-trace.dev specification v0.1.0\n */\nexport const TraceRecordSchema = z.object({\n version: z.string().min(1, \"Version is required\"),\n id: z.string().min(1, \"Trace ID is required\"),\n timestamp: z.string().datetime(),\n trajectory: z.string().optional(),\n files: z.array(TraceFileSchema),\n});\n\n/**\n * Trajectory trace reference schema\n */\nexport const TrajectoryTraceRefSchema = z.object({\n startRef: z.string().min(1, \"Start ref is required\"),\n endRef: z.string().optional(),\n traceId: z.string().optional(),\n});\n\n/**\n * Full trajectory schema\n */\nexport const TrajectorySchema = z.object({\n id: z.string().regex(/^traj_[a-z0-9_]+$/, \"Invalid trajectory ID format\"),\n version: z.literal(1),\n task: TaskReferenceSchema,\n status: TrajectoryStatusSchema,\n startedAt: z.string().datetime(),\n completedAt: z.string().datetime().optional(),\n agents: z.array(AgentParticipationSchema),\n chapters: z.array(ChapterSchema),\n retrospective: RetrospectiveSchema.optional(),\n commits: z.array(z.string()).default([]),\n filesChanged: z.array(z.string()).default([]),\n projectId: z.string().optional(),\n workflowId: z.string().optional(),\n tags: z.array(z.string()).default([]),\n _trace: TrajectoryTraceRefSchema.optional(),\n});\n\n/**\n * Create trajectory input schema\n */\nexport const CreateTrajectoryInputSchema = z.object({\n title: z\n .string()\n .min(1, \"Trajectory title is required\")\n .max(500, \"Trajectory title must be 500 characters or less\"),\n description: z.string().optional(),\n source: TaskSourceSchema.optional(),\n projectId: z.string().optional(),\n tags: z.array(z.string()).optional(),\n});\n\n/**\n * Add chapter input schema\n */\nexport const AddChapterInputSchema = z.object({\n title: z.string().min(1, \"Chapter title is required\"),\n agentName: z.string().min(1, \"Agent name is required\"),\n});\n\n/**\n * Add event input schema\n */\nexport const AddEventInputSchema = z.object({\n type: TrajectoryEventTypeSchema,\n content: z.string().min(1, \"Event content is required\"),\n raw: z.unknown().optional(),\n significance: EventSignificanceSchema.optional(),\n tags: z.array(z.string()).optional(),\n});\n\n/**\n * Complete trajectory input schema\n */\nexport const CompleteTrajectoryInputSchema = z.object({\n summary: z.string().min(1, \"Retrospective summary is required\"),\n approach: z.string().min(1, \"Approach description is required\"),\n decisions: z.array(DecisionSchema).optional(),\n challenges: z.array(z.string()).optional(),\n learnings: z.array(z.string()).optional(),\n suggestions: z.array(z.string()).optional(),\n confidence: z\n .number()\n .min(0, \"Confidence must be between 0 and 1\")\n .max(1, \"Confidence must be between 0 and 1\"),\n});\n\n/**\n * Trajectory query schema\n */\nexport const TrajectoryQuerySchema = z.object({\n status: TrajectoryStatusSchema.optional(),\n since: z.string().datetime().optional(),\n until: z.string().datetime().optional(),\n limit: z.number().int().positive().max(100).optional(),\n offset: z.number().int().nonnegative().optional(),\n sortBy: z.enum([\"startedAt\", \"completedAt\", \"title\"]).optional(),\n sortOrder: z.enum([\"asc\", \"desc\"]).optional(),\n});\n\n/**\n * Validate a trajectory object\n * @param data - The data to validate\n * @returns Validation result with success flag and errors\n */\nexport function validateTrajectory(data: unknown): {\n success: boolean;\n data?: z.infer<typeof TrajectorySchema>;\n errors?: z.ZodError;\n} {\n const result = TrajectorySchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, errors: result.error };\n}\n\n/**\n * Validate create trajectory input\n */\nexport function validateCreateInput(data: unknown): {\n success: boolean;\n data?: z.infer<typeof CreateTrajectoryInputSchema>;\n errors?: z.ZodError;\n} {\n const result = CreateTrajectoryInputSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, errors: result.error };\n}\n\n/**\n * Validate complete trajectory input\n */\nexport function validateCompleteInput(data: unknown): {\n success: boolean;\n data?: z.infer<typeof CompleteTrajectoryInputSchema>;\n errors?: z.ZodError;\n} {\n const result = CompleteTrajectoryInputSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, errors: result.error };\n}\n\n// Type exports inferred from schemas\nexport type TaskSourceSchema = z.infer<typeof TaskSourceSchema>;\nexport type TaskReferenceSchema = z.infer<typeof TaskReferenceSchema>;\nexport type TrajectoryEventSchema = z.infer<typeof TrajectoryEventSchema>;\nexport type ChapterSchema = z.infer<typeof ChapterSchema>;\nexport type RetrospectiveSchema = z.infer<typeof RetrospectiveSchema>;\nexport type TrajectorySchemaType = z.infer<typeof TrajectorySchema>;\nexport type TraceRangeSchemaType = z.infer<typeof TraceRangeSchema>;\nexport type TraceContributorSchemaType = z.infer<typeof TraceContributorSchema>;\nexport type TraceConversationSchemaType = z.infer<\n typeof TraceConversationSchema\n>;\nexport type TraceFileSchemaType = z.infer<typeof TraceFileSchema>;\nexport type TraceRecordSchemaType = z.infer<typeof TraceRecordSchema>;\nexport type TrajectoryTraceRefSchemaType = z.infer<\n typeof TrajectoryTraceRefSchema\n>;\n","/**\n * Trajectory operations\n *\n * Pure functions for creating and manipulating trajectories.\n * These functions return new trajectory objects (immutable updates).\n */\n\nimport { generateChapterId, generateTrajectoryId } from \"./id.js\";\nimport {\n CompleteTrajectoryInputSchema,\n CreateTrajectoryInputSchema,\n} from \"./schema.js\";\nimport type {\n AddChapterInput,\n AddEventInput,\n AgentParticipation,\n Chapter,\n CompleteTrajectoryInput,\n CreateTrajectoryInput,\n Decision,\n Trajectory,\n} from \"./types.js\";\n\n/**\n * Custom error class for trajectory operations\n */\nexport class TrajectoryError extends Error {\n constructor(\n message: string,\n public code: string,\n public suggestion?: string,\n ) {\n super(message);\n this.name = \"TrajectoryError\";\n }\n}\n\n/**\n * Create a new trajectory\n * @param input - Trajectory creation input\n * @returns New trajectory object\n * @throws TrajectoryError if validation fails\n */\nexport function createTrajectory(input: CreateTrajectoryInput): Trajectory {\n // Validate input\n const validation = CreateTrajectoryInputSchema.safeParse(input);\n if (!validation.success) {\n const firstError = validation.error.errors[0];\n throw new TrajectoryError(\n firstError.message,\n \"VALIDATION_ERROR\",\n \"Check your input and try again\",\n );\n }\n\n const now = new Date().toISOString();\n\n return {\n id: generateTrajectoryId(),\n version: 1,\n task: {\n title: input.title,\n description: input.description,\n source: input.source,\n },\n status: \"active\",\n startedAt: now,\n agents: [],\n chapters: [],\n commits: [],\n filesChanged: [],\n projectId: input.projectId ?? process.cwd(),\n tags: input.tags ?? [],\n };\n}\n\n/**\n * Add a chapter to a trajectory\n * @param trajectory - The trajectory to update\n * @param input - Chapter creation input\n * @returns Updated trajectory with new chapter\n * @throws TrajectoryError if trajectory is completed\n */\nexport function addChapter(\n trajectory: Trajectory,\n input: AddChapterInput,\n): Trajectory {\n if (trajectory.status === \"completed\") {\n throw new TrajectoryError(\n \"Cannot add chapter to completed trajectory\",\n \"TRAJECTORY_ALREADY_COMPLETED\",\n \"Start a new trajectory instead\",\n );\n }\n\n const now = new Date().toISOString();\n\n // End the previous chapter if one exists\n const updatedChapters = trajectory.chapters.map((chapter, index) => {\n if (index === trajectory.chapters.length - 1 && !chapter.endedAt) {\n return { ...chapter, endedAt: now };\n }\n return chapter;\n });\n\n const newChapter: Chapter = {\n id: generateChapterId(),\n title: input.title,\n agentName: input.agentName,\n startedAt: now,\n events: [],\n };\n\n // Add agent to trajectory.agents if not already present\n let updatedAgents: AgentParticipation[] = trajectory.agents;\n const agentExists = trajectory.agents.some((a) => a.name === input.agentName);\n if (!agentExists) {\n const isFirstAgent = trajectory.agents.length === 0;\n updatedAgents = [\n ...trajectory.agents,\n {\n name: input.agentName,\n role: isFirstAgent ? \"lead\" : \"contributor\",\n joinedAt: now,\n },\n ];\n }\n\n return {\n ...trajectory,\n agents: updatedAgents,\n chapters: [...updatedChapters, newChapter],\n };\n}\n\n/**\n * Add an event to the current chapter\n * Auto-creates a chapter if none exists\n * @param trajectory - The trajectory to update\n * @param input - Event creation input\n * @returns Updated trajectory with new event\n */\nexport function addEvent(\n trajectory: Trajectory,\n input: AddEventInput,\n): Trajectory {\n // Auto-create a chapter if none exists\n let updatedTrajectory = trajectory;\n if (trajectory.chapters.length === 0) {\n updatedTrajectory = addChapter(trajectory, {\n title: \"Work\",\n agentName: \"default\",\n });\n }\n\n const event = {\n ts: Date.now(),\n type: input.type,\n content: input.content,\n raw: input.raw,\n significance: input.significance,\n tags: input.tags,\n };\n\n const chapters = [...updatedTrajectory.chapters];\n const lastChapter = chapters[chapters.length - 1];\n chapters[chapters.length - 1] = {\n ...lastChapter,\n events: [...lastChapter.events, event],\n };\n\n return {\n ...updatedTrajectory,\n chapters,\n };\n}\n\n/**\n * Add a structured decision to the trajectory\n * @param trajectory - The trajectory to update\n * @param decision - Decision details\n * @returns Updated trajectory with decision event\n */\nexport function addDecision(\n trajectory: Trajectory,\n decision: Decision,\n): Trajectory {\n return addEvent(trajectory, {\n type: \"decision\",\n content: `${decision.question}: ${decision.chosen}`,\n raw: decision,\n significance: \"high\",\n });\n}\n\n/**\n * Complete a trajectory with retrospective\n * @param trajectory - The trajectory to complete\n * @param input - Retrospective input\n * @returns Completed trajectory\n * @throws TrajectoryError if already completed or validation fails\n */\nexport function completeTrajectory(\n trajectory: Trajectory,\n input: CompleteTrajectoryInput,\n): Trajectory {\n if (trajectory.status === \"completed\") {\n throw new TrajectoryError(\n \"Trajectory is already completed\",\n \"TRAJECTORY_ALREADY_COMPLETED\",\n \"Start a new trajectory instead\",\n );\n }\n\n // Validate input\n const validation = CompleteTrajectoryInputSchema.safeParse(input);\n if (!validation.success) {\n const firstError = validation.error.errors[0];\n throw new TrajectoryError(\n firstError.message,\n \"VALIDATION_ERROR\",\n \"Check your input and try again\",\n );\n }\n\n const now = new Date().toISOString();\n\n // End the last chapter if one exists\n const chapters = trajectory.chapters.map((chapter, index) => {\n if (index === trajectory.chapters.length - 1 && !chapter.endedAt) {\n return { ...chapter, endedAt: now };\n }\n return chapter;\n });\n\n return {\n ...trajectory,\n status: \"completed\",\n completedAt: now,\n chapters,\n retrospective: {\n summary: input.summary,\n approach: input.approach,\n decisions: input.decisions,\n challenges: input.challenges,\n learnings: input.learnings,\n suggestions: input.suggestions,\n confidence: input.confidence,\n },\n };\n}\n\n/**\n * Abandon a trajectory without completing\n * @param trajectory - The trajectory to abandon\n * @param reason - Reason for abandonment\n * @returns Abandoned trajectory\n */\nexport function abandonTrajectory(\n trajectory: Trajectory,\n reason?: string,\n): Trajectory {\n const now = new Date().toISOString();\n\n // End the last chapter if one exists\n const chapters = trajectory.chapters.map((chapter, index) => {\n if (index === trajectory.chapters.length - 1 && !chapter.endedAt) {\n return { ...chapter, endedAt: now };\n }\n return chapter;\n });\n\n // Add abandonment note if reason provided\n let updatedChapters = chapters;\n if (reason && chapters.length > 0) {\n const lastChapter = chapters[chapters.length - 1];\n updatedChapters = [\n ...chapters.slice(0, -1),\n {\n ...lastChapter,\n events: [\n ...lastChapter.events,\n {\n ts: Date.now(),\n type: \"note\" as const,\n content: `Abandoned: ${reason}`,\n significance: \"high\" as const,\n },\n ],\n },\n ];\n }\n\n return {\n ...trajectory,\n status: \"abandoned\",\n completedAt: now,\n chapters: updatedChapters,\n };\n}\n","/**\n * JSON export for trajectories\n */\n\nimport type { Trajectory } from \"../core/types.js\";\n\nexport interface JSONExportOptions {\n /** Output compact JSON without formatting */\n compact?: boolean;\n}\n\n/**\n * Export a trajectory to JSON format\n * @param trajectory - The trajectory to export\n * @param options - Export options\n * @returns JSON string\n */\nexport function exportToJSON(\n trajectory: Trajectory,\n options?: JSONExportOptions,\n): string {\n if (options?.compact) {\n return JSON.stringify(trajectory);\n }\n return JSON.stringify(trajectory, null, 2);\n}\n","/**\n * Markdown export for trajectories\n *\n * Generates human-readable Notion-style documentation.\n */\n\nimport type { Decision, Trajectory } from \"../core/types.js\";\n\n/**\n * Export a trajectory to markdown format\n * @param trajectory - The trajectory to export\n * @returns Markdown string\n */\nexport function exportToMarkdown(trajectory: Trajectory): string {\n const lines: string[] = [];\n\n // Title\n lines.push(`# Trajectory: ${trajectory.task.title}`);\n lines.push(\"\");\n\n // Metadata block\n lines.push(`> **Status:** ${formatStatus(trajectory.status)}`);\n if (trajectory.task.source) {\n const linkText = trajectory.task.source.url\n ? `[${trajectory.task.source.id}](${trajectory.task.source.url})`\n : trajectory.task.source.id;\n lines.push(`> **Task:** ${linkText}`);\n }\n if (trajectory.retrospective?.confidence !== undefined) {\n lines.push(\n `> **Confidence:** ${Math.round(trajectory.retrospective.confidence * 100)}%`,\n );\n }\n lines.push(`> **Started:** ${formatDate(trajectory.startedAt)}`);\n if (trajectory.completedAt) {\n lines.push(`> **Completed:** ${formatDate(trajectory.completedAt)}`);\n }\n lines.push(\"\");\n\n // Summary (from retrospective)\n if (trajectory.retrospective) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Summary\");\n lines.push(\"\");\n lines.push(trajectory.retrospective.summary);\n lines.push(\"\");\n\n if (trajectory.retrospective.approach) {\n lines.push(`**Approach:** ${trajectory.retrospective.approach}`);\n lines.push(\"\");\n }\n }\n\n // Key Decisions\n const decisions = extractDecisions(trajectory);\n if (decisions.length > 0) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Key Decisions\");\n lines.push(\"\");\n\n for (const decision of decisions) {\n lines.push(`### ${decision.question}`);\n lines.push(`- **Chose:** ${decision.chosen}`);\n if (decision.alternatives.length > 0) {\n const altStrings = decision.alternatives.map((a) =>\n typeof a === \"string\" ? a : a.option,\n );\n lines.push(`- **Rejected:** ${altStrings.join(\", \")}`);\n }\n lines.push(`- **Reasoning:** ${decision.reasoning}`);\n lines.push(\"\");\n }\n }\n\n // Chapters\n if (trajectory.chapters.length > 0) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Chapters\");\n lines.push(\"\");\n\n trajectory.chapters.forEach((chapter, index) => {\n lines.push(`### ${index + 1}. ${chapter.title}`);\n lines.push(`*Agent: ${chapter.agentName}*`);\n lines.push(\"\");\n\n if (chapter.events.length > 0) {\n const significantEvents = chapter.events.filter(\n (e) =>\n e.significance === \"high\" ||\n e.significance === \"critical\" ||\n e.type === \"decision\",\n );\n if (significantEvents.length > 0) {\n for (const event of significantEvents) {\n lines.push(`- ${event.content}`);\n }\n lines.push(\"\");\n }\n }\n });\n }\n\n // Challenges\n if (\n trajectory.retrospective?.challenges &&\n trajectory.retrospective.challenges.length > 0\n ) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Challenges\");\n lines.push(\"\");\n for (const challenge of trajectory.retrospective.challenges) {\n lines.push(`- ${challenge}`);\n }\n lines.push(\"\");\n }\n\n // Learnings\n if (\n trajectory.retrospective?.learnings &&\n trajectory.retrospective.learnings.length > 0\n ) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Learnings\");\n lines.push(\"\");\n for (const learning of trajectory.retrospective.learnings) {\n lines.push(`- ${learning}`);\n }\n lines.push(\"\");\n }\n\n // Suggestions\n if (\n trajectory.retrospective?.suggestions &&\n trajectory.retrospective.suggestions.length > 0\n ) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Suggestions\");\n lines.push(\"\");\n for (const suggestion of trajectory.retrospective.suggestions) {\n lines.push(`- ${suggestion}`);\n }\n lines.push(\"\");\n }\n\n // Artifacts\n if (trajectory.commits.length > 0 || trajectory.filesChanged.length > 0) {\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(\"## Artifacts\");\n lines.push(\"\");\n if (trajectory.commits.length > 0) {\n lines.push(`**Commits:** ${trajectory.commits.join(\", \")}`);\n }\n if (trajectory.filesChanged.length > 0) {\n lines.push(`**Files changed:** ${trajectory.filesChanged.length}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n// Helper functions\n\nfunction formatStatus(status: string): string {\n switch (status) {\n case \"active\":\n return \"🔄 Active\";\n case \"completed\":\n return \"✅ Completed\";\n case \"abandoned\":\n return \"❌ Abandoned\";\n default:\n return status;\n }\n}\n\nfunction formatDate(isoString: string): string {\n const date = new Date(isoString);\n return date.toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nfunction extractDecisions(trajectory: Trajectory): Decision[] {\n const decisions: Decision[] = [];\n\n // From retrospective\n if (trajectory.retrospective?.decisions) {\n decisions.push(...trajectory.retrospective.decisions);\n }\n\n // From events\n for (const chapter of trajectory.chapters) {\n for (const event of chapter.events) {\n if (event.type === \"decision\" && event.raw) {\n const raw = event.raw as Decision;\n if (raw.question && raw.chosen && raw.reasoning) {\n // Avoid duplicates\n if (!decisions.some((d) => d.question === raw.question)) {\n decisions.push(raw);\n }\n }\n }\n }\n }\n\n return decisions;\n}\n","/**\n * PR Summary export for trajectories\n *\n * Generates a concise summary suitable for pull request descriptions.\n */\n\nimport type { Trajectory } from \"../core/types.js\";\n\nexport interface PRSummaryOptions {\n /** Path to the full trajectory file for linking */\n trajectoryPath?: string;\n}\n\n/**\n * Export a trajectory to PR summary format\n * @param trajectory - The trajectory to export\n * @param options - Export options\n * @returns PR summary markdown string\n */\nexport function exportToPRSummary(\n trajectory: Trajectory,\n options?: PRSummaryOptions,\n): string {\n const lines: string[] = [];\n\n lines.push(\"## Trajectory Summary\");\n lines.push(\"\");\n\n // Summary\n if (trajectory.retrospective?.summary) {\n lines.push(trajectory.retrospective.summary);\n lines.push(\"\");\n }\n\n // Key metrics\n const decisionCount = trajectory.chapters.reduce(\n (count, chapter) =>\n count + chapter.events.filter((e) => e.type === \"decision\").length,\n 0,\n );\n\n lines.push(`**Key decisions:** ${decisionCount}`);\n\n if (trajectory.retrospective?.confidence !== undefined) {\n lines.push(\n `**Confidence:** ${Math.round(trajectory.retrospective.confidence * 100)}%`,\n );\n }\n\n // Link to full trajectory\n if (options?.trajectoryPath) {\n lines.push(\"\");\n lines.push(`[Full trajectory](${options.trajectoryPath})`);\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Timeline export for trajectories\n *\n * Generates a chronological Linear-style view.\n */\n\nimport type { Trajectory } from \"../core/types.js\";\n\n/**\n * Export a trajectory to timeline format\n * @param trajectory - The trajectory to export\n * @returns Timeline string\n */\nexport function exportToTimeline(trajectory: Trajectory): string {\n const lines: string[] = [];\n\n // Start marker\n lines.push(\n `● ${formatTime(trajectory.startedAt)} Started: ${trajectory.task.title}`,\n );\n lines.push(\"│\");\n\n // Chapters and events\n for (const chapter of trajectory.chapters) {\n lines.push(\n `├─ ${formatTime(chapter.startedAt)} Chapter: ${chapter.title}`,\n );\n lines.push(`│ Agent: ${chapter.agentName}`);\n lines.push(\"│\");\n\n for (const event of chapter.events) {\n const prefix = event.type === \"decision\" ? \"├─ Decision: \" : \"├─ \";\n const timeStr = formatTime(new Date(event.ts).toISOString());\n\n if (event.type === \"decision\") {\n lines.push(`│ ${timeStr} ${prefix}${event.content}`);\n } else if (\n event.significance === \"high\" ||\n event.significance === \"critical\"\n ) {\n lines.push(`│ ${timeStr} ${prefix}${event.content}`);\n }\n }\n\n if (chapter.endedAt) {\n lines.push(\"│\");\n }\n }\n\n // End marker\n if (trajectory.completedAt) {\n const status =\n trajectory.status === \"completed\" ? \"Completed\" : \"Abandoned\";\n lines.push(`○ ${formatTime(trajectory.completedAt)} ${status}`);\n\n if (trajectory.retrospective) {\n lines.push(\"\");\n lines.push(` Summary: ${trajectory.retrospective.summary}`);\n lines.push(\n ` Confidence: ${Math.round(trajectory.retrospective.confidence * 100)}%`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatTime(isoString: string): string {\n const date = new Date(isoString);\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n","/**\n * File system storage adapter for trajectories\n *\n * Stores each trajectory in its own directory under .agentworkforce/trajectories.\n * Active trajectories go in active/<id>/, completed in completed/YYYY-MM/<id>/.\n */\n\nimport { type Dirent, existsSync } from \"node:fs\";\nimport {\n mkdir,\n readFile,\n readdir,\n rename,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from \"node:path\";\nimport type { z } from \"zod\";\nimport { validateTrajectory } from \"../core/schema.js\";\nimport type {\n Trajectory,\n TrajectoryQuery,\n TrajectorySummary,\n} from \"../core/types.js\";\nimport { exportToMarkdown } from \"../export/markdown.js\";\nimport type { StorageAdapter } from \"./interface.js\";\n\nconst TRAJECTORY_FILE = \"trajectory.json\";\nconst SUMMARY_FILE = \"summary.md\";\nconst COMPACTION_FILE = \"compaction.json\";\nconst LEGACY_COMPACTION_SUFFIX = \".compaction.json\";\nexport const DEFAULT_TRAJECTORY_DATA_DIR = join(\n \".agentworkforce\",\n \"trajectories\",\n);\nexport const LEGACY_TRAJECTORY_DATA_DIR = \".trajectories\";\n\nexport function getDefaultTrajectoryDataDir(baseDir = process.cwd()): string {\n return join(baseDir, DEFAULT_TRAJECTORY_DATA_DIR);\n}\n\n/**\n * Expand ~ to home directory in a path\n */\nfunction expandPath(path: string): string {\n if (path.startsWith(\"~\")) {\n return join(process.env.HOME ?? \"\", path.slice(1));\n }\n return path;\n}\n\n/**\n * Get trajectory search paths from environment variable\n * TRAJECTORIES_SEARCH_PATHS is colon-separated (like PATH)\n * Falls back to current directory's .agentworkforce/trajectories if not set\n */\nexport function getSearchPaths(): string[] {\n const searchPathsEnv = process.env.TRAJECTORIES_SEARCH_PATHS;\n if (searchPathsEnv) {\n return searchPathsEnv\n .split(\":\")\n .map((p) => p.trim())\n .filter(Boolean)\n .map(expandPath);\n }\n\n // Default: check for TRAJECTORIES_DATA_DIR, then fall back to ./.agentworkforce/trajectories\n const dataDir = process.env.TRAJECTORIES_DATA_DIR;\n if (dataDir) {\n return [expandPath(dataDir)];\n }\n\n return [getDefaultTrajectoryDataDir()];\n}\n\ninterface CompactionMarker {\n trajectoryId: string;\n compactedInto: string;\n compactedAt: string;\n}\n\nexport interface DeleteTrajectorySummary {\n removedTrajectories: number;\n deletedJsonFiles: number;\n deletedMarkdownFiles: number;\n deletedTraceFiles: number;\n deletedCompactionFiles: number;\n}\n\n/**\n * Tagged result from reading a trajectory file. Lets callers distinguish\n * missing files, malformed JSON, and schema violations so they can pick\n * their own policy (reconcile counts and moves on; `get()` returns null;\n * a future `getStrict()` could throw).\n */\nexport type ReadTrajectoryResult =\n | { ok: true; trajectory: Trajectory }\n | {\n ok: false;\n reason: \"malformed_json\" | \"schema_violation\" | \"io_error\";\n path: string;\n error: unknown;\n };\n\n/**\n * Reason a single trajectory file was skipped during reconcile.\n */\nexport type ReconcileFailureReason =\n | \"malformed_json\"\n | \"schema_violation\"\n | \"io_error\";\n\n/**\n * Per-file failure record for a skipped trajectory. `message` is a\n * pre-rendered, single-line description suitable for direct display in\n * CLI output — callers should not have to know about Zod or fs error\n * shapes to render diagnostics.\n */\nexport interface ReconcileFailure {\n path: string;\n reason: ReconcileFailureReason;\n message: string;\n}\n\n/**\n * Aggregated counts emitted by reconcileIndex for observability. Exposed\n * on the return value so tests and callers can assert on counts without\n * parsing log output. `failures` carries the per-file detail so a CLI\n * doctor or `--verbose` mode can print actionable info without re-walking\n * the directory tree.\n */\nexport interface ReconcileSummary {\n scanned: number;\n added: number;\n alreadyIndexed: number;\n skippedMalformedJson: number;\n skippedSchemaViolation: number;\n skippedIoError: number;\n failures: ReconcileFailure[];\n}\n\n/**\n * Render a read failure into a single-line, human-readable message.\n * Knows enough about Zod and Node's fs errors to extract the most\n * useful field; falls back to String(error) for anything else.\n */\nfunction describeReadFailure(\n reason: ReconcileFailureReason,\n error: unknown,\n): string {\n if (\n reason === \"schema_violation\" &&\n error &&\n typeof error === \"object\" &&\n \"issues\" in error\n ) {\n const issues = (error as z.ZodError).issues ?? [];\n if (issues.length > 0) {\n const first = issues[0];\n const where = first.path.length > 0 ? first.path.join(\".\") : \"root\";\n const extra = issues.length > 1 ? ` (+${issues.length - 1} more)` : \"\";\n return `${where}: ${first.message}${extra}`;\n }\n return \"schema validation failed\";\n }\n if (error instanceof Error) return error.message;\n return String(error);\n}\n\n/**\n * File system storage adapter\n */\nexport class FileStorage implements StorageAdapter {\n private baseDir: string;\n private trajectoriesDir: string;\n private activeDir: string;\n private completedDir: string;\n private lastReconcileSummary?: ReconcileSummary;\n private shouldMigrateLegacyDefault = false;\n\n constructor(baseDir?: string) {\n this.baseDir = baseDir ?? process.cwd();\n\n // Check for TRAJECTORIES_DATA_DIR env var first\n // When set, use the path directly (no default suffix)\n const dataDir = process.env.TRAJECTORIES_DATA_DIR;\n if (dataDir) {\n this.trajectoriesDir = expandPath(dataDir);\n } else {\n this.trajectoriesDir = getDefaultTrajectoryDataDir(this.baseDir);\n this.shouldMigrateLegacyDefault = true;\n }\n\n this.activeDir = join(this.trajectoriesDir, \"active\");\n this.completedDir = join(this.trajectoriesDir, \"completed\");\n }\n\n /**\n * Initialize storage directories\n */\n async initialize(): Promise<void> {\n await this.migrateLegacyDefaultDir();\n await mkdir(this.trajectoriesDir, { recursive: true });\n await mkdir(this.activeDir, { recursive: true });\n await mkdir(this.completedDir, { recursive: true });\n\n await this.migrateLegacyIndexCompactionMarkers();\n await rm(join(this.trajectoriesDir, \"index.json\"), { force: true });\n\n // Scan on-disk trajectories so status/doctor can surface invalid files.\n await this.reconcileIndex();\n }\n\n private async migrateLegacyDefaultDir(): Promise<void> {\n if (!this.shouldMigrateLegacyDefault) {\n return;\n }\n\n const legacyDir = join(this.baseDir, LEGACY_TRAJECTORY_DATA_DIR);\n if (!existsSync(legacyDir) || existsSync(this.trajectoriesDir)) {\n return;\n }\n\n await mkdir(dirname(this.trajectoriesDir), { recursive: true });\n await rename(legacyDir, this.trajectoriesDir);\n }\n\n /**\n * Scan active/ and completed/ recursively and report trajectory files\n * that can be loaded plus files that should be surfaced by doctor.\n *\n * Handles three on-disk layouts in completed/:\n * - flat: completed/{id}.json (legacy workforce data)\n * - monthly: completed/YYYY-MM/{id}.json (legacy monthly layout)\n * - directory: completed/YYYY-MM/{id}/trajectory.json (current layout)\n * - nested: completed/.../{id}.json (defensive — any depth)\n *\n * The method name is kept for callers such as `trail doctor`, but no\n * shared index file is written.\n */\n async reconcileIndex(): Promise<ReconcileSummary> {\n const summary: ReconcileSummary = {\n scanned: 0,\n added: 0,\n alreadyIndexed: 0,\n skippedMalformedJson: 0,\n skippedSchemaViolation: 0,\n skippedIoError: 0,\n failures: [],\n };\n\n const discovered = await this.listTrajectoryFiles();\n\n for (const filePath of discovered) {\n summary.scanned += 1;\n const result = await this.readTrajectoryFile(filePath);\n if (!result.ok) {\n if (result.reason === \"malformed_json\") {\n summary.skippedMalformedJson += 1;\n } else if (result.reason === \"schema_violation\") {\n summary.skippedSchemaViolation += 1;\n } else {\n summary.skippedIoError += 1;\n }\n summary.failures.push({\n path: result.path,\n reason: result.reason,\n message: describeReadFailure(result.reason, result.error),\n });\n continue;\n }\n summary.added += 1;\n }\n\n // Only log when something interesting happened. Noise is worse than\n // silence here — the CLI spinner is the user's feedback.\n const hadSkips =\n summary.skippedMalformedJson +\n summary.skippedSchemaViolation +\n summary.skippedIoError >\n 0;\n if (hadSkips) {\n const parts = [`reconciled ${summary.added}/${summary.scanned}`];\n if (summary.skippedMalformedJson > 0) {\n parts.push(`malformed: ${summary.skippedMalformedJson}`);\n }\n if (summary.skippedSchemaViolation > 0) {\n parts.push(`invalid: ${summary.skippedSchemaViolation}`);\n }\n if (summary.skippedIoError > 0) {\n parts.push(`io: ${summary.skippedIoError}`);\n }\n console.warn(`[trajectories] ${parts.join(\", \")}`);\n }\n\n this.lastReconcileSummary = summary;\n return summary;\n }\n\n /**\n * Returns the most recent reconcile summary, if any. Lets the CLI\n * inspect the failures collected during `initialize()` without having\n * to re-walk the directory tree (and re-emit the warn line).\n */\n getLastReconcileSummary(): ReconcileSummary | undefined {\n return this.lastReconcileSummary;\n }\n\n /**\n * Move trajectory files that fail to load into `.agentworkforce/trajectories/invalid/`\n * so reconcile no longer scans them. Only quarantines parse and schema\n * failures — transient io_error failures are left in place because the\n * file may load fine on the next attempt.\n *\n * Returns the list of files that were moved (with their original paths\n * and the destination directory) so the caller can report what changed.\n */\n async quarantineInvalid(): Promise<{\n moved: ReconcileFailure[];\n targetDir: string;\n }> {\n const summary = await this.reconcileIndex();\n const targetDir = join(this.trajectoriesDir, \"invalid\");\n const candidates = summary.failures.filter((f) => f.reason !== \"io_error\");\n if (candidates.length === 0) {\n return { moved: [], targetDir };\n }\n await mkdir(targetDir, { recursive: true });\n const moved: ReconcileFailure[] = [];\n for (const failure of candidates) {\n const dest = await this.resolveQuarantineDest(failure.path, targetDir);\n try {\n await mkdir(dirname(dest), { recursive: true });\n await rename(failure.path, dest);\n moved.push(failure);\n } catch (error) {\n // Skip and surface — never silently lose a file. The doctor\n // command rolls these into its output so the user can intervene.\n console.warn(\n `[trajectories] failed to quarantine ${failure.path}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n return { moved, targetDir };\n }\n\n /**\n * Pick a destination path under `targetDir` for a quarantined file.\n *\n * Preserves the file's relative location under the trajectories root\n * (e.g. `completed/2026-04/foo.json` → `invalid/completed/2026-04/foo.json`)\n * so two invalid files that share a basename across `active/` and\n * `completed/` don't collapse onto each other and silently overwrite.\n *\n * Falls back to a numeric-suffix scheme for paths that live outside\n * the trajectories directory or that, after relative resolution, would\n * still collide with something already quarantined.\n */\n private async resolveQuarantineDest(\n sourcePath: string,\n targetDir: string,\n ): Promise<string> {\n const rel = relative(this.trajectoriesDir, sourcePath);\n const safeRel =\n rel && !rel.startsWith(\"..\") && !isAbsolute(rel)\n ? rel\n : basename(sourcePath);\n let dest = join(targetDir, safeRel);\n if (!existsSync(dest)) return dest;\n\n // Defensive: someone (or a previous quarantine run) already put a\n // file at this path. Append an incrementing suffix so we still keep\n // both copies for inspection.\n const ext = safeRel.endsWith(\".json\") ? \".json\" : \"\";\n const stem = ext ? safeRel.slice(0, -ext.length) : safeRel;\n for (let i = 1; i < 1000; i += 1) {\n dest = join(targetDir, `${stem}.${i}${ext}`);\n if (!existsSync(dest)) return dest;\n }\n // 1000 collisions on the same basename is pathological; fall through\n // with the last candidate so rename surfaces the EEXIST itself.\n return dest;\n }\n\n /**\n * Recursively collect trajectory JSON file paths under `dir` into `out`.\n * Silently treats a missing directory as empty.\n */\n private async walkJsonFilesInto(dir: string, out: string[]): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n await this.walkJsonFilesInto(entryPath, out);\n } else if (entry.isFile() && isTrajectoryJsonFile(entry.name)) {\n out.push(entryPath);\n }\n }\n }\n\n /**\n * Save a trajectory.\n *\n * Validates the input against the trajectory schema before touching\n * disk. Closes the historical read/write asymmetry where save() would\n * happily write data that the reader then rejected, producing files\n * that could never be loaded back.\n */\n async save(input: Trajectory): Promise<void> {\n const validation = validateTrajectory(input);\n if (!validation.success) {\n const issues =\n validation.errors?.issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"root\";\n return `${path}: ${issue.message}`;\n })\n .join(\"; \") ?? \"unknown validation error\";\n throw new Error(`Cannot save invalid trajectory: ${issues}`);\n }\n // Use the parsed (defaulted) trajectory so newly-written files\n // always carry normalized fields like commits/filesChanged/tags.\n const trajectory = validation.data as Trajectory;\n\n const isCompleted =\n trajectory.status === \"completed\" || trajectory.status === \"abandoned\";\n\n const existingPaths = await this.findTrajectoryFilePaths(trajectory.id);\n let trajectoryDir: string;\n if (isCompleted) {\n const date = new Date(trajectory.completedAt ?? trajectory.startedAt);\n const monthDir = join(\n this.completedDir,\n `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, \"0\")}`,\n );\n trajectoryDir = join(monthDir, trajectory.id);\n } else {\n trajectoryDir = join(this.activeDir, trajectory.id);\n }\n\n const filePath = join(trajectoryDir, TRAJECTORY_FILE);\n await this.removeTrajectoryFiles(existingPaths, filePath);\n await mkdir(trajectoryDir, { recursive: true });\n\n if (isCompleted) {\n const markdown = exportToMarkdown(trajectory);\n await writeFile(join(trajectoryDir, SUMMARY_FILE), markdown, \"utf-8\");\n }\n\n await writeFile(filePath, JSON.stringify(trajectory, null, 2), \"utf-8\");\n }\n\n /**\n * Get a trajectory by ID\n */\n async get(id: string): Promise<Trajectory | null> {\n for (const filePath of this.getActiveCandidatePaths(id)) {\n if (!existsSync(filePath)) continue;\n const trajectory = await this.readTrajectoryOrNull(filePath);\n if (trajectory?.id === id) {\n return trajectory;\n }\n }\n\n const paths = await this.findTrajectoryFilePaths(id);\n for (const filePath of paths) {\n const trajectory = await this.readTrajectoryOrNull(filePath);\n if (trajectory?.id === id) {\n return trajectory;\n }\n }\n\n return null;\n }\n\n /**\n * Get the currently active trajectory\n */\n async getActive(): Promise<Trajectory | null> {\n const activeFiles = await this.collectTrajectoryFiles(this.activeDir);\n\n if (activeFiles.length === 0) {\n return null;\n }\n\n // Get most recently started\n let mostRecent: Trajectory | null = null;\n let mostRecentTime = 0;\n\n for (const filePath of activeFiles) {\n const trajectory = await this.readTrajectoryOrNull(filePath);\n if (trajectory?.status !== \"active\") continue;\n\n const startTime = new Date(trajectory.startedAt).getTime();\n if (startTime > mostRecentTime) {\n mostRecentTime = startTime;\n mostRecent = trajectory;\n }\n }\n\n return mostRecent;\n }\n\n /**\n * List trajectories with optional filtering\n */\n async list(query: TrajectoryQuery): Promise<TrajectorySummary[]> {\n let trajectories = await this.loadAllTrajectories();\n\n // Filter by status\n if (query.status) {\n trajectories = trajectories.filter((t) => t.status === query.status);\n }\n\n // Filter by date range\n if (query.since) {\n const sinceTime = new Date(query.since).getTime();\n trajectories = trajectories.filter(\n (trajectory) => new Date(trajectory.startedAt).getTime() >= sinceTime,\n );\n }\n if (query.until) {\n const untilTime = new Date(query.until).getTime();\n trajectories = trajectories.filter(\n (trajectory) => new Date(trajectory.startedAt).getTime() <= untilTime,\n );\n }\n\n // Sort (default: startedAt desc)\n const sortBy = query.sortBy ?? \"startedAt\";\n const sortOrder = query.sortOrder ?? \"desc\";\n trajectories.sort((a, b) => {\n const aVal = this.getSortValue(a, sortBy);\n const bVal = this.getSortValue(b, sortBy);\n const cmp = String(aVal).localeCompare(String(bVal));\n return sortOrder === \"asc\" ? cmp : -cmp;\n });\n\n // Pagination\n const offset = query.offset ?? 0;\n const limit = query.limit ?? 500;\n trajectories = trajectories.slice(offset, offset + limit);\n\n // Convert to summaries\n return trajectories.map((trajectory) => this.toSummary(trajectory));\n }\n\n /**\n * Delete a trajectory\n */\n async delete(id: string): Promise<void> {\n await this.deleteWithSummary(id);\n }\n\n /**\n * Search trajectories by text\n */\n async search(\n text: string,\n options?: { limit?: number },\n ): Promise<TrajectorySummary[]> {\n const allTrajectories = await this.list({});\n const searchLower = text.toLowerCase();\n const limit = options?.limit ?? 20;\n\n const matches: TrajectorySummary[] = [];\n\n for (const summary of allTrajectories) {\n if (matches.length >= limit) break;\n\n // Check title\n if (summary.title.toLowerCase().includes(searchLower)) {\n matches.push(summary);\n continue;\n }\n\n // Load full trajectory for deeper search\n const trajectory = await this.get(summary.id);\n if (!trajectory) continue;\n\n // Check retrospective\n if (\n trajectory.retrospective?.summary.toLowerCase().includes(searchLower)\n ) {\n matches.push(summary);\n continue;\n }\n\n // Check decisions\n const hasMatchingDecision = trajectory.chapters.some((chapter) =>\n chapter.events.some(\n (event) =>\n event.type === \"decision\" &&\n event.content.toLowerCase().includes(searchLower),\n ),\n );\n if (hasMatchingDecision) {\n matches.push(summary);\n }\n }\n\n return matches;\n }\n\n /**\n * Mark a trajectory as compacted without writing to a shared index.\n */\n async markCompacted(id: string, compactedInto: string): Promise<boolean> {\n const markedIds = await this.markCompactedMany([id], compactedInto);\n return markedIds.has(id);\n }\n\n /**\n * Mark multiple trajectories as compacted with one filesystem scan.\n */\n async markCompactedMany(\n ids: string[],\n compactedInto: string,\n ): Promise<Set<string>> {\n const pathsById = await this.findTrajectoryFilePathsForIds(ids);\n const markedIds = new Set<string>();\n const compactedAt = new Date().toISOString();\n const writes: Promise<void>[] = [];\n\n for (const [id, paths] of pathsById.entries()) {\n if (paths.length === 0) {\n continue;\n }\n\n markedIds.add(id);\n const marker: CompactionMarker = {\n trajectoryId: id,\n compactedInto,\n compactedAt,\n };\n\n for (const filePath of paths) {\n writes.push(\n writeFile(\n this.getCompactionMarkerPath(filePath, id),\n JSON.stringify(marker, null, 2),\n \"utf-8\",\n ),\n );\n }\n }\n\n await Promise.all(writes);\n return markedIds;\n }\n\n /**\n * Return trajectory IDs that have a per-trajectory compaction marker.\n */\n async getCompactedTrajectoryIds(): Promise<Set<string>> {\n const markerPaths = await this.listCompactionMarkerFiles();\n const compactedIds = new Set<string>();\n\n for (const markerPath of markerPaths) {\n try {\n const marker = JSON.parse(\n await readFile(markerPath, \"utf-8\"),\n ) as Partial<CompactionMarker>;\n const trajectoryId =\n typeof marker.trajectoryId === \"string\"\n ? marker.trajectoryId\n : this.getTrajectoryIdFromCompactionMarkerPath(markerPath);\n if (trajectoryId && typeof marker.compactedInto === \"string\") {\n compactedIds.add(trajectoryId);\n }\n } catch {\n // Ignore malformed compaction markers. They should not block normal\n // list/search/compact operations.\n }\n }\n\n return compactedIds;\n }\n\n /**\n * Delete a trajectory and return file counts for CLI reporting.\n */\n async deleteWithSummary(id: string): Promise<DeleteTrajectorySummary> {\n return this.deleteManyWithSummary([id]);\n }\n\n /**\n * Delete multiple trajectories with one filesystem scan.\n */\n async deleteManyWithSummary(ids: string[]): Promise<DeleteTrajectorySummary> {\n const summary: DeleteTrajectorySummary = {\n removedTrajectories: 0,\n deletedJsonFiles: 0,\n deletedMarkdownFiles: 0,\n deletedTraceFiles: 0,\n deletedCompactionFiles: 0,\n };\n const pathsById = await this.findTrajectoryFilePathsForIds(ids);\n const deletedPaths = new Set<string>();\n\n for (const paths of pathsById.values()) {\n for (const filePath of paths) {\n if (deletedPaths.has(filePath)) {\n continue;\n }\n deletedPaths.add(filePath);\n await this.removeTrajectoryFile(filePath, summary);\n }\n }\n\n return summary;\n }\n\n /**\n * Close storage (no-op for file storage)\n */\n async close(): Promise<void> {\n // No cleanup needed for file storage\n }\n\n // Private helpers\n\n private getActiveCandidatePaths(id: string): string[] {\n if (!isSafeTrajectoryId(id)) {\n return [];\n }\n\n return [\n join(this.activeDir, id, TRAJECTORY_FILE),\n // Legacy layout from v0.5.x and earlier.\n join(this.activeDir, `${id}.json`),\n ];\n }\n\n private async loadAllTrajectories(): Promise<Trajectory[]> {\n const files = await this.listTrajectoryFiles();\n const trajectories = new Map<string, Trajectory>();\n\n for (const filePath of files) {\n const trajectory = await this.readTrajectoryOrNull(filePath);\n if (!trajectory) {\n continue;\n }\n\n const current = trajectories.get(trajectory.id);\n if (!current || this.isNewerTrajectory(trajectory, current)) {\n trajectories.set(trajectory.id, trajectory);\n }\n }\n\n return Array.from(trajectories.values());\n }\n\n private async listTrajectoryFiles(): Promise<string[]> {\n const [activeFiles, completedFiles] = await Promise.all([\n this.collectTrajectoryFiles(this.activeDir),\n this.collectTrajectoryFiles(this.completedDir),\n ]);\n\n return [...activeFiles, ...completedFiles];\n }\n\n private async collectTrajectoryFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n await this.walkJsonFilesInto(dir, files);\n return files;\n }\n\n private async findTrajectoryFilePaths(id: string): Promise<string[]> {\n const pathsById = await this.findTrajectoryFilePathsForIds([id]);\n return pathsById.get(id) ?? [];\n }\n\n private async findTrajectoryFilePathsForIds(\n ids: Iterable<string>,\n ): Promise<Map<string, string[]>> {\n const targetIds = new Set(Array.from(ids).filter(isSafeTrajectoryId));\n const pathsById = new Map<string, string[]>(\n Array.from(targetIds).map((id) => [id, []]),\n );\n if (targetIds.size === 0) {\n return pathsById;\n }\n\n const allFiles = await this.listTrajectoryFiles();\n for (const filePath of allFiles) {\n const trajectoryId = this.getTrajectoryIdFromPath(filePath);\n if (!trajectoryId || !targetIds.has(trajectoryId)) {\n continue;\n }\n pathsById.get(trajectoryId)?.push(filePath);\n }\n\n return pathsById;\n }\n\n private getTrajectoryIdFromPath(filePath: string): string | undefined {\n if (basename(filePath) === TRAJECTORY_FILE) {\n const id = basename(dirname(filePath));\n return isSafeTrajectoryId(id) ? id : undefined;\n }\n\n const name = basename(filePath);\n if (name.endsWith(\".json\")) {\n const id = name.slice(0, -\".json\".length);\n return isSafeTrajectoryId(id) ? id : undefined;\n }\n\n return undefined;\n }\n\n private async removeTrajectoryFiles(\n paths: string[],\n exceptPath?: string,\n ): Promise<void> {\n const summary = this.emptyDeleteSummary();\n\n for (const filePath of paths) {\n if (filePath === exceptPath) {\n continue;\n }\n await this.removeTrajectoryFile(filePath, summary);\n }\n }\n\n private async removeTrajectoryFile(\n filePath: string,\n summary: DeleteTrajectorySummary,\n ): Promise<void> {\n if (basename(filePath) === TRAJECTORY_FILE) {\n const trajectoryDir = dirname(filePath);\n await this.countDirectoryTrajectoryFiles(trajectoryDir, summary);\n await this.removeFileIfExists(\n join(dirname(trajectoryDir), `${basename(trajectoryDir)}.trace.json`),\n \"trace\",\n summary,\n );\n await rm(trajectoryDir, { recursive: true, force: true });\n return;\n }\n\n await this.removeFileIfExists(filePath, \"json\", summary);\n await this.removeFileIfExists(\n getMarkdownOutputPath(filePath),\n \"markdown\",\n summary,\n );\n await this.removeFileIfExists(\n getTraceOutputPath(filePath),\n \"trace\",\n summary,\n );\n await this.removeFileIfExists(\n getLegacyCompactionMarkerPath(filePath),\n \"compaction\",\n summary,\n );\n }\n\n private async countDirectoryTrajectoryFiles(\n trajectoryDir: string,\n summary: DeleteTrajectorySummary,\n ): Promise<void> {\n await this.countFileIfExists(\n join(trajectoryDir, TRAJECTORY_FILE),\n \"json\",\n summary,\n );\n await this.countFileIfExists(\n join(trajectoryDir, SUMMARY_FILE),\n \"markdown\",\n summary,\n );\n await this.countFileIfExists(\n join(trajectoryDir, `${basename(trajectoryDir)}.trace.json`),\n \"trace\",\n summary,\n );\n await this.countFileIfExists(\n join(trajectoryDir, \"trace.json\"),\n \"trace\",\n summary,\n );\n await this.countFileIfExists(\n join(trajectoryDir, COMPACTION_FILE),\n \"compaction\",\n summary,\n );\n }\n\n private async removeFileIfExists(\n path: string,\n kind: \"json\" | \"markdown\" | \"trace\" | \"compaction\",\n summary: DeleteTrajectorySummary,\n ): Promise<void> {\n if (!existsSync(path)) {\n return;\n }\n await rm(path, { force: true });\n this.incrementDeleteSummary(kind, summary);\n }\n\n private async countFileIfExists(\n path: string,\n kind: \"json\" | \"markdown\" | \"trace\" | \"compaction\",\n summary: DeleteTrajectorySummary,\n ): Promise<void> {\n if (existsSync(path)) {\n this.incrementDeleteSummary(kind, summary);\n }\n }\n\n private incrementDeleteSummary(\n kind: \"json\" | \"markdown\" | \"trace\" | \"compaction\",\n summary: DeleteTrajectorySummary,\n ): void {\n if (kind === \"json\") {\n summary.deletedJsonFiles += 1;\n summary.removedTrajectories += 1;\n } else if (kind === \"markdown\") {\n summary.deletedMarkdownFiles += 1;\n } else if (kind === \"trace\") {\n summary.deletedTraceFiles += 1;\n } else {\n summary.deletedCompactionFiles += 1;\n }\n }\n\n private emptyDeleteSummary(): DeleteTrajectorySummary {\n return {\n removedTrajectories: 0,\n deletedJsonFiles: 0,\n deletedMarkdownFiles: 0,\n deletedTraceFiles: 0,\n deletedCompactionFiles: 0,\n };\n }\n\n private async listCompactionMarkerFiles(): Promise<string[]> {\n const markerPaths: string[] = [];\n await this.walkFilesInto(\n this.activeDir,\n markerPaths,\n isCompactionMarkerFile,\n );\n await this.walkFilesInto(\n this.completedDir,\n markerPaths,\n isCompactionMarkerFile,\n );\n return markerPaths;\n }\n\n private getCompactionMarkerPath(filePath: string, id: string): string {\n if (basename(filePath) === TRAJECTORY_FILE) {\n return join(dirname(filePath), COMPACTION_FILE);\n }\n\n return join(dirname(filePath), `${id}${LEGACY_COMPACTION_SUFFIX}`);\n }\n\n private getTrajectoryIdFromCompactionMarkerPath(\n markerPath: string,\n ): string | undefined {\n if (basename(markerPath) === COMPACTION_FILE) {\n const id = basename(dirname(markerPath));\n return id.startsWith(\"traj_\") ? id : undefined;\n }\n\n const markerName = basename(markerPath);\n return markerName.endsWith(LEGACY_COMPACTION_SUFFIX)\n ? markerName.slice(0, -LEGACY_COMPACTION_SUFFIX.length)\n : undefined;\n }\n\n private async migrateLegacyIndexCompactionMarkers(): Promise<void> {\n const indexPath = join(this.trajectoriesDir, \"index.json\");\n if (!existsSync(indexPath)) {\n return;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(await readFile(indexPath, \"utf-8\"));\n } catch {\n return;\n }\n\n if (parsed === null || typeof parsed !== \"object\") {\n return;\n }\n\n const trajectories = (parsed as { trajectories?: unknown }).trajectories;\n if (\n trajectories === null ||\n typeof trajectories !== \"object\" ||\n Array.isArray(trajectories)\n ) {\n return;\n }\n\n await Promise.all(\n Object.entries(trajectories).map(async ([id, entry]) => {\n if (\n entry === null ||\n typeof entry !== \"object\" ||\n !isSafeTrajectoryId(id)\n ) {\n return;\n }\n\n const compactedInto = (entry as { compactedInto?: unknown })\n .compactedInto;\n const path = (entry as { path?: unknown }).path;\n if (typeof compactedInto !== \"string\") {\n return;\n }\n\n const paths =\n typeof path === \"string\" &&\n existsSync(path) &&\n this.isPathInsideTrajectoriesDir(path)\n ? [path]\n : await this.findTrajectoryFilePaths(id);\n if (paths.length === 0) return;\n\n const marker: CompactionMarker = {\n trajectoryId: id,\n compactedInto,\n compactedAt: new Date().toISOString(),\n };\n\n await Promise.all(\n paths.map((filePath) =>\n writeFile(\n this.getCompactionMarkerPath(filePath, id),\n JSON.stringify(marker, null, 2),\n \"utf-8\",\n ),\n ),\n );\n }),\n );\n }\n\n private isPathInsideTrajectoriesDir(path: string): boolean {\n const rel = relative(resolve(this.trajectoriesDir), resolve(path));\n return Boolean(rel && !rel.startsWith(\"..\") && !isAbsolute(rel));\n }\n\n private async walkFilesInto(\n dir: string,\n out: string[],\n predicate: (name: string) => boolean,\n ): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n await this.walkFilesInto(entryPath, out, predicate);\n } else if (entry.isFile() && predicate(entry.name)) {\n out.push(entryPath);\n }\n }\n }\n\n private getSortValue(\n trajectory: Trajectory,\n sortBy: NonNullable<TrajectoryQuery[\"sortBy\"]>,\n ): string {\n if (sortBy === \"title\") {\n return trajectory.task.title;\n }\n\n return trajectory[sortBy] ?? \"\";\n }\n\n private toSummary(trajectory: Trajectory): TrajectorySummary {\n return {\n id: trajectory.id,\n title: trajectory.task.title,\n status: trajectory.status,\n startedAt: trajectory.startedAt,\n completedAt: trajectory.completedAt,\n confidence: trajectory.retrospective?.confidence,\n chapterCount: trajectory.chapters.length,\n decisionCount: trajectory.chapters.reduce(\n (count, chapter) =>\n count +\n chapter.events.filter((event) => event.type === \"decision\").length,\n 0,\n ),\n };\n }\n\n private isNewerTrajectory(\n candidate: Trajectory,\n current: Trajectory,\n ): boolean {\n const candidateTime = new Date(\n candidate.completedAt ?? candidate.startedAt,\n ).getTime();\n const currentTime = new Date(\n current.completedAt ?? current.startedAt,\n ).getTime();\n\n return candidateTime > currentTime;\n }\n\n /**\n * Read a trajectory file and return a tagged result so callers can\n * distinguish missing files, malformed JSON, and schema violations.\n *\n * Does NOT log. Callers choose whether to warn, swallow, or throw.\n */\n private async readTrajectoryFile(\n path: string,\n ): Promise<ReadTrajectoryResult> {\n let content: string;\n try {\n content = await readFile(path, \"utf-8\");\n } catch (error) {\n return { ok: false, reason: \"io_error\", path, error };\n }\n\n let data: unknown;\n try {\n data = JSON.parse(content);\n } catch (error) {\n return { ok: false, reason: \"malformed_json\", path, error };\n }\n\n const validation = validateTrajectory(data);\n if (validation.success) {\n return { ok: true, trajectory: validation.data as Trajectory };\n }\n return {\n ok: false,\n reason: \"schema_violation\",\n path,\n error: validation.errors,\n };\n }\n\n /**\n * Convenience wrapper for callers that only care whether they got a\n * trajectory. Returns null for any failure and writes nothing to the\n * console — so nothing leaks into test output or the CLI spinner.\n */\n private async readTrajectoryOrNull(path: string): Promise<Trajectory | null> {\n const result = await this.readTrajectoryFile(path);\n return result.ok ? result.trajectory : null;\n }\n}\n\nfunction isTrajectoryJsonFile(name: string): boolean {\n return (\n name === TRAJECTORY_FILE ||\n (name.endsWith(\".json\") &&\n name !== \"index.json\" &&\n !name.endsWith(\".trace.json\") &&\n !name.endsWith(LEGACY_COMPACTION_SUFFIX) &&\n name !== COMPACTION_FILE)\n );\n}\n\nfunction isSafeTrajectoryId(id: string): boolean {\n return (\n id.length > 0 &&\n !id.includes(\"..\") &&\n !id.includes(\"/\") &&\n !id.includes(\"\\\\\")\n );\n}\n\nfunction isCompactionMarkerFile(name: string): boolean {\n return name === COMPACTION_FILE || name.endsWith(LEGACY_COMPACTION_SUFFIX);\n}\n\nfunction getMarkdownOutputPath(outputPath: string): string {\n return outputPath.endsWith(\".json\")\n ? outputPath.slice(0, -\".json\".length).concat(\".md\")\n : `${outputPath}.md`;\n}\n\nfunction getTraceOutputPath(outputPath: string): string {\n return outputPath.endsWith(\".json\")\n ? outputPath.slice(0, -\".json\".length).concat(\".trace.json\")\n : `${outputPath}.trace.json`;\n}\n\nfunction getLegacyCompactionMarkerPath(outputPath: string): string {\n return outputPath.endsWith(\".json\")\n ? outputPath.slice(0, -\".json\".length).concat(LEGACY_COMPACTION_SUFFIX)\n : `${outputPath}${LEGACY_COMPACTION_SUFFIX}`;\n}\n","/**\n * Trajectory Builder\n *\n * Fluent builder pattern for creating trajectories without storage.\n * Useful for programmatically constructing trajectories in memory.\n */\n\nimport {\n abandonTrajectory,\n addChapter,\n addDecision,\n addEvent,\n completeTrajectory,\n createTrajectory,\n} from \"../core/trajectory.js\";\nimport type {\n CompleteTrajectoryInput,\n CreateTrajectoryInput,\n Decision,\n EventSignificance,\n TaskSource,\n Trajectory,\n TrajectoryEventType,\n} from \"../core/types.js\";\nimport { exportToJSON } from \"../export/json.js\";\nimport { exportToMarkdown } from \"../export/markdown.js\";\nimport { exportToPRSummary } from \"../export/pr-summary.js\";\nimport { exportToTimeline } from \"../export/timeline.js\";\n\n/**\n * Fluent builder for creating trajectories in memory\n *\n * @example\n * ```typescript\n * import { TrajectoryBuilder } from 'agent-trajectories/sdk';\n *\n * const trajectory = TrajectoryBuilder\n * .create('Implement feature X')\n * .withDescription('Add new authentication flow')\n * .withSource({ system: 'github', id: 'GH#123' })\n * .chapter('Research', 'claude')\n * .note('Found existing auth patterns')\n * .finding('Current implementation uses JWT')\n * .chapter('Implementation', 'claude')\n * .decide('JWT vs Session', 'JWT', 'Better for API clients')\n * .note('Implemented token refresh')\n * .complete({\n * summary: 'Added JWT-based authentication',\n * approach: 'Extended existing auth module',\n * confidence: 0.95\n * });\n *\n * console.log(trajectory.toMarkdown());\n * ```\n */\nexport class TrajectoryBuilder {\n private trajectory: Trajectory;\n\n private constructor(input: CreateTrajectoryInput) {\n this.trajectory = createTrajectory(input);\n }\n\n /**\n * Create a new trajectory builder\n * @param title - Task title\n */\n static create(title: string): TrajectoryBuilder {\n return new TrajectoryBuilder({ title });\n }\n\n /**\n * Set the task description\n */\n withDescription(description: string): TrajectoryBuilder {\n this.trajectory = {\n ...this.trajectory,\n task: {\n ...this.trajectory.task,\n description,\n },\n };\n return this;\n }\n\n /**\n * Set the external task source\n */\n withSource(source: TaskSource): TrajectoryBuilder {\n this.trajectory = {\n ...this.trajectory,\n task: {\n ...this.trajectory.task,\n source,\n },\n };\n return this;\n }\n\n /**\n * Set the project ID\n */\n withProject(projectId: string): TrajectoryBuilder {\n this.trajectory = {\n ...this.trajectory,\n projectId,\n };\n return this;\n }\n\n /**\n * Add tags\n */\n withTags(...tags: string[]): TrajectoryBuilder {\n this.trajectory = {\n ...this.trajectory,\n tags: [...this.trajectory.tags, ...tags],\n };\n return this;\n }\n\n /**\n * Add a single tag\n */\n tag(tag: string): TrajectoryBuilder {\n if (!this.trajectory.tags.includes(tag)) {\n this.trajectory = {\n ...this.trajectory,\n tags: [...this.trajectory.tags, tag],\n };\n }\n return this;\n }\n\n /**\n * Start a new chapter\n * @param title - Chapter title\n * @param agentName - Agent name\n */\n chapter(title: string, agentName: string): TrajectoryBuilder {\n this.trajectory = addChapter(this.trajectory, { title, agentName });\n return this;\n }\n\n /**\n * Add a generic event\n */\n event(\n type: TrajectoryEventType,\n content: string,\n options?: {\n raw?: unknown;\n significance?: EventSignificance;\n tags?: string[];\n },\n ): TrajectoryBuilder {\n this.trajectory = addEvent(this.trajectory, {\n type,\n content,\n ...options,\n });\n return this;\n }\n\n /**\n * Add a note event\n */\n note(content: string, significance?: EventSignificance): TrajectoryBuilder {\n return this.event(\"note\", content, { significance });\n }\n\n /**\n * Add a finding event\n */\n finding(\n content: string,\n significance?: EventSignificance,\n ): TrajectoryBuilder {\n return this.event(\"finding\", content, {\n significance: significance ?? \"medium\",\n });\n }\n\n /**\n * Add a reflection event — a higher-level synthesis of recent observations.\n * Reflections are always high significance since they represent\n * periodic course-correction insights.\n */\n reflect(content: string, confidence?: number): TrajectoryBuilder {\n return this.event(\"reflection\", content, {\n significance: \"high\",\n ...(confidence !== undefined\n ? { tags: [`confidence:${confidence}`] }\n : {}),\n });\n }\n\n /**\n * Add an error event\n */\n error(content: string): TrajectoryBuilder {\n return this.event(\"error\", content, { significance: \"high\" });\n }\n\n /**\n * Add a thinking event\n */\n thinking(content: string): TrajectoryBuilder {\n return this.event(\"thinking\", content, { significance: \"low\" });\n }\n\n /**\n * Add a tool call event\n */\n toolCall(content: string, raw?: unknown): TrajectoryBuilder {\n return this.event(\"tool_call\", content, { raw });\n }\n\n /**\n * Add a tool result event\n */\n toolResult(content: string, raw?: unknown): TrajectoryBuilder {\n return this.event(\"tool_result\", content, { raw });\n }\n\n /**\n * Add a prompt event\n */\n prompt(content: string): TrajectoryBuilder {\n return this.event(\"prompt\", content, { significance: \"medium\" });\n }\n\n /**\n * Add a message sent event\n */\n messageSent(content: string): TrajectoryBuilder {\n return this.event(\"message_sent\", content);\n }\n\n /**\n * Add a message received event\n */\n messageReceived(content: string): TrajectoryBuilder {\n return this.event(\"message_received\", content);\n }\n\n /**\n * Add a structured decision\n */\n decision(decision: Decision): TrajectoryBuilder {\n this.trajectory = addDecision(this.trajectory, decision);\n return this;\n }\n\n /**\n * Quick decision helper\n */\n decide(\n question: string,\n chosen: string,\n reasoning: string,\n alternatives?: Array<{ option: string; reason?: string }>,\n ): TrajectoryBuilder {\n return this.decision({\n question,\n chosen,\n reasoning,\n alternatives: alternatives ?? [],\n });\n }\n\n /**\n * Record git commits\n */\n commits(...hashes: string[]): TrajectoryBuilder {\n this.trajectory = {\n ...this.trajectory,\n commits: [...this.trajectory.commits, ...hashes],\n };\n return this;\n }\n\n /**\n * Record files changed\n */\n filesChanged(...paths: string[]): TrajectoryBuilder {\n this.trajectory = {\n ...this.trajectory,\n filesChanged: [...this.trajectory.filesChanged, ...paths],\n };\n return this;\n }\n\n /**\n * Complete the trajectory with a retrospective\n * @param input - Retrospective details\n * @returns The completed trajectory\n */\n complete(input: CompleteTrajectoryInput): Trajectory {\n this.trajectory = completeTrajectory(this.trajectory, input);\n return this.trajectory;\n }\n\n /**\n * Quick complete with minimal fields\n */\n done(summary: string, confidence: number, approach?: string): Trajectory {\n return this.complete({\n summary,\n confidence,\n approach: approach ?? \"Standard approach\",\n });\n }\n\n /**\n * Abandon the trajectory\n */\n abandon(reason?: string): Trajectory {\n this.trajectory = abandonTrajectory(this.trajectory, reason);\n return this.trajectory;\n }\n\n /**\n * Get the current trajectory (without completing)\n */\n build(): Trajectory {\n return this.trajectory;\n }\n\n /**\n * Export to markdown\n */\n toMarkdown(): string {\n return exportToMarkdown(this.trajectory);\n }\n\n /**\n * Export to JSON\n */\n toJSON(compact?: boolean): string {\n return exportToJSON(this.trajectory, { compact });\n }\n\n /**\n * Export to timeline format\n */\n toTimeline(): string {\n return exportToTimeline(this.trajectory);\n }\n\n /**\n * Export to PR summary format\n */\n toPRSummary(): string {\n return exportToPRSummary(this.trajectory);\n }\n}\n\n/**\n * Shorthand function to create a trajectory builder\n *\n * @example\n * ```typescript\n * import { trajectory } from 'agent-trajectories/sdk';\n *\n * const result = trajectory('Fix bug in auth')\n * .chapter('Investigation', 'claude')\n * .finding('Found null pointer in login handler')\n * .done('Fixed null pointer exception', 0.95);\n * ```\n */\nexport function trajectory(title: string): TrajectoryBuilder {\n return TrajectoryBuilder.create(title);\n}\n","/**\n * Git trailer utilities for linking commits to trajectories\n *\n * Appends structured metadata to commit messages using git's trailer convention:\n * Trajectory: traj_xxxxxxxxxxxx\n *\n * This creates a bidirectional link: trajectories reference commits,\n * and commits reference trajectories.\n */\n\nimport { execSync } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { isGitRepo, isValidGitRef } from \"./trace.js\";\n\n/** Trailer key for trajectory ID */\nexport const TRAJECTORY_TRAILER_KEY = \"Trajectory\";\n\n/**\n * Format a trajectory trailer for appending to a commit message\n * @param trajectoryId - The trajectory ID to link\n * @returns Formatted trailer string (e.g., \"Trajectory: traj_abc123\")\n */\nexport function formatTrailer(trajectoryId: string): string {\n return `${TRAJECTORY_TRAILER_KEY}: ${trajectoryId}`;\n}\n\n/**\n * Parse trajectory ID from a commit message's trailers\n * @param commitMessage - Full commit message text\n * @returns The trajectory ID if found, null otherwise\n */\nexport function parseTrajectoryFromMessage(\n commitMessage: string,\n): string | null {\n const lines = commitMessage.split(\"\\n\");\n for (const line of lines) {\n // Character class must include `_` to match legacy\n // `traj_<timestamp>_<hex>` ids produced by the workforce workflow runner\n // in addition to the canonical `traj_<12hex>` shape. This must stay in\n // sync with the regex in src/core/schema.ts and src/core/id.ts.\n const match = line.match(\n new RegExp(`^${TRAJECTORY_TRAILER_KEY}:\\\\s*(traj_[a-z0-9_]+)$`),\n );\n if (match) {\n return match[1];\n }\n }\n return null;\n}\n\n/**\n * Get the trajectory ID linked to a specific commit\n * @param commitHash - Git commit hash\n * @returns The trajectory ID if found, null otherwise\n */\nexport function getTrajectoryFromCommit(commitHash: string): string | null {\n if (!isGitRepo() || !isValidGitRef(commitHash)) {\n return null;\n }\n\n try {\n const message = execSync(`git log -1 --format=%B ${commitHash}`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return parseTrajectoryFromMessage(message);\n } catch {\n return null;\n }\n}\n\n/**\n * Commit info returned by getCommitsBetween\n */\nexport interface CommitInfo {\n /** Short commit hash */\n hash: string;\n /** Full commit hash */\n fullHash: string;\n /** Commit subject line */\n subject: string;\n /** Commit author */\n author: string;\n /** Commit timestamp (ISO) */\n date: string;\n}\n\n/**\n * Get all commits between two git refs\n * @param startRef - Starting commit (exclusive)\n * @param endRef - Ending commit (inclusive, defaults to HEAD)\n * @returns Array of commit info objects\n */\nexport function getCommitsBetween(\n startRef: string,\n endRef = \"HEAD\",\n): CommitInfo[] {\n if (!isGitRepo()) {\n return [];\n }\n\n if (!isValidGitRef(startRef) || !isValidGitRef(endRef)) {\n return [];\n }\n\n try {\n const output = execSync(\n `git log --format=%H%n%h%n%s%n%an%n%aI%n--- ${startRef}..${endRef}`,\n {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n },\n );\n\n if (!output.trim()) {\n return [];\n }\n\n const commits: CommitInfo[] = [];\n const entries = output.trim().split(\"\\n---\\n\");\n\n for (const entry of entries) {\n const lines = entry.trim().split(\"\\n\");\n if (lines.length >= 5) {\n commits.push({\n fullHash: lines[0],\n hash: lines[1],\n subject: lines[2],\n author: lines[3],\n date: lines[4],\n });\n }\n }\n\n return commits;\n } catch {\n return [];\n }\n}\n\n/**\n * Get file paths changed between two git refs\n * @param startRef - Starting commit (exclusive)\n * @param endRef - Ending commit (inclusive, defaults to HEAD)\n * @returns Array of changed file paths\n */\nexport function getFilesChangedBetween(\n startRef: string,\n endRef = \"HEAD\",\n): string[] {\n if (!isGitRepo()) {\n return [];\n }\n\n if (!isValidGitRef(startRef) || !isValidGitRef(endRef)) {\n return [];\n }\n\n try {\n const output = execSync(`git diff --name-only ${startRef}..${endRef}`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n return output.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Generate the content of a prepare-commit-msg hook script\n * that appends trajectory trailers to commits\n */\nexport function generateHookScript(): string {\n return `#!/bin/sh\n# Added by agent-trajectories - appends Trajectory trailer to commits\n# This hook reads the active trajectory and links it to your commit.\n\nCOMMIT_MSG_FILE=\"$1\"\nCOMMIT_SOURCE=\"$2\"\n\n# Skip for merge, squash, and amend commits\nif [ \"$COMMIT_SOURCE\" = \"merge\" ] || [ \"$COMMIT_SOURCE\" = \"squash\" ] || [ \"$COMMIT_SOURCE\" = \"commit\" ]; then\n exit 0\nfi\n\n# Find the trajectories data directory\nTRAJ_DIR=\"\\${TRAJECTORIES_DATA_DIR:-\\$(git rev-parse --show-toplevel)/.agentworkforce/trajectories}\"\nACTIVE_DIR=\"$TRAJ_DIR/active\"\n\n# Check if there's an active trajectory\nif [ ! -d \"$ACTIVE_DIR\" ]; then\n exit 0\nfi\n\n# Find the most recent active trajectory file\nACTIVE_FILE=$(ls -t \"$ACTIVE_DIR\"/*.json 2>/dev/null | head -1)\nif [ -z \"$ACTIVE_FILE\" ]; then\n exit 0\nfi\n\n# Extract trajectory ID (grep for the \"id\" field). Character class must\n# include underscore to match legacy traj_<timestamp>_<hex> ids -- without\n# it, grep -o silently truncates at the first internal underscore and\n# emits a wrong (shorter) id into the commit trailer.\nTRAJ_ID=$(grep -o '\"id\"[[:space:]]*:[[:space:]]*\"traj_[a-z0-9_]*\"' \"$ACTIVE_FILE\" | head -1 | grep -o 'traj_[a-z0-9_]*')\nif [ -z \"$TRAJ_ID\" ]; then\n exit 0\nfi\n\n# Check if trailer already exists in the message\nif grep -q \"^Trajectory: \" \"$COMMIT_MSG_FILE\" 2>/dev/null; then\n exit 0\nfi\n\n# Append the trailer with a blank line separator\necho \"\" >> \"$COMMIT_MSG_FILE\"\necho \"Trajectory: $TRAJ_ID\" >> \"$COMMIT_MSG_FILE\"\n`;\n}\n\n/**\n * Check if a prepare-commit-msg hook already exists and contains our marker\n * @returns 'none' if no hook exists, 'ours' if our hook, 'other' if different hook\n */\nexport function detectExistingHook(): \"none\" | \"ours\" | \"other\" {\n if (!isGitRepo()) {\n return \"none\";\n }\n\n try {\n const hooksDir = execSync(\"git rev-parse --git-dir\", {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n\n const hookPath = `${hooksDir}/hooks/prepare-commit-msg`;\n\n try {\n const content = readFileSync(hookPath, \"utf-8\");\n\n if (content.includes(\"agent-trajectories\")) {\n return \"ours\";\n }\n return \"other\";\n } catch {\n return \"none\";\n }\n } catch {\n return \"none\";\n }\n}\n","/**\n * Agent Trace generation logic\n *\n * Captures git state before and after agent work to generate\n * trace records that attribute code contributions to agents.\n */\n\nimport { execSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport type {\n TraceFile,\n TraceRange,\n TraceRecord,\n Trajectory,\n TrajectoryTraceRef,\n} from \"./types.js\";\n\n/**\n * Validate a git reference to prevent command injection\n * @param ref - Git reference to validate\n * @returns True if the ref is safe to use in git commands\n */\nexport function isValidGitRef(ref: string): boolean {\n // Allow HEAD, branch names, and commit hashes\n // Git refs can contain alphanumeric, -, _, /, and .\n // Commit hashes are 7-40 hex characters\n const validRefPattern = /^[a-zA-Z0-9_\\-./]+$/;\n const commitHashPattern = /^[a-fA-F0-9]{7,40}$/;\n\n if (ref === \"HEAD\" || ref === \"working\") {\n return true;\n }\n\n if (commitHashPattern.test(ref)) {\n return true;\n }\n\n // For branch names, ensure no shell metacharacters\n if (validRefPattern.test(ref) && ref.length <= 255) {\n // Additional check: no consecutive dots (prevents .. traversal tricks)\n if (!ref.includes(\"..\") || ref.split(\"..\").every((p) => p.length > 0)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if the current directory is inside a git repository\n * @returns True if in a git repo, false otherwise\n */\nexport function isGitRepo(): boolean {\n try {\n execSync(\"git rev-parse --is-inside-work-tree\", {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get the current git HEAD reference\n * @returns The current HEAD commit hash, or null if not in a git repo\n */\nexport function getGitHead(): string | null {\n if (!isGitRepo()) {\n return null;\n }\n\n try {\n const head = execSync(\"git rev-parse HEAD\", {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n return head;\n } catch {\n return null;\n }\n}\n\n/**\n * Capture the current git state for trace tracking\n * @returns The start reference (commit hash) or null if not in git repo\n */\nexport function captureGitState(): string | null {\n return getGitHead();\n}\n\n/**\n * Parse git diff output to extract changed files and line ranges\n * @param diffOutput - Raw git diff output\n * @returns Array of file paths with their changed line ranges\n */\nfunction parseDiffOutput(\n diffOutput: string,\n): Array<{ path: string; ranges: TraceRange[] }> {\n const files: Array<{ path: string; ranges: TraceRange[] }> = [];\n const lines = diffOutput.split(\"\\n\");\n\n let currentFile: string | null = null;\n let currentRanges: TraceRange[] = [];\n\n for (const line of lines) {\n // Match diff header for file path\n // Format: diff --git a/path/to/file b/path/to/file\n const diffHeaderMatch = line.match(/^diff --git a\\/.+ b\\/(.+)$/);\n if (diffHeaderMatch) {\n // Save previous file if exists\n if (currentFile) {\n files.push({ path: currentFile, ranges: currentRanges });\n }\n currentFile = diffHeaderMatch[1];\n currentRanges = [];\n continue;\n }\n\n // Match hunk header for line ranges\n // Format: @@ -start,count +start,count @@ optional context\n const hunkMatch = line.match(/^@@ -\\d+(?:,\\d+)? \\+(\\d+)(?:,(\\d+))? @@/);\n if (hunkMatch && currentFile) {\n const startLine = Number.parseInt(hunkMatch[1], 10);\n const lineCount = hunkMatch[2] ? Number.parseInt(hunkMatch[2], 10) : 1;\n\n if (lineCount > 0) {\n currentRanges.push({\n start_line: startLine,\n end_line: startLine + lineCount - 1,\n });\n }\n }\n }\n\n // Don't forget the last file\n if (currentFile) {\n files.push({ path: currentFile, ranges: currentRanges });\n }\n\n return files;\n}\n\n/**\n * Get the list of changed files between two git refs\n * @param startRef - Starting commit reference\n * @param endRef - Ending commit reference (defaults to HEAD)\n * @returns Array of changed file paths with line ranges\n */\nexport function getChangedFiles(\n startRef: string,\n endRef = \"HEAD\",\n): Array<{ path: string; ranges: TraceRange[] }> {\n if (!isGitRepo()) {\n return [];\n }\n\n // Validate git refs to prevent command injection\n if (!isValidGitRef(startRef) || !isValidGitRef(endRef)) {\n return [];\n }\n\n try {\n const diffOutput = execSync(`git diff ${startRef}..${endRef}`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer for large diffs\n });\n\n return parseDiffOutput(diffOutput);\n } catch {\n return [];\n }\n}\n\n/**\n * Detect the model from environment variables\n * Returns model ID using models.dev convention (org/model-name)\n * @returns Model identifier or 'unknown'\n */\nexport function detectModel(): string {\n // Check custom env var first (pass through as-is if already org/model format)\n if (process.env.TRAIL_TRACE_MODEL) {\n return process.env.TRAIL_TRACE_MODEL;\n }\n\n // Check Anthropic model env var - normalize to models.dev convention\n if (process.env.ANTHROPIC_MODEL) {\n const model = process.env.ANTHROPIC_MODEL;\n return model.includes(\"/\") ? model : `anthropic/${model}`;\n }\n\n // Check common AI provider model env vars - normalize to models.dev convention\n if (process.env.OPENAI_MODEL) {\n const model = process.env.OPENAI_MODEL;\n return model.includes(\"/\") ? model : `openai/${model}`;\n }\n\n return \"unknown\";\n}\n\n/**\n * Generate a unique trace ID using UUID v4\n * Follows agent-trace.dev spec which requires UUID format\n * @returns UUID v4 string\n */\nexport function generateTraceId(): string {\n return crypto.randomUUID();\n}\n\n/**\n * Compute content hash for a given string\n * @param content - Content to hash\n * @returns SHA-256 hash (first 16 chars)\n */\nexport function computeContentHash(content: string): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Generate a trace record from a trajectory and git state\n * @param trajectory - The trajectory to generate trace for\n * @param startRef - The git ref from when work started\n * @returns TraceRecord with file contributions, or null if not in git repo\n */\nexport function generateTrace(\n trajectory: Trajectory,\n startRef: string,\n): TraceRecord | null {\n if (!isGitRepo()) {\n return null;\n }\n\n const endRef = getGitHead();\n if (!endRef) {\n return null;\n }\n\n // Get changed files with line ranges\n const changedFiles = getChangedFiles(startRef, endRef);\n\n // Return null if no files changed\n if (changedFiles.length === 0) {\n return null;\n }\n\n // Detect the model used\n const model = detectModel();\n\n // Build trace files\n const traceFiles: TraceFile[] = changedFiles.map(({ path, ranges }) => ({\n path,\n conversations: [\n {\n contributor: {\n type: \"ai\",\n ...(model !== \"unknown\" ? { model_id: model } : {}),\n },\n ranges: ranges.map((range) => ({\n ...range,\n revision: endRef,\n })),\n },\n ],\n }));\n\n return {\n version: \"1.0.0\",\n id: generateTraceId(),\n timestamp: new Date().toISOString(),\n trajectory: trajectory.id,\n files: traceFiles,\n };\n}\n\n/**\n * Migrate a legacy trace record to the current spec format.\n * Handles records written before agent-trace 0.1.0 compliance:\n * - version: 1 (number) → \"1.0.0\" (semver string)\n * - contributor.type: \"agent\" → \"ai\"\n * - contributor.model → contributor.model_id (omitted if \"unknown\")\n *\n * The trace ID (trace_xxx format) is intentionally left unchanged\n * to preserve the reference stored in the parent trajectory's _trace.traceId.\n *\n * @returns { record, migrated } — migrated=true means the caller should persist the updated record\n */\nexport function migrateTraceRecord(raw: unknown): {\n record: TraceRecord;\n migrated: boolean;\n} {\n const data = raw as Record<string, unknown>;\n let migrated = false;\n\n // Migrate version: number → semver string\n if (typeof data.version === \"number\") {\n data.version = \"1.0.0\";\n migrated = true;\n }\n\n // Migrate contributor fields in each file's conversations\n if (Array.isArray(data.files)) {\n for (const file of data.files as Array<Record<string, unknown>>) {\n if (Array.isArray(file.conversations)) {\n for (const conv of file.conversations as Array<\n Record<string, unknown>\n >) {\n const contributor = conv.contributor as Record<string, unknown>;\n if (!contributor) continue;\n\n // Migrate type: \"agent\" → \"ai\"\n if (contributor.type === \"agent\") {\n contributor.type = \"ai\";\n migrated = true;\n }\n\n // Migrate model → model_id, drop if \"unknown\"\n if (\"model\" in contributor) {\n const modelValue = contributor.model;\n contributor.model = undefined;\n if (modelValue && modelValue !== \"unknown\") {\n contributor.model_id = modelValue;\n }\n migrated = true;\n }\n }\n }\n }\n }\n\n return { record: data as unknown as TraceRecord, migrated };\n}\n\n/**\n * Create a trace reference for embedding in a trajectory\n * @param startRef - Git ref when trace started\n * @param traceId - Optional ID of the generated trace record\n * @returns TrajectoryTraceRef object\n */\nexport function createTraceRef(\n startRef: string,\n traceId?: string,\n): TrajectoryTraceRef {\n const endRef = getGitHead();\n\n return {\n startRef,\n endRef: endRef ?? undefined,\n traceId,\n };\n}\n"],"mappings":"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","names":["existsSync","dirname","trajectory","trajectory","trajectory","trajectory","trajectory","trajectory","require","dirname","existsSync","resolve","trajectory","execSync","readFileSync","execSync"]}
|