@joshski/dust 0.1.97 → 0.1.99
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/agent-events.d.ts +13 -0
- package/dist/artifacts/index.d.ts +14 -2
- package/dist/artifacts/parsed-artifact.d.ts +32 -0
- package/dist/artifacts.js +166 -1
- package/dist/audits/checks-audit.d.ts +13 -13
- package/dist/audits.js +49 -271
- package/dist/bucket/agent-capabilities.d.ts +30 -0
- package/dist/bucket/repository-git.d.ts +2 -1
- package/dist/bucket/repository.d.ts +9 -1
- package/dist/bucket/server-messages.d.ts +36 -1
- package/dist/cli/commands/focus.d.ts +1 -1
- package/dist/cli/process-runner.d.ts +35 -0
- package/dist/dust.js +1015 -791
- package/dist/lint/validators/content-validator.d.ts +5 -4
- package/dist/lint/validators/filename-validator.d.ts +2 -1
- package/dist/lint/validators/idea-validator.d.ts +4 -3
- package/dist/lint/validators/link-validator.d.ts +4 -3
- package/dist/lint/validators/principle-hierarchy.d.ts +3 -2
- package/dist/loop/events.d.ts +18 -1
- package/dist/loop/iteration.d.ts +8 -1
- package/dist/patch/fact.d.ts +15 -0
- package/dist/patch/idea.d.ts +23 -0
- package/dist/patch/index.d.ts +54 -0
- package/dist/patch/principle.d.ts +17 -0
- package/dist/patch/task.d.ts +25 -0
- package/dist/patch.js +1645 -0
- package/dist/tech-stack/index.d.ts +22 -0
- package/dist/validation/validation-pipeline.d.ts +42 -0
- package/dist/validation.js +451 -407
- package/package.json +5 -1
package/dist/agent-events.d.ts
CHANGED
|
@@ -29,6 +29,19 @@ export type AgentSessionEvent = {
|
|
|
29
29
|
} | {
|
|
30
30
|
type: 'command-event';
|
|
31
31
|
commandEvent: CommandEvent;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'preflight-started';
|
|
34
|
+
step: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
} | {
|
|
37
|
+
type: 'preflight-completed';
|
|
38
|
+
step: string;
|
|
39
|
+
output?: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'preflight-failed';
|
|
42
|
+
step: string;
|
|
43
|
+
output: string;
|
|
44
|
+
title?: string;
|
|
32
45
|
};
|
|
33
46
|
export interface EventMessage {
|
|
34
47
|
sequence: number;
|
|
@@ -4,8 +4,9 @@ import { type Idea, type IdeaOpenQuestion, type IdeaOption, type ParsedIdeaConte
|
|
|
4
4
|
import { extractTitle } from '../markdown/markdown-utilities';
|
|
5
5
|
import { type Principle } from './principles';
|
|
6
6
|
import { type Task } from './tasks';
|
|
7
|
+
import { type ParsedArtifact, type ParsedMarkdownLink, type ParsedSection, parseArtifact } from './parsed-artifact';
|
|
7
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';
|
|
8
|
-
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedCaptureIdeaTask, ParsedIdeaContent, Principle, Task, WorkflowTaskMatch, WorkflowTaskType, };
|
|
9
|
+
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedArtifact, ParsedCaptureIdeaTask, ParsedIdeaContent, ParsedMarkdownLink, ParsedSection, Principle, Task, WorkflowTaskMatch, WorkflowTaskType, };
|
|
9
10
|
export interface TaskGraphNode {
|
|
10
11
|
task: Task;
|
|
11
12
|
workflowType: WorkflowTaskType | null;
|
|
@@ -17,9 +18,20 @@ export interface TaskGraph {
|
|
|
17
18
|
to: string;
|
|
18
19
|
}>;
|
|
19
20
|
}
|
|
20
|
-
export { CAPTURE_IDEA_PREFIX, extractTitle, findAllWorkflowTasks, ideaContentToMarkdown, parseIdeaContent, parseOpenQuestions, parseResolvedQuestions, };
|
|
21
|
+
export { CAPTURE_IDEA_PREFIX, extractTitle, findAllWorkflowTasks, ideaContentToMarkdown, parseArtifact, parseIdeaContent, parseOpenQuestions, parseResolvedQuestions, };
|
|
21
22
|
export type { IdeaInProgress };
|
|
22
23
|
export type ArtifactType = 'ideas' | 'tasks' | 'principles' | 'facts';
|
|
24
|
+
export declare const ARTIFACT_TYPES: ArtifactType[];
|
|
25
|
+
export declare const DUST_PATH_PREFIX = ".dust/";
|
|
26
|
+
/**
|
|
27
|
+
* Parses an artifact path into its type and slug components.
|
|
28
|
+
* This is the inverse of ArtifactsRepository.artifactPath().
|
|
29
|
+
* Works with relative paths (e.g., '.dust/tasks/my-task.md').
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseArtifactPath(path: string): {
|
|
32
|
+
type: ArtifactType;
|
|
33
|
+
slug: string;
|
|
34
|
+
} | null;
|
|
23
35
|
export interface ReadOnlyArtifactsRepository {
|
|
24
36
|
artifactPath(type: ArtifactType, slug: string): string;
|
|
25
37
|
parseIdea(options: {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed artifact types with positional metadata for validation.
|
|
3
|
+
*
|
|
4
|
+
* These types enrich artifact parsing with line numbers to support
|
|
5
|
+
* single-pass validation and better error reporting.
|
|
6
|
+
*/
|
|
7
|
+
export interface ParsedMarkdownLink {
|
|
8
|
+
text: string;
|
|
9
|
+
target: string;
|
|
10
|
+
line: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ParsedSection {
|
|
13
|
+
heading: string;
|
|
14
|
+
level: number;
|
|
15
|
+
startLine: number;
|
|
16
|
+
endLine: number;
|
|
17
|
+
links: ParsedMarkdownLink[];
|
|
18
|
+
}
|
|
19
|
+
export interface ParsedArtifact {
|
|
20
|
+
filePath: string;
|
|
21
|
+
rawContent: string;
|
|
22
|
+
title: string | null;
|
|
23
|
+
titleLine: number | null;
|
|
24
|
+
openingSentence: string | null;
|
|
25
|
+
openingSentenceLine: number | null;
|
|
26
|
+
sections: ParsedSection[];
|
|
27
|
+
allLinks: ParsedMarkdownLink[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parses markdown content into a ParsedArtifact with positional metadata.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseArtifact(filePath: string, content: string): ParsedArtifact;
|
package/dist/artifacts.js
CHANGED
|
@@ -379,6 +379,143 @@ async function parseTask(fileSystem, dustPath, slug) {
|
|
|
379
379
|
};
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
+
// lib/artifacts/parsed-artifact.ts
|
|
383
|
+
var MARKDOWN_LINK_PATTERN2 = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
384
|
+
function parseArtifact(filePath, content) {
|
|
385
|
+
const lines = content.split(`
|
|
386
|
+
`);
|
|
387
|
+
let title = null;
|
|
388
|
+
let titleLine = null;
|
|
389
|
+
let openingSentence = null;
|
|
390
|
+
let openingSentenceLine = null;
|
|
391
|
+
const sections = [];
|
|
392
|
+
const allLinks = [];
|
|
393
|
+
let currentSection = null;
|
|
394
|
+
let inCodeFence = false;
|
|
395
|
+
let openingSentenceResolved = false;
|
|
396
|
+
for (let i = 0;i < lines.length; i++) {
|
|
397
|
+
const line = lines[i];
|
|
398
|
+
const lineNumber = i + 1;
|
|
399
|
+
if (line.startsWith("```")) {
|
|
400
|
+
inCodeFence = !inCodeFence;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (inCodeFence) {
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
const h1Match = line.match(/^#\s+(.+)$/);
|
|
407
|
+
if (h1Match) {
|
|
408
|
+
if (title === null) {
|
|
409
|
+
title = h1Match[1].trim();
|
|
410
|
+
titleLine = lineNumber;
|
|
411
|
+
} else {
|
|
412
|
+
if (currentSection !== null) {
|
|
413
|
+
currentSection.endLine = findLastNonEmptyLine(lines, currentSection.startLine, lineNumber - 2);
|
|
414
|
+
sections.push(currentSection);
|
|
415
|
+
currentSection = null;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
const headingMatch = line.match(/^(#{2,6})\s+(.+)$/);
|
|
421
|
+
if (headingMatch) {
|
|
422
|
+
openingSentenceResolved = true;
|
|
423
|
+
if (currentSection !== null) {
|
|
424
|
+
currentSection.endLine = findLastNonEmptyLine(lines, currentSection.startLine, lineNumber - 2);
|
|
425
|
+
sections.push(currentSection);
|
|
426
|
+
}
|
|
427
|
+
currentSection = {
|
|
428
|
+
heading: headingMatch[2].trim(),
|
|
429
|
+
level: headingMatch[1].length,
|
|
430
|
+
startLine: lineNumber,
|
|
431
|
+
endLine: -1,
|
|
432
|
+
links: []
|
|
433
|
+
};
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
if (shouldCheckForOpeningSentence(title, openingSentenceResolved, line)) {
|
|
437
|
+
const result = tryExtractOpeningSentence(lines, i);
|
|
438
|
+
openingSentence = result.sentence;
|
|
439
|
+
openingSentenceLine = result.sentence !== null ? lineNumber : null;
|
|
440
|
+
openingSentenceResolved = true;
|
|
441
|
+
}
|
|
442
|
+
const linkMatches = line.matchAll(MARKDOWN_LINK_PATTERN2);
|
|
443
|
+
for (const match of linkMatches) {
|
|
444
|
+
const link = {
|
|
445
|
+
text: match[1],
|
|
446
|
+
target: match[2],
|
|
447
|
+
line: lineNumber
|
|
448
|
+
};
|
|
449
|
+
allLinks.push(link);
|
|
450
|
+
if (currentSection !== null) {
|
|
451
|
+
currentSection.links.push(link);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (currentSection !== null) {
|
|
456
|
+
currentSection.endLine = findLastNonEmptyLine(lines, currentSection.startLine, lines.length - 1);
|
|
457
|
+
sections.push(currentSection);
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
filePath,
|
|
461
|
+
rawContent: content,
|
|
462
|
+
title,
|
|
463
|
+
titleLine,
|
|
464
|
+
openingSentence,
|
|
465
|
+
openingSentenceLine,
|
|
466
|
+
sections,
|
|
467
|
+
allLinks
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
function shouldCheckForOpeningSentence(title, resolved, line) {
|
|
471
|
+
if (title === null || resolved) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
const trimmed = line.trim();
|
|
475
|
+
return trimmed !== "" && !isStructuralElement2(trimmed);
|
|
476
|
+
}
|
|
477
|
+
function tryExtractOpeningSentence(lines, startIndex) {
|
|
478
|
+
const paragraph = collectParagraph2(lines, startIndex);
|
|
479
|
+
return { sentence: extractFirstSentence2(paragraph) };
|
|
480
|
+
}
|
|
481
|
+
function findLastNonEmptyLine(lines, contentStartIndex, fromIndex) {
|
|
482
|
+
for (let i = fromIndex;i >= contentStartIndex; i--) {
|
|
483
|
+
if (lines[i].trim() !== "") {
|
|
484
|
+
return i + 1;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return contentStartIndex;
|
|
488
|
+
}
|
|
489
|
+
var LIST_ITEM_PREFIXES2 = ["-", "*", "+"];
|
|
490
|
+
var STRUCTURAL_PREFIXES2 = ["#", "```", ">"];
|
|
491
|
+
function isStructuralElement2(line) {
|
|
492
|
+
if (STRUCTURAL_PREFIXES2.some((prefix) => line.startsWith(prefix))) {
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
if (LIST_ITEM_PREFIXES2.some((prefix) => line.startsWith(prefix))) {
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
return /^\d+\./.test(line);
|
|
499
|
+
}
|
|
500
|
+
function isBlockBreak2(line) {
|
|
501
|
+
return STRUCTURAL_PREFIXES2.some((prefix) => line.startsWith(prefix));
|
|
502
|
+
}
|
|
503
|
+
function collectParagraph2(lines, startIndex) {
|
|
504
|
+
const parts = [];
|
|
505
|
+
for (let i = startIndex;i < lines.length; i++) {
|
|
506
|
+
const line = lines[i].trim();
|
|
507
|
+
if (line === "" || isBlockBreak2(line)) {
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
parts.push(line);
|
|
511
|
+
}
|
|
512
|
+
return parts.join(" ");
|
|
513
|
+
}
|
|
514
|
+
function extractFirstSentence2(paragraph) {
|
|
515
|
+
const match = paragraph.match(/^(.+?[.?!])(?:\s|$)/);
|
|
516
|
+
return match ? match[1] : null;
|
|
517
|
+
}
|
|
518
|
+
|
|
382
519
|
// lib/artifacts/workflow-tasks.ts
|
|
383
520
|
var CAPTURE_IDEA_PREFIX = "Add Idea: ";
|
|
384
521
|
var EXPEDITE_IDEA_PREFIX = "Expedite Idea: ";
|
|
@@ -756,6 +893,30 @@ async function parseCaptureIdeaTask(fileSystem, dustPath, taskSlug) {
|
|
|
756
893
|
}
|
|
757
894
|
|
|
758
895
|
// lib/artifacts/index.ts
|
|
896
|
+
var ARTIFACT_TYPES = [
|
|
897
|
+
"facts",
|
|
898
|
+
"ideas",
|
|
899
|
+
"principles",
|
|
900
|
+
"tasks"
|
|
901
|
+
];
|
|
902
|
+
var DUST_PATH_PREFIX = ".dust/";
|
|
903
|
+
function parseArtifactPath(path) {
|
|
904
|
+
if (!path.startsWith(DUST_PATH_PREFIX) || !path.endsWith(".md")) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
const withoutPrefix = path.slice(DUST_PATH_PREFIX.length);
|
|
908
|
+
const slashIndex = withoutPrefix.indexOf("/");
|
|
909
|
+
if (slashIndex === -1) {
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
const type = withoutPrefix.slice(0, slashIndex);
|
|
913
|
+
if (!ARTIFACT_TYPES.includes(type)) {
|
|
914
|
+
return null;
|
|
915
|
+
}
|
|
916
|
+
const filename = withoutPrefix.slice(slashIndex + 1);
|
|
917
|
+
const slug = filename.slice(0, -3);
|
|
918
|
+
return { type, slug };
|
|
919
|
+
}
|
|
759
920
|
function buildReadOperations(fileSystem, dustPath) {
|
|
760
921
|
return {
|
|
761
922
|
artifactPath(type, slug) {
|
|
@@ -861,10 +1022,14 @@ export {
|
|
|
861
1022
|
parseResolvedQuestions,
|
|
862
1023
|
parseOpenQuestions,
|
|
863
1024
|
parseIdeaContent,
|
|
1025
|
+
parseArtifactPath,
|
|
1026
|
+
parseArtifact,
|
|
864
1027
|
ideaContentToMarkdown,
|
|
865
1028
|
findAllWorkflowTasks,
|
|
866
1029
|
extractTitle,
|
|
867
1030
|
buildReadOnlyArtifactsRepository,
|
|
868
1031
|
buildArtifactsRepository,
|
|
869
|
-
|
|
1032
|
+
DUST_PATH_PREFIX,
|
|
1033
|
+
CAPTURE_IDEA_PREFIX,
|
|
1034
|
+
ARTIFACT_TYPES
|
|
870
1035
|
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Checks Audit - Pure functions for detecting
|
|
2
|
+
* Checks Audit - Pure functions for detecting configured checks and suggesting improvements.
|
|
3
3
|
*
|
|
4
4
|
* This module provides the functional core for the checks-audit stock audit.
|
|
5
|
-
* It
|
|
6
|
-
*
|
|
5
|
+
* It identifies configured checks, parses CI configuration files, and suggests
|
|
6
|
+
* missing check categories.
|
|
7
|
+
*
|
|
8
|
+
* Tech stack detection is imported from lib/tech-stack/.
|
|
7
9
|
*/
|
|
8
10
|
import type { DustSettings } from '../cli/types';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
packageManager?: string;
|
|
14
|
-
}
|
|
11
|
+
import type { Ecosystem, TechStackDetection } from '../tech-stack';
|
|
12
|
+
import { detectTechStack } from '../tech-stack';
|
|
13
|
+
export { detectTechStack };
|
|
14
|
+
export type { Ecosystem, TechStackDetection };
|
|
15
15
|
export interface CheckOption {
|
|
16
16
|
name: string;
|
|
17
17
|
command: string;
|
|
@@ -29,10 +29,6 @@ export interface CIFileContent {
|
|
|
29
29
|
path: string;
|
|
30
30
|
content: string;
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Detects tech stacks based on project files.
|
|
34
|
-
*/
|
|
35
|
-
export declare function detectTechStack(projectFiles: string[]): TechStackDetection[];
|
|
36
32
|
/**
|
|
37
33
|
* Extracts check categories from existing dust settings.
|
|
38
34
|
*/
|
|
@@ -51,5 +47,9 @@ export declare function suggestChecks(techStack: TechStackDetection[], projectFi
|
|
|
51
47
|
export declare function renderCheckIdea(suggestion: CheckSuggestion, packageManager?: string): string;
|
|
52
48
|
/**
|
|
53
49
|
* Returns the checks-audit stock audit template.
|
|
50
|
+
*
|
|
51
|
+
* This template is tech-stack agnostic. Agents should discover appropriate
|
|
52
|
+
* checks by examining the project structure rather than receiving
|
|
53
|
+
* ecosystem-specific tool prescriptions.
|
|
54
54
|
*/
|
|
55
55
|
export declare function checksAuditTemplate(): string;
|