agent-trajectories 0.4.1 → 0.5.1

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 CHANGED
@@ -30,6 +30,18 @@ Works with any task system: Beads, Linear, Jira, GitHub Issues, or standalone. T
30
30
  - **Timeline** - Linear-style chronological view
31
31
  - **JSON** - Full structured data for tooling
32
32
 
33
+ ### Native Multi-Agent Support
34
+
35
+ Trajectories is built for teams of agents working together:
36
+
37
+ - **Shared trajectory** — Multiple agents collaborate on a single task record
38
+ - **Agent participation** — Each agent logged as lead, contributor, or reviewer with timestamps
39
+ - **Chapter handoffs** — When work moves between agents, chapters capture the context shift
40
+ - **Cross-agent messaging** — Integrates with [agent-relay](https://github.com/khaliqgant/agent-relay) to record inter-agent communication as trajectory events
41
+ - **Parallel coordination** — Multiple agents working in parallel on related tasks can reference each other's trajectories
42
+
43
+ This is a key differentiator: no other tool in the AI dev stack tracks *who* (which agent, which model) made *which decisions* and *why*, across a coordinated multi-agent workflow.
44
+
33
45
  ### Integration Ready
34
46
  - Complements [claude-mem](https://github.com/thedotmack/claude-mem) for observation-level memory
35
47
  - Integrates with [agent-relay](https://github.com/khaliqgant/agent-relay) for multi-agent messaging
@@ -112,6 +124,35 @@ trail list --search "auth"
112
124
  # Export for documentation (markdown, json, timeline, or html)
113
125
  trail export traj_abc123 --format markdown
114
126
  trail export --format html --open # Opens in browser
127
+
128
+ # Compact trajectories (consolidate similar decisions)
129
+ trail compact # Uncompacted trajectories (default)
130
+ trail compact --branch main # Trajectories with commits not in main
131
+ trail compact --commits abc1234,def5678 # Trajectories matching specific commit SHAs
132
+ trail compact --pr 123 # Trajectories mentioning PR #123
133
+ trail compact --since 7d # Last 7 days
134
+ trail compact --all # Everything (including previously compacted)
135
+ ```
136
+
137
+ ### Automatic Compaction (GitHub Action)
138
+
139
+ Add these steps to any workflow that runs on PR merge (e.g., your release or publish flow). Requires `ref: ${{ github.event.pull_request.base.ref }}` and `fetch-depth: 0` on checkout, plus `contents: write` permission:
140
+
141
+ ```yaml
142
+ - name: Compact trajectories
143
+ run: |
144
+ PR_COMMITS=$(git log ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} --format=%H | paste -sd, -)
145
+ OUTPUT=".trajectories/compacted/pr-${{ github.event.pull_request.number }}.json"
146
+ if [ -n "$PR_COMMITS" ]; then
147
+ npx agent-trajectories compact --commits "$PR_COMMITS" --output "$OUTPUT"
148
+ else
149
+ npx agent-trajectories compact --pr ${{ github.event.pull_request.number }} --output "$OUTPUT"
150
+ fi
151
+ - name: Commit compacted trajectories
152
+ run: |
153
+ git add .trajectories/compacted/ || true
154
+ git diff --cached --quiet || \
155
+ (git commit -m "chore: compact trajectories for PR #${{ github.event.pull_request.number }}" && git push)
115
156
  ```
116
157
 
117
158
  ### SDK
@@ -279,6 +320,36 @@ When an agent starts a new task, it can query the workspace for:
279
320
 
280
321
  Each layer is independent and can be used alone, but together they form a complete agent memory stack.
281
322
 
323
+ ## The Narrative Layer in Your AI Stack
324
+
325
+ Trajectories sits at the top of an emerging ecosystem of AI development tools. Each layer answers a different question:
326
+
327
+ ```
328
+ ┌─────────────────────────────────────────────────────────────────┐
329
+ │ AGENT-TRAJECTORIES │
330
+ │ "Why was this built this way?" │
331
+ │ Narrative, decisions, retrospectives, institutional memory │
332
+ │ ▲ │
333
+ │ │ gives meaning to │
334
+ │ ENTIRE (entireio/cli) │
335
+ │ "What happened in this session?" │
336
+ │ Raw session capture, transcripts, recovery, rewind │
337
+ │ ▲ │
338
+ │ │ attributes │
339
+ │ AGENT-TRACE (agent-trace.dev) │
340
+ │ "Who wrote this line of code?" │
341
+ │ Line-level code attribution, model identification │
342
+ └─────────────────────────────────────────────────────────────────┘
343
+ ```
344
+
345
+ **Agent Trace** ([agent-trace.dev](https://agent-trace.dev)) is the attribution spec — trajectories implements it automatically, generating `.trace.json` files that comply with the spec on every `trail complete`.
346
+
347
+ **Entire** ([entireio/cli](https://github.com/entireio/cli)) captures raw session transcripts via git hooks — a complementary layer focused on recovery and rewind.
348
+
349
+ **Trajectories** is the narrative layer: structured meaning on top of raw events. Where entire captures *what happened*, trajectories captures *why decisions were made* and *what was learned*. Where agent-trace says *who wrote the code*, trajectories explains *why this approach was chosen*.
350
+
351
+ Used together, these tools give you a complete audit trail of AI-assisted development from attribution through narrative.
352
+
282
353
  ## The Trajectory Format
283
354
 
284
355
  ```json
@@ -463,10 +534,29 @@ const t = TrajectoryBuilder.create('Task')
463
534
  });
