@joshski/dust 0.1.110 → 0.1.112
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 +4 -0
- package/dist/artifacts/facts.d.ts +2 -5
- package/dist/artifacts/ideas.d.ts +2 -15
- package/dist/artifacts/index.d.ts +2 -38
- package/dist/artifacts/principles.d.ts +2 -7
- package/dist/artifacts/repository-principle-hierarchy.d.ts +16 -0
- package/dist/artifacts/tasks.d.ts +2 -8
- package/dist/artifacts/types.d.ts +98 -0
- package/dist/artifacts/workflow-tasks.d.ts +2 -16
- package/dist/artifacts.js +40 -4
- package/dist/bucket/repository-loop.d.ts +1 -1
- package/dist/bucket/repository-types.d.ts +58 -0
- package/dist/bucket/repository.d.ts +2 -52
- package/dist/bucket/server-messages.d.ts +8 -2
- package/dist/cli/types.d.ts +5 -1
- package/dist/core-principles.js +608 -608
- package/dist/dust.js +1302 -842
- package/dist/execution-order.d.ts +17 -0
- package/dist/execution-order.js +39 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -47,3 +47,7 @@ Details live in the [.dust/facts](./.dust/facts) directory:
|
|
|
47
47
|
- [Directory Structure](./.dust/facts/dust-directory-structure.md) — how `.dust/` is organized
|
|
48
48
|
- [Configuration](./.dust/facts/configuration-system.md) — settings and quality checks
|
|
49
49
|
- [CLI Commands](./.dust/facts/unified-cli.md) — full command reference
|
|
50
|
+
|
|
51
|
+
## Dust Bucket Worker
|
|
52
|
+
|
|
53
|
+
The `dust bucket worker` command runs a background worker that syncs agent sessions to [dustbucket.com](https://dustbucket.com). This requires a dustbucket.com account (currently in private alpha, invite only).
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { FileReader } from '../filesystem/types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title: string;
|
|
5
|
-
content: string;
|
|
6
|
-
}
|
|
2
|
+
import type { Fact } from './types';
|
|
3
|
+
export type { Fact };
|
|
7
4
|
/**
|
|
8
5
|
* Parses a fact markdown file into a structured Fact object.
|
|
9
6
|
*/
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import type { FileReader } from '../filesystem/types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
description: string;
|
|
5
|
-
}
|
|
6
|
-
export interface IdeaOpenQuestion {
|
|
7
|
-
question: string;
|
|
8
|
-
options: IdeaOption[];
|
|
9
|
-
}
|
|
10
|
-
export interface Idea {
|
|
11
|
-
slug: string;
|
|
12
|
-
title: string;
|
|
13
|
-
openingSentence: string | null;
|
|
14
|
-
content: string;
|
|
15
|
-
openQuestions: IdeaOpenQuestion[];
|
|
16
|
-
}
|
|
2
|
+
import type { Idea, IdeaOpenQuestion, IdeaOption } from './types';
|
|
3
|
+
export type { Idea, IdeaOpenQuestion, IdeaOption };
|
|
17
4
|
export interface ParsedIdeaContent {
|
|
18
5
|
title: string | null;
|
|
19
6
|
body: string;
|
|
@@ -6,21 +6,11 @@ import { type Principle } from './principles';
|
|
|
6
6
|
import { type Task } from './tasks';
|
|
7
7
|
import { type ParsedArtifact, type ParsedMarkdownLink, type ParsedSection, parseArtifact } from './parsed-artifact';
|
|
8
8
|
import { type AllWorkflowTasks, CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllWorkflowTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, parseResolvedQuestions, type TaskType, type WorkflowTaskMatch } from './workflow-tasks';
|
|
9
|
+
import type { ArtifactType, ReadOnlyArtifactsRepository } from './types';
|
|
10
|
+
export type { ArtifactType, ReadOnlyArtifactsRepository, RepositoryPrincipleNode, TaskGraph, TaskGraphNode, } from './types';
|
|
9
11
|
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedArtifact, ParsedCaptureIdeaTask, ParsedIdeaContent, ParsedMarkdownLink, ParsedSection, Principle, Task, TaskType, WorkflowTaskMatch, };
|
|
10
|
-
export interface TaskGraphNode {
|
|
11
|
-
task: Task;
|
|
12
|
-
workflowType: TaskType | null;
|
|
13
|
-
}
|
|
14
|
-
export interface TaskGraph {
|
|
15
|
-
nodes: TaskGraphNode[];
|
|
16
|
-
edges: Array<{
|
|
17
|
-
from: string;
|
|
18
|
-
to: string;
|
|
19
|
-
}>;
|
|
20
|
-
}
|
|
21
12
|
export { CAPTURE_IDEA_PREFIX, extractTitle, findAllWorkflowTasks, ideaContentToMarkdown, parseArtifact, parseIdeaContent, parseOpenQuestions, parseResolvedQuestions, };
|
|
22
13
|
export type { IdeaInProgress };
|
|
23
|
-
export type ArtifactType = 'ideas' | 'tasks' | 'principles' | 'facts';
|
|
24
14
|
export declare const ARTIFACT_TYPES: ArtifactType[];
|
|
25
15
|
export declare const DUST_PATH_PREFIX = ".dust/";
|
|
26
16
|
/**
|
|
@@ -32,32 +22,6 @@ export declare function parseArtifactPath(path: string): {
|
|
|
32
22
|
type: ArtifactType;
|
|
33
23
|
slug: string;
|
|
34
24
|
} | null;
|
|
35
|
-
export interface ReadOnlyArtifactsRepository {
|
|
36
|
-
artifactPath(type: ArtifactType, slug: string): string;
|
|
37
|
-
parseIdea(options: {
|
|
38
|
-
slug: string;
|
|
39
|
-
}): Promise<Idea>;
|
|
40
|
-
listIdeas(): Promise<string[]>;
|
|
41
|
-
parsePrinciple(options: {
|
|
42
|
-
slug: string;
|
|
43
|
-
}): Promise<Principle>;
|
|
44
|
-
listPrinciples(): Promise<string[]>;
|
|
45
|
-
parseFact(options: {
|
|
46
|
-
slug: string;
|
|
47
|
-
}): Promise<Fact>;
|
|
48
|
-
listFacts(): Promise<string[]>;
|
|
49
|
-
parseTask(options: {
|
|
50
|
-
slug: string;
|
|
51
|
-
}): Promise<Task>;
|
|
52
|
-
listTasks(): Promise<string[]>;
|
|
53
|
-
findWorkflowTaskForIdea(options: {
|
|
54
|
-
ideaSlug: string;
|
|
55
|
-
}): Promise<WorkflowTaskMatch | null>;
|
|
56
|
-
parseCaptureIdeaTask(options: {
|
|
57
|
-
taskSlug: string;
|
|
58
|
-
}): Promise<ParsedCaptureIdeaTask | null>;
|
|
59
|
-
buildTaskGraph(): Promise<TaskGraph>;
|
|
60
|
-
}
|
|
61
25
|
export interface ArtifactsRepository extends ReadOnlyArtifactsRepository {
|
|
62
26
|
createRefineIdeaTask(options: {
|
|
63
27
|
ideaSlug: string;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { FileReader } from '../filesystem/types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title: string;
|
|
5
|
-
content: string;
|
|
6
|
-
parentPrinciple: string | null;
|
|
7
|
-
subPrinciples: string[];
|
|
8
|
-
}
|
|
2
|
+
import type { Principle } from './types';
|
|
3
|
+
export type { Principle };
|
|
9
4
|
/**
|
|
10
5
|
* Parses a principle markdown file into a structured Principle object.
|
|
11
6
|
*/
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository Principle Hierarchy API
|
|
3
|
+
*
|
|
4
|
+
* Provides pure functional access to build hierarchical trees of principles
|
|
5
|
+
* from a repository's .dust/principles/ directory.
|
|
6
|
+
*/
|
|
7
|
+
import type { ReadOnlyArtifactsRepository, RepositoryPrincipleNode } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Builds a hierarchy tree of repository principles from .dust/principles/.
|
|
10
|
+
* Returns root nodes (principles with no parent or filtered parent).
|
|
11
|
+
* Children are sorted alphabetically by title (recursive).
|
|
12
|
+
*
|
|
13
|
+
* @param repository - The repository to read principles from
|
|
14
|
+
* @returns Array of root principle nodes, empty array if no principles exist
|
|
15
|
+
*/
|
|
16
|
+
export declare function getRepositoryPrincipleHierarchy(repository: ReadOnlyArtifactsRepository): Promise<RepositoryPrincipleNode[]>;
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import type { FileReader } from '../filesystem/types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title: string;
|
|
5
|
-
content: string;
|
|
6
|
-
principles: string[];
|
|
7
|
-
blockedBy: string[];
|
|
8
|
-
definitionOfDone: string[];
|
|
9
|
-
}
|
|
2
|
+
import type { Task } from './types';
|
|
3
|
+
export type { Task };
|
|
10
4
|
/**
|
|
11
5
|
* Parses a task markdown file into a structured Task object.
|
|
12
6
|
*/
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export type TaskType = 'implement' | 'capture' | 'refine' | 'decompose' | 'shelve';
|
|
2
|
+
export interface Fact {
|
|
3
|
+
slug: string;
|
|
4
|
+
title: string;
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
export interface IdeaOption {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
export interface IdeaOpenQuestion {
|
|
12
|
+
question: string;
|
|
13
|
+
options: IdeaOption[];
|
|
14
|
+
}
|
|
15
|
+
export interface Idea {
|
|
16
|
+
slug: string;
|
|
17
|
+
title: string;
|
|
18
|
+
openingSentence: string | null;
|
|
19
|
+
content: string;
|
|
20
|
+
openQuestions: IdeaOpenQuestion[];
|
|
21
|
+
}
|
|
22
|
+
export interface Principle {
|
|
23
|
+
slug: string;
|
|
24
|
+
title: string;
|
|
25
|
+
content: string;
|
|
26
|
+
parentPrinciple: string | null;
|
|
27
|
+
subPrinciples: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface Task {
|
|
30
|
+
slug: string;
|
|
31
|
+
title: string;
|
|
32
|
+
content: string;
|
|
33
|
+
principles: string[];
|
|
34
|
+
blockedBy: string[];
|
|
35
|
+
definitionOfDone: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface OpenQuestionResponse {
|
|
38
|
+
question: string;
|
|
39
|
+
chosenOption: string;
|
|
40
|
+
}
|
|
41
|
+
export interface WorkflowTaskMatch {
|
|
42
|
+
type: TaskType;
|
|
43
|
+
ideaSlug: string;
|
|
44
|
+
taskSlug: string;
|
|
45
|
+
resolvedQuestions: OpenQuestionResponse[];
|
|
46
|
+
}
|
|
47
|
+
export interface ParsedCaptureIdeaTask {
|
|
48
|
+
ideaTitle: string;
|
|
49
|
+
ideaDescription: string;
|
|
50
|
+
expedite: boolean;
|
|
51
|
+
}
|
|
52
|
+
export type ArtifactType = 'ideas' | 'tasks' | 'principles' | 'facts';
|
|
53
|
+
export interface TaskGraphNode {
|
|
54
|
+
task: Task;
|
|
55
|
+
workflowType: TaskType | null;
|
|
56
|
+
}
|
|
57
|
+
export interface TaskGraph {
|
|
58
|
+
nodes: TaskGraphNode[];
|
|
59
|
+
edges: Array<{
|
|
60
|
+
from: string;
|
|
61
|
+
to: string;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Node in the principle hierarchy tree
|
|
66
|
+
*/
|
|
67
|
+
export interface RepositoryPrincipleNode {
|
|
68
|
+
slug: string;
|
|
69
|
+
title: string;
|
|
70
|
+
children: RepositoryPrincipleNode[];
|
|
71
|
+
}
|
|
72
|
+
export interface ReadOnlyArtifactsRepository {
|
|
73
|
+
artifactPath(type: ArtifactType, slug: string): string;
|
|
74
|
+
parseIdea(options: {
|
|
75
|
+
slug: string;
|
|
76
|
+
}): Promise<Idea>;
|
|
77
|
+
listIdeas(): Promise<string[]>;
|
|
78
|
+
parsePrinciple(options: {
|
|
79
|
+
slug: string;
|
|
80
|
+
}): Promise<Principle>;
|
|
81
|
+
listPrinciples(): Promise<string[]>;
|
|
82
|
+
parseFact(options: {
|
|
83
|
+
slug: string;
|
|
84
|
+
}): Promise<Fact>;
|
|
85
|
+
listFacts(): Promise<string[]>;
|
|
86
|
+
parseTask(options: {
|
|
87
|
+
slug: string;
|
|
88
|
+
}): Promise<Task>;
|
|
89
|
+
listTasks(): Promise<string[]>;
|
|
90
|
+
findWorkflowTaskForIdea(options: {
|
|
91
|
+
ideaSlug: string;
|
|
92
|
+
}): Promise<WorkflowTaskMatch | null>;
|
|
93
|
+
parseCaptureIdeaTask(options: {
|
|
94
|
+
taskSlug: string;
|
|
95
|
+
}): Promise<ParsedCaptureIdeaTask | null>;
|
|
96
|
+
buildTaskGraph(): Promise<TaskGraph>;
|
|
97
|
+
getRepositoryPrincipleHierarchy(): Promise<RepositoryPrincipleNode[]>;
|
|
98
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { FileSystem, ReadableFileSystem } from '../filesystem/types';
|
|
2
|
+
import type { OpenQuestionResponse, ParsedCaptureIdeaTask, TaskType, WorkflowTaskMatch } from './types';
|
|
3
|
+
export type { OpenQuestionResponse, ParsedCaptureIdeaTask, TaskType, WorkflowTaskMatch, };
|
|
2
4
|
export declare const IDEA_TRANSITION_PREFIXES: string[];
|
|
3
5
|
export declare const CAPTURE_IDEA_PREFIX = "Add Idea: ";
|
|
4
6
|
export declare const EXPEDITE_IDEA_PREFIX = "Expedite Idea: ";
|
|
@@ -6,11 +8,6 @@ export interface IdeaInProgress {
|
|
|
6
8
|
taskSlug: string;
|
|
7
9
|
ideaTitle: string;
|
|
8
10
|
}
|
|
9
|
-
export interface ParsedCaptureIdeaTask {
|
|
10
|
-
ideaTitle: string;
|
|
11
|
-
ideaDescription: string;
|
|
12
|
-
expedite: boolean;
|
|
13
|
-
}
|
|
14
11
|
/**
|
|
15
12
|
* Converts a markdown title to the expected filename using deterministic rules:
|
|
16
13
|
* 1. Convert to lowercase
|
|
@@ -22,18 +19,11 @@ export interface ParsedCaptureIdeaTask {
|
|
|
22
19
|
*/
|
|
23
20
|
export declare function titleToFilename(title: string): string;
|
|
24
21
|
export declare const VALID_TASK_TYPES: readonly ["implement", "capture", "refine", "decompose", "shelve"];
|
|
25
|
-
export type TaskType = (typeof VALID_TASK_TYPES)[number];
|
|
26
22
|
/**
|
|
27
23
|
* Extracts and validates the task type from the ## Task Type section.
|
|
28
24
|
* Returns the task type if found and valid, null otherwise.
|
|
29
25
|
*/
|
|
30
26
|
export declare function parseTaskType(content: string): TaskType | null;
|
|
31
|
-
export interface WorkflowTaskMatch {
|
|
32
|
-
type: TaskType;
|
|
33
|
-
ideaSlug: string;
|
|
34
|
-
taskSlug: string;
|
|
35
|
-
resolvedQuestions: OpenQuestionResponse[];
|
|
36
|
-
}
|
|
37
27
|
export interface AllWorkflowTasks {
|
|
38
28
|
captureIdeaTasks: IdeaInProgress[];
|
|
39
29
|
workflowTasksByIdeaSlug: Map<string, WorkflowTaskMatch>;
|
|
@@ -43,10 +33,6 @@ export declare function findWorkflowTaskForIdea(fileSystem: ReadableFileSystem,
|
|
|
43
33
|
export interface CreateIdeaTransitionTaskResult {
|
|
44
34
|
filePath: string;
|
|
45
35
|
}
|
|
46
|
-
export interface OpenQuestionResponse {
|
|
47
|
-
question: string;
|
|
48
|
-
chosenOption: string;
|
|
49
|
-
}
|
|
50
36
|
export interface DecomposeIdeaOptions {
|
|
51
37
|
ideaSlug: string;
|
|
52
38
|
description?: string;
|
package/dist/artifacts.js
CHANGED
|
@@ -294,10 +294,7 @@ async function parsePrinciple(fileSystem, dustPath, slug) {
|
|
|
294
294
|
throw new Error(`Principle not found: "${slug}" (expected file at ${principlePath})`);
|
|
295
295
|
}
|
|
296
296
|
const content = await fileSystem.readFile(principlePath);
|
|
297
|
-
const title = extractTitle(content);
|
|
298
|
-
if (!title) {
|
|
299
|
-
throw new Error(`Principle file has no title: ${principlePath}`);
|
|
300
|
-
}
|
|
297
|
+
const title = extractTitle(content) || slug;
|
|
301
298
|
const parentPrinciple = extractSingleLinkFromSection(content, "Parent Principle");
|
|
302
299
|
const subPrinciples = extractLinksFromSection(content, "Sub-Principles");
|
|
303
300
|
return {
|
|
@@ -999,6 +996,42 @@ async function parseCaptureIdeaTask(fileSystem, dustPath, taskSlug) {
|
|
|
999
996
|
return { ideaTitle, ideaDescription, expedite };
|
|
1000
997
|
}
|
|
1001
998
|
|
|
999
|
+
// lib/artifacts/repository-principle-hierarchy.ts
|
|
1000
|
+
function sortNodes(nodes) {
|
|
1001
|
+
nodes.sort((a, b) => a.title.localeCompare(b.title));
|
|
1002
|
+
for (const node of nodes) {
|
|
1003
|
+
sortNodes(node.children);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
async function getRepositoryPrincipleHierarchy(repository) {
|
|
1007
|
+
const slugs = await repository.listPrinciples();
|
|
1008
|
+
if (slugs.length === 0) {
|
|
1009
|
+
return [];
|
|
1010
|
+
}
|
|
1011
|
+
const principles = await Promise.all(slugs.map((slug) => repository.parsePrinciple({ slug })));
|
|
1012
|
+
const principleSet = new Set(slugs);
|
|
1013
|
+
const nodeBySlug = new Map;
|
|
1014
|
+
for (const p of principles) {
|
|
1015
|
+
nodeBySlug.set(p.slug, {
|
|
1016
|
+
slug: p.slug,
|
|
1017
|
+
title: p.title,
|
|
1018
|
+
children: []
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
const roots = [];
|
|
1022
|
+
for (const p of principles) {
|
|
1023
|
+
const node = nodeBySlug.get(p.slug);
|
|
1024
|
+
const parentSlug = p.parentPrinciple;
|
|
1025
|
+
if (!parentSlug || !principleSet.has(parentSlug)) {
|
|
1026
|
+
roots.push(node);
|
|
1027
|
+
} else {
|
|
1028
|
+
nodeBySlug.get(parentSlug).children.push(node);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
sortNodes(roots);
|
|
1032
|
+
return roots;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1002
1035
|
// lib/artifacts/index.ts
|
|
1003
1036
|
var ARTIFACT_TYPES = [
|
|
1004
1037
|
"facts",
|
|
@@ -1099,6 +1132,9 @@ function buildReadOperations(fileSystem, dustPath) {
|
|
|
1099
1132
|
}
|
|
1100
1133
|
}
|
|
1101
1134
|
return { nodes, edges };
|
|
1135
|
+
},
|
|
1136
|
+
async getRepositoryPrincipleHierarchy() {
|
|
1137
|
+
return getRepositoryPrincipleHierarchy(this);
|
|
1102
1138
|
}
|
|
1103
1139
|
};
|
|
1104
1140
|
}
|
|
@@ -12,7 +12,7 @@ import type { SendAgentEventFn } from '../loop/wire-events';
|
|
|
12
12
|
import { type RunnerDependencies as CodexRunnerDependencies, run as codexRun } from '../codex/run';
|
|
13
13
|
import type { SendEventFn } from './events';
|
|
14
14
|
import { type LogBuffer } from './log-buffer';
|
|
15
|
-
import type { RepositoryDependencies, RepositoryState } from './repository';
|
|
15
|
+
import type { RepositoryDependencies, RepositoryState } from './repository-types';
|
|
16
16
|
/**
|
|
17
17
|
* Create stdout/stderr callbacks that append to a log buffer.
|
|
18
18
|
* Extracted for testability (v8 coverage limitation on inline callbacks).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for repository management.
|
|
3
|
+
*
|
|
4
|
+
* Extracted to break the cyclic dependency between repository.ts and repository-loop.ts.
|
|
5
|
+
*/
|
|
6
|
+
import { spawn as nodeSpawn } from 'node:child_process';
|
|
7
|
+
import type { run as claudeRun } from '../claude/run';
|
|
8
|
+
import type { FileSystem } from '../cli/types';
|
|
9
|
+
import type { DockerDependencies } from '../docker/docker-agent';
|
|
10
|
+
import type { AuthConfig, RuntimeConfig, SessionConfig } from '../env-config';
|
|
11
|
+
import type { ToolExecutionRequest, ToolExecutionResult } from './command-events-proxy';
|
|
12
|
+
import type { LogBuffer } from './log-buffer';
|
|
13
|
+
import type { RepositoryLifecycleState } from './repository-lifecycle';
|
|
14
|
+
import type { ToolDefinition } from './server-messages';
|
|
15
|
+
export interface Repository {
|
|
16
|
+
name: string;
|
|
17
|
+
gitUrl: string;
|
|
18
|
+
gitSshUrl: string;
|
|
19
|
+
url: string;
|
|
20
|
+
id: number;
|
|
21
|
+
agentProvider?: string;
|
|
22
|
+
branch?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface RepositoryState {
|
|
25
|
+
repository: Repository;
|
|
26
|
+
path: string;
|
|
27
|
+
logBuffer: LogBuffer;
|
|
28
|
+
lifecycle: RepositoryLifecycleState;
|
|
29
|
+
agentStatus: 'idle' | 'busy';
|
|
30
|
+
wakeUp?: () => void;
|
|
31
|
+
taskAvailablePending?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface RepositoryDependencies {
|
|
34
|
+
spawn: typeof nodeSpawn;
|
|
35
|
+
run: typeof claudeRun;
|
|
36
|
+
fileSystem: FileSystem;
|
|
37
|
+
sleep: (ms: number) => Promise<void>;
|
|
38
|
+
getReposDir: () => string;
|
|
39
|
+
session: SessionConfig;
|
|
40
|
+
runtime: RuntimeConfig;
|
|
41
|
+
auth: AuthConfig;
|
|
42
|
+
/** Optional overrides for Docker dependency functions (for testing) */
|
|
43
|
+
dockerDeps?: Partial<DockerDependencies>;
|
|
44
|
+
/** Function to get current tool definitions */
|
|
45
|
+
getTools?: () => ToolDefinition[];
|
|
46
|
+
/** Function to get revealed tool families (for progressive disclosure) */
|
|
47
|
+
getRevealedFamilies?: () => Set<string>;
|
|
48
|
+
/** Forward tool execution requests to the bucket server */
|
|
49
|
+
forwardToolExecution?: (request: ToolExecutionRequest) => Promise<ToolExecutionResult>;
|
|
50
|
+
/** Mark a tool family as revealed (for progressive disclosure) */
|
|
51
|
+
revealFamily?: (familyName: string) => void;
|
|
52
|
+
/** Shell runner for pre-flight commands (install, check) */
|
|
53
|
+
shellRunner?: import('../cli/process-runner').ShellRunner;
|
|
54
|
+
/** Force Docker mode using bundled default Dockerfile */
|
|
55
|
+
forceDocker?: boolean;
|
|
56
|
+
/** Force Apple Container mode using bundled default Dockerfile */
|
|
57
|
+
forceAppleContainer?: boolean;
|
|
58
|
+
}
|
|
@@ -4,37 +4,13 @@
|
|
|
4
4
|
* Git operations live in repository-git.ts.
|
|
5
5
|
* Loop orchestration lives in repository-loop.ts.
|
|
6
6
|
*/
|
|
7
|
-
import { spawn as nodeSpawn } from 'node:child_process';
|
|
8
|
-
import { run as claudeRun } from '../claude/run';
|
|
9
7
|
import type { CommandDependencies, FileSystem } from '../cli/types';
|
|
10
|
-
import type { DockerDependencies } from '../docker/docker-agent';
|
|
11
|
-
import { type AuthConfig, type RuntimeConfig, type SessionConfig } from '../env-config';
|
|
12
|
-
import type { ToolExecutionRequest, ToolExecutionResult } from './command-events-proxy';
|
|
13
8
|
import { type BucketEmitFn, type SendEventFn } from './events';
|
|
14
9
|
import { type LogBuffer } from './log-buffer';
|
|
15
|
-
import {
|
|
16
|
-
import type { ToolDefinition } from './server-messages';
|
|
10
|
+
import type { Repository, RepositoryDependencies, RepositoryState } from './repository-types';
|
|
17
11
|
export { cloneRepository, getRepoPath, removeRepository, } from './repository-git';
|
|
18
12
|
export { runRepositoryLoop } from './repository-loop';
|
|
19
|
-
export type {
|
|
20
|
-
export interface Repository {
|
|
21
|
-
name: string;
|
|
22
|
-
gitUrl: string;
|
|
23
|
-
gitSshUrl: string;
|
|
24
|
-
url: string;
|
|
25
|
-
id: number;
|
|
26
|
-
agentProvider?: string;
|
|
27
|
-
branch?: string;
|
|
28
|
-
}
|
|
29
|
-
export interface RepositoryState {
|
|
30
|
-
repository: Repository;
|
|
31
|
-
path: string;
|
|
32
|
-
logBuffer: LogBuffer;
|
|
33
|
-
lifecycle: RepositoryLifecycleState;
|
|
34
|
-
agentStatus: 'idle' | 'busy';
|
|
35
|
-
wakeUp?: () => void;
|
|
36
|
-
taskAvailablePending?: boolean;
|
|
37
|
-
}
|
|
13
|
+
export type { Repository, RepositoryDependencies, RepositoryState, } from './repository-types';
|
|
38
14
|
/**
|
|
39
15
|
* Interface for the subset of bucket state needed by repository management.
|
|
40
16
|
* Avoids circular dependency between repository.ts and bucket.ts.
|
|
@@ -46,32 +22,6 @@ export interface RepositoryManager {
|
|
|
46
22
|
sendEvent: SendEventFn;
|
|
47
23
|
sessionId: string;
|
|
48
24
|
}
|
|
49
|
-
export interface RepositoryDependencies {
|
|
50
|
-
spawn: typeof nodeSpawn;
|
|
51
|
-
run: typeof claudeRun;
|
|
52
|
-
fileSystem: FileSystem;
|
|
53
|
-
sleep: (ms: number) => Promise<void>;
|
|
54
|
-
getReposDir: () => string;
|
|
55
|
-
session: SessionConfig;
|
|
56
|
-
runtime: RuntimeConfig;
|
|
57
|
-
auth: AuthConfig;
|
|
58
|
-
/** Optional overrides for Docker dependency functions (for testing) */
|
|
59
|
-
dockerDeps?: Partial<DockerDependencies>;
|
|
60
|
-
/** Function to get current tool definitions */
|
|
61
|
-
getTools?: () => ToolDefinition[];
|
|
62
|
-
/** Function to get revealed tool families (for progressive disclosure) */
|
|
63
|
-
getRevealedFamilies?: () => Set<string>;
|
|
64
|
-
/** Forward tool execution requests to the bucket server */
|
|
65
|
-
forwardToolExecution?: (request: ToolExecutionRequest) => Promise<ToolExecutionResult>;
|
|
66
|
-
/** Mark a tool family as revealed (for progressive disclosure) */
|
|
67
|
-
revealFamily?: (familyName: string) => void;
|
|
68
|
-
/** Shell runner for pre-flight commands (install, check) */
|
|
69
|
-
shellRunner?: import('../cli/process-runner').ShellRunner;
|
|
70
|
-
/** Force Docker mode using bundled default Dockerfile */
|
|
71
|
-
forceDocker?: boolean;
|
|
72
|
-
/** Force Apple Container mode using bundled default Dockerfile */
|
|
73
|
-
forceAppleContainer?: boolean;
|
|
74
|
-
}
|
|
75
25
|
/**
|
|
76
26
|
* Handle loop completion: transition lifecycle and reset agent status.
|
|
77
27
|
* Extracted as a named function for testability.
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Typed server-to-client WebSocket messages for the bucket protocol.
|
|
3
3
|
*/
|
|
4
|
-
import type { Repository } from './repository';
|
|
5
4
|
import type { AgentCapability } from './agent-capabilities';
|
|
6
5
|
export interface RepositoryListMessage {
|
|
7
6
|
type: 'repository-list';
|
|
8
7
|
repositories: RepositoryListItem[];
|
|
9
8
|
}
|
|
10
|
-
export interface RepositoryListItem
|
|
9
|
+
export interface RepositoryListItem {
|
|
10
|
+
name: string;
|
|
11
|
+
gitUrl: string;
|
|
12
|
+
gitSshUrl: string;
|
|
13
|
+
url: string;
|
|
14
|
+
id: number;
|
|
15
|
+
agentProvider?: string;
|
|
16
|
+
branch?: string;
|
|
11
17
|
hasTask: boolean;
|
|
12
18
|
}
|
|
13
19
|
export interface TaskAvailableMessage {
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -29,7 +29,11 @@ export interface DustSettings {
|
|
|
29
29
|
excludeCorePrinciples?: string[];
|
|
30
30
|
extraDirectories?: string[];
|
|
31
31
|
}
|
|
32
|
-
export
|
|
32
|
+
export interface FileWithTimestamp {
|
|
33
|
+
file: string;
|
|
34
|
+
lastCommittedAt: string | null;
|
|
35
|
+
}
|
|
36
|
+
export type DirectoryFileSorter = (dir: string, files: string[]) => Promise<FileWithTimestamp[]>;
|
|
33
37
|
/**
|
|
34
38
|
* Dependencies passed to all CLI commands
|
|
35
39
|
*/
|