Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Build and Development Commands

```bash
npm run build # Compile TypeScript to dist/
npm run build # Compile TypeScript to dist/
npm run dev -- <args> # Run CLI directly via tsx (e.g., npm run dev -- list)
npm link # Install 'threads' command globally
threads <command> # Run installed CLI
npm run test # Run Jest test suite
npm run typecheck # Type check without emitting
npm link # Install 'threads' command globally
threads <command> # Run installed CLI
```

## Architecture

Threads is a CLI tool for tracking streams of activity through self-reported progress rather than task management. Data is stored in `~/.threads/threads.json` and accessed only through the CLI.

### Philosophy

- **Self-reported progress over task management**: Users describe what they're doing, not what needs to be done
- **Temperature = momentum**: How actively you're working on something (hot = active focus, frozen = dormant)
- **Threads evolve**: Status, temperature, and details change as work progresses

### Core Concepts

- **Thread**: A stream of activity with status, temperature (momentum), size (scope), and importance
- **Progress**: Timestamped notes you report to yourself about a thread
- **Details**: Versioned snapshots of structured information about a thread (latest is current)
- **Sub-threads**: Threads can spawn children via `parentId`
- **Groups**: Organizational containers for threads
- **Dependencies**: Links between threads with why/what/how/when context
Expand All @@ -35,22 +44,23 @@ src/utils/format.ts # Console output formatting with chalk

### Data Flow

Commands import from `storage` for data operations and `utils` for display. Storage reads/writes `~/.threads/threads.json` on every operation (no in-memory caching).
Commands import from `storage` for data operations and `utils` for display. Storage reads/writes `~/.threads/threads.json` on every operation (no in-memory caching). A backup is created before each write operation.

### Thread Properties

| Property | Values |
|----------|--------|
| status | active, paused, stopped, completed, archived |
| temperature | frozen, freezing, cold, tepid, warm, hot |
| size | tiny, small, medium, large, huge |
| importance | 1-5 |
| Property | Values | Description |
|----------|--------|-------------|
| status | active, paused, stopped, completed, archived | Lifecycle state |
| temperature | frozen, freezing, cold, tepid, warm, hot | Momentum/recency indicator |
| size | tiny, small, medium, large, huge | Scope of work |
| importance | 1-5 | Priority level (5 = highest) |

### Adding New Commands

1. Create `src/commands/<name>.ts` exporting a `Command` object
2. Add export to `src/commands/index.ts`
3. Import and register in `src/index.ts` via `program.addCommand()`
4. Follow the Commander.js pattern: `.argument()` for positional args, `.option()` for flags

## CLI Usage Notes

Expand Down
33 changes: 33 additions & 0 deletions src/.claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# src/ - Source Root

This is the main source directory for the Threads CLI application.

## Entry Point

- `index.ts` - CLI entry point using Commander.js
- Imports all commands from `./commands/`
- Creates the root `program` with name, description, version
- Registers each command via `program.addCommand()`
- Calls `program.parse()` to process CLI arguments

## Module Structure

| Directory | Purpose |
|-----------|---------|
| `commands/` | CLI command implementations (one per file) |
| `models/` | TypeScript types and interfaces |
| `storage/` | Data persistence layer (JSON file I/O) |
| `utils/` | Formatting and display utilities |

## Import Conventions

- Each subdirectory has an `index.ts` that re-exports its public API
- Commands import from `../storage` and `../utils`
- Commands import types from `../models`

## Adding New Modules

When adding new functionality:
1. Create the module in the appropriate directory
2. Export from that directory's `index.ts`
3. Import using the directory path (e.g., `from '../storage'`)
83 changes: 83 additions & 0 deletions src/commands/.claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# commands/ - CLI Commands

Each file implements a single CLI command. All commands follow the same pattern.

## Command Pattern

