@joshski/dust 0.1.103 → 0.1.104
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/dist/agents/detection.d.ts +1 -1
- package/dist/agents.js +1 -1
- package/dist/artifacts/facts.d.ts +2 -2
- package/dist/artifacts/ideas.d.ts +2 -2
- package/dist/artifacts/index.d.ts +2 -2
- package/dist/artifacts/principles.d.ts +2 -2
- package/dist/artifacts/tasks.d.ts +2 -2
- package/dist/artifacts/workflow-tasks.d.ts +6 -0
- package/dist/artifacts.js +142 -25
- package/dist/audits/index.d.ts +1 -0
- package/dist/audits.js +24 -1
- package/dist/bucket/repository-loop.d.ts +4 -4
- package/dist/bucket/repository.d.ts +10 -0
- package/dist/claude/run.d.ts +3 -9
- package/dist/claude/spawn-claude-code.d.ts +1 -1
- package/dist/claude/types.d.ts +9 -0
- package/dist/cli/commands/focus.d.ts +2 -1
- package/dist/cli/shared/agent-shared.d.ts +4 -4
- package/dist/cli/types.d.ts +1 -1
- package/dist/codex/run.d.ts +3 -9
- package/dist/codex/spawn-codex.d.ts +1 -1
- package/dist/config/settings.d.ts +5 -5
- package/dist/core-principles.js +5 -16
- package/dist/docker/docker-agent.d.ts +0 -4
- package/dist/dust.js +375 -422
- package/dist/filesystem/types.d.ts +5 -1
- package/dist/lint/validators/content-validator.d.ts +1 -0
- package/dist/lint/validators/directory-validator.d.ts +3 -3
- package/dist/lint/validators/idea-validator.d.ts +3 -3
- package/dist/lint/validators/link-validator.d.ts +2 -2
- package/dist/loop/iteration.d.ts +2 -3
- package/dist/patch/index.d.ts +13 -0
- package/dist/patch.js +48 -115
- package/dist/proxy/helper-token.d.ts +2 -2
- package/dist/validation.js +38 -115
- package/package.json +2 -2
package/dist/agents.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FileReader } from '../filesystem/types';
|
|
2
2
|
export interface Fact {
|
|
3
3
|
slug: string;
|
|
4
4
|
title: string;
|
|
@@ -7,4 +7,4 @@ export interface Fact {
|
|
|
7
7
|
/**
|
|
8
8
|
* Parses a fact markdown file into a structured Fact object.
|
|
9
9
|
*/
|
|
10
|
-
export declare function parseFact(fileSystem:
|
|
10
|
+
export declare function parseFact(fileSystem: FileReader, dustPath: string, slug: string): Promise<Fact>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FileReader } from '../filesystem/types';
|
|
2
2
|
export interface IdeaOption {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
@@ -27,7 +27,7 @@ export declare function parseOpenQuestions(content: string): IdeaOpenQuestion[];
|
|
|
27
27
|
/**
|
|
28
28
|
* Parses an idea markdown file into a structured Idea object.
|
|
29
29
|
*/
|
|
30
|
-
export declare function parseIdea(fileSystem:
|
|
30
|
+
export declare function parseIdea(fileSystem: FileReader, dustPath: string, slug: string): Promise<Idea>;
|
|
31
31
|
/**
|
|
32
32
|
* Parses idea markdown into a structured object that can be bound to a UI
|
|
33
33
|
* and serialized back to markdown.
|
|
@@ -5,8 +5,8 @@ import { extractTitle } from '../markdown/markdown-utilities';
|
|
|
5
5
|
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
|
-
import { type AllWorkflowTasks, CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllWorkflowTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, parseResolvedQuestions, type WorkflowTaskMatch, type WorkflowTaskType } from './workflow-tasks';
|
|
9
|
-
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedArtifact, ParsedCaptureIdeaTask, ParsedIdeaContent, ParsedMarkdownLink, ParsedSection, Principle, Task, WorkflowTaskMatch, WorkflowTaskType, };
|
|
8
|
+
import { type AllWorkflowTasks, CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllWorkflowTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, parseResolvedQuestions, type TaskType, type WorkflowTaskMatch, type WorkflowTaskType } from './workflow-tasks';
|
|
9
|
+
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedArtifact, ParsedCaptureIdeaTask, ParsedIdeaContent, ParsedMarkdownLink, ParsedSection, Principle, Task, TaskType, WorkflowTaskMatch, WorkflowTaskType, };
|
|
10
10
|
export interface TaskGraphNode {
|
|
11
11
|
task: Task;
|
|
12
12
|
workflowType: WorkflowTaskType | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FileReader } from '../filesystem/types';
|
|
2
2
|
export interface Principle {
|
|
3
3
|
slug: string;
|
|
4
4
|
title: string;
|
|
@@ -9,4 +9,4 @@ export interface Principle {
|
|
|
9
9
|
/**
|
|
10
10
|
* Parses a principle markdown file into a structured Principle object.
|
|
11
11
|
*/
|
|
12
|
-
export declare function parsePrinciple(fileSystem:
|
|
12
|
+
export declare function parsePrinciple(fileSystem: FileReader, dustPath: string, slug: string): Promise<Principle>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FileReader } from '../filesystem/types';
|
|
2
2
|
export interface Task {
|
|
3
3
|
slug: string;
|
|
4
4
|
title: string;
|
|
@@ -10,4 +10,4 @@ export interface Task {
|
|
|
10
10
|
/**
|
|
11
11
|
* Parses a task markdown file into a structured Task object.
|
|
12
12
|
*/
|
|
13
|
-
export declare function parseTask(fileSystem:
|
|
13
|
+
export declare function parseTask(fileSystem: FileReader, dustPath: string, slug: string): Promise<Task>;
|
|
@@ -21,6 +21,12 @@ export interface ParsedCaptureIdeaTask {
|
|
|
21
21
|
* 6. Add .md extension
|
|
22
22
|
*/
|
|
23
23
|
export declare function titleToFilename(title: string): string;
|
|
24
|
+
export type TaskType = 'implement' | 'capture' | 'refine' | 'decompose' | 'shelve';
|
|
25
|
+
/**
|
|
26
|
+
* Extracts and validates the task type from the ## Task Type section.
|
|
27
|
+
* Returns the task type if found and valid, null otherwise.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseTaskType(content: string): TaskType | null;
|
|
24
30
|
export type WorkflowTaskType = 'refine-idea' | 'decompose-idea' | 'shelve-idea' | 'expedite-idea';
|
|
25
31
|
export interface WorkflowTaskMatch {
|
|
26
32
|
type: WorkflowTaskType;
|
package/dist/artifacts.js
CHANGED
|
@@ -522,6 +522,54 @@ var EXPEDITE_IDEA_PREFIX = "Expedite Idea: ";
|
|
|
522
522
|
function titleToFilename(title) {
|
|
523
523
|
return `${title.toLowerCase().replace(/\./g, "-").replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
524
524
|
}
|
|
525
|
+
var VALID_TASK_TYPES = [
|
|
526
|
+
"implement",
|
|
527
|
+
"capture",
|
|
528
|
+
"refine",
|
|
529
|
+
"decompose",
|
|
530
|
+
"shelve"
|
|
531
|
+
];
|
|
532
|
+
function parseTaskType(content) {
|
|
533
|
+
const lines = content.split(`
|
|
534
|
+
`);
|
|
535
|
+
let inSection = false;
|
|
536
|
+
let inCodeFence = false;
|
|
537
|
+
for (const line of lines) {
|
|
538
|
+
if (line.startsWith("```")) {
|
|
539
|
+
inCodeFence = !inCodeFence;
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
if (inCodeFence)
|
|
543
|
+
continue;
|
|
544
|
+
if (line.startsWith("## ")) {
|
|
545
|
+
inSection = line.trimEnd() === "## Task Type";
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
if (!inSection)
|
|
549
|
+
continue;
|
|
550
|
+
if (line.startsWith("# "))
|
|
551
|
+
break;
|
|
552
|
+
const trimmed = line.trim();
|
|
553
|
+
if (trimmed && VALID_TASK_TYPES.includes(trimmed)) {
|
|
554
|
+
return trimmed;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return null;
|
|
558
|
+
}
|
|
559
|
+
function taskTypeToWorkflowType(taskType) {
|
|
560
|
+
switch (taskType) {
|
|
561
|
+
case "refine":
|
|
562
|
+
return "refine-idea";
|
|
563
|
+
case "decompose":
|
|
564
|
+
return "decompose-idea";
|
|
565
|
+
case "shelve":
|
|
566
|
+
return "shelve-idea";
|
|
567
|
+
case "implement":
|
|
568
|
+
return "expedite-idea";
|
|
569
|
+
default:
|
|
570
|
+
return null;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
525
573
|
var WORKFLOW_HINT_PATHS = {
|
|
526
574
|
"refine-idea": "config/hints/refine-idea.md",
|
|
527
575
|
"decompose-idea": "config/hints/decompose-idea.md",
|
|
@@ -588,16 +636,32 @@ async function findAllWorkflowTasks(fileSystem, dustPath) {
|
|
|
588
636
|
continue;
|
|
589
637
|
const title = titleMatch[1].trim();
|
|
590
638
|
const taskSlug = file.replace(/\.md$/, "");
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
639
|
+
const taskType = parseTaskType(content);
|
|
640
|
+
if (taskType === "capture" || taskType === "implement") {
|
|
641
|
+
let ideaTitle = null;
|
|
642
|
+
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
643
|
+
ideaTitle = title.slice(CAPTURE_IDEA_PREFIX.length);
|
|
644
|
+
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
645
|
+
ideaTitle = title.slice(EXPEDITE_IDEA_PREFIX.length);
|
|
646
|
+
}
|
|
647
|
+
if (ideaTitle) {
|
|
648
|
+
captureIdeaTasks.push({
|
|
649
|
+
taskSlug,
|
|
650
|
+
ideaTitle
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
} else if (!taskType) {
|
|
654
|
+
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
655
|
+
captureIdeaTasks.push({
|
|
656
|
+
taskSlug,
|
|
657
|
+
ideaTitle: title.slice(CAPTURE_IDEA_PREFIX.length)
|
|
658
|
+
});
|
|
659
|
+
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
660
|
+
captureIdeaTasks.push({
|
|
661
|
+
taskSlug,
|
|
662
|
+
ideaTitle: title.slice(EXPEDITE_IDEA_PREFIX.length)
|
|
663
|
+
});
|
|
664
|
+
}
|
|
601
665
|
}
|
|
602
666
|
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
603
667
|
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
@@ -625,17 +689,49 @@ async function findWorkflowTaskForIdea(fileSystem, dustPath, ideaSlug) {
|
|
|
625
689
|
const files = await fileSystem.readdir(tasksPath);
|
|
626
690
|
for (const file of files.filter((f) => f.endsWith(".md")).toSorted()) {
|
|
627
691
|
const content = await fileSystem.readFile(`${tasksPath}/${file}`);
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
692
|
+
const taskSlug = file.replace(/\.md$/, "");
|
|
693
|
+
const match = findWorkflowMatch(content, ideaSlug, taskSlug);
|
|
694
|
+
if (match) {
|
|
695
|
+
return match;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
function findWorkflowMatch(content, ideaSlug, taskSlug) {
|
|
701
|
+
const taskType = parseTaskType(content);
|
|
702
|
+
if (taskType) {
|
|
703
|
+
const workflowType = taskTypeToWorkflowType(taskType);
|
|
704
|
+
if (workflowType) {
|
|
705
|
+
const match = findWorkflowMatchByType(content, ideaSlug, taskSlug, workflowType);
|
|
706
|
+
if (match)
|
|
707
|
+
return match;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
711
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
712
|
+
if (linkedSlug === ideaSlug) {
|
|
713
|
+
return {
|
|
714
|
+
type,
|
|
715
|
+
ideaSlug,
|
|
716
|
+
taskSlug,
|
|
717
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
return null;
|
|
722
|
+
}
|
|
723
|
+
function findWorkflowMatchByType(content, ideaSlug, taskSlug, workflowType) {
|
|
724
|
+
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
725
|
+
if (type !== workflowType)
|
|
726
|
+
continue;
|
|
727
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
728
|
+
if (linkedSlug === ideaSlug) {
|
|
729
|
+
return {
|
|
730
|
+
type: workflowType,
|
|
731
|
+
ideaSlug,
|
|
732
|
+
taskSlug,
|
|
733
|
+
resolvedQuestions: parseResolvedQuestions(content)
|
|
734
|
+
};
|
|
639
735
|
}
|
|
640
736
|
}
|
|
641
737
|
return null;
|
|
@@ -719,7 +815,7 @@ function renderRepositoryHintsSection(repositoryHint) {
|
|
|
719
815
|
${repositoryHint}
|
|
720
816
|
`;
|
|
721
817
|
}
|
|
722
|
-
function renderTask(title, openingSentence, definitionOfDone, ideaSection, options) {
|
|
818
|
+
function renderTask(title, openingSentence, definitionOfDone, ideaSection, taskType, options) {
|
|
723
819
|
const descriptionParagraph = options?.description !== undefined ? `
|
|
724
820
|
${options.description}
|
|
725
821
|
` : "";
|
|
@@ -733,7 +829,12 @@ ${renderIdeaSection(ideaSection)}
|
|
|
733
829
|
return `# ${title}
|
|
734
830
|
|
|
735
831
|
${openingSentence}
|
|
736
|
-
${descriptionParagraph}${resolvedSection}${ideaSectionContent}
|
|
832
|
+
${descriptionParagraph}${resolvedSection}${ideaSectionContent}
|
|
833
|
+
## Task Type
|
|
834
|
+
|
|
835
|
+
${taskType}
|
|
836
|
+
|
|
837
|
+
## Blocked By
|
|
737
838
|
|
|
738
839
|
(none)
|
|
739
840
|
${repositoryHintsSection}
|
|
@@ -752,7 +853,8 @@ async function createIdeaTransitionTask(fileSystem, dustPath, workflowType, pref
|
|
|
752
853
|
const baseOpeningSentence = openingSentenceTemplate(ideaTitle);
|
|
753
854
|
const hint = await readWorkflowHint(fileSystem, dustPath, workflowType);
|
|
754
855
|
const ideaSection = { heading: ideaSectionHeading, ideaTitle, ideaSlug };
|
|
755
|
-
const
|
|
856
|
+
const taskType = workflowType === "refine-idea" ? "refine" : workflowType === "decompose-idea" ? "decompose" : workflowType === "shelve-idea" ? "shelve" : "implement";
|
|
857
|
+
const content = renderTask(taskTitle, baseOpeningSentence, definitionOfDone, ideaSection, taskType, {
|
|
756
858
|
description: taskOptions?.description,
|
|
757
859
|
resolvedQuestions: taskOptions?.resolvedQuestions,
|
|
758
860
|
repositoryHint: hint ?? undefined
|
|
@@ -818,6 +920,10 @@ ${baseOpeningSentence2}
|
|
|
818
920
|
|
|
819
921
|
${description}
|
|
820
922
|
|
|
923
|
+
## Task Type
|
|
924
|
+
|
|
925
|
+
implement
|
|
926
|
+
|
|
821
927
|
## Blocked By
|
|
822
928
|
|
|
823
929
|
(none)
|
|
@@ -846,6 +952,10 @@ ${baseOpeningSentence}
|
|
|
846
952
|
|
|
847
953
|
${description}
|
|
848
954
|
|
|
955
|
+
## Task Type
|
|
956
|
+
|
|
957
|
+
capture
|
|
958
|
+
|
|
849
959
|
## Blocked By
|
|
850
960
|
|
|
851
961
|
(none)
|
|
@@ -873,9 +983,16 @@ async function parseCaptureIdeaTask(fileSystem, dustPath, taskSlug) {
|
|
|
873
983
|
return null;
|
|
874
984
|
}
|
|
875
985
|
const title = titleMatch[1].trim();
|
|
986
|
+
const taskType = parseTaskType(content);
|
|
876
987
|
let ideaTitle;
|
|
877
988
|
let expedite;
|
|
878
|
-
if (
|
|
989
|
+
if (taskType === "implement") {
|
|
990
|
+
expedite = true;
|
|
991
|
+
ideaTitle = title.startsWith(EXPEDITE_IDEA_PREFIX) ? title.slice(EXPEDITE_IDEA_PREFIX.length) : title;
|
|
992
|
+
} else if (taskType === "capture") {
|
|
993
|
+
expedite = false;
|
|
994
|
+
ideaTitle = title.startsWith(CAPTURE_IDEA_PREFIX) ? title.slice(CAPTURE_IDEA_PREFIX.length) : title;
|
|
995
|
+
} else if (title.startsWith(EXPEDITE_IDEA_PREFIX)) {
|
|
879
996
|
ideaTitle = title.slice(EXPEDITE_IDEA_PREFIX.length);
|
|
880
997
|
expedite = true;
|
|
881
998
|
} else if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
package/dist/audits/index.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export interface AuditsRepository {
|
|
|
32
32
|
/**
|
|
33
33
|
* Transforms audit template content for the task file.
|
|
34
34
|
* Changes the title from "# Original Title" to "# Audit: Original Title"
|
|
35
|
+
* and adds the Task Type section.
|
|
35
36
|
*/
|
|
36
37
|
export declare function transformAuditContent(content: string): string;
|
|
37
38
|
/**
|
package/dist/audits.js
CHANGED
|
@@ -2497,7 +2497,30 @@ function transformAuditContent(content) {
|
|
|
2497
2497
|
return content;
|
|
2498
2498
|
}
|
|
2499
2499
|
const originalTitle = titleMatch[1];
|
|
2500
|
-
|
|
2500
|
+
let transformed = content.replace(/^#\s+.+$/m, `# Audit: ${originalTitle}`);
|
|
2501
|
+
const lines = transformed.split(`
|
|
2502
|
+
`);
|
|
2503
|
+
let inCodeFence = false;
|
|
2504
|
+
let blockedByIndex = -1;
|
|
2505
|
+
for (let i = 0;i < lines.length; i++) {
|
|
2506
|
+
const line = lines[i];
|
|
2507
|
+
if (line.startsWith("```")) {
|
|
2508
|
+
inCodeFence = !inCodeFence;
|
|
2509
|
+
continue;
|
|
2510
|
+
}
|
|
2511
|
+
if (inCodeFence)
|
|
2512
|
+
continue;
|
|
2513
|
+
if (line === "## Blocked By") {
|
|
2514
|
+
blockedByIndex = i;
|
|
2515
|
+
break;
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
if (blockedByIndex !== -1) {
|
|
2519
|
+
lines.splice(blockedByIndex, 0, "## Task Type", "", "implement", "");
|
|
2520
|
+
transformed = lines.join(`
|
|
2521
|
+
`);
|
|
2522
|
+
}
|
|
2523
|
+
return transformed;
|
|
2501
2524
|
}
|
|
2502
2525
|
function injectComment(content, comment) {
|
|
2503
2526
|
const scopeMatch = content.match(/\n## Scope\n/);
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* for a single repository.
|
|
6
6
|
*/
|
|
7
7
|
import type { EventMessage } from '../agent-events';
|
|
8
|
-
import { type
|
|
9
|
-
import type { OutputSink } from '../claude/types';
|
|
8
|
+
import { type RunnerDependencies } from '../claude/run';
|
|
9
|
+
import type { BoundRunFn, OutputSink } from '../claude/types';
|
|
10
10
|
import { type LoopEmitFn } from '../loop/events';
|
|
11
11
|
import type { SendAgentEventFn } from '../loop/wire-events';
|
|
12
12
|
import { type RunnerDependencies as CodexRunnerDependencies, run as codexRun } from '../codex/run';
|
|
@@ -64,11 +64,11 @@ export declare function createStdoutSinkFactory(loopState: LoopState, logBuffer:
|
|
|
64
64
|
/**
|
|
65
65
|
* Create a run function that redirects Claude output to a log buffer.
|
|
66
66
|
*/
|
|
67
|
-
export declare function createBufferRun(run: RepositoryDependencies['run'], bufferSinkDeps: RunnerDependencies):
|
|
67
|
+
export declare function createBufferRun(run: RepositoryDependencies['run'], bufferSinkDeps: RunnerDependencies): BoundRunFn;
|
|
68
68
|
/**
|
|
69
69
|
* Create a run function that redirects Codex output to a log buffer.
|
|
70
70
|
*/
|
|
71
|
-
export declare function createCodexBufferRun(run: typeof codexRun, codexBufferSinkDeps: CodexRunnerDependencies):
|
|
71
|
+
export declare function createCodexBufferRun(run: typeof codexRun, codexBufferSinkDeps: CodexRunnerDependencies): BoundRunFn;
|
|
72
72
|
/** No-op postEvent for LoopDependencies. */
|
|
73
73
|
export declare function noOpPostEvent(): Promise<void>;
|
|
74
74
|
/**
|
|
@@ -72,6 +72,16 @@ export interface RepositoryDependencies {
|
|
|
72
72
|
/** Force Apple Container mode using bundled default Dockerfile */
|
|
73
73
|
forceAppleContainer?: boolean;
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Handle loop completion: transition lifecycle and reset agent status.
|
|
77
|
+
* Extracted as a named function for testability.
|
|
78
|
+
*/
|
|
79
|
+
export declare function handleLoopFinished(repoState: RepositoryState): void;
|
|
80
|
+
/**
|
|
81
|
+
* Create a cancel function for a running repository loop.
|
|
82
|
+
* Extracted as a named function for testability.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createLoopCancel(repoState: RepositoryState): () => void;
|
|
75
85
|
/**
|
|
76
86
|
* Start (or restart) the per-repository loop and keep lifecycle state accurate.
|
|
77
87
|
*/
|
package/dist/claude/run.d.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import { spawnClaudeCode as defaultSpawnClaudeCode } from './spawn-claude-code';
|
|
2
1
|
import { createStdoutSink as defaultCreateStdoutSink, streamEvents as defaultStreamEvents } from './streamer';
|
|
3
|
-
import type {
|
|
4
|
-
interface RunOptions {
|
|
5
|
-
spawnOptions?: SpawnOptions;
|
|
6
|
-
onRawEvent?: RawEventCallback;
|
|
7
|
-
}
|
|
2
|
+
import type { RawEvent, RunOptions, SpawnOptions } from './types';
|
|
8
3
|
export interface RunnerDependencies {
|
|
9
|
-
spawnClaudeCode:
|
|
4
|
+
spawnClaudeCode: (prompt: string, options: SpawnOptions) => AsyncGenerator<RawEvent>;
|
|
10
5
|
createStdoutSink: typeof defaultCreateStdoutSink;
|
|
11
6
|
streamEvents: typeof defaultStreamEvents;
|
|
12
7
|
}
|
|
13
8
|
export declare const defaultRunnerDependencies: RunnerDependencies;
|
|
14
|
-
export declare function run(prompt: string, options
|
|
15
|
-
export {};
|
|
9
|
+
export declare function run(prompt: string, options: SpawnOptions | RunOptions, dependencies: RunnerDependencies): Promise<void>;
|
|
@@ -21,4 +21,4 @@ export declare const defaultDependencies: EventSourceDependencies;
|
|
|
21
21
|
* Build docker run arguments for spawning claude in a container.
|
|
22
22
|
*/
|
|
23
23
|
export declare function buildDockerRunArguments(docker: DockerSpawnConfig, claudeArguments: string[], env: Record<string, string>): string[];
|
|
24
|
-
export declare function spawnClaudeCode(prompt: string, options
|
|
24
|
+
export declare function spawnClaudeCode(prompt: string, options: SpawnOptions, dependencies: EventSourceDependencies): AsyncGenerator<RawEvent>;
|
package/dist/claude/types.d.ts
CHANGED
|
@@ -79,3 +79,12 @@ export interface SpawnOptions {
|
|
|
79
79
|
docker?: DockerSpawnConfig;
|
|
80
80
|
}
|
|
81
81
|
export type RawEventCallback = (event: RawEvent) => void;
|
|
82
|
+
export interface RunOptions {
|
|
83
|
+
spawnOptions?: SpawnOptions;
|
|
84
|
+
onRawEvent?: RawEventCallback;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A run function with its runner dependencies already bound.
|
|
88
|
+
* Used in LoopDependencies, AgentRunParams, etc.
|
|
89
|
+
*/
|
|
90
|
+
export type BoundRunFn = (prompt: string, options: SpawnOptions | RunOptions) => Promise<void>;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Usage: dust focus "add login box"
|
|
8
8
|
*/
|
|
9
|
+
import type { TaskType } from '../../artifacts/workflow-tasks';
|
|
9
10
|
import type { CommandDependencies, CommandResult } from '../types';
|
|
10
|
-
export declare function buildImplementationInstructions(bin: string, hooksInstalled: boolean, taskTitle?: string, taskPath?: string, installCommand?: string, skipPreflightSteps?: boolean): string;
|
|
11
|
+
export declare function buildImplementationInstructions(bin: string, hooksInstalled: boolean, taskTitle?: string, taskPath?: string, installCommand?: string, skipPreflightSteps?: boolean, taskType?: TaskType): string;
|
|
11
12
|
export declare function focus(dependencies: CommandDependencies): Promise<CommandResult>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides common functionality used across all agent-* command files.
|
|
5
5
|
*/
|
|
6
6
|
import { type AgentType } from '../../agents/detection';
|
|
7
|
-
import type { CommandDependencies, DustSettings,
|
|
7
|
+
import type { CommandDependencies, DustSettings, FileReader } from '../types';
|
|
8
8
|
/**
|
|
9
9
|
* Type-safe template variables for agent commands.
|
|
10
10
|
* Uses real booleans instead of string-encoded booleans.
|
|
@@ -23,14 +23,14 @@ export interface TemplateVarsWithInstructions extends TemplateVars {
|
|
|
23
23
|
* Loads agent-specific instructions from .dust/config/agents/{agent-type}.md
|
|
24
24
|
* Returns empty string if file doesn't exist.
|
|
25
25
|
*/
|
|
26
|
-
export declare function loadAgentInstructions(cwd: string, fileSystem:
|
|
27
|
-
export declare function templateVariables(settings: DustSettings, hooksInstalled: boolean, env
|
|
26
|
+
export declare function loadAgentInstructions(cwd: string, fileSystem: FileReader, agentType: AgentType): Promise<string>;
|
|
27
|
+
export declare function templateVariables(settings: DustSettings, hooksInstalled: boolean, env: NodeJS.ProcessEnv, options?: {
|
|
28
28
|
hasIdeaFile?: boolean;
|
|
29
29
|
}): TemplateVars;
|
|
30
30
|
/**
|
|
31
31
|
* Creates template variables with agent-specific instructions loaded.
|
|
32
32
|
*/
|
|
33
|
-
export declare function templateVariablesWithInstructions(cwd: string, fileSystem:
|
|
33
|
+
export declare function templateVariablesWithInstructions(cwd: string, fileSystem: FileReader, settings: DustSettings, hooksInstalled: boolean, env: NodeJS.ProcessEnv, options?: {
|
|
34
34
|
hasIdeaFile?: boolean;
|
|
35
35
|
}): Promise<TemplateVarsWithInstructions>;
|
|
36
36
|
/**
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import type { CommandEvent } from '../command-events';
|
|
5
5
|
import type { RuntimeConfig } from '../env-config';
|
|
6
6
|
import type { FileSystem, GlobScanner } from '../filesystem/types';
|
|
7
|
-
export type { FileSystem, GlobScanner, ReadableFileSystem, } from '../filesystem/types';
|
|
7
|
+
export type { FileReader, FileSystem, GlobScanner, ReadableFileSystem, } from '../filesystem/types';
|
|
8
8
|
export interface CommandContext {
|
|
9
9
|
cwd: string;
|
|
10
10
|
stdout: (message: string) => void;
|
package/dist/codex/run.d.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { createStdoutSink as defaultCreateStdoutSink } from '../claude/streamer';
|
|
2
|
-
import type {
|
|
3
|
-
import { spawnCodex as defaultSpawnCodex } from './spawn-codex';
|
|
2
|
+
import type { RawEvent, RunOptions, SpawnOptions } from '../claude/types';
|
|
4
3
|
import { streamCodexEvents as defaultStreamCodexEvents } from './streamer';
|
|
5
|
-
interface RunOptions {
|
|
6
|
-
spawnOptions?: SpawnOptions;
|
|
7
|
-
onRawEvent?: RawEventCallback;
|
|
8
|
-
}
|
|
9
4
|
export interface RunnerDependencies {
|
|
10
|
-
spawnCodex:
|
|
5
|
+
spawnCodex: (prompt: string, options: SpawnOptions) => AsyncGenerator<RawEvent>;
|
|
11
6
|
createStdoutSink: typeof defaultCreateStdoutSink;
|
|
12
7
|
streamCodexEvents: typeof defaultStreamCodexEvents;
|
|
13
8
|
}
|
|
14
9
|
export declare const defaultRunnerDependencies: RunnerDependencies;
|
|
15
|
-
export declare function run(prompt: string, options
|
|
16
|
-
export {};
|
|
10
|
+
export declare function run(prompt: string, options: SpawnOptions | RunOptions, dependencies: RunnerDependencies): Promise<void>;
|
|
@@ -9,4 +9,4 @@ export declare const defaultDependencies: EventSourceDependencies;
|
|
|
9
9
|
* Build docker run arguments for spawning codex in a container.
|
|
10
10
|
*/
|
|
11
11
|
export declare function buildDockerRunArguments(docker: DockerSpawnConfig, codexArguments: string[], env: Record<string, string>): string[];
|
|
12
|
-
export declare function spawnCodex(prompt: string, options
|
|
12
|
+
export declare function spawnCodex(prompt: string, options: SpawnOptions, dependencies: EventSourceDependencies): AsyncGenerator<RawEvent>;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Reads optional configuration from .dust/config/settings.json
|
|
5
5
|
*/
|
|
6
|
-
import type { CheckConfig, DustSettings,
|
|
6
|
+
import type { CheckConfig, DustSettings, FileReader } from '../cli/types';
|
|
7
7
|
import type { RuntimeConfig } from '../env-config';
|
|
8
8
|
export type { CheckConfig, DustSettings };
|
|
9
9
|
interface SettingsViolation {
|
|
@@ -19,7 +19,7 @@ export declare function validateSettingsJson(content: string): SettingsViolation
|
|
|
19
19
|
* 4. No lockfile + BUN_INSTALL env var set → bunx dust
|
|
20
20
|
* 5. Default → npx dust
|
|
21
21
|
*/
|
|
22
|
-
export declare function detectDustCommand(cwd: string, fileSystem:
|
|
22
|
+
export declare function detectDustCommand(cwd: string, fileSystem: FileReader, runtime: RuntimeConfig): string;
|
|
23
23
|
/**
|
|
24
24
|
* Detects the appropriate install command based on lockfiles.
|
|
25
25
|
* Returns null when:
|
|
@@ -28,7 +28,7 @@ export declare function detectDustCommand(cwd: string, fileSystem: ReadableFileS
|
|
|
28
28
|
*
|
|
29
29
|
* Priority within each ecosystem follows the order in LOCKFILE_COMMANDS.
|
|
30
30
|
*/
|
|
31
|
-
export declare function detectInstallCommand(cwd: string, fileSystem:
|
|
31
|
+
export declare function detectInstallCommand(cwd: string, fileSystem: FileReader): string | null;
|
|
32
32
|
/**
|
|
33
33
|
* Detects the appropriate test command based on lockfiles and environment.
|
|
34
34
|
* Priority:
|
|
@@ -40,5 +40,5 @@ export declare function detectInstallCommand(cwd: string, fileSystem: ReadableFi
|
|
|
40
40
|
* 6. package.json exists → npm test
|
|
41
41
|
* 7. Default → null (no test command)
|
|
42
42
|
*/
|
|
43
|
-
export declare function detectTestCommand(cwd: string, fileSystem:
|
|
44
|
-
export declare function loadSettings(cwd: string, fileSystem:
|
|
43
|
+
export declare function detectTestCommand(cwd: string, fileSystem: FileReader, runtime: RuntimeConfig): string | null;
|
|
44
|
+
export declare function loadSettings(cwd: string, fileSystem: FileReader, runtime: RuntimeConfig): Promise<DustSettings>;
|
package/dist/core-principles.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// lib/core-principles.ts
|
|
2
2
|
import { join, dirname } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { existsSync, readdirSync
|
|
4
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
5
5
|
import { readFile } from "node:fs/promises";
|
|
6
6
|
|
|
7
7
|
// lib/markdown/markdown-utilities.ts
|
|
@@ -111,10 +111,7 @@ function getCorePrincipleTree(allPrinciples, config) {
|
|
|
111
111
|
if (!parentSlug || !filteredSlugs.has(parentSlug)) {
|
|
112
112
|
roots.push(node);
|
|
113
113
|
} else {
|
|
114
|
-
|
|
115
|
-
if (parentNode) {
|
|
116
|
-
parentNode.children.push(node);
|
|
117
|
-
}
|
|
114
|
+
nodeBySlug.get(parentSlug).children.push(node);
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
117
|
sortNodes(roots);
|
|
@@ -122,18 +119,10 @@ function getCorePrincipleTree(allPrinciples, config) {
|
|
|
122
119
|
}
|
|
123
120
|
|
|
124
121
|
// lib/core-principles.ts
|
|
125
|
-
function
|
|
122
|
+
function createFileReader() {
|
|
126
123
|
return {
|
|
127
124
|
exists: existsSync,
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
return statSync(path).isDirectory();
|
|
131
|
-
} catch {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
readFile: (path) => readFile(path, "utf-8"),
|
|
136
|
-
readdir: async (path) => readdirSync(path)
|
|
125
|
+
readFile: (path) => readFile(path, "utf-8")
|
|
137
126
|
};
|
|
138
127
|
}
|
|
139
128
|
function locatePackagePrinciplesDir() {
|
|
@@ -150,7 +139,7 @@ async function readAllCorePrinciples() {
|
|
|
150
139
|
const principlesDir = locatePackagePrinciplesDir();
|
|
151
140
|
const packageRoot = dirname(dirname(principlesDir));
|
|
152
141
|
const dustPath = join(packageRoot, ".dust");
|
|
153
|
-
const fileSystem =
|
|
142
|
+
const fileSystem = createFileReader();
|
|
154
143
|
const files = readdirSync(principlesDir);
|
|
155
144
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
156
145
|
const principles = [];
|
|
@@ -23,10 +23,6 @@ export declare function buildDockerImage(config: {
|
|
|
23
23
|
success: false;
|
|
24
24
|
error: string;
|
|
25
25
|
}>;
|
|
26
|
-
/**
|
|
27
|
-
* Check if a Dockerfile exists at the legacy .dust/Dockerfile location.
|
|
28
|
-
*/
|
|
29
|
-
export declare function hasLegacyDockerfile(repoPath: string, dependencies: ContainerDependencies): boolean;
|
|
30
26
|
type ContainerPrepareEvent = {
|
|
31
27
|
type: 'loop.docker_detected';
|
|
32
28
|
imageTag: string;
|