open-local-audit 0.62.0 → 0.64.0
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/CHANGELOG.md +12 -0
- package/README.md +22 -0
- package/dist/batch.d.ts +1 -0
- package/dist/batch.js +9 -3
- package/dist/batch.js.map +1 -1
- package/dist/cli.js +64 -10
- package/dist/cli.js.map +1 -1
- package/dist/discovery-runner.d.ts +1 -0
- package/dist/discovery-runner.js +9 -7
- package/dist/discovery-runner.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +1 -0
- package/dist/output.js +20 -3
- package/dist/output.js.map +1 -1
- package/dist/shortlist-runner.js +4 -3
- package/dist/shortlist-runner.js.map +1 -1
- package/dist/workflow-output.d.ts +5 -0
- package/dist/workflow-output.js +70 -0
- package/dist/workflow-output.js.map +1 -0
- package/dist/workflow-paths.d.ts +19 -0
- package/dist/workflow-paths.js +111 -0
- package/dist/workflow-paths.js.map +1 -0
- package/dist/workflow-plan.d.ts +47 -0
- package/dist/workflow-plan.js +186 -0
- package/dist/workflow-plan.js.map +1 -0
- package/dist/workflow-preflight.d.ts +43 -0
- package/dist/workflow-preflight.js +214 -0
- package/dist/workflow-preflight.js.map +1 -0
- package/dist/workflow.js +6 -27
- package/dist/workflow.js.map +1 -1
- package/docs/architecture/workflow-command.md +106 -0
- package/docs/architecture/workflow-plan.md +229 -0
- package/docs/architecture/workflow-preflight.md +133 -0
- package/package.json +5 -2
package/dist/output.js
CHANGED
|
@@ -2,6 +2,7 @@ import { mkdir, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { renderPdfReport } from "./pdf.js";
|
|
4
4
|
import { renderHtmlReport, renderJsonReport, renderMarkdownReport } from "./reporters.js";
|
|
5
|
+
import { writeWorkflowOutputFile } from "./workflow-output.js";
|
|
5
6
|
async function outputFor(report, format, options) {
|
|
6
7
|
const pretty = options.pretty ?? false;
|
|
7
8
|
return {
|
|
@@ -32,10 +33,19 @@ export async function writeReportOutputs(report, options) {
|
|
|
32
33
|
throw new Error("--out or --out-dir is required when --format pdf is used");
|
|
33
34
|
}
|
|
34
35
|
if (options.outDir) {
|
|
35
|
-
|
|
36
|
+
if (!options.managedOutputRoot) {
|
|
37
|
+
await mkdir(options.outDir, { recursive: true });
|
|
38
|
+
}
|
|
36
39
|
for (const output of outputs) {
|
|
37
40
|
output.path = join(options.outDir, defaultReportName(output.format));
|
|
38
|
-
|
|
41
|
+
if (options.managedOutputRoot) {
|
|
42
|
+
await writeWorkflowOutputFile(output.path, output.content, {
|
|
43
|
+
managedOutputRoot: options.managedOutputRoot
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
await writeFile(output.path, output.content);
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
return outputs;
|
|
41
51
|
}
|
|
@@ -44,7 +54,14 @@ export async function writeReportOutputs(report, options) {
|
|
|
44
54
|
}
|
|
45
55
|
if (options.out) {
|
|
46
56
|
outputs[0].path = options.out;
|
|
47
|
-
|
|
57
|
+
if (options.managedOutputRoot) {
|
|
58
|
+
await writeWorkflowOutputFile(options.out, outputs[0].content, {
|
|
59
|
+
managedOutputRoot: options.managedOutputRoot
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
await writeFile(options.out, outputs[0].content);
|
|
64
|
+
}
|
|
48
65
|
}
|
|
49
66
|
return outputs;
|
|
50
67
|
}
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
|
package/dist/shortlist-runner.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { mkdir, readFile
|
|
1
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { buildLeadShortlist, readShortlistReviewCsv, renderShortlistCsv, renderShortlistJson, renderShortlistMarkdown, renderShortlistSummaryJson } from "./shortlist.js";
|
|
4
|
+
import { writeWorkflowOutputFile } from "./workflow-output.js";
|
|
4
5
|
export async function runShortlistReport(options) {
|
|
5
6
|
const input = await readFile(options.input, "utf8");
|
|
6
7
|
const reviewRows = options.reviewCsv ? readShortlistReviewCsv(await readFile(options.reviewCsv, "utf8")) : [];
|
|
@@ -14,10 +15,10 @@ export async function runShortlistReport(options) {
|
|
|
14
15
|
? renderShortlistCsv(result)
|
|
15
16
|
: renderShortlistMarkdown(result);
|
|
16
17
|
await mkdir(dirname(options.out), { recursive: true });
|
|
17
|
-
await
|
|
18
|
+
await writeWorkflowOutputFile(options.out, output);
|
|
18
19
|
if (options.summaryJson) {
|
|
19
20
|
await mkdir(dirname(options.summaryJson), { recursive: true });
|
|
20
|
-
await
|
|
21
|
+
await writeWorkflowOutputFile(options.summaryJson, renderShortlistSummaryJson(result));
|
|
21
22
|
}
|
|
22
23
|
return result;
|
|
23
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortlist-runner.js","sourceRoot":"","sources":["../src/shortlist-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"shortlist-runner.js","sourceRoot":"","sources":["../src/shortlist-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,0BAA0B,EAI3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAW/D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA4B;IACnE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9G,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,EAAE;QACvC,GAAG,OAAO,CAAC,SAAS;QACpB,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,MAAM,GACV,OAAO,CAAC,MAAM,KAAK,MAAM;QACvB,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC;QAC7B,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK;YACxB,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;YAC5B,CAAC,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAExC,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEnD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,uBAAuB,CAAC,OAAO,CAAC,WAAW,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { lstat, mkdir, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
function isMissingPath(error) {
|
|
5
|
+
return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
|
|
6
|
+
}
|
|
7
|
+
function isContainedPath(root, path) {
|
|
8
|
+
const relativePath = relative(root, path);
|
|
9
|
+
return relativePath === "" || (!relativePath.startsWith(`..${sep}`) && relativePath !== ".." && !isAbsolute(relativePath));
|
|
10
|
+
}
|
|
11
|
+
async function ensureManagedOutputDirectory(directory, managedOutputRoot) {
|
|
12
|
+
const resolvedRoot = resolve(managedOutputRoot);
|
|
13
|
+
const resolvedDirectory = resolve(directory);
|
|
14
|
+
if (!isContainedPath(resolvedRoot, resolvedDirectory)) {
|
|
15
|
+
throw new Error("Managed output directory escapes managed output root");
|
|
16
|
+
}
|
|
17
|
+
async function inspectDirectory() {
|
|
18
|
+
const rootInfo = await lstat(resolvedRoot);
|
|
19
|
+
if (rootInfo.isSymbolicLink()) {
|
|
20
|
+
throw new Error("Managed output directory must not be linked");
|
|
21
|
+
}
|
|
22
|
+
if (!rootInfo.isDirectory()) {
|
|
23
|
+
throw new Error("Managed output directory must be a directory");
|
|
24
|
+
}
|
|
25
|
+
let directoryInfo;
|
|
26
|
+
try {
|
|
27
|
+
directoryInfo = await lstat(resolvedDirectory);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (isMissingPath(error)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
if (directoryInfo.isSymbolicLink()) {
|
|
36
|
+
throw new Error("Managed output directory must not be linked");
|
|
37
|
+
}
|
|
38
|
+
if (!directoryInfo.isDirectory()) {
|
|
39
|
+
throw new Error("Managed output directory must be a directory");
|
|
40
|
+
}
|
|
41
|
+
const [realRoot, realDirectory] = await Promise.all([realpath(resolvedRoot), realpath(resolvedDirectory)]);
|
|
42
|
+
if (!isContainedPath(realRoot, realDirectory)) {
|
|
43
|
+
throw new Error("Managed output directory escapes managed output root");
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (!(await inspectDirectory())) {
|
|
48
|
+
await mkdir(resolvedDirectory, { recursive: true });
|
|
49
|
+
await inspectDirectory();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export async function writeWorkflowOutputFile(path, content, options = {}) {
|
|
53
|
+
if (options.managedOutputRoot) {
|
|
54
|
+
await ensureManagedOutputDirectory(dirname(path), options.managedOutputRoot);
|
|
55
|
+
}
|
|
56
|
+
const temporaryPath = join(dirname(path), `.${basename(path)}-${randomUUID()}.tmp`);
|
|
57
|
+
try {
|
|
58
|
+
await writeFile(temporaryPath, content, "utf8");
|
|
59
|
+
await rename(temporaryPath, path);
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
try {
|
|
63
|
+
await rm(temporaryPath, { force: true });
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Preserve the write or replacement failure when its temporary cleanup also fails.
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=workflow-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-output.js","sourceRoot":"","sources":["../src/workflow-output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { lstat } from "node:fs/promises";
|
|
2
|
+
import type { ResolvedWorkflowConfig } from "./workflow-config.js";
|
|
3
|
+
export type WorkflowPathIssueId = "output-linked" | "reports-linked" | "packages-linked" | "managed-file-linked" | "reports-escape" | "packages-escape";
|
|
4
|
+
export interface WorkflowPathIssue {
|
|
5
|
+
id: WorkflowPathIssueId;
|
|
6
|
+
message: string;
|
|
7
|
+
path: string;
|
|
8
|
+
}
|
|
9
|
+
export interface WorkflowPathInspection {
|
|
10
|
+
status: "safe" | "unsafe";
|
|
11
|
+
issues: WorkflowPathIssue[];
|
|
12
|
+
}
|
|
13
|
+
interface WorkflowPathDependencies {
|
|
14
|
+
lstat(path: string): ReturnType<typeof lstat>;
|
|
15
|
+
realpath(path: string): Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
export declare function inspectWorkflowManagedPaths(config: ResolvedWorkflowConfig, dependencies?: Partial<WorkflowPathDependencies>): Promise<WorkflowPathInspection>;
|
|
18
|
+
export declare function prepareWorkflowManagedDirectories(config: ResolvedWorkflowConfig): Promise<void>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { lstat, mkdir, realpath } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute, relative, sep } from "node:path";
|
|
3
|
+
const defaultDependencies = { lstat, realpath };
|
|
4
|
+
function isMissingPath(error) {
|
|
5
|
+
return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
|
|
6
|
+
}
|
|
7
|
+
async function pathInfo(path, dependencies) {
|
|
8
|
+
try {
|
|
9
|
+
return await dependencies.lstat(path);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (isMissingPath(error)) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function inspectWorkflowManagedPaths(config, dependencies = {}) {
|
|
19
|
+
const resolvedDependencies = { ...defaultDependencies, ...dependencies };
|
|
20
|
+
const outputInfo = await pathInfo(config.outDir, resolvedDependencies);
|
|
21
|
+
if (!outputInfo) {
|
|
22
|
+
return { status: "safe", issues: [] };
|
|
23
|
+
}
|
|
24
|
+
if (outputInfo.isSymbolicLink()) {
|
|
25
|
+
return {
|
|
26
|
+
status: "unsafe",
|
|
27
|
+
issues: [
|
|
28
|
+
{
|
|
29
|
+
id: "output-linked",
|
|
30
|
+
message: "Managed output directory must not be linked",
|
|
31
|
+
path: config.outDir
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const realOutDir = await resolvedDependencies.realpath(config.outDir);
|
|
37
|
+
const directories = [
|
|
38
|
+
{
|
|
39
|
+
id: "reports",
|
|
40
|
+
path: config.paths.reportsDir
|
|
41
|
+
},
|
|
42
|
+
...(config.packageReports
|
|
43
|
+
? [
|
|
44
|
+
{
|
|
45
|
+
id: "packages",
|
|
46
|
+
path: config.paths.packagesDir
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
: [])
|
|
50
|
+
];
|
|
51
|
+
const issues = [];
|
|
52
|
+
for (const path of [
|
|
53
|
+
config.paths.leadsCsv,
|
|
54
|
+
config.paths.discoverySummaryJson,
|
|
55
|
+
config.paths.shortlistCsv,
|
|
56
|
+
config.paths.shortlistSummaryJson,
|
|
57
|
+
config.paths.reviewSummaryJson,
|
|
58
|
+
config.paths.workflowSummaryJson
|
|
59
|
+
]) {
|
|
60
|
+
const fileInfo = await pathInfo(path, resolvedDependencies);
|
|
61
|
+
if (fileInfo?.isSymbolicLink()) {
|
|
62
|
+
issues.push({
|
|
63
|
+
id: "managed-file-linked",
|
|
64
|
+
message: "Managed output file must not be linked",
|
|
65
|
+
path
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const directory of directories) {
|
|
70
|
+
const directoryInfo = await pathInfo(directory.path, resolvedDependencies);
|
|
71
|
+
if (!directoryInfo) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (directoryInfo.isSymbolicLink()) {
|
|
75
|
+
issues.push({
|
|
76
|
+
id: `${directory.id}-linked`,
|
|
77
|
+
message: `Managed ${directory.id} directory must not be linked`,
|
|
78
|
+
path: directory.path
|
|
79
|
+
});
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const realDirectory = await resolvedDependencies.realpath(directory.path);
|
|
83
|
+
const relativeDirectory = relative(realOutDir, realDirectory);
|
|
84
|
+
if (relativeDirectory === ".." ||
|
|
85
|
+
relativeDirectory.startsWith(`..${sep}`) ||
|
|
86
|
+
isAbsolute(relativeDirectory)) {
|
|
87
|
+
issues.push({
|
|
88
|
+
id: `${directory.id}-escape`,
|
|
89
|
+
message: `Managed ${directory.id} directory escapes output directory`,
|
|
90
|
+
path: directory.path
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return issues.length === 0 ? { status: "safe", issues } : { status: "unsafe", issues };
|
|
95
|
+
}
|
|
96
|
+
export async function prepareWorkflowManagedDirectories(config) {
|
|
97
|
+
await mkdir(config.outDir, { recursive: true });
|
|
98
|
+
const initialInspection = await inspectWorkflowManagedPaths(config);
|
|
99
|
+
if (initialInspection.status === "unsafe") {
|
|
100
|
+
throw new Error(initialInspection.issues[0].message);
|
|
101
|
+
}
|
|
102
|
+
await mkdir(config.paths.reportsDir, { recursive: true });
|
|
103
|
+
if (config.packageReports) {
|
|
104
|
+
await mkdir(config.paths.packagesDir, { recursive: true });
|
|
105
|
+
}
|
|
106
|
+
const inspection = await inspectWorkflowManagedPaths(config);
|
|
107
|
+
if (inspection.status === "unsafe") {
|
|
108
|
+
throw new Error(inspection.issues[0].message);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=workflow-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-paths.js","sourceRoot":"","sources":["../src/workflow-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AA2BtD,MAAM,mBAAmB,GAA6B,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAE1E,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AACnG,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,IAAY,EACZ,YAAsC;IAEtC,IAAI,CAAC;QACH,OAAO,MAAM,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,MAA8B,EAC9B,eAAkD,EAAE;IAEpD,MAAM,oBAAoB,GAA6B,EAAE,GAAG,mBAAmB,EAAE,GAAG,YAAY,EAAE,CAAC;IACnG,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACvE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACxC,CAAC;IAED,IAAI,UAAU,CAAC,cAAc,EAAE,EAAE,CAAC;QAChC,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE;gBACN;oBACE,EAAE,EAAE,eAAe;oBACnB,OAAO,EAAE,6CAA6C;oBACtD,IAAI,EAAE,MAAM,CAAC,MAAM;iBACpB;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG;QAClB;YACE,EAAE,EAAE,SAAkB;YACtB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;SAC9B;QACD,GAAG,CAAC,MAAM,CAAC,cAAc;YACvB,CAAC,CAAC;gBACE;oBACE,EAAE,EAAE,UAAmB;oBACvB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;iBAC/B;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,MAAM,MAAM,GAAwB,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI;QACjB,MAAM,CAAC,KAAK,CAAC,QAAQ;QACrB,MAAM,CAAC,KAAK,CAAC,oBAAoB;QACjC,MAAM,CAAC,KAAK,CAAC,YAAY;QACzB,MAAM,CAAC,KAAK,CAAC,oBAAoB;QACjC,MAAM,CAAC,KAAK,CAAC,iBAAiB;QAC9B,MAAM,CAAC,KAAK,CAAC,mBAAmB;KACjC,EAAE,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAC5D,IAAI,QAAQ,EAAE,cAAc,EAAE,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,qBAAqB;gBACzB,OAAO,EAAE,wCAAwC;gBACjD,IAAI;aACL,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,WAAW,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAC3E,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,SAAS;QACX,CAAC;QAED,IAAI,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,GAAG,SAAS,CAAC,EAAE,SAAS;gBAC5B,OAAO,EAAE,WAAW,SAAS,CAAC,EAAE,+BAA+B;gBAC/D,IAAI,EAAE,SAAS,CAAC,IAAI;aACrB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1E,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC9D,IACE,iBAAiB,KAAK,IAAI;YAC1B,iBAAiB,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC;YACxC,UAAU,CAAC,iBAAiB,CAAC,EAC7B,CAAC;YACD,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,GAAG,SAAS,CAAC,EAAE,SAAS;gBAC5B,OAAO,EAAE,WAAW,SAAS,CAAC,EAAE,qCAAqC;gBACrE,IAAI,EAAE,SAAS,CAAC,IAAI;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CAAC,MAA8B;IACpF,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,iBAAiB,GAAG,MAAM,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpE,IAAI,iBAAiB,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,UAAU,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { WorkflowPreflightEvaluation, WorkflowPreflightReport, WorkflowPreflightStatus } from "./workflow-preflight.js";
|
|
2
|
+
import type { ResolvedWorkflowConfig } from "./workflow-config.js";
|
|
3
|
+
export type WorkflowPlanStatus = WorkflowPreflightStatus;
|
|
4
|
+
export type WorkflowPlanStepId = "discovery" | "shortlist" | "review" | "packaging" | "summary";
|
|
5
|
+
export type WorkflowPlanStepState = "will-run" | "conditional" | "disabled";
|
|
6
|
+
export type WorkflowPlanNetworkAccess = "google-places" | "website-audits";
|
|
7
|
+
export type WorkflowPlanArtifactId = "manual-input-csv" | "review-csv" | "leads-csv" | "discovery-summary-json" | "reports-dir" | "shortlist-csv" | "shortlist-summary-json" | "review-summary-json" | "packages-dir" | "workflow-summary-json";
|
|
8
|
+
interface WorkflowPlanStepBase<Id extends WorkflowPlanStepId, State extends WorkflowPlanStepState, Settings> {
|
|
9
|
+
id: Id;
|
|
10
|
+
state: State;
|
|
11
|
+
dependsOn: WorkflowPlanStepId[];
|
|
12
|
+
inputs: WorkflowPlanArtifactId[];
|
|
13
|
+
outputs: WorkflowPlanArtifactId[];
|
|
14
|
+
networkAccess: WorkflowPlanNetworkAccess[];
|
|
15
|
+
reason?: string;
|
|
16
|
+
settings: Settings;
|
|
17
|
+
}
|
|
18
|
+
export type WorkflowPlanStep = WorkflowPlanStepBase<"discovery", "will-run", {
|
|
19
|
+
provider: ResolvedWorkflowConfig["discovery"]["provider"];
|
|
20
|
+
profile: ResolvedWorkflowConfig["discovery"]["profile"];
|
|
21
|
+
concurrency: number;
|
|
22
|
+
maxCandidates: number | null;
|
|
23
|
+
maxAudits: number | null;
|
|
24
|
+
}> | WorkflowPlanStepBase<"shortlist", "will-run", {
|
|
25
|
+
top: number;
|
|
26
|
+
minOpportunityScore: number | null;
|
|
27
|
+
sort: ResolvedWorkflowConfig["shortlist"]["sort"];
|
|
28
|
+
}> | WorkflowPlanStepBase<"review", "will-run" | "disabled", {
|
|
29
|
+
staleBefore: string | null;
|
|
30
|
+
}> | WorkflowPlanStepBase<"packaging", "conditional" | "disabled", {
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
}> | WorkflowPlanStepBase<"summary", "will-run", Record<string, never>>;
|
|
33
|
+
export interface WorkflowPlanReport {
|
|
34
|
+
version: 1;
|
|
35
|
+
status: WorkflowPlanStatus;
|
|
36
|
+
preflight: WorkflowPreflightReport;
|
|
37
|
+
artifacts: Partial<Record<WorkflowPlanArtifactId, string>>;
|
|
38
|
+
steps: WorkflowPlanStep[];
|
|
39
|
+
}
|
|
40
|
+
interface WorkflowPlanDependencies {
|
|
41
|
+
evaluatePreflight(configPath: string): Promise<WorkflowPreflightEvaluation>;
|
|
42
|
+
}
|
|
43
|
+
export declare function renderWorkflowPlanTerminal(report: WorkflowPlanReport, configPath: string): string;
|
|
44
|
+
export declare function renderWorkflowPlanJson(report: WorkflowPlanReport): string;
|
|
45
|
+
export declare function runWorkflowPlan(configPath: string): Promise<WorkflowPlanReport>;
|
|
46
|
+
export declare function runWorkflowPlanWithDependencies(configPath: string, overrides?: Partial<WorkflowPlanDependencies>): Promise<WorkflowPlanReport>;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { runWorkflowPreflightEvaluationWithDependencies } from "./workflow-preflight.js";
|
|
2
|
+
const workflowPlanArtifactIds = [
|
|
3
|
+
"manual-input-csv",
|
|
4
|
+
"review-csv",
|
|
5
|
+
"leads-csv",
|
|
6
|
+
"discovery-summary-json",
|
|
7
|
+
"reports-dir",
|
|
8
|
+
"shortlist-csv",
|
|
9
|
+
"shortlist-summary-json",
|
|
10
|
+
"review-summary-json",
|
|
11
|
+
"packages-dir",
|
|
12
|
+
"workflow-summary-json"
|
|
13
|
+
];
|
|
14
|
+
const defaultDependencies = {
|
|
15
|
+
evaluatePreflight: runWorkflowPreflightEvaluationWithDependencies
|
|
16
|
+
};
|
|
17
|
+
function buildPlan(evaluation) {
|
|
18
|
+
const { config, report: preflight } = evaluation;
|
|
19
|
+
if (!config) {
|
|
20
|
+
return { version: 1, status: preflight.status, preflight, artifacts: {}, steps: [] };
|
|
21
|
+
}
|
|
22
|
+
const artifacts = {
|
|
23
|
+
...(config.discovery.provider === "manual-csv" ? { "manual-input-csv": config.discovery.input } : {}),
|
|
24
|
+
...(config.review ? { "review-csv": config.review.csv } : {}),
|
|
25
|
+
"leads-csv": config.paths.leadsCsv,
|
|
26
|
+
"discovery-summary-json": config.paths.discoverySummaryJson,
|
|
27
|
+
"reports-dir": config.paths.reportsDir,
|
|
28
|
+
"shortlist-csv": config.paths.shortlistCsv,
|
|
29
|
+
"shortlist-summary-json": config.paths.shortlistSummaryJson,
|
|
30
|
+
...(config.review ? { "review-summary-json": config.paths.reviewSummaryJson } : {}),
|
|
31
|
+
...(config.packageReports ? { "packages-dir": config.paths.packagesDir } : {}),
|
|
32
|
+
"workflow-summary-json": config.paths.workflowSummaryJson
|
|
33
|
+
};
|
|
34
|
+
const reviewEnabled = Boolean(config.review);
|
|
35
|
+
const packagingEnabled = config.packageReports;
|
|
36
|
+
const discoveryNetworkAccess = [
|
|
37
|
+
...(config.discovery.provider === "google-places" ? ["google-places"] : []),
|
|
38
|
+
...(config.discovery.maxAudits === 0 ? [] : ["website-audits"])
|
|
39
|
+
];
|
|
40
|
+
const summaryDependency = packagingEnabled ? "packaging" : reviewEnabled ? "review" : "shortlist";
|
|
41
|
+
const steps = [
|
|
42
|
+
{
|
|
43
|
+
id: "discovery",
|
|
44
|
+
state: "will-run",
|
|
45
|
+
dependsOn: [],
|
|
46
|
+
inputs: [
|
|
47
|
+
...(config.discovery.provider === "manual-csv" ? ["manual-input-csv"] : []),
|
|
48
|
+
...(config.review ? ["review-csv"] : [])
|
|
49
|
+
],
|
|
50
|
+
outputs: [
|
|
51
|
+
"leads-csv",
|
|
52
|
+
"discovery-summary-json",
|
|
53
|
+
"reports-dir",
|
|
54
|
+
...(config.review ? ["review-csv"] : [])
|
|
55
|
+
],
|
|
56
|
+
networkAccess: discoveryNetworkAccess,
|
|
57
|
+
settings: {
|
|
58
|
+
provider: config.discovery.provider,
|
|
59
|
+
profile: config.discovery.profile,
|
|
60
|
+
concurrency: config.discovery.concurrency,
|
|
61
|
+
maxCandidates: config.discovery.provider === "google-places" ? config.discovery.limit : null,
|
|
62
|
+
maxAudits: config.discovery.maxAudits ?? null
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "shortlist",
|
|
67
|
+
state: "will-run",
|
|
68
|
+
dependsOn: ["discovery"],
|
|
69
|
+
inputs: ["leads-csv", ...(config.review ? ["review-csv"] : [])],
|
|
70
|
+
outputs: ["shortlist-csv", "shortlist-summary-json"],
|
|
71
|
+
networkAccess: [],
|
|
72
|
+
settings: {
|
|
73
|
+
top: config.shortlist.top,
|
|
74
|
+
minOpportunityScore: config.shortlist.minOpportunityScore ?? null,
|
|
75
|
+
sort: config.shortlist.sort
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
config.review
|
|
79
|
+
? {
|
|
80
|
+
id: "review",
|
|
81
|
+
state: "will-run",
|
|
82
|
+
dependsOn: ["shortlist"],
|
|
83
|
+
inputs: ["review-csv"],
|
|
84
|
+
outputs: ["review-summary-json"],
|
|
85
|
+
networkAccess: [],
|
|
86
|
+
settings: { staleBefore: config.review.staleBefore ?? null }
|
|
87
|
+
}
|
|
88
|
+
: {
|
|
89
|
+
id: "review",
|
|
90
|
+
state: "disabled",
|
|
91
|
+
dependsOn: [],
|
|
92
|
+
inputs: [],
|
|
93
|
+
outputs: [],
|
|
94
|
+
networkAccess: [],
|
|
95
|
+
reason: "Review is not configured",
|
|
96
|
+
settings: { staleBefore: null }
|
|
97
|
+
},
|
|
98
|
+
packagingEnabled
|
|
99
|
+
? {
|
|
100
|
+
id: "packaging",
|
|
101
|
+
state: "conditional",
|
|
102
|
+
dependsOn: [reviewEnabled ? "review" : "shortlist"],
|
|
103
|
+
inputs: ["reports-dir"],
|
|
104
|
+
outputs: ["packages-dir"],
|
|
105
|
+
networkAccess: [],
|
|
106
|
+
reason: "Runs for selected leads with successful report artifacts",
|
|
107
|
+
settings: { enabled: true }
|
|
108
|
+
}
|
|
109
|
+
: {
|
|
110
|
+
id: "packaging",
|
|
111
|
+
state: "disabled",
|
|
112
|
+
dependsOn: [],
|
|
113
|
+
inputs: [],
|
|
114
|
+
outputs: [],
|
|
115
|
+
networkAccess: [],
|
|
116
|
+
reason: "Report packaging is not enabled",
|
|
117
|
+
settings: { enabled: false }
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: "summary",
|
|
121
|
+
state: "will-run",
|
|
122
|
+
dependsOn: [summaryDependency],
|
|
123
|
+
inputs: [],
|
|
124
|
+
outputs: ["workflow-summary-json"],
|
|
125
|
+
networkAccess: [],
|
|
126
|
+
settings: {}
|
|
127
|
+
}
|
|
128
|
+
];
|
|
129
|
+
return { version: 1, status: preflight.status, preflight, artifacts, steps };
|
|
130
|
+
}
|
|
131
|
+
function renderNetworkCapabilities(step) {
|
|
132
|
+
return step.networkAccess.flatMap((access) => {
|
|
133
|
+
if (access === "google-places") {
|
|
134
|
+
return "Google Places";
|
|
135
|
+
}
|
|
136
|
+
return step.id !== "discovery" || step.settings.maxAudits === null
|
|
137
|
+
? "website audits (no configured cap)"
|
|
138
|
+
: `website audits (up to ${step.settings.maxAudits})`;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function renderWorkflowPlanStep(step, index) {
|
|
142
|
+
const networkCapabilities = renderNetworkCapabilities(step);
|
|
143
|
+
return [
|
|
144
|
+
`${index + 1}. ${step.id} [${step.state.toUpperCase().replace("-", " ")}]`,
|
|
145
|
+
...(step.reason !== undefined ? [` Reason: ${step.reason}`] : []),
|
|
146
|
+
...(networkCapabilities.length > 0 ? [` Network: ${networkCapabilities.join(", ")}`] : []),
|
|
147
|
+
...(step.inputs.length > 0 ? [` Inputs: ${step.inputs.join(", ")}`] : []),
|
|
148
|
+
...(step.outputs.length > 0 ? [` Outputs: ${step.outputs.join(", ")}`] : [])
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
export function renderWorkflowPlanTerminal(report, configPath) {
|
|
152
|
+
const discovery = report.steps.find((step) => step.id === "discovery");
|
|
153
|
+
const artifactLines = workflowPlanArtifactIds.flatMap((id) => {
|
|
154
|
+
const path = report.artifacts[id];
|
|
155
|
+
return path !== undefined ? [`- ${id}: ${path}`] : [];
|
|
156
|
+
});
|
|
157
|
+
const lines = [
|
|
158
|
+
`Workflow plan: ${report.status.toUpperCase()}`,
|
|
159
|
+
`Config: ${configPath}`,
|
|
160
|
+
...(discovery ? [`Provider: ${discovery.settings.provider}`] : []),
|
|
161
|
+
"",
|
|
162
|
+
"Readiness:",
|
|
163
|
+
...report.preflight.checks.map((check) => `${check.status.toUpperCase().padEnd(5)} ${check.message}`),
|
|
164
|
+
"",
|
|
165
|
+
"Execution plan:",
|
|
166
|
+
...(report.steps.length > 0
|
|
167
|
+
? report.steps.flatMap((step, index) => [
|
|
168
|
+
...renderWorkflowPlanStep(step, index),
|
|
169
|
+
...(index < report.steps.length - 1 ? [""] : [])
|
|
170
|
+
])
|
|
171
|
+
: ["No execution plan is available"]),
|
|
172
|
+
...(artifactLines.length > 0 ? ["", "Artifacts:", ...artifactLines] : [])
|
|
173
|
+
];
|
|
174
|
+
return `${lines.join("\n")}\n`;
|
|
175
|
+
}
|
|
176
|
+
export function renderWorkflowPlanJson(report) {
|
|
177
|
+
return `${JSON.stringify(report, null, 2)}\n`;
|
|
178
|
+
}
|
|
179
|
+
export async function runWorkflowPlan(configPath) {
|
|
180
|
+
return runWorkflowPlanWithDependencies(configPath);
|
|
181
|
+
}
|
|
182
|
+
export async function runWorkflowPlanWithDependencies(configPath, overrides = {}) {
|
|
183
|
+
const dependencies = { ...defaultDependencies, ...overrides };
|
|
184
|
+
return buildPlan(await dependencies.evaluatePreflight(configPath));
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=workflow-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-plan.js","sourceRoot":"","sources":["../src/workflow-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Stats } from "node:fs";
|
|
2
|
+
import type { ResolvedWorkflowConfig, WorkflowManagedPaths } from "./workflow-config.js";
|
|
3
|
+
import type { WorkflowPathInspection } from "./workflow-paths.js";
|
|
4
|
+
export type WorkflowPreflightStatus = "ready" | "blocked";
|
|
5
|
+
export type WorkflowPreflightCheckStatus = "pass" | "warn" | "fail";
|
|
6
|
+
export type WorkflowPreflightStage = "discovery" | "shortlist" | "review" | "packaging";
|
|
7
|
+
export type WorkflowPreflightCheckId = "configuration" | "discovery-input" | "google-api-key" | "review-csv" | "output-access" | "managed-paths";
|
|
8
|
+
export interface WorkflowPreflightCheck {
|
|
9
|
+
id: WorkflowPreflightCheckId;
|
|
10
|
+
status: WorkflowPreflightCheckStatus;
|
|
11
|
+
message: string;
|
|
12
|
+
path?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface WorkflowPreflightReport {
|
|
15
|
+
version: 1;
|
|
16
|
+
status: WorkflowPreflightStatus;
|
|
17
|
+
checks: WorkflowPreflightCheck[];
|
|
18
|
+
provider?: "manual-csv" | "google-places";
|
|
19
|
+
stages?: WorkflowPreflightStage[];
|
|
20
|
+
outputs?: {
|
|
21
|
+
outDir: string;
|
|
22
|
+
} & WorkflowManagedPaths;
|
|
23
|
+
limits?: {
|
|
24
|
+
maxCandidates: number | null;
|
|
25
|
+
maxAudits: number | null;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface WorkflowPreflightEvaluation {
|
|
29
|
+
config?: ResolvedWorkflowConfig;
|
|
30
|
+
report: WorkflowPreflightReport;
|
|
31
|
+
}
|
|
32
|
+
export interface WorkflowPreflightDependencies {
|
|
33
|
+
readWorkflowConfig(configPath: string): Promise<ResolvedWorkflowConfig>;
|
|
34
|
+
resolveGoogleMapsApiKey(): string | undefined;
|
|
35
|
+
lstat(path: string): Promise<Stats>;
|
|
36
|
+
access(path: string, mode?: number): Promise<void>;
|
|
37
|
+
inspectWorkflowManagedPaths(config: ResolvedWorkflowConfig): Promise<WorkflowPathInspection>;
|
|
38
|
+
}
|
|
39
|
+
export declare function renderWorkflowPreflightTerminal(report: WorkflowPreflightReport, configPath: string): string;
|
|
40
|
+
export declare function renderWorkflowPreflightJson(report: WorkflowPreflightReport): string;
|
|
41
|
+
export declare function runWorkflowPreflight(configPath: string): Promise<WorkflowPreflightReport>;
|
|
42
|
+
export declare function runWorkflowPreflightWithDependencies(configPath: string, overrides?: Partial<WorkflowPreflightDependencies>): Promise<WorkflowPreflightReport>;
|
|
43
|
+
export declare function runWorkflowPreflightEvaluationWithDependencies(configPath: string, overrides?: Partial<WorkflowPreflightDependencies>): Promise<WorkflowPreflightEvaluation>;
|