```typescript
import { Command } from 'commander';
import { /* storage functions */ } from '../storage';
import { /* types */ } from '../models';
import { /* formatters */ } from '../utils';
import chalk from 'chalk';

export const myCommand = new Command('command-name')
.description('What this command does')
.argument('<required>', 'Description of required arg')
.argument('[optional]', 'Description of optional arg')
.option('-f, --flag', 'Boolean flag')
.option('-v, --value <val>', 'Option with value')
.action((arg1, arg2, options) => {
// Implementation
});
```

## Available Commands

| Command | Alias | Purpose |
|---------|-------|---------|
| new | - | Create a new thread |
| list | - | List threads with filters |
| show | - | Show thread details |
| progress | p | Add progress note |
| edit-progress | - | Edit or delete progress entries |
| set | - | Update thread properties |
| spawn | - | Create a sub-thread |
| details | - | Add/update thread details |
| group | - | Manage groups |
| tag | - | Add/remove tags |
| depend | - | Manage dependencies |
| archive | - | Archive threads |
| clone | - | Clone a thread |
| merge | - | Merge threads |
| search | - | Search threads |
| overview | - | Show summary view |
| agenda | - | Show prioritized view |
| timeline | - | Show chronological view |
| next | - | Suggest next thread |
| batch | - | Batch operations |
| move-progress | - | Move progress between threads |
| undo | - | Restore from backup |

## Thread Resolution Pattern

Most commands accept a thread identifier that can be:
1. Full UUID
2. Partial UUID (prefix match)
3. Exact thread name
4. Partial name (substring match)

Standard resolution pattern:
```typescript
let thread = getThreadById(identifier);
if (!thread) {
thread = getThreadByName(identifier);
}
if (!thread) {
// Try partial match...
}
```

## Output Conventions

- Use `chalk.green()` for success messages
- Use `chalk.red()` for errors
- Use `chalk.yellow()` for warnings or multiple matches
- Use `chalk.dim()` for secondary information
- Import formatters from `../utils` for consistent thread display

## Adding a New Command

1. Create `src/commands/<name>.ts` with the command pattern above
2. Export from `src/commands/index.ts`: `export { myCommand } from './my-command';`
3. Import and register in `src/index.ts`: `program.addCommand(myCommand);`
60 changes: 60 additions & 0 deletions src/models/.claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# models/ - TypeScript Types

Contains all type definitions for the Threads CLI. No runtime code, only types.

## Core Types

### Thread
The main entity - a stream of activity being tracked.

```typescript
interface Thread {
id: string; // UUID
name: string; // Display name (unique)
description: string; // Brief summary
status: ThreadStatus; // Lifecycle state
importance: Importance; // Priority 1-5
temperature: Temperature; // Momentum indicator
size: ThreadSize; // Scope of work
parentId: string | null; // For sub-threads
groupId: string | null; // Organizational group
tags: string[]; // User-defined tags
dependencies: Dependency[];
progress: ProgressEntry[];
details: DetailsEntry[];
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
}
```

### Enums

| Type | Values |
|------|--------|
| `ThreadStatus` | active, paused, stopped, completed, archived |
| `Temperature` | frozen, freezing, cold, tepid, warm, hot |
| `ThreadSize` | tiny, small, medium, large, huge |
| `Importance` | 1, 2, 3, 4, 5 |

### Supporting Types

- **ProgressEntry**: `{ id, timestamp, note }` - Timestamped progress notes
- **DetailsEntry**: `{ id, timestamp, content }` - Versioned detail snapshots
- **Dependency**: `{ threadId, why, what, how, when }` - Inter-thread links
- **Group**: `{ id, name, description, createdAt, updatedAt }` - Thread containers
- **ThreadsData**: `{ threads, groups, version }` - Root data structure

## Usage

Import types from the models module:
```typescript
import { Thread, ThreadStatus, ProgressEntry } from '../models';
```

## Design Notes

- All IDs are UUIDs (generated via `uuid` package)
- All timestamps are ISO 8601 strings
- Thread names are unique (case-insensitive matching)
- Progress entries are append-only in normal operation
- Details are versioned; the last entry is the "current" state
66 changes: 66 additions & 0 deletions src/storage/.claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# storage/ - Data Persistence

