@joshski/dust 0.1.67 → 0.1.68
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 +10 -0
- package/dist/artifacts.js +4 -4
- package/dist/audits/index.d.ts +5 -0
- package/dist/audits.js +278 -1
- package/dist/bucket/events.d.ts +50 -0
- package/dist/bucket/log-buffer.d.ts +40 -0
- package/dist/bucket/paths.d.ts +26 -0
- package/dist/bucket/repository-git.d.ts +22 -0
- package/dist/bucket/repository-loop.d.ts +45 -0
- package/dist/bucket/repository.d.ts +70 -0
- package/dist/claude/event-parser.d.ts +2 -0
- package/dist/claude/run.d.ts +15 -0
- package/dist/claude/spawn-claude-code.d.ts +9 -0
- package/dist/claude/streamer.d.ts +17 -0
- package/dist/claude/tool-formatters.d.ts +13 -0
- package/dist/claude/types.d.ts +61 -0
- package/dist/cli/colors.d.ts +25 -0
- package/dist/cli/commands/agent-shared.d.ts +44 -0
- package/dist/cli/commands/focus.d.ts +11 -0
- package/dist/cli/commands/loop.d.ts +92 -0
- package/dist/cli/commands/next.d.ts +25 -0
- package/dist/config/settings.d.ts +44 -0
- package/dist/dust.js +401 -55
- package/dist/git/hooks.d.ts +17 -0
- package/dist/session.d.ts +7 -0
- package/dist/types.d.ts +1 -0
- package/dist/version.d.ts +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-friendly formatters for Claude tool invocations.
|
|
3
|
+
*
|
|
4
|
+
* Each formatter transforms a tool's input arguments into readable output lines.
|
|
5
|
+
* Unknown tools fall back to JSON rendering.
|
|
6
|
+
*/
|
|
7
|
+
type FormatterResult = string[];
|
|
8
|
+
/**
|
|
9
|
+
* Format a tool invocation for human-readable output.
|
|
10
|
+
* Returns an array of lines to display.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatToolUse(name: string, input: Record<string, unknown>): FormatterResult;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type RawEvent = Record<string, unknown>;
|
|
2
|
+
export type TextDeltaEvent = {
|
|
3
|
+
type: 'text_delta';
|
|
4
|
+
text: string;
|
|
5
|
+
};
|
|
6
|
+
export type ToolUseEvent = {
|
|
7
|
+
type: 'tool_use';
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
input: Record<string, unknown>;
|
|
11
|
+
};
|
|
12
|
+
export type ToolResultEvent = {
|
|
13
|
+
type: 'tool_result';
|
|
14
|
+
toolUseId: string;
|
|
15
|
+
content: string;
|
|
16
|
+
};
|
|
17
|
+
export type AssistantMessageEvent = {
|
|
18
|
+
type: 'assistant_message';
|
|
19
|
+
content: Array<{
|
|
20
|
+
type: string;
|
|
21
|
+
text?: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
input?: unknown;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
export type ResultEvent = {
|
|
27
|
+
type: 'result';
|
|
28
|
+
subtype: 'success' | 'error';
|
|
29
|
+
result?: string;
|
|
30
|
+
error?: string;
|
|
31
|
+
cost_usd: number;
|
|
32
|
+
duration_ms: number;
|
|
33
|
+
num_turns: number;
|
|
34
|
+
session_id: string;
|
|
35
|
+
};
|
|
36
|
+
export type ClaudeEvent = TextDeltaEvent | ToolUseEvent | ToolResultEvent | AssistantMessageEvent | ResultEvent;
|
|
37
|
+
export type WriteOp = {
|
|
38
|
+
op: 'write';
|
|
39
|
+
text: string;
|
|
40
|
+
};
|
|
41
|
+
export type LineOp = {
|
|
42
|
+
op: 'line';
|
|
43
|
+
text: string;
|
|
44
|
+
};
|
|
45
|
+
export type OutputOp = WriteOp | LineOp;
|
|
46
|
+
export interface OutputSink {
|
|
47
|
+
write(text: string): void;
|
|
48
|
+
line(text: string): void;
|
|
49
|
+
}
|
|
50
|
+
export interface SpawnOptions {
|
|
51
|
+
cwd?: string;
|
|
52
|
+
allowedTools?: string[];
|
|
53
|
+
maxTurns?: number;
|
|
54
|
+
model?: string;
|
|
55
|
+
systemPrompt?: string;
|
|
56
|
+
sessionId?: string;
|
|
57
|
+
dangerouslySkipPermissions?: boolean;
|
|
58
|
+
env?: Record<string, string>;
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
}
|
|
61
|
+
export type RawEventCallback = (event: RawEvent) => void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ANSI color utilities with support for NO_COLOR and TTY detection.
|
|
3
|
+
*
|
|
4
|
+
* Colors are disabled when:
|
|
5
|
+
* - NO_COLOR environment variable is set (per no-color.org standard)
|
|
6
|
+
* - TERM=dumb environment variable is set
|
|
7
|
+
* - stdout is not a TTY (piped output, non-interactive environments)
|
|
8
|
+
*/
|
|
9
|
+
interface Colors {
|
|
10
|
+
reset: string;
|
|
11
|
+
bold: string;
|
|
12
|
+
dim: string;
|
|
13
|
+
cyan: string;
|
|
14
|
+
green: string;
|
|
15
|
+
yellow: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Determines whether colors should be disabled based on environment.
|
|
19
|
+
*/
|
|
20
|
+
export declare function shouldDisableColors(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the appropriate colors object based on environment detection.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getColors(): Colors;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for agent commands
|
|
3
|
+
*
|
|
4
|
+
* Provides common functionality used across all agent-* command files.
|
|
5
|
+
*/
|
|
6
|
+
import { type AgentType } from '../../agents/detection';
|
|
7
|
+
import type { CommandDependencies, DustSettings, ReadableFileSystem } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* Type-safe template variables for agent commands.
|
|
10
|
+
* Uses real booleans instead of string-encoded booleans.
|
|
11
|
+
*/
|
|
12
|
+
export interface TemplateVars {
|
|
13
|
+
bin: string;
|
|
14
|
+
agentName: string;
|
|
15
|
+
hooksInstalled: boolean;
|
|
16
|
+
isClaudeCodeWeb: boolean;
|
|
17
|
+
hasIdeaFile: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface TemplateVarsWithInstructions extends TemplateVars {
|
|
20
|
+
agentInstructions: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Loads agent-specific instructions from .dust/config/agents/{agent-type}.md
|
|
24
|
+
* Returns empty string if file doesn't exist.
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadAgentInstructions(cwd: string, fileSystem: ReadableFileSystem, agentType: AgentType): Promise<string>;
|
|
27
|
+
export declare function templateVariables(settings: DustSettings, hooksInstalled: boolean, env?: NodeJS.ProcessEnv, options?: {
|
|
28
|
+
hasIdeaFile?: boolean;
|
|
29
|
+
}): TemplateVars;
|
|
30
|
+
/**
|
|
31
|
+
* Creates template variables with agent-specific instructions loaded.
|
|
32
|
+
*/
|
|
33
|
+
export declare function templateVariablesWithInstructions(cwd: string, fileSystem: ReadableFileSystem, settings: DustSettings, hooksInstalled: boolean, env?: NodeJS.ProcessEnv, options?: {
|
|
34
|
+
hasIdeaFile?: boolean;
|
|
35
|
+
}): Promise<TemplateVarsWithInstructions>;
|
|
36
|
+
/**
|
|
37
|
+
* Manages git hook installation for agent commands.
|
|
38
|
+
* Automatically installs pre-push hooks if:
|
|
39
|
+
* - Git is available
|
|
40
|
+
* - Hooks are not already installed
|
|
41
|
+
* Also verifies and updates the binary path if needed.
|
|
42
|
+
* Returns whether hooks are installed.
|
|
43
|
+
*/
|
|
44
|
+
export declare function manageGitHooks(dependencies: CommandDependencies): Promise<boolean>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dust focus - Declare current objective and show implementation instructions
|
|
3
|
+
*
|
|
4
|
+
* Outputs the current focus/objective to stdout, followed by implementation
|
|
5
|
+
* instructions (check, implement, commit, push).
|
|
6
|
+
*
|
|
7
|
+
* Usage: dust focus "add login box"
|
|
8
|
+
*/
|
|
9
|
+
import type { CommandDependencies, CommandResult } from '../types';
|
|
10
|
+
export declare function buildImplementationInstructions(bin: string, hooksInstalled: boolean, taskTitle?: string): string;
|
|
11
|
+
export declare function focus(dependencies: CommandDependencies): Promise<CommandResult>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dust loop claude - Continuous Claude iteration on available tasks
|
|
3
|
+
*
|
|
4
|
+
* Runs Claude Code in a loop to work on tasks continuously:
|
|
5
|
+
* 1. Sync with remote (git pull)
|
|
6
|
+
* 2. Check for available tasks via `dust next`
|
|
7
|
+
* 3. If no tasks, sleep and retry
|
|
8
|
+
* 4. If tasks available, invoke Claude Code
|
|
9
|
+
* 5. Repeat until max iterations reached (default: 10)
|
|
10
|
+
*
|
|
11
|
+
* Usage: dust loop claude [max-iterations]
|
|
12
|
+
* - max-iterations: Maximum number of task iterations (default: 10)
|
|
13
|
+
* - Sleep iterations (when no tasks) don't count toward max
|
|
14
|
+
*
|
|
15
|
+
* Settings (.dust/config/settings.json):
|
|
16
|
+
* - eventsUrl: When set, HTTP POST every event to this URL with sequence number
|
|
17
|
+
*/
|
|
18
|
+
import { spawn as nodeSpawn } from 'node:child_process';
|
|
19
|
+
import { type AgentSessionEvent, type EventMessage } from '../../agent-events';
|
|
20
|
+
import { run as claudeRun } from '../../claude/run';
|
|
21
|
+
import type { CommandDependencies, CommandResult } from '../types';
|
|
22
|
+
import { type UnblockedTask } from './next';
|
|
23
|
+
export interface LoopWarningEvent {
|
|
24
|
+
type: 'loop.warning';
|
|
25
|
+
}
|
|
26
|
+
export interface LoopStartedEvent {
|
|
27
|
+
type: 'loop.started';
|
|
28
|
+
maxIterations: number;
|
|
29
|
+
agentType?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface LoopSyncingEvent {
|
|
32
|
+
type: 'loop.syncing';
|
|
33
|
+
}
|
|
34
|
+
export interface LoopSyncSkippedEvent {
|
|
35
|
+
type: 'loop.sync_skipped';
|
|
36
|
+
reason: string;
|
|
37
|
+
}
|
|
38
|
+
export interface LoopCheckingTasksEvent {
|
|
39
|
+
type: 'loop.checking_tasks';
|
|
40
|
+
}
|
|
41
|
+
export interface LoopNoTasksEvent {
|
|
42
|
+
type: 'loop.no_tasks';
|
|
43
|
+
}
|
|
44
|
+
export interface LoopTasksFoundEvent {
|
|
45
|
+
type: 'loop.tasks_found';
|
|
46
|
+
}
|
|
47
|
+
export interface LoopIterationCompleteEvent {
|
|
48
|
+
type: 'loop.iteration_complete';
|
|
49
|
+
iteration: number;
|
|
50
|
+
maxIterations: number;
|
|
51
|
+
}
|
|
52
|
+
export interface LoopEndedEvent {
|
|
53
|
+
type: 'loop.ended';
|
|
54
|
+
maxIterations: number;
|
|
55
|
+
}
|
|
56
|
+
export type LoopEvent = LoopWarningEvent | LoopStartedEvent | LoopSyncingEvent | LoopSyncSkippedEvent | LoopCheckingTasksEvent | LoopNoTasksEvent | LoopTasksFoundEvent | LoopIterationCompleteEvent | LoopEndedEvent;
|
|
57
|
+
export type LoopEmitFn = (event: LoopEvent) => void;
|
|
58
|
+
export declare function formatLoopEvent(event: LoopEvent): string | null;
|
|
59
|
+
export type PostEventFn = (url: string, payload: EventMessage) => Promise<void>;
|
|
60
|
+
export interface LoopDependencies {
|
|
61
|
+
spawn: typeof nodeSpawn;
|
|
62
|
+
run: typeof claudeRun;
|
|
63
|
+
sleep: (ms: number) => Promise<void>;
|
|
64
|
+
postEvent: PostEventFn;
|
|
65
|
+
agentType?: string;
|
|
66
|
+
fetch?: typeof fetch;
|
|
67
|
+
}
|
|
68
|
+
export declare function createPostEvent(fetchFn: typeof fetch): PostEventFn;
|
|
69
|
+
export declare function createDefaultDependencies(): LoopDependencies;
|
|
70
|
+
export type SendAgentEventFn = (event: AgentSessionEvent) => void;
|
|
71
|
+
export declare function createWireEventSender(eventsUrl: string | undefined, sessionId: string, postEvent: PostEventFn, onError: (error: unknown) => void, getAgentSessionId?: () => string | undefined, repository?: string): SendAgentEventFn;
|
|
72
|
+
type GitPullResult = {
|
|
73
|
+
success: true;
|
|
74
|
+
} | {
|
|
75
|
+
success: false;
|
|
76
|
+
message: string;
|
|
77
|
+
};
|
|
78
|
+
export declare function gitPull(cwd: string, spawn: typeof nodeSpawn): Promise<GitPullResult>;
|
|
79
|
+
export declare function findAvailableTasks(dependencies: CommandDependencies): Promise<UnblockedTask[]>;
|
|
80
|
+
type IterationResult = 'no_tasks' | 'ran_claude' | 'claude_error' | 'resolved_pull_conflict';
|
|
81
|
+
type LogFn = (message: string) => void;
|
|
82
|
+
interface IterationOptions {
|
|
83
|
+
onRawEvent?: (rawEvent: Record<string, unknown>) => void;
|
|
84
|
+
hooksInstalled?: boolean;
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
logger?: LogFn;
|
|
87
|
+
repositoryId?: string;
|
|
88
|
+
}
|
|
89
|
+
export declare function runOneIteration(dependencies: CommandDependencies, loopDependencies: LoopDependencies, onLoopEvent: LoopEmitFn, onAgentEvent?: SendAgentEventFn, options?: IterationOptions): Promise<IterationResult>;
|
|
90
|
+
export declare function parseMaxIterations(commandArguments: string[]): number;
|
|
91
|
+
export declare function loopClaude(dependencies: CommandDependencies, loopDependencies?: LoopDependencies): Promise<CommandResult>;
|
|
92
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dust next - List tasks that are ready to work on
|
|
3
|
+
*
|
|
4
|
+
* Displays tasks from .dust/tasks/ that are not blocked by any incomplete tasks.
|
|
5
|
+
* A task is blocked if its "## Blocked By" section references task files that still exist.
|
|
6
|
+
*/
|
|
7
|
+
import type { CommandContext, CommandDependencies, CommandResult, DirectoryFileSorter, FileSystem } from '../types';
|
|
8
|
+
export interface UnblockedTask {
|
|
9
|
+
path: string;
|
|
10
|
+
title: string | null;
|
|
11
|
+
openingSentence: string | null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Finds unblocked tasks in .dust/tasks/.
|
|
15
|
+
* Returns null if .dust directory is missing, otherwise an array of unblocked tasks.
|
|
16
|
+
*/
|
|
17
|
+
export declare function findUnblockedTasks(cwd: string, fileSystem: FileSystem, directoryFileSorter?: DirectoryFileSorter): Promise<{
|
|
18
|
+
error?: string;
|
|
19
|
+
tasks: UnblockedTask[];
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Formats unblocked tasks for display.
|
|
23
|
+
*/
|
|
24
|
+
export declare function printTaskList(context: CommandContext, tasks: UnblockedTask[]): void;
|
|
25
|
+
export declare function next(dependencies: CommandDependencies): Promise<CommandResult>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings module for dust CLI
|
|
3
|
+
*
|
|
4
|
+
* Reads optional configuration from .dust/config/settings.json
|
|
5
|
+
*/
|
|
6
|
+
import type { CheckConfig, DustSettings, ReadableFileSystem } from '../cli/types';
|
|
7
|
+
export type { CheckConfig, DustSettings };
|
|
8
|
+
interface SettingsViolation {
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function validateSettingsJson(content: string): SettingsViolation[];
|
|
12
|
+
/**
|
|
13
|
+
* Detects the appropriate dust command based on lockfiles and environment.
|
|
14
|
+
* Priority:
|
|
15
|
+
* 1. bun.lockb exists → bunx dust
|
|
16
|
+
* 2. pnpm-lock.yaml exists → pnpx dust
|
|
17
|
+
* 3. package-lock.json exists → npx dust
|
|
18
|
+
* 4. No lockfile + BUN_INSTALL env var set → bunx dust
|
|
19
|
+
* 5. Default → npx dust
|
|
20
|
+
*/
|
|
21
|
+
export declare function detectDustCommand(cwd: string, fileSystem: ReadableFileSystem): string;
|
|
22
|
+
/**
|
|
23
|
+
* Detects the appropriate install command based on lockfiles and environment.
|
|
24
|
+
* Priority:
|
|
25
|
+
* 1. bun.lockb exists → bun install
|
|
26
|
+
* 2. pnpm-lock.yaml exists → pnpm install
|
|
27
|
+
* 3. package-lock.json exists → npm install
|
|
28
|
+
* 4. No lockfile + BUN_INSTALL env var set → bun install
|
|
29
|
+
* 5. Default → npm install
|
|
30
|
+
*/
|
|
31
|
+
export declare function detectInstallCommand(cwd: string, fileSystem: ReadableFileSystem): string;
|
|
32
|
+
/**
|
|
33
|
+
* Detects the appropriate test command based on lockfiles and environment.
|
|
34
|
+
* Priority:
|
|
35
|
+
* 1. bun.lockb or bun.lock exists → bun test
|
|
36
|
+
* 2. pnpm-lock.yaml exists → pnpm test
|
|
37
|
+
* 3. package-lock.json exists → npm test
|
|
38
|
+
* 4. yarn.lock exists → yarn test
|
|
39
|
+
* 5. No lockfile + BUN_INSTALL env var set → bun test
|
|
40
|
+
* 6. package.json exists → npm test
|
|
41
|
+
* 7. Default → null (no test command)
|
|
42
|
+
*/
|
|
43
|
+
export declare function detectTestCommand(cwd: string, fileSystem: ReadableFileSystem): string | null;
|
|
44
|
+
export declare function loadSettings(cwd: string, fileSystem: ReadableFileSystem): Promise<DustSettings>;
|