@jakkrichm/create-nexus-devflow 2.0.15 → 2.0.18

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.
Files changed (82) hide show
  1. package/dist/bin/create-nexus-devflow.d.ts +15 -1
  2. package/dist/bin/create-nexus-devflow.js +125 -9
  3. package/dist/bin/create-nexus-devflow.js.map +1 -1
  4. package/dist/lib/current-work.d.ts +29 -0
  5. package/dist/lib/current-work.js +235 -0
  6. package/dist/lib/current-work.js.map +1 -0
  7. package/dist/lib/findings.d.ts +26 -0
  8. package/dist/lib/findings.js +110 -0
  9. package/dist/lib/findings.js.map +1 -0
  10. package/dist/lib/git-status.d.ts +13 -0
  11. package/dist/lib/git-status.js +98 -0
  12. package/dist/lib/git-status.js.map +1 -0
  13. package/dist/lib/project-metadata.d.ts +22 -0
  14. package/dist/lib/project-metadata.js +84 -0
  15. package/dist/lib/project-metadata.js.map +1 -0
  16. package/dist/lib/project-root.d.ts +3 -0
  17. package/dist/lib/project-root.js +76 -0
  18. package/dist/lib/project-root.js.map +1 -0
  19. package/dist/lib/status.d.ts +62 -0
  20. package/dist/lib/status.js +273 -0
  21. package/dist/lib/status.js.map +1 -0
  22. package/dist/lib/uninstall.d.ts +20 -0
  23. package/dist/lib/uninstall.js +129 -0
  24. package/dist/lib/uninstall.js.map +1 -0
  25. package/dist/scripts/prepare-template.js +120 -10
  26. package/dist/scripts/prepare-template.js.map +1 -1
  27. package/package.json +4 -3
  28. package/template/.agents/skills/00-discover/SKILL.md +2 -2
  29. package/template/.agents/skills/10-define/SKILL.md +24 -140
  30. package/template/.agents/skills/20-spec/SKILL.md +2 -2
  31. package/template/.agents/skills/30-plan/SKILL.md +2 -2
  32. package/template/.agents/skills/50-verify/SKILL.md +2 -2
  33. package/template/.agents/skills/60-report/SKILL.md +1 -1
  34. package/template/.agents/skills/70-release/SKILL.md +19 -143
  35. package/template/.agents/skills/check/SKILL.md +10 -10
  36. package/template/.agents/skills/ci/SKILL.md +1 -1
  37. package/template/.agents/skills/complete/SKILL.md +49 -28
  38. package/template/.agents/skills/deploy/SKILL.md +1 -1
  39. package/template/.agents/skills/devflow/SKILL.md +5 -5
  40. package/template/.agents/skills/feature/SKILL.md +25 -20
  41. package/template/.agents/skills/fix/SKILL.md +25 -19
  42. package/template/.agents/skills/implement/SKILL.md +10 -10
  43. package/template/.agents/skills/insight/SKILL.md +1 -1
  44. package/template/.agents/skills/overview/SKILL.md +3 -3
  45. package/template/.agents/skills/report-html/SKILL.md +3 -3
  46. package/template/.agents/skills/security-review/SKILL.md +1 -1
  47. package/template/.agents/skills/spec/SKILL.md +7 -6
  48. package/template/.agents/skills/spec-driven-development/SKILL.md +2 -2
  49. package/template/.agents/skills/test/SKILL.md +1 -1
  50. package/template/.claude/skills/00-discover/SKILL.md +2 -2
  51. package/template/.claude/skills/10-define/SKILL.md +24 -140
  52. package/template/.claude/skills/20-spec/SKILL.md +2 -2
  53. package/template/.claude/skills/30-plan/SKILL.md +2 -2
  54. package/template/.claude/skills/50-verify/SKILL.md +2 -2
  55. package/template/.claude/skills/60-report/SKILL.md +1 -1
  56. package/template/.claude/skills/70-release/SKILL.md +19 -143
  57. package/template/.claude/skills/check/SKILL.md +10 -10
  58. package/template/.claude/skills/ci/SKILL.md +1 -1
  59. package/template/.claude/skills/complete/SKILL.md +49 -28
  60. package/template/.claude/skills/deploy/SKILL.md +1 -1
  61. package/template/.claude/skills/devflow/SKILL.md +5 -5
  62. package/template/.claude/skills/feature/SKILL.md +25 -20
  63. package/template/.claude/skills/fix/SKILL.md +25 -19
  64. package/template/.claude/skills/implement/SKILL.md +10 -10
  65. package/template/.claude/skills/insight/SKILL.md +1 -1
  66. package/template/.claude/skills/overview/SKILL.md +3 -3
  67. package/template/.claude/skills/report-html/SKILL.md +3 -3
  68. package/template/.claude/skills/security-review/SKILL.md +1 -1
  69. package/template/.claude/skills/spec/SKILL.md +7 -6
  70. package/template/.claude/skills/spec-driven-development/SKILL.md +2 -2
  71. package/template/.claude/skills/test/SKILL.md +1 -1
  72. package/template/AGENTS.md +15 -59
  73. package/template/devflow/context/ai-interaction.md +110 -23
  74. package/template/devflow/context/coding-standards.md +123 -32
  75. package/template/devflow/context/current-feature.md +3 -0
  76. package/template/devflow/context/current-stage.md +6 -6
  77. package/template/devflow/context/findings.md +10 -10
  78. package/template/devflow/context/project-overview.md +18 -32
  79. package/template/devflow/history/HISTORY.md +10 -24
  80. package/template/devflow/ideas.md +9 -5
  81. package/template/devflow/reference/running-id-contract.md +39 -39
  82. package/template/devflow/runs/.gitkeep +0 -0
