@joshski/dust 0.1.68 → 0.1.70
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 +3 -3
- package/dist/artifacts/workflow-tasks.d.ts +6 -1
- package/dist/artifacts.js +42 -2
- package/dist/audits.js +57 -0
- package/dist/bucket/repository.d.ts +2 -2
- package/dist/dust.js +90 -46
- package/package.json +1 -1
|
@@ -3,9 +3,9 @@ import { type Fact } from './facts';
|
|
|
3
3
|
import { type Idea, type IdeaOpenQuestion, type IdeaOption, parseOpenQuestions } from './ideas';
|
|
4
4
|
import { type Principle } from './principles';
|
|
5
5
|
import { type Task } from './tasks';
|
|
6
|
-
import { CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllCaptureIdeaTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, type WorkflowTaskMatch } from './workflow-tasks';
|
|
7
|
-
export type { CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedCaptureIdeaTask, Principle, Task, WorkflowTaskMatch, };
|
|
8
|
-
export { CAPTURE_IDEA_PREFIX, findAllCaptureIdeaTasks, parseOpenQuestions };
|
|
6
|
+
import { type AllWorkflowTasks, CAPTURE_IDEA_PREFIX, type CreateIdeaTransitionTaskResult, type DecomposeIdeaOptions, findAllCaptureIdeaTasks, findAllWorkflowTasks, type IdeaInProgress, type OpenQuestionResponse, type ParsedCaptureIdeaTask, type WorkflowTaskMatch } from './workflow-tasks';
|
|
7
|
+
export type { AllWorkflowTasks, CreateIdeaTransitionTaskResult, DecomposeIdeaOptions, Fact, Idea, IdeaOpenQuestion, IdeaOption, OpenQuestionResponse, ParsedCaptureIdeaTask, Principle, Task, WorkflowTaskMatch, };
|
|
8
|
+
export { CAPTURE_IDEA_PREFIX, findAllCaptureIdeaTasks, findAllWorkflowTasks, parseOpenQuestions, };
|
|
9
9
|
export type { IdeaInProgress };
|
|
10
10
|
export interface ArtifactsRepository {
|
|
11
11
|
parseIdea(options: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FileSystem, ReadableFileSystem } from '../filesystem/types';
|
|
2
2
|
export declare const IDEA_TRANSITION_PREFIXES: string[];
|
|
3
3
|
export declare const CAPTURE_IDEA_PREFIX = "Add Idea: ";
|
|
4
|
-
export declare const BUILD_IDEA_PREFIX = "
|
|
4
|
+
export declare const BUILD_IDEA_PREFIX = "Decompose Idea: ";
|
|
5
5
|
export interface IdeaInProgress {
|
|
6
6
|
taskSlug: string;
|
|
7
7
|
ideaTitle: string;
|
|
@@ -28,6 +28,11 @@ export interface WorkflowTaskMatch {
|
|
|
28
28
|
ideaSlug: string;
|
|
29
29
|
taskSlug: string;
|
|
30
30
|
}
|
|
31
|
+
export interface AllWorkflowTasks {
|
|
32
|
+
captureIdeaTasks: IdeaInProgress[];
|
|
33
|
+
workflowTasksByIdeaSlug: Map<string, WorkflowTaskMatch>;
|
|
34
|
+
}
|
|
35
|
+
export declare function findAllWorkflowTasks(fileSystem: ReadableFileSystem, dustPath: string): Promise<AllWorkflowTasks>;
|
|
31
36
|
export declare function findWorkflowTaskForIdea(fileSystem: ReadableFileSystem, dustPath: string, ideaSlug: string): Promise<WorkflowTaskMatch | null>;
|
|
32
37
|
export interface CreateIdeaTransitionTaskResult {
|
|
33
38
|
filePath: string;
|
package/dist/artifacts.js
CHANGED
|
@@ -272,7 +272,7 @@ async function parseTask(fileSystem, dustPath, slug) {
|
|
|
272
272
|
|
|
273
273
|
// lib/artifacts/workflow-tasks.ts
|
|
274
274
|
var CAPTURE_IDEA_PREFIX = "Add Idea: ";
|
|
275
|
-
var BUILD_IDEA_PREFIX = "
|
|
275
|
+
var BUILD_IDEA_PREFIX = "Decompose Idea: ";
|
|
276
276
|
async function findAllCaptureIdeaTasks(fileSystem, dustPath) {
|
|
277
277
|
const tasksPath = `${dustPath}/tasks`;
|
|
278
278
|
if (!fileSystem.exists(tasksPath))
|
|
@@ -290,7 +290,7 @@ async function findAllCaptureIdeaTasks(fileSystem, dustPath) {
|
|
|
290
290
|
taskSlug: file.replace(/\.md$/, ""),
|
|
291
291
|
ideaTitle: title.slice(CAPTURE_IDEA_PREFIX.length)
|
|
292
292
|
});
|
|
293
|
-
} else if (title.startsWith(BUILD_IDEA_PREFIX)) {
|
|
293
|
+
} else if (title.startsWith(BUILD_IDEA_PREFIX) && !content.includes("## Decomposes Idea")) {
|
|
294
294
|
results.push({
|
|
295
295
|
taskSlug: file.replace(/\.md$/, ""),
|
|
296
296
|
ideaTitle: title.slice(BUILD_IDEA_PREFIX.length)
|
|
@@ -331,6 +331,45 @@ function extractIdeaSlugFromSection(content, sectionHeading) {
|
|
|
331
331
|
}
|
|
332
332
|
return null;
|
|
333
333
|
}
|
|
334
|
+
async function findAllWorkflowTasks(fileSystem, dustPath) {
|
|
335
|
+
const tasksPath = `${dustPath}/tasks`;
|
|
336
|
+
const captureIdeaTasks = [];
|
|
337
|
+
const workflowTasksByIdeaSlug = new Map;
|
|
338
|
+
if (!fileSystem.exists(tasksPath)) {
|
|
339
|
+
return { captureIdeaTasks, workflowTasksByIdeaSlug };
|
|
340
|
+
}
|
|
341
|
+
const files = await fileSystem.readdir(tasksPath);
|
|
342
|
+
for (const file of files.filter((f) => f.endsWith(".md")).sort()) {
|
|
343
|
+
const content = await fileSystem.readFile(`${tasksPath}/${file}`);
|
|
344
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
345
|
+
if (!titleMatch)
|
|
346
|
+
continue;
|
|
347
|
+
const title = titleMatch[1].trim();
|
|
348
|
+
const taskSlug = file.replace(/\.md$/, "");
|
|
349
|
+
if (title.startsWith(CAPTURE_IDEA_PREFIX)) {
|
|
350
|
+
captureIdeaTasks.push({
|
|
351
|
+
taskSlug,
|
|
352
|
+
ideaTitle: title.slice(CAPTURE_IDEA_PREFIX.length)
|
|
353
|
+
});
|
|
354
|
+
} else if (title.startsWith(BUILD_IDEA_PREFIX) && !content.includes("## Decomposes Idea")) {
|
|
355
|
+
captureIdeaTasks.push({
|
|
356
|
+
taskSlug,
|
|
357
|
+
ideaTitle: title.slice(BUILD_IDEA_PREFIX.length)
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
for (const { type, heading } of WORKFLOW_SECTION_HEADINGS) {
|
|
361
|
+
const linkedSlug = extractIdeaSlugFromSection(content, heading);
|
|
362
|
+
if (linkedSlug) {
|
|
363
|
+
workflowTasksByIdeaSlug.set(linkedSlug, {
|
|
364
|
+
type,
|
|
365
|
+
ideaSlug: linkedSlug,
|
|
366
|
+
taskSlug
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return { captureIdeaTasks, workflowTasksByIdeaSlug };
|
|
372
|
+
}
|
|
334
373
|
async function findWorkflowTaskForIdea(fileSystem, dustPath, ideaSlug) {
|
|
335
374
|
const ideaPath = `${dustPath}/ideas/${ideaSlug}.md`;
|
|
336
375
|
if (!fileSystem.exists(ideaPath)) {
|
|
@@ -652,6 +691,7 @@ function buildReadOnlyArtifactsRepository(fileSystem, dustPath) {
|
|
|
652
691
|
}
|
|
653
692
|
export {
|
|
654
693
|
parseOpenQuestions,
|
|
694
|
+
findAllWorkflowTasks,
|
|
655
695
|
findAllCaptureIdeaTasks,
|
|
656
696
|
buildReadOnlyArtifactsRepository,
|
|
657
697
|
buildArtifactsRepository,
|
package/dist/audits.js
CHANGED
|
@@ -614,6 +614,62 @@ function errorHandling() {
|
|
|
614
614
|
- [ ] Proposed ideas for any error handling improvements identified
|
|
615
615
|
`;
|
|
616
616
|
}
|
|
617
|
+
function globalState() {
|
|
618
|
+
return dedent`
|
|
619
|
+
# Global State
|
|
620
|
+
|
|
621
|
+
Find global state and singletons that introduce hidden coupling and hurt testability.
|
|
622
|
+
|
|
623
|
+
${ideasHint}
|
|
624
|
+
|
|
625
|
+
## Scope
|
|
626
|
+
|
|
627
|
+
Focus on these patterns:
|
|
628
|
+
|
|
629
|
+
1. **Module-level mutable variables** - Variables declared outside functions that can be modified
|
|
630
|
+
2. **Singleton patterns** - Classes or objects that enforce a single instance (getInstance, static instance fields)
|
|
631
|
+
3. **Global registries** - Maps, arrays, or sets that accumulate state across module loads
|
|
632
|
+
4. **Implicit dependencies** - Functions that read from or write to module-level state instead of using parameters
|
|
633
|
+
5. **Shared configuration objects** - Mutable config objects imported and modified by multiple modules
|
|
634
|
+
6. **Lazy initialization with caching** - Values computed once and stored at module level
|
|
635
|
+
|
|
636
|
+
## Analysis Steps
|
|
637
|
+
|
|
638
|
+
1. Search for \`let\` and \`var\` declarations at module level (outside functions/classes)
|
|
639
|
+
2. Look for singleton patterns: \`getInstance\`, \`static instance\`, \`export const instance\`
|
|
640
|
+
3. Find module-level \`Map\`, \`Set\`, \`Array\`, or \`Object\` that gets modified
|
|
641
|
+
4. Identify functions that reference module-level variables not passed as parameters
|
|
642
|
+
5. Check for \`process.env\` access scattered throughout the codebase instead of centralized
|
|
643
|
+
|
|
644
|
+
## Output
|
|
645
|
+
|
|
646
|
+
For each global state instance identified, provide:
|
|
647
|
+
- **Location** - File path and line number
|
|
648
|
+
- **Pattern** - Which category (mutable variable, singleton, registry, etc.)
|
|
649
|
+
- **Impact** - How this affects testability or coupling (e.g., "Tests must reset this state", "Cannot run tests in parallel")
|
|
650
|
+
- **Suggestion** - How to refactor (e.g., "Pass as dependency", "Use factory function", "Move to function scope")
|
|
651
|
+
|
|
652
|
+
## Principles
|
|
653
|
+
|
|
654
|
+
- [Dependency Injection](../principles/dependency-injection.md) - Dependencies should be passed in, not accessed globally
|
|
655
|
+
- [Decoupled Code](../principles/decoupled-code.md) - Code should be organized into independent units
|
|
656
|
+
- [Test Isolation](../principles/test-isolation.md) - Tests should not affect each other
|
|
657
|
+
|
|
658
|
+
## Blocked By
|
|
659
|
+
|
|
660
|
+
(none)
|
|
661
|
+
|
|
662
|
+
## Definition of Done
|
|
663
|
+
|
|
664
|
+
- [ ] Searched for module-level mutable variables (let/var outside functions)
|
|
665
|
+
- [ ] Identified singleton patterns and getInstance methods
|
|
666
|
+
- [ ] Found global registries (Maps, Sets, Arrays modified at module level)
|
|
667
|
+
- [ ] Located functions with implicit dependencies on module-level state
|
|
668
|
+
- [ ] Checked for scattered process.env access
|
|
669
|
+
- [ ] Documented impact of each global state instance on testing
|
|
670
|
+
- [ ] Proposed ideas for refactoring global state to explicit dependencies
|
|
671
|
+
`;
|
|
672
|
+
}
|
|
617
673
|
function ubiquitousLanguage() {
|
|
618
674
|
return dedent`
|
|
619
675
|
# Ubiquitous Language
|
|
@@ -675,6 +731,7 @@ var stockAuditFunctions = {
|
|
|
675
731
|
"dead-code": deadCode,
|
|
676
732
|
"error-handling": errorHandling,
|
|
677
733
|
"facts-verification": factsVerification,
|
|
734
|
+
"global-state": globalState,
|
|
678
735
|
"ideas-from-commits": ideasFromCommits,
|
|
679
736
|
"ideas-from-principles": ideasFromPrinciples,
|
|
680
737
|
"performance-review": performanceReview,
|
|
@@ -14,8 +14,8 @@ export { runRepositoryLoop } from './repository-loop';
|
|
|
14
14
|
export interface Repository {
|
|
15
15
|
name: string;
|
|
16
16
|
gitUrl: string;
|
|
17
|
-
url
|
|
18
|
-
id
|
|
17
|
+
url: string;
|
|
18
|
+
id: number;
|
|
19
19
|
}
|
|
20
20
|
export interface RepositoryState {
|
|
21
21
|
repository: Repository;
|
package/dist/dust.js
CHANGED
|
@@ -275,7 +275,7 @@ async function loadSettings(cwd, fileSystem) {
|
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
// lib/version.ts
|
|
278
|
-
var DUST_VERSION = "0.1.
|
|
278
|
+
var DUST_VERSION = "0.1.70";
|
|
279
279
|
|
|
280
280
|
// lib/session.ts
|
|
281
281
|
var DUST_UNATTENDED = "DUST_UNATTENDED";
|
|
@@ -537,6 +537,8 @@ ${vars.agentInstructions}` : "";
|
|
|
537
537
|
6. **Unclear** → \`${vars.bin} help\`
|
|
538
538
|
If none of the above clearly apply, run this to see all available commands.
|
|
539
539
|
|
|
540
|
+
Note: "tasks" here refers to dust task files in \`.dust/tasks/\`, not internal task tracking tools.
|
|
541
|
+
|
|
540
542
|
Do NOT proceed without running one of these commands.${instructions}
|
|
541
543
|
`;
|
|
542
544
|
}
|
|
@@ -1159,6 +1161,62 @@ function errorHandling() {
|
|
|
1159
1161
|
- [ ] Proposed ideas for any error handling improvements identified
|
|
1160
1162
|
`;
|
|
1161
1163
|
}
|
|
1164
|
+
function globalState() {
|
|
1165
|
+
return dedent`
|
|
1166
|
+
# Global State
|
|
1167
|
+
|
|
1168
|
+
Find global state and singletons that introduce hidden coupling and hurt testability.
|
|
1169
|
+
|
|
1170
|
+
${ideasHint}
|
|
1171
|
+
|
|
1172
|
+
## Scope
|
|
1173
|
+
|
|
1174
|
+
Focus on these patterns:
|
|
1175
|
+
|
|
1176
|
+
1. **Module-level mutable variables** - Variables declared outside functions that can be modified
|
|
1177
|
+
2. **Singleton patterns** - Classes or objects that enforce a single instance (getInstance, static instance fields)
|
|
1178
|
+
3. **Global registries** - Maps, arrays, or sets that accumulate state across module loads
|
|
1179
|
+
4. **Implicit dependencies** - Functions that read from or write to module-level state instead of using parameters
|
|
1180
|
+
5. **Shared configuration objects** - Mutable config objects imported and modified by multiple modules
|
|
1181
|
+
6. **Lazy initialization with caching** - Values computed once and stored at module level
|
|
1182
|
+
|
|
1183
|
+
## Analysis Steps
|
|
1184
|
+
|
|
1185
|
+
1. Search for \`let\` and \`var\` declarations at module level (outside functions/classes)
|
|
1186
|
+
2. Look for singleton patterns: \`getInstance\`, \`static instance\`, \`export const instance\`
|
|
1187
|
+
3. Find module-level \`Map\`, \`Set\`, \`Array\`, or \`Object\` that gets modified
|
|
1188
|
+
4. Identify functions that reference module-level variables not passed as parameters
|
|
1189
|
+
5. Check for \`process.env\` access scattered throughout the codebase instead of centralized
|
|
1190
|
+
|
|
1191
|
+
## Output
|
|
1192
|
+
|
|
1193
|
+
For each global state instance identified, provide:
|
|
1194
|
+
- **Location** - File path and line number
|
|
1195
|
+
- **Pattern** - Which category (mutable variable, singleton, registry, etc.)
|
|
1196
|
+
- **Impact** - How this affects testability or coupling (e.g., "Tests must reset this state", "Cannot run tests in parallel")
|
|
1197
|
+
- **Suggestion** - How to refactor (e.g., "Pass as dependency", "Use factory function", "Move to function scope")
|
|
1198
|
+
|
|
1199
|
+
## Principles
|
|
1200
|
+
|
|
1201
|
+
- [Dependency Injection](../principles/dependency-injection.md) - Dependencies should be passed in, not accessed globally
|
|
1202
|
+
- [Decoupled Code](../principles/decoupled-code.md) - Code should be organized into independent units
|
|
1203
|
+
- [Test Isolation](../principles/test-isolation.md) - Tests should not affect each other
|
|
1204
|
+
|
|
1205
|
+
## Blocked By
|
|
1206
|
+
|
|
1207
|
+
(none)
|
|
1208
|
+
|
|
1209
|
+
## Definition of Done
|
|
1210
|
+
|
|
1211
|
+
- [ ] Searched for module-level mutable variables (let/var outside functions)
|
|
1212
|
+
- [ ] Identified singleton patterns and getInstance methods
|
|
1213
|
+
- [ ] Found global registries (Maps, Sets, Arrays modified at module level)
|
|
1214
|
+
- [ ] Located functions with implicit dependencies on module-level state
|
|
1215
|
+
- [ ] Checked for scattered process.env access
|
|
1216
|
+
- [ ] Documented impact of each global state instance on testing
|
|
1217
|
+
- [ ] Proposed ideas for refactoring global state to explicit dependencies
|
|
1218
|
+
`;
|
|
1219
|
+
}
|
|
1162
1220
|
function ubiquitousLanguage() {
|
|
1163
1221
|
return dedent`
|
|
1164
1222
|
# Ubiquitous Language
|
|
@@ -1220,6 +1278,7 @@ var stockAuditFunctions = {
|
|
|
1220
1278
|
"dead-code": deadCode,
|
|
1221
1279
|
"error-handling": errorHandling,
|
|
1222
1280
|
"facts-verification": factsVerification,
|
|
1281
|
+
"global-state": globalState,
|
|
1223
1282
|
"ideas-from-commits": ideasFromCommits,
|
|
1224
1283
|
"ideas-from-principles": ideasFromPrinciples,
|
|
1225
1284
|
"performance-review": performanceReview,
|
|
@@ -2226,7 +2285,7 @@ var IDEA_TRANSITION_PREFIXES = [
|
|
|
2226
2285
|
"Decompose Idea: ",
|
|
2227
2286
|
"Shelve Idea: "
|
|
2228
2287
|
];
|
|
2229
|
-
var BUILD_IDEA_PREFIX = "
|
|
2288
|
+
var BUILD_IDEA_PREFIX = "Decompose Idea: ";
|
|
2230
2289
|
function titleToFilename(title) {
|
|
2231
2290
|
return `${title.toLowerCase().replace(/\./g, "-").replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}.md`;
|
|
2232
2291
|
}
|
|
@@ -2811,7 +2870,7 @@ async function runRepositoryLoop(repoState, repoDeps, sendEvent, sessionId) {
|
|
|
2811
2870
|
result = await runOneIteration(commandDeps, loopDeps, onLoopEvent, onAgentEvent, {
|
|
2812
2871
|
hooksInstalled,
|
|
2813
2872
|
signal: abortController.signal,
|
|
2814
|
-
repositoryId: repoState.repository.id,
|
|
2873
|
+
repositoryId: repoState.repository.id.toString(),
|
|
2815
2874
|
onRawEvent: (rawEvent) => {
|
|
2816
2875
|
onAgentEvent(rawEventToAgentEvent(rawEvent));
|
|
2817
2876
|
}
|
|
@@ -2870,23 +2929,15 @@ function startRepositoryLoop(repoState, repoDeps, sendEvent, sessionId) {
|
|
|
2870
2929
|
});
|
|
2871
2930
|
}
|
|
2872
2931
|
function parseRepository(data) {
|
|
2873
|
-
if (typeof data === "string") {
|
|
2874
|
-
return { name: data, gitUrl: data };
|
|
2875
|
-
}
|
|
2876
2932
|
if (typeof data === "object" && data !== null && "name" in data && "gitUrl" in data) {
|
|
2877
2933
|
const repositoryData = data;
|
|
2878
|
-
if (typeof repositoryData.name === "string" && typeof repositoryData.gitUrl === "string") {
|
|
2879
|
-
|
|
2934
|
+
if (typeof repositoryData.name === "string" && typeof repositoryData.gitUrl === "string" && typeof repositoryData.url === "string" && typeof repositoryData.id === "number") {
|
|
2935
|
+
return {
|
|
2880
2936
|
name: repositoryData.name,
|
|
2881
|
-
gitUrl: repositoryData.gitUrl
|
|
2937
|
+
gitUrl: repositoryData.gitUrl,
|
|
2938
|
+
url: repositoryData.url,
|
|
2939
|
+
id: repositoryData.id
|
|
2882
2940
|
};
|
|
2883
|
-
if (typeof repositoryData.url === "string") {
|
|
2884
|
-
repo.url = repositoryData.url;
|
|
2885
|
-
}
|
|
2886
|
-
if (typeof repositoryData.id === "string") {
|
|
2887
|
-
repo.id = repositoryData.id;
|
|
2888
|
-
}
|
|
2889
|
-
return repo;
|
|
2890
2941
|
}
|
|
2891
2942
|
}
|
|
2892
2943
|
return null;
|
|
@@ -2991,20 +3042,16 @@ function parseServerMessage(data) {
|
|
|
2991
3042
|
if (typeof repo.name !== "string" || typeof repo.gitUrl !== "string") {
|
|
2992
3043
|
return null;
|
|
2993
3044
|
}
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
gitUrl: repo.gitUrl
|
|
2997
|
-
};
|
|
2998
|
-
if (typeof repo.url === "string") {
|
|
2999
|
-
item.url = repo.url;
|
|
3000
|
-
}
|
|
3001
|
-
if (typeof repo.id === "string") {
|
|
3002
|
-
item.id = repo.id;
|
|
3003
|
-
}
|
|
3004
|
-
if (typeof repo.hasTask === "boolean") {
|
|
3005
|
-
item.hasTask = repo.hasTask;
|
|
3045
|
+
if (typeof repo.id !== "number" || typeof repo.url !== "string" || typeof repo.hasTask !== "boolean") {
|
|
3046
|
+
return null;
|
|
3006
3047
|
}
|
|
3007
|
-
repositories.push(
|
|
3048
|
+
repositories.push({
|
|
3049
|
+
id: repo.id,
|
|
3050
|
+
name: repo.name,
|
|
3051
|
+
gitUrl: repo.gitUrl,
|
|
3052
|
+
url: repo.url,
|
|
3053
|
+
hasTask: repo.hasTask
|
|
3054
|
+
});
|
|
3008
3055
|
}
|
|
3009
3056
|
return { type: "repository-list", repositories };
|
|
3010
3057
|
}
|
|
@@ -3741,16 +3788,10 @@ function connectWebSocket(token, state, bucketDependencies, context, fileSystem,
|
|
|
3741
3788
|
for (const r of repos) {
|
|
3742
3789
|
const attrs = [];
|
|
3743
3790
|
attrs.push(`name=${r.name}`);
|
|
3744
|
-
|
|
3745
|
-
attrs.push(`id=${r.id}`);
|
|
3746
|
-
}
|
|
3791
|
+
attrs.push(`id=${r.id}`);
|
|
3747
3792
|
attrs.push(`gitUrl=${r.gitUrl}`);
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
}
|
|
3751
|
-
if (r.hasTask !== undefined) {
|
|
3752
|
-
attrs.push(`hasTask=${r.hasTask}`);
|
|
3753
|
-
}
|
|
3793
|
+
attrs.push(`url=${r.url}`);
|
|
3794
|
+
attrs.push(`hasTask=${r.hasTask}`);
|
|
3754
3795
|
logMessage(state, context, useTUI, ` - ${attrs.join(", ")}`);
|
|
3755
3796
|
}
|
|
3756
3797
|
}
|
|
@@ -3997,14 +4038,15 @@ function createDefaultUploadDependencies() {
|
|
|
3997
4038
|
const file = Bun.file(path);
|
|
3998
4039
|
return file.exists();
|
|
3999
4040
|
},
|
|
4000
|
-
uploadFile: async (url, token, fileBytes, contentType) => {
|
|
4041
|
+
uploadFile: async (url, token, fileBytes, contentType, fileName) => {
|
|
4042
|
+
const formData = new FormData;
|
|
4043
|
+
formData.append("file", new Blob([fileBytes.buffer], { type: contentType }), fileName);
|
|
4001
4044
|
const response = await fetch(url, {
|
|
4002
4045
|
method: "POST",
|
|
4003
4046
|
headers: {
|
|
4004
|
-
Authorization: `Bearer ${token}
|
|
4005
|
-
"Content-Type": contentType
|
|
4047
|
+
Authorization: `Bearer ${token}`
|
|
4006
4048
|
},
|
|
4007
|
-
body:
|
|
4049
|
+
body: formData
|
|
4008
4050
|
});
|
|
4009
4051
|
if (!response.ok) {
|
|
4010
4052
|
const text = await response.text();
|
|
@@ -4089,9 +4131,10 @@ async function bucketAssetUpload(dependencies, uploadDeps = createDefaultUploadD
|
|
|
4089
4131
|
}
|
|
4090
4132
|
const fileBytes = await uploadDeps.readFileBytes(filePath);
|
|
4091
4133
|
const contentType = getContentType(filePath);
|
|
4134
|
+
const fileName = filePath.split("/").pop();
|
|
4092
4135
|
const uploadUrl = `${getDustbucketHost()}/api/assets?repositoryId=${encodeURIComponent(repositoryId)}`;
|
|
4093
4136
|
try {
|
|
4094
|
-
const result = await uploadDeps.uploadFile(uploadUrl, token, fileBytes, contentType);
|
|
4137
|
+
const result = await uploadDeps.uploadFile(uploadUrl, token, fileBytes, contentType, fileName);
|
|
4095
4138
|
context.stdout(result.url);
|
|
4096
4139
|
return { exitCode: 0 };
|
|
4097
4140
|
} catch (error) {
|
|
@@ -5036,7 +5079,7 @@ async function runSingleCheck(check, cwd, runner) {
|
|
|
5036
5079
|
output: result.output,
|
|
5037
5080
|
hints: check.hints,
|
|
5038
5081
|
durationMs,
|
|
5039
|
-
timedOut: result.timedOut,
|
|
5082
|
+
timedOut: result.timedOut ?? false,
|
|
5040
5083
|
timeoutSeconds: timeoutMs / 1000
|
|
5041
5084
|
};
|
|
5042
5085
|
}
|
|
@@ -5075,7 +5118,8 @@ async function runValidationCheck(dependencies) {
|
|
|
5075
5118
|
output: outputLines.join(`
|
|
5076
5119
|
`),
|
|
5077
5120
|
isBuiltIn: true,
|
|
5078
|
-
durationMs
|
|
5121
|
+
durationMs,
|
|
5122
|
+
timedOut: false
|
|
5079
5123
|
};
|
|
5080
5124
|
}
|
|
5081
5125
|
function displayResults(results, context) {
|
|
@@ -5085,7 +5129,7 @@ function displayResults(results, context) {
|
|
|
5085
5129
|
if (result.timedOut) {
|
|
5086
5130
|
context.stdout(`✗ ${result.name} [timed out after ${result.timeoutSeconds}s]`);
|
|
5087
5131
|
} else {
|
|
5088
|
-
const timing = result.durationMs
|
|
5132
|
+
const timing = result.durationMs >= 1000 ? ` [${(result.durationMs / 1000).toFixed(1)}s]` : "";
|
|
5089
5133
|
if (result.exitCode === 0) {
|
|
5090
5134
|
context.stdout(`✓ ${result.name}${timing}`);
|
|
5091
5135
|
} else {
|