@joshski/dust 0.1.92 → 0.1.93
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/artifacts/index.d.ts +1 -0
- package/dist/artifacts/workflow-tasks.d.ts +1 -1
- package/dist/artifacts.js +6 -3
- package/dist/dust.js +45 -7
- package/package.json +1 -1
|
@@ -40,6 +40,7 @@ export interface ArtifactsRepository {
|
|
|
40
40
|
createRefineIdeaTask(options: {
|
|
41
41
|
ideaSlug: string;
|
|
42
42
|
description?: string;
|
|
43
|
+
openQuestionResponses?: OpenQuestionResponse[];
|
|
43
44
|
dustCommand?: string;
|
|
44
45
|
}): Promise<CreateIdeaTransitionTaskResult>;
|
|
45
46
|
createDecomposeIdeaTask(options: DecomposeIdeaOptions & {
|
|
@@ -45,7 +45,7 @@ export interface DecomposeIdeaOptions {
|
|
|
45
45
|
description?: string;
|
|
46
46
|
openQuestionResponses?: OpenQuestionResponse[];
|
|
47
47
|
}
|
|
48
|
-
export declare function createRefineIdeaTask(fileSystem: FileSystem, dustPath: string, ideaSlug: string, description?: string, dustCommand?: string): Promise<CreateIdeaTransitionTaskResult>;
|
|
48
|
+
export declare function createRefineIdeaTask(fileSystem: FileSystem, dustPath: string, ideaSlug: string, description?: string, openQuestionResponses?: OpenQuestionResponse[], dustCommand?: string): Promise<CreateIdeaTransitionTaskResult>;
|
|
49
49
|
export declare function decomposeIdea(fileSystem: FileSystem, dustPath: string, options: DecomposeIdeaOptions, dustCommand?: string): Promise<CreateIdeaTransitionTaskResult>;
|
|
50
50
|
export declare function createShelveIdeaTask(fileSystem: FileSystem, dustPath: string, ideaSlug: string, description?: string, _dustCommand?: string): Promise<CreateIdeaTransitionTaskResult>;
|
|
51
51
|
export declare function createIdeaTask(fileSystem: FileSystem, dustPath: string, options: {
|
package/dist/artifacts.js
CHANGED
|
@@ -460,14 +460,17 @@ async function createIdeaTransitionTask(fileSystem, dustPath, workflowType, pref
|
|
|
460
460
|
await fileSystem.writeFile(filePath, content);
|
|
461
461
|
return { filePath };
|
|
462
462
|
}
|
|
463
|
-
async function createRefineIdeaTask(fileSystem, dustPath, ideaSlug, description, dustCommand) {
|
|
463
|
+
async function createRefineIdeaTask(fileSystem, dustPath, ideaSlug, description, openQuestionResponses, dustCommand) {
|
|
464
464
|
const cmd = dustCommand ?? "dust";
|
|
465
465
|
return createIdeaTransitionTask(fileSystem, dustPath, "refine-idea", "Refine Idea: ", ideaSlug, (ideaTitle) => `Thoroughly research this idea and refine it into a well-defined proposal. Read the idea file, explore the codebase for relevant context, and identify any ambiguity. Where aspects are unclear or could go multiple ways, add open questions to the idea file. Run \`${cmd} principles\` for alignment and \`${cmd} facts\` for relevant design decisions. See [${ideaTitle}](../ideas/${ideaSlug}.md). If you add open questions, use \`## Open Questions\` with \`### Question?\` headings and one or more \`#### Option\` headings beneath each question, and only add questions that are meaningful decisions worth asking.`, [
|
|
466
466
|
"Idea is thoroughly researched with relevant codebase context",
|
|
467
467
|
"Open questions are added for any ambiguous or underspecified aspects",
|
|
468
468
|
"Open questions follow the required heading format and focus on high-value decisions",
|
|
469
469
|
"Idea file is updated with findings"
|
|
470
|
-
], "Refines Idea", {
|
|
470
|
+
], "Refines Idea", {
|
|
471
|
+
description,
|
|
472
|
+
resolvedQuestions: openQuestionResponses
|
|
473
|
+
});
|
|
471
474
|
}
|
|
472
475
|
async function decomposeIdea(fileSystem, dustPath, options, dustCommand) {
|
|
473
476
|
const cmd = dustCommand ?? "dust";
|
|
@@ -632,7 +635,7 @@ function buildArtifactsRepository(fileSystem, dustPath) {
|
|
|
632
635
|
return files.filter((f) => f.endsWith(".md")).map((f) => f.replace(/\.md$/, "")).sort();
|
|
633
636
|
},
|
|
634
637
|
async createRefineIdeaTask(options) {
|
|
635
|
-
return createRefineIdeaTask(fileSystem, dustPath, options.ideaSlug, options.description, options.dustCommand);
|
|
638
|
+
return createRefineIdeaTask(fileSystem, dustPath, options.ideaSlug, options.description, options.openQuestionResponses, options.dustCommand);
|
|
636
639
|
},
|
|
637
640
|
async createDecomposeIdeaTask(options) {
|
|
638
641
|
return decomposeIdea(fileSystem, dustPath, options, options.dustCommand);
|
package/dist/dust.js
CHANGED
|
@@ -500,7 +500,7 @@ async function loadSettings(cwd, fileSystem) {
|
|
|
500
500
|
}
|
|
501
501
|
|
|
502
502
|
// lib/version.ts
|
|
503
|
-
var DUST_VERSION = "0.1.
|
|
503
|
+
var DUST_VERSION = "0.1.93";
|
|
504
504
|
|
|
505
505
|
// lib/session.ts
|
|
506
506
|
var DUST_UNATTENDED = "DUST_UNATTENDED";
|
|
@@ -2563,6 +2563,25 @@ function selectAgentCapabilities(input) {
|
|
|
2563
2563
|
}
|
|
2564
2564
|
return agents;
|
|
2565
2565
|
}
|
|
2566
|
+
async function fetchCodexModelsFromApi(apiKey) {
|
|
2567
|
+
try {
|
|
2568
|
+
const response = await fetch("https://api.openai.com/v1/models", {
|
|
2569
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2570
|
+
});
|
|
2571
|
+
if (!response.ok) {
|
|
2572
|
+
log2(`OpenAI models API returned ${response.status}`);
|
|
2573
|
+
return [];
|
|
2574
|
+
}
|
|
2575
|
+
const body = await response.json();
|
|
2576
|
+
if (!body.data || !Array.isArray(body.data)) {
|
|
2577
|
+
return [];
|
|
2578
|
+
}
|
|
2579
|
+
return body.data.map((m) => m.id).filter((id) => id.includes("codex")).sort();
|
|
2580
|
+
} catch (error) {
|
|
2581
|
+
log2(`OpenAI models API fetch failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2582
|
+
return [];
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2566
2585
|
async function discoverAgentCapabilities(dependencies) {
|
|
2567
2586
|
const [claudeVersionProbe, codexVersionProbe] = await Promise.all([
|
|
2568
2587
|
probeCommand(dependencies.spawn, "claude", ["--version"]),
|
|
@@ -2570,10 +2589,18 @@ async function discoverAgentCapabilities(dependencies) {
|
|
|
2570
2589
|
]);
|
|
2571
2590
|
let codexModelsProbe = null;
|
|
2572
2591
|
if (codexVersionProbe.success) {
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2592
|
+
const getEnv = dependencies.getEnv ?? ((name) => process.env[name]);
|
|
2593
|
+
const apiKey = getEnv("OPENAI_API_KEY");
|
|
2594
|
+
if (apiKey) {
|
|
2595
|
+
const fetcher = dependencies.fetchCodexModelsFromApi ?? fetchCodexModelsFromApi;
|
|
2596
|
+
const models = await fetcher(apiKey);
|
|
2597
|
+
if (models.length > 0) {
|
|
2598
|
+
codexModelsProbe = {
|
|
2599
|
+
success: true,
|
|
2600
|
+
stdout: JSON.stringify(models)
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2577
2604
|
}
|
|
2578
2605
|
return {
|
|
2579
2606
|
type: "agent-capabilities",
|
|
@@ -7840,7 +7867,12 @@ function renderHierarchy(nodes, output, prefix = "") {
|
|
|
7840
7867
|
}
|
|
7841
7868
|
}
|
|
7842
7869
|
async function list(dependencies) {
|
|
7843
|
-
const {
|
|
7870
|
+
const {
|
|
7871
|
+
arguments: commandArguments,
|
|
7872
|
+
context,
|
|
7873
|
+
fileSystem,
|
|
7874
|
+
settings
|
|
7875
|
+
} = dependencies;
|
|
7844
7876
|
const dustPath = `${context.cwd}/.dust`;
|
|
7845
7877
|
const colors = getColors();
|
|
7846
7878
|
if (!fileSystem.exists(dustPath)) {
|
|
@@ -7855,6 +7887,7 @@ async function list(dependencies) {
|
|
|
7855
7887
|
return { exitCode: 1 };
|
|
7856
7888
|
}
|
|
7857
7889
|
const specificTypeRequested = commandArguments.length > 0;
|
|
7890
|
+
const showTaskCreationHint = specificTypeRequested && typesToList.length === 1 && typesToList[0] === "tasks";
|
|
7858
7891
|
const workflowTasks = typesToList.includes("ideas") && fileSystem.exists(dustPath) ? await findAllWorkflowTasks(fileSystem, dustPath) : null;
|
|
7859
7892
|
for (const type of typesToList) {
|
|
7860
7893
|
const dirPath = `${dustPath}/${type}`;
|
|
@@ -7939,6 +7972,11 @@ async function list(dependencies) {
|
|
|
7939
7972
|
});
|
|
7940
7973
|
}
|
|
7941
7974
|
}
|
|
7975
|
+
if (showTaskCreationHint) {
|
|
7976
|
+
context.stdout("➕ Add a New Task");
|
|
7977
|
+
context.stdout("");
|
|
7978
|
+
context.stdout(`Run \`${settings.dustCommand} new task\``);
|
|
7979
|
+
}
|
|
7942
7980
|
return { exitCode: 0 };
|
|
7943
7981
|
}
|
|
7944
7982
|
|
|
@@ -8141,7 +8179,7 @@ function newTaskInstructions(vars) {
|
|
|
8141
8179
|
steps.push(" - The goal is a task description with minimal ambiguity at implementation time");
|
|
8142
8180
|
steps.push("4. Create a new markdown file in `.dust/tasks/` with a descriptive kebab-case name (e.g., `add-user-authentication.md`)");
|
|
8143
8181
|
steps.push("5. Add a title as the first line using an H1 heading (e.g., `# Add user authentication`)");
|
|
8144
|
-
steps.push('6. Write a comprehensive description starting with an imperative opening sentence (e.g., "Add caching to the API layer." not "This task adds caching."). Include technical details and references to relevant files.');
|
|
8182
|
+
steps.push('6. Write a comprehensive description starting with an imperative opening sentence (e.g., "Add caching to the API layer." not "This task adds caching."). The opening sentence must be 150 characters or fewer. Include technical details and references to relevant files.');
|
|
8145
8183
|
steps.push("7. Add a `## Principles` section with links to relevant principles this task supports (e.g., `- [Principle Name](../principles/principle-name.md)`)");
|
|
8146
8184
|
steps.push("8. Add a `## Blocked By` section listing any tasks that must complete first, or `(none)` if there are no blockers");
|
|
8147
8185
|
steps.push("9. Add a `## Definition of Done` section with a checklist of completion criteria using `- [ ]` for each item");
|