@@ -0,0 +1,110 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ const DEVFLOW_FINDINGS_PATH = path.join("devflow", "context", "findings.md");
4
+ const BLUEPRINT_FINDINGS_PATH = path.join("blueprint", "context", "findings.md");
5
+ const FINDING_PATTERN = /^###\s+(\S+)\s+\[(P[0-3])\]\s+(unverified|open|fixed|closed|accepted|invalid)\s+-\s+(.+?)\s*$/i;
6
+ async function readFindings(projectRoot) {
7
+ let findingsPath = path.join(projectRoot, DEVFLOW_FINDINGS_PATH);
8
+ try {
9
+ let stats = await fs.lstat(findingsPath);
10
+ if (!stats.isFile()) {
11
+ const altPath = path.join(projectRoot, BLUEPRINT_FINDINGS_PATH);
12
+ const altStats = await fs.lstat(altPath).catch(() => null);
13
+ if (altStats?.isFile()) {
14
+ findingsPath = altPath;
15
+ stats = altStats;
16
+ }
17
+ }
18
+ if (stats.isSymbolicLink()) {
19
+ return emptySummary({
20
+ code: "unsafe_findings_path",
21
+ message: "Findings file is a symbolic link and was not read."
22
+ });
23
+ }
24
+ if (!stats.isFile()) {
25
+ return emptySummary({
26
+ code: "invalid_findings_path",
27
+ message: "Findings path is not a regular file."
28
+ });
29
+ }
30
+ return parseFindings(await fs.readFile(findingsPath, "utf8"));
31
+ }
32
+ catch (error) {
33
+ if (getErrorCode(error) === "ENOENT") {
34
+ try {
35
+ const altPath = path.join(projectRoot, BLUEPRINT_FINDINGS_PATH);
36
+ const altContent = await fs.readFile(altPath, "utf8");
37
+ return parseFindings(altContent);
38
+ }
39
+ catch {
40
+ return emptySummary();
41
+ }
42
+ }
43
+ throw error;
44
+ }
45
+ }
46
+ function parseFindings(markdown) {
47
+ const items = [];
48
+ let malformed = false;
49
+ for (const [index, line] of markdown.split(/\r?\n/).entries()) {
50
+ const match = line.match(FINDING_PATTERN);
51
+ if (match) {
52
+ items.push({
53
+ id: match[1] || "",
54
+ severity: (match[2] || "").toUpperCase(),
55
+ status: (match[3] || "").toLowerCase(),
56
+ title: (match[4] || "").trim(),
57
+ line: index + 1
58
+ });
59
+ }
60
+ else if (/^###\s+\S+\s+\[P/i.test(line)) {
61
+ malformed = true;
62
+ }
63
+ }
64
+ const byStatus = createStatusCounts();
65
+ for (const finding of items) {
66
+ byStatus[finding.status] += 1;
67
+ }
68
+ return {
69
+ items,
70
+ total: items.length,
71
+ byStatus,
72
+ blockers: items.filter((finding) => (finding.severity === "P0" || finding.severity === "P1") &&
73
+ (finding.status === "open" || finding.status === "fixed")),
74
+ warnings: malformed
75
+ ? [{
76
+ code: "malformed_findings",
77
+ message: "One or more finding headings do not match the required ledger format."
78
+ }]
79
+ : []
80
+ };
81
+ }
82
+ function createStatusCounts() {
83
+ return {
84
+ unverified: 0,
85
+ open: 0,
86
+ fixed: 0,
87
+ closed: 0,
88
+ accepted: 0,
89
+ invalid: 0
90
+ };
91
+ }
92
+ function emptySummary(warning) {
93
+ return {
94
+ items: [],
95
+ total: 0,
96
+ byStatus: createStatusCounts(),
97
+ blockers: [],
98
+ warnings: warning ? [warning] : []
99
+ };
100
+ }
101
+ function getErrorCode(error) {
102
+ return typeof error === "object" &&
103
+ error !== null &&
104
+ "code" in error &&
105
+ typeof error.code === "string"
106
+ ? error.code
107
+ : undefined;
108
+ }
109
+ export { DEVFLOW_FINDINGS_PATH, parseFindings, readFindings };
110
+ //# sourceMappingURL=findings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findings.js","sourceRoot":"","sources":["../../lib/findings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ interface GitStatusSummary {
2
+ available: boolean;
3
+ branch: string | null;
4
+ clean: boolean | null;
5
+ changedFiles: number;
6
+ lastCommit: string | null;
7
+ upstream: string | null;
8
+ ahead: number | null;
9
+ behind: number | null;
10
+ }
11
+ declare function readGitStatus(projectRoot: string): Promise<GitStatusSummary>;
12
+ export { readGitStatus };
13
+ export type { GitStatusSummary };
@@ -0,0 +1,98 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ async function readGitStatus(projectRoot) {
5
+ if (!(await isGitRepository(projectRoot))) {
6
+ return unavailableSummary();
7
+ }
8
+ const porcelain = await runGit(projectRoot, [
9
+ "status",
10
+ "--porcelain=v1",
11
+ "--untracked-files=all"
12
+ ]);
13
+ const changedFiles = porcelain
14
+ .split(/\r?\n/)
15
+ .filter((line) => line.length > 0)
16
+ .length;
17
+ const branch = await readBranch(projectRoot);
18
+ const lastCommit = await runOptionalGit(projectRoot, [
19
+ "log",
20
+ "-1",
21
+ "--format=%s"
22
+ ]);
23
+ const upstream = await runOptionalGit(projectRoot, [
24
+ "rev-parse",
25
+ "--abbrev-ref",
26
+ "--symbolic-full-name",
27
+ "@{upstream}"
28
+ ]);
29
+ const divergence = upstream
30
+ ? await readDivergence(projectRoot)
31
+ : { ahead: null, behind: null };
32
+ return {
33
+ available: true,
34
+ branch,
35
+ clean: changedFiles === 0,
36
+ changedFiles,
37
+ lastCommit,
38
+ upstream,
39
+ ahead: divergence.ahead,
40
+ behind: divergence.behind
41
+ };
42
+ }
43
+ async function isGitRepository(projectRoot) {
44
+ return (await runOptionalGit(projectRoot, [
45
+ "rev-parse",
46
+ "--is-inside-work-tree"
47
+ ])) === "true";
48
+ }
49
+ async function readBranch(projectRoot) {
50
+ const branch = await runOptionalGit(projectRoot, [
51
+ "symbolic-ref",
52
+ "--quiet",
53
+ "--short",
54
+ "HEAD"
55
+ ]);
56
+ return branch || "(detached HEAD)";
57
+ }
58
+ async function readDivergence(projectRoot) {
59
+ const counts = await runOptionalGit(projectRoot, [
60
+ "rev-list",
61
+ "--left-right",
62
+ "--count",
63
+ "HEAD...@{upstream}"
64
+ ]);
65
+ const match = counts?.match(/^(\d+)\s+(\d+)$/);
66
+ return match
67
+ ? { ahead: Number(match[1]), behind: Number(match[2]) }
68
+ : { ahead: null, behind: null };
69
+ }
70
+ async function runOptionalGit(projectRoot, args) {
71
+ try {
72
+ return await runGit(projectRoot, args);
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ async function runGit(projectRoot, args) {
79
+ const result = await execFileAsync("git", ["-C", projectRoot, ...args], {
80
+ encoding: "utf8",
81
+ maxBuffer: 1024 * 1024
82
+ });
83
+ return result.stdout.trim();
84
+ }
85
+ function unavailableSummary() {
86
+ return {
87
+ available: false,
88
+ branch: null,
89
+ clean: null,
90
+ changedFiles: 0,
91
+ lastCommit: null,
92
+ upstream: null,
93
+ ahead: null,
94
+ behind: null
95
+ };
96
+ }
97
+ export { readGitStatus };
98
+ //# sourceMappingURL=git-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-status.js","sourceRoot":"","sources":["../../lib/git-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ declare const PROJECT_STATE_SCHEMA_VERSION: 1;
2
+ type ProjectAdapter = "codex" | "claude" | "antigravity";
3
+ interface ProjectWarning {
4
+ code: "invalid_manifest";
5
+ message: string;
6
+ }
7
+ interface ProjectMetadata {
8
+ schemaVersion: typeof PROJECT_STATE_SCHEMA_VERSION;
9
+ project: {
10
+ name: string;
11
+ root: string;
12
+ };
13
+ devflow: {
14
+ version: string | null;
15
+ adapters: ProjectAdapter[];
16
+ };
17
+ warnings: ProjectWarning[];
18
+ }
19
+ declare function readProjectMetadata(startPath?: string): Promise<ProjectMetadata>;
20
+ declare function detectAdapters(projectRoot: string): Promise<ProjectAdapter[]>;
21
+ export { PROJECT_STATE_SCHEMA_VERSION, detectAdapters, readProjectMetadata };
22
+ export type { ProjectAdapter, ProjectMetadata, ProjectWarning };
@@ -0,0 +1,84 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { findProjectRoot } from "./project-root.js";
4
+ import { readManifest } from "./update.js";
5
+ const PROJECT_STATE_SCHEMA_VERSION = 1;
6
+ const ADAPTER_PATHS = {
7
+ codex: path.join(".agents", "skills"),
8
+ claude: path.join(".claude", "skills"),
9
+ antigravity: path.join(".agents", "skills")
10
+ };
11
+ async function readProjectMetadata(startPath = process.cwd()) {
12
+ const projectRoot = await findProjectRoot(startPath);
13
+ if (!projectRoot) {
14
+ throw new Error(`No Nexus-DevFlow project found from: ${path.resolve(startPath)}`);
15
+ }
16
+ const warnings = [];
17
+ let manifest = null;
18
+ try {
19
+ manifest = await readManifest(projectRoot);
20
+ }
21
+ catch (error) {
22
+ warnings.push({
23
+ code: "invalid_manifest",
24
+ message: error instanceof Error ? error.message : String(error)
25
+ });
26
+ }
27
+ let projectVersion = manifest?.version || null;
28
+ if (!projectVersion) {
29
+ try {
30
+ const packageJsonPath = path.join(projectRoot, "package.json");
31
+ const packageContent = await fs.readFile(packageJsonPath, "utf8");
32
+ const pkg = JSON.parse(packageContent);
33
+ if (pkg.version) {
34
+ projectVersion = pkg.version;
35
+ }
36
+ }
37
+ catch {
38
+ // Ignore fallback failure
39
+ }
40
+ }
41
+ return {
42
+ schemaVersion: PROJECT_STATE_SCHEMA_VERSION,
43
+ project: {
44
+ name: path.basename(projectRoot),
45
+ root: projectRoot
46
+ },
47
+ devflow: {
48
+ version: projectVersion,
49
+ adapters: await detectAdapters(projectRoot)
50
+ },
51
+ warnings
52
+ };
53
+ }
54
+ async function detectAdapters(projectRoot) {
55
+ const adapters = [];
56
+ for (const adapter of ["codex", "claude"]) {
57
+ if (await isDirectory(path.join(projectRoot, ADAPTER_PATHS[adapter]))) {
58
+ adapters.push(adapter);
59
+ }
60
+ }
61
+ return adapters;
62
+ }
63
+ async function isDirectory(targetPath) {
64
+ try {
65
+ return (await fs.lstat(targetPath)).isDirectory();
66
+ }
67
+ catch (error) {
68
+ const code = getErrorCode(error);
69
+ if (code === "ENOENT" || code === "ENOTDIR") {
70
+ return false;
71
+ }
72
+ throw error;
73
+ }
74
+ }
75
+ function getErrorCode(error) {
76
+ return typeof error === "object" &&
77
+ error !== null &&
78
+ "code" in error &&
79
+ typeof error.code === "string"
80
+ ? error.code
81
+ : undefined;
82
+ }
83
+ export { PROJECT_STATE_SCHEMA_VERSION, detectAdapters, readProjectMetadata };
84
+ //# sourceMappingURL=project-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-metadata.js","sourceRoot":"","sources":["../../lib/project-metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare function findProjectRoot(startPath?: string): Promise<string | null>;
2
+ declare function isDevFlowProjectRoot(directory: string): Promise<boolean>;
3
+ export { findProjectRoot, isDevFlowProjectRoot };
@@ -0,0 +1,76 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ const DEVFLOW_MANIFEST_PATH = path.join("devflow", ".state", "manifest.json");
4
+ const BLUEPRINT_MANIFEST_PATH = path.join("blueprint", ".state", "manifest.json");
5
+ async function findProjectRoot(startPath = process.cwd()) {
6
+ const resolvedStart = await fs.realpath(startPath);
7
+ const stats = await fs.stat(resolvedStart);
8
+ let currentDir = stats.isDirectory()
9
+ ? resolvedStart
10
+ : path.dirname(resolvedStart);
11
+ while (true) {
12
+ if (await isDevFlowProjectRoot(currentDir)) {
13
+ return currentDir;
14
+ }
15
+ const parentDir = path.dirname(currentDir);
16
+ if (parentDir === currentDir) {
17
+ return null;
18
+ }
19
+ currentDir = parentDir;
20
+ }
21
+ }
22
+ async function isDevFlowProjectRoot(directory) {
23
+ const devflowDir = path.join(directory, "devflow");
24
+ const blueprintDir = path.join(directory, "blueprint");
25
+ const hasDevFlowDir = await isDirectory(devflowDir);
26
+ const hasBlueprintDir = await isDirectory(blueprintDir);
27
+ if (!hasDevFlowDir && !hasBlueprintDir) {
28
+ return false;
29
+ }
30
+ return ((await hasInstallManifest(directory)) ||
31
+ (await isFile(path.join(directory, "AGENTS.md"))));
32
+ }
33
+ async function hasInstallManifest(directory) {
34
+ const devflowStateDir = path.join(directory, "devflow", ".state");
35
+ const blueprintStateDir = path.join(directory, "blueprint", ".state");
36
+ if ((await isDirectory(devflowStateDir)) &&
37
+ (await isFile(path.join(directory, DEVFLOW_MANIFEST_PATH)))) {
38
+ return true;
39
+ }
40
+ return ((await isDirectory(blueprintStateDir)) &&
41
+ (await isFile(path.join(directory, BLUEPRINT_MANIFEST_PATH))));
42
+ }
43
+ async function isDirectory(targetPath) {
44
+ try {
45
+ return (await fs.lstat(targetPath)).isDirectory();
46
+ }
47
+ catch (error) {
48
+ const code = getErrorCode(error);
49
+ if (code === "ENOENT" || code === "ENOTDIR") {
50
+ return false;
51
+ }
52
+ throw error;
53
+ }
54
+ }
55
+ async function isFile(targetPath) {
56
+ try {
57
+ return (await fs.lstat(targetPath)).isFile();
58
+ }
59
+ catch (error) {
60
+ const code = getErrorCode(error);
61
+ if (code === "ENOENT" || code === "ENOTDIR") {
62
+ return false;
63
+ }
64
+ throw error;
65
+ }
66
+ }
67
+ function getErrorCode(error) {
68
+ return typeof error === "object" &&
69
+ error !== null &&
70
+ "code" in error &&
71
+ typeof error.code === "string"
72
+ ? error.code
73
+ : undefined;
74
+ }
75
+ export { findProjectRoot, isDevFlowProjectRoot };
76
+ //# sourceMappingURL=project-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-root.js","sourceRoot":"","sources":["../../lib/project-root.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { CurrentWorkSummary, CurrentWorkType } from "./current-work.js";
2
+ import type { Finding, FindingStatus } from "./findings.js";
3
+ import type { GitStatusSummary } from "./git-status.js";
4
+ import type { ProjectAdapter } from "./project-metadata.js";
5
+ type CompletionState = "blocked" | "needs_verification" | "ready";
6
+ interface StatusWarning {
7
+ code: string;
8
+ message: string;
9
+ }
10
+ interface StatusCurrentWork {
11
+ state: CurrentWorkSummary["state"];
12
+ type: CurrentWorkType | null;
13
+ title: string | null;
14
+ status: string | null;
15
+ runId: string | null;
16
+ completed: number;
17
+ remaining: number;
18
+ total: number;
19
+ nextStep: {
20
+ title: string;
21
+ } | null;
22
+ }
23
+ interface StatusFindings {
24
+ total: number;
25
+ byStatus: Record<FindingStatus, number>;
26
+ active: Array<Pick<Finding, "id" | "severity" | "status" | "title">>;
27
+ blockers: Array<Pick<Finding, "id" | "severity" | "status" | "title">>;
28
+ }
29
+ interface StatusNextAction {
30
+ command: string | null;
31
+ reason: string;
32
+ }
33
+ interface StatusCompletion {
34
+ state: CompletionState;
35
+ blockers: string[];
36
+ }
37
+ interface HumanStatusOptions {
38
+ color?: boolean;
39
+ }
40
+ interface ProjectStatus {
41
+ schemaVersion: 1;
42
+ health: "ok" | "warning";
43
+ project: {
44
+ name: string;
45
+ root: string;
46
+ };
47
+ devflow: {
48
+ version: string | null;
49
+ adapters: ProjectAdapter[];
50
+ };
51
+ currentWork: StatusCurrentWork;
52
+ findings: StatusFindings;
53
+ git: GitStatusSummary;
54
+ completion: StatusCompletion;
55
+ nextAction: StatusNextAction;
56
+ warnings: StatusWarning[];
57
+ }
58
+ declare function readProjectStatus(startPath?: string): Promise<ProjectStatus>;
59
+ declare function formatHumanStatus(status: ProjectStatus, options?: HumanStatusOptions): string;
60
+ declare function shouldUseColor(isTTY?: boolean | undefined, environment?: NodeJS.ProcessEnv): boolean;
61
+ export { formatHumanStatus, readProjectStatus, shouldUseColor };
62
+ export type { CompletionState, HumanStatusOptions, ProjectStatus, StatusCompletion, StatusCurrentWork, StatusFindings, StatusNextAction, StatusWarning };