464
535
  ```
465
536
 
466
- ## Status
537
+ ## Roadmap
467
538
 
468
539
  This project is in early development. See [PROPOSAL-trajectories.md](./PROPOSAL-trajectories.md) for the full design document.
469
540
 
541
+ **v1.0 (current)**
542
+ - [x] File-based storage (`.trajectories/`)
543
+ - [x] Core CLI commands (`start`, `decision`, `complete`, `list`, `show`, `export`)
544
+ - [x] Agent Trace spec compliance (`.trace.json` generation)
545
+ - [x] Multi-agent participation tracking
546
+ - [x] Rich export formats (Markdown, JSON, Timeline, HTML)
547
+
548
+ **v1.1 (next)**
549
+ - [ ] **MCP server** — Real-time bidirectional queries so Claude Code, Cursor, and other tools can read and write trajectories directly within agent sessions
550
+ - [ ] **Claude Code hooks** — Auto-capture on `PostToolUse` and session boundaries
551
+ - [ ] **SQLite storage** — Full-text search across all trajectories
552
+ - [ ] **Git hook integration** — Auto-start/complete trajectories on commit events
553
+ - [ ] **`CLAUDE.md` generation** — Extract patterns from trajectories into reusable context files
554
+
555
+ **Future**
556
+ - Workspace knowledge base (decisions, patterns, conventions as queryable memory)
557
+ - PostgreSQL/S3 storage for teams
558
+ - Training data export for project-specific model fine-tuning
559
+
470
560
  ## License
471
561
 
472
562
  MIT
@@ -119,10 +119,15 @@ var TraceRangeSchema = z.object({
119
119
  revision: z.string().optional(),
120
120
  content_hash: z.string().optional()
121
121
  });
122
- var ContributorTypeSchema = z.enum(["human", "agent"]);
122
+ var ContributorTypeSchema = z.enum([
123
+ "human",
124
+ "ai",
125
+ "mixed",
126
+ "unknown"
127
+ ]);
123
128
  var TraceContributorSchema = z.object({
124
129
  type: ContributorTypeSchema,
125
- model: z.string().optional()
130
+ model_id: z.string().max(250).optional()
126
131
  });
127
132
  var TraceConversationSchema = z.object({
128
133
  contributor: TraceContributorSchema,
@@ -134,8 +139,8 @@ var TraceFileSchema = z.object({
134
139
  conversations: z.array(TraceConversationSchema)
135
140
  });
136
141
  var TraceRecordSchema = z.object({
137
- version: z.literal(1),
138
- id: z.string().regex(/^trace_[a-z0-9]+$/, "Invalid trace ID format"),
142
+ version: z.string().min(1, "Version is required"),
143
+ id: z.string().min(1, "Trace ID is required"),
139
144
  timestamp: z.string().datetime(),
140
145
  trajectory: z.string().optional(),
141
146
  files: z.array(TraceFileSchema)
@@ -1723,4 +1728,4 @@ export {
1723
1728
  getCommitsBetween,
1724
1729
  getFilesChangedBetween
1725
1730
  };
1726
- //# sourceMappingURL=chunk-JZTS4PXQ.js.map
1731
+ //# sourceMappingURL=chunk-4MACDCF4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../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/client.ts","../src/sdk/builder.ts","../src/core/trailers.ts","../src/core/trace.ts"],"sourcesContent":["/**\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 return /^traj_[a-z0-9]{12}$/.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/**\n * Event type schema\n */\nexport const TrajectoryEventTypeSchema = z.enum([\n \"prompt\",\n \"thinking\",\n \"tool_call\",\n \"tool_result\",\n \"message_sent\",\n \"message_received\",\n \"decision\",\n \"finding\",\n \"reflection\",\n \"note\",\n \"error\",\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.enum([\"lead\", \"contributor\", \"reviewer\"]),\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()),\n filesChanged: z.array(z.string()),\n projectId: z.string(),\n tags: z.array(z.string()),\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 trajectories as JSON files in a .trajectories directory.\n * Active trajectories go in active/, completed in completed/YYYY-MM/.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, readdir, unlink, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\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\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 .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 ./.trajectories\n const dataDir = process.env.TRAJECTORIES_DATA_DIR;\n if (dataDir) {\n return [expandPath(dataDir)];\n }\n\n return [join(process.cwd(), \".trajectories\")];\n}\n\n/**\n * Index file structure for quick lookups\n */\ninterface TrajectoryIndex {\n version: number;\n lastUpdated: string;\n trajectories: Record<\n string,\n {\n title: string;\n status: string;\n startedAt: string;\n completedAt?: string;\n path: string;\n }\n >;\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 indexPath: string;\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 .trajectories suffix)\n const dataDir = process.env.TRAJECTORIES_DATA_DIR;\n if (dataDir) {\n this.trajectoriesDir = expandPath(dataDir);\n } else {\n this.trajectoriesDir = join(this.baseDir, \".trajectories\");\n }\n\n this.activeDir = join(this.trajectoriesDir, \"active\");\n this.completedDir = join(this.trajectoriesDir, \"completed\");\n this.indexPath = join(this.trajectoriesDir, \"index.json\");\n }\n\n /**\n * Initialize storage directories\n */\n async initialize(): Promise<void> {\n await mkdir(this.trajectoriesDir, { recursive: true });\n await mkdir(this.activeDir, { recursive: true });\n await mkdir(this.completedDir, { recursive: true });\n\n // Create index if it doesn't exist\n if (!existsSync(this.indexPath)) {\n await this.saveIndex({\n version: 1,\n lastUpdated: new Date().toISOString(),\n trajectories: {},\n });\n }\n }\n\n /**\n * Save a trajectory\n */\n async save(trajectory: Trajectory): Promise<void> {\n const isCompleted =\n trajectory.status === \"completed\" || trajectory.status === \"abandoned\";\n\n // Determine file path\n let filePath: 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 await mkdir(monthDir, { recursive: true });\n filePath = join(monthDir, `${trajectory.id}.json`);\n\n // Remove from active if it was there\n const activePath = join(this.activeDir, `${trajectory.id}.json`);\n if (existsSync(activePath)) {\n await unlink(activePath);\n }\n\n // Generate markdown summary for completed trajectories\n const mdPath = join(monthDir, `${trajectory.id}.md`);\n const markdown = exportToMarkdown(trajectory);\n await writeFile(mdPath, markdown, \"utf-8\");\n } else {\n filePath = join(this.activeDir, `${trajectory.id}.json`);\n }\n\n // Write trajectory file\n await writeFile(filePath, JSON.stringify(trajectory, null, 2), \"utf-8\");\n\n // Update index\n await this.updateIndex(trajectory, filePath);\n }\n\n /**\n * Get a trajectory by ID\n */\n async get(id: string): Promise<Trajectory | null> {\n // Check active first\n const activePath = join(this.activeDir, `${id}.json`);\n if (existsSync(activePath)) {\n return this.readTrajectoryFile(activePath);\n }\n\n // Check completed (need to search subdirectories)\n const index = await this.loadIndex();\n const entry = index.trajectories[id];\n if (entry?.path && existsSync(entry.path)) {\n return this.readTrajectoryFile(entry.path);\n }\n\n // Search completed directories manually if not in index\n try {\n const months = await readdir(this.completedDir);\n for (const month of months) {\n const filePath = join(this.completedDir, month, `${id}.json`);\n if (existsSync(filePath)) {\n return this.readTrajectoryFile(filePath);\n }\n }\n } catch (error) {\n // ENOENT means directory doesn't exist yet - this is expected\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n console.error(\"Error searching completed trajectories:\", error);\n }\n }\n\n return null;\n }\n\n /**\n * Get the currently active trajectory\n */\n async getActive(): Promise<Trajectory | null> {\n try {\n const files = await readdir(this.activeDir);\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.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 file of jsonFiles) {\n const trajectory = await this.readTrajectoryFile(\n join(this.activeDir, file),\n );\n if (trajectory) {\n const startTime = new Date(trajectory.startedAt).getTime();\n if (startTime > mostRecentTime) {\n mostRecentTime = startTime;\n mostRecent = trajectory;\n }\n }\n }\n\n return mostRecent;\n } catch (error) {\n // ENOENT means directory doesn't exist yet - this is expected\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n // Log unexpected errors for debugging\n console.error(\"Error reading active trajectories:\", error);\n return null;\n }\n }\n\n /**\n * List trajectories with optional filtering\n */\n async list(query: TrajectoryQuery): Promise<TrajectorySummary[]> {\n const index = await this.loadIndex();\n let entries = Object.entries(index.trajectories);\n\n // Filter by status\n if (query.status) {\n entries = entries.filter(([, entry]) => entry.status === query.status);\n }\n\n // Filter by date range\n if (query.since) {\n const sinceTime = new Date(query.since).getTime();\n entries = entries.filter(\n ([, entry]) => new Date(entry.startedAt).getTime() >= sinceTime,\n );\n }\n if (query.until) {\n const untilTime = new Date(query.until).getTime();\n entries = entries.filter(\n ([, entry]) => new Date(entry.startedAt).getTime() <= untilTime,\n );\n }\n\n // Sort (default: startedAt desc)\n const sortBy = query.sortBy ?? \"startedAt\";\n const sortOrder = query.sortOrder ?? \"desc\";\n entries.sort((a, b) => {\n const aVal = a[1][sortBy as keyof (typeof a)[1]] ?? \"\";\n const bVal = b[1][sortBy as keyof (typeof b)[1]] ?? \"\";\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 ?? 50;\n entries = entries.slice(offset, offset + limit);\n\n // Convert to summaries\n return Promise.all(\n entries.map(async ([id, entry]) => {\n // Load full trajectory to get counts\n const trajectory = await this.get(id);\n return {\n id,\n title: entry.title,\n status: entry.status as \"active\" | \"completed\" | \"abandoned\",\n startedAt: entry.startedAt,\n completedAt: entry.completedAt,\n confidence: trajectory?.retrospective?.confidence,\n chapterCount: trajectory?.chapters.length ?? 0,\n decisionCount:\n trajectory?.chapters.reduce(\n (count, chapter) =>\n count +\n chapter.events.filter((e) => e.type === \"decision\").length,\n 0,\n ) ?? 0,\n };\n }),\n );\n }\n\n /**\n * Delete a trajectory\n */\n async delete(id: string): Promise<void> {\n // Remove from active\n const activePath = join(this.activeDir, `${id}.json`);\n if (existsSync(activePath)) {\n await unlink(activePath);\n }\n\n // Remove from completed (search subdirectories)\n const index = await this.loadIndex();\n const entry = index.trajectories[id];\n if (entry?.path && existsSync(entry.path)) {\n await unlink(entry.path);\n // Also remove markdown if exists\n const mdPath = entry.path.replace(\".json\", \".md\");\n if (existsSync(mdPath)) {\n await unlink(mdPath);\n }\n }\n\n // Update index\n delete index.trajectories[id];\n await this.saveIndex(index);\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 * 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 async readTrajectoryFile(path: string): Promise<Trajectory | null> {\n try {\n const content = await readFile(path, \"utf-8\");\n const data = JSON.parse(content);\n const validation = validateTrajectory(data);\n if (validation.success) {\n return validation.data as Trajectory;\n }\n console.error(`Invalid trajectory at ${path}:`, validation.errors);\n return null;\n } catch (error) {\n console.error(`Failed to read trajectory at ${path}:`, error);\n return null;\n }\n }\n\n private async loadIndex(): Promise<TrajectoryIndex> {\n try {\n const content = await readFile(this.indexPath, \"utf-8\");\n return JSON.parse(content);\n } catch (error) {\n // ENOENT means index doesn't exist yet - this is expected on first run\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n console.error(\n \"Error loading trajectory index, using empty index:\",\n error,\n );\n }\n return {\n version: 1,\n lastUpdated: new Date().toISOString(),\n trajectories: {},\n };\n }\n }\n\n private async saveIndex(index: TrajectoryIndex): Promise<void> {\n index.lastUpdated = new Date().toISOString();\n await writeFile(this.indexPath, JSON.stringify(index, null, 2), \"utf-8\");\n }\n\n private async updateIndex(\n trajectory: Trajectory,\n filePath: string,\n ): Promise<void> {\n const index = await this.loadIndex();\n index.trajectories[trajectory.id] = {\n title: trajectory.task.title,\n status: trajectory.status,\n startedAt: trajectory.startedAt,\n completedAt: trajectory.completedAt,\n path: filePath,\n };\n await this.saveIndex(index);\n }\n}\n","/**\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 {\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\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 file storage. Defaults to .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\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 /**\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 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\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 }\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 trajectory = createTrajectory({\n title,\n projectId: this.projectId,\n ...options,\n });\n\n await this.storage.save(trajectory);\n return new TrajectorySession(trajectory, 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 * 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 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)/.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)\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":["trajectory","trajectory","trajectory","trajectory","trajectory","trajectory","trajectory","execSync","execSync"]}