Handles all file I/O for the Threads CLI. Data is stored in `~/.threads/threads.json`.

## File Locations

```
~/.threads/
threads.json # Main data file
threads.backup.json # Automatic backup (created before each write)
```

## Core Functions

### Data Loading/Saving
- `loadData(): ThreadsData` - Load entire data store
- `saveData(data: ThreadsData): void` - Save with automatic backup

### Thread CRUD
- `getAllThreads(): Thread[]`
- `getThreadById(id: string): Thread | undefined`
- `getThreadByName(name: string): Thread | undefined` - Case-insensitive
- `findThreads(predicate): Thread[]` - Filter with callback
- `addThread(thread: Thread): void`
- `updateThread(id, updates): Thread | undefined` - Partial update
- `deleteThread(id: string): boolean`

### Group CRUD
- `getAllGroups(): Group[]`
- `getGroupById(id: string): Group | undefined`
- `getGroupByName(name: string): Group | undefined` - Case-insensitive
- `addGroup(group: Group): void`
- `updateGroup(id, updates): Group | undefined`
- `deleteGroup(id: string): boolean`

### Backup/Undo
- `getBackupInfo(): BackupInfo` - Check if backup exists
- `loadBackupData(): ThreadsData | undefined`
- `restoreFromBackup(): boolean` - Swap current with backup

## Design Patterns

### No Caching
Every read operation loads from disk. This ensures:
- CLI invocations always see current data
- External edits are never lost
- Simple mental model (no cache invalidation)

### Automatic Backup
Every `saveData()` call copies current file to backup first:
1. Copy `threads.json` to `threads.backup.json`
2. Write new data to `threads.json`

This enables single-step undo via `threads undo`.

### Partial Updates
`updateThread()` merges partial updates and auto-sets `updatedAt`:
```typescript
updateThread(id, { temperature: 'hot' }); // Only changes temperature
```

## Usage

```typescript
import { getAllThreads, updateThread, addThread } from '../storage';
```
71 changes: 71 additions & 0 deletions src/utils/.claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# utils/ - Formatting and Display

Provides consistent formatting for CLI output using chalk for colors.

## Color Conventions

### Status Colors
| Status | Color |
|--------|-------|
| active | green |
| paused | yellow |
| stopped | red |
| completed | blue |
| archived | gray |

### Temperature Colors
| Temperature | Color |
|-------------|-------|
| frozen | bright blue |
| freezing | cyan |
| cold | blue |
| tepid | white |
| warm | yellow |
| hot | red |

## Format Functions

### Thread Display
- `formatStatus(status)` - Colored uppercase status
- `formatTemperature(temp)` - Colored temperature label
- `formatSize(size)` - Capitalized size label
- `formatImportance(imp)` - `[*][*][*][ ][ ]` style rating
- `formatImportanceStars(imp)` - Star characters for compact view
- `formatTags(tags)` - Cyan `#tag` labels
- `formatThreadSummary(thread)` - Two-line summary
- `formatThreadDetail(thread)` - Full detail view with progress

### Tree View
- `TreeChars` - Box-drawing characters (├── └── │)
- `formatThreadTreeLine(thread)` - Compact single-line format
- `formatGroupHeader(group)` - Bold underlined group name
- `buildTree(threads, groups): TreeNode[]` - Build hierarchical structure
- `renderTree(nodes): string[]` - Render tree to output lines

## TreeNode Structure

```typescript
interface TreeNode {
type: 'group' | 'thread' | 'ungrouped-header';
group?: Group;
thread?: Thread;
children: TreeNode[];
}
```

The tree builder:
1. Groups threads by `groupId`
2. Builds parent-child relationships via `parentId`
3. Sorts groups alphabetically
4. Places ungrouped threads at the end

## Usage

```typescript
import { formatThreadSummary, buildTree, renderTree } from '../utils';

console.log(formatThreadSummary(thread));

const tree = buildTree(threads, groups);
renderTree(tree).forEach(line => console.log(line));
```