hadara 0.1.0-rc.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/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/agent/evidence.js +50 -0
- package/dist/agent/loop.js +124 -0
- package/dist/cli/args.js +70 -0
- package/dist/cli/dashboard.js +185 -0
- package/dist/cli/debt.js +41 -0
- package/dist/cli/doctor.js +68 -0
- package/dist/cli/errors.js +58 -0
- package/dist/cli/evidence-json.js +75 -0
- package/dist/cli/evidence.js +80 -0
- package/dist/cli/handoff.js +16 -0
- package/dist/cli/harness.js +57 -0
- package/dist/cli/hermes-json.js +31 -0
- package/dist/cli/hermes.js +28 -0
- package/dist/cli/init.js +142 -0
- package/dist/cli/install.js +34 -0
- package/dist/cli/main.js +216 -0
- package/dist/cli/mcp.js +15 -0
- package/dist/cli/package-smoke.js +37 -0
- package/dist/cli/policy-json.js +22 -0
- package/dist/cli/policy.js +43 -0
- package/dist/cli/release-artifact.js +47 -0
- package/dist/cli/release-dry-run.js +24 -0
- package/dist/cli/release-gate.js +28 -0
- package/dist/cli/release-publish.js +41 -0
- package/dist/cli/run-scaffold.js +68 -0
- package/dist/cli/run-state.js +41 -0
- package/dist/cli/run.js +191 -0
- package/dist/cli/smoke.js +58 -0
- package/dist/cli/status-json.js +6 -0
- package/dist/cli/status.js +26 -0
- package/dist/cli/task-json.js +8 -0
- package/dist/cli/task.js +64 -0
- package/dist/cli/tools.js +25 -0
- package/dist/cli/tui.js +72 -0
- package/dist/cli/write-preflight.js +27 -0
- package/dist/core/audit.js +41 -0
- package/dist/core/events.js +63 -0
- package/dist/core/fs.js +44 -0
- package/dist/core/paths.js +59 -0
- package/dist/core/redaction.js +178 -0
- package/dist/core/schema.js +253 -0
- package/dist/core/workspace.js +47 -0
- package/dist/evidence/evidence.js +170 -0
- package/dist/evidence/private-manifest.js +101 -0
- package/dist/handoff/handoff.js +49 -0
- package/dist/harness/replay.js +200 -0
- package/dist/harness/validate.js +465 -0
- package/dist/hermes/context-export.js +104 -0
- package/dist/index.js +29 -0
- package/dist/mcp/server.js +104 -0
- package/dist/mcp/tool-dispatch.js +159 -0
- package/dist/mcp/tool-registry.js +150 -0
- package/dist/mcp/tool-schemas.js +18 -0
- package/dist/policy/command-risk.js +39 -0
- package/dist/policy/permission-matrix.js +42 -0
- package/dist/policy/policy.js +20 -0
- package/dist/policy/preflight.js +47 -0
- package/dist/policy/presets.js +24 -0
- package/dist/policy/tokenizer.js +53 -0
- package/dist/providers/fallback-executor.js +46 -0
- package/dist/providers/mock-provider.js +49 -0
- package/dist/providers/provider-contract.js +2 -0
- package/dist/providers/provider-preparation.js +220 -0
- package/dist/providers/scripted-provider.js +69 -0
- package/dist/schemas/active-run-projection.schema.json +73 -0
- package/dist/schemas/active-run-resume.schema.json +68 -0
- package/dist/schemas/clean-checkout-smoke.schema.json +126 -0
- package/dist/schemas/context-export.schema.json +35 -0
- package/dist/schemas/event.schema.json +17 -0
- package/dist/schemas/evidence-list.schema.json +49 -0
- package/dist/schemas/feature-smoke.schema.json +67 -0
- package/dist/schemas/install-plan.schema.json +93 -0
- package/dist/schemas/package-smoke.schema.json +130 -0
- package/dist/schemas/private-evidence.schema.json +48 -0
- package/dist/schemas/provider-call.schema.json +42 -0
- package/dist/schemas/provider-config.schema.json +43 -0
- package/dist/schemas/release-artifact-manifest.schema.json +55 -0
- package/dist/schemas/release-artifact.schema.json +140 -0
- package/dist/schemas/release-dry-run.schema.json +141 -0
- package/dist/schemas/release-gate.schema.json +42 -0
- package/dist/schemas/release-publish.schema.json +114 -0
- package/dist/schemas/schema-index.json +145 -0
- package/dist/schemas/smoke-evidence-summary.schema.json +88 -0
- package/dist/schemas/tools-list.schema.json +78 -0
- package/dist/schemas/write-preflight.schema.json +47 -0
- package/dist/services/active-run-state.js +215 -0
- package/dist/services/capability-registry.js +540 -0
- package/dist/services/clean-checkout-smoke.js +393 -0
- package/dist/services/evidence-list.js +136 -0
- package/dist/services/feature-smoke.js +155 -0
- package/dist/services/harness-service.js +7 -0
- package/dist/services/install-plan.js +233 -0
- package/dist/services/operational-debt.js +767 -0
- package/dist/services/operations-status-service.js +195 -0
- package/dist/services/package-smoke.js +676 -0
- package/dist/services/policy-service.js +25 -0
- package/dist/services/project-read-model.js +101 -0
- package/dist/services/release-artifact-evidence.js +77 -0
- package/dist/services/release-artifact.js +351 -0
- package/dist/services/release-dry-run.js +253 -0
- package/dist/services/release-evidence.js +138 -0
- package/dist/services/release-publish.js +163 -0
- package/dist/services/smoke-evidence.js +104 -0
- package/dist/services/task-read-model.js +125 -0
- package/dist/services/tools-list.js +26 -0
- package/dist/services/write-preflight.js +240 -0
- package/dist/task/task-capsule.js +121 -0
- package/dist/tools/fake-shell.js +56 -0
- package/dist/tui/cache.js +341 -0
- package/dist/tui/constants.js +44 -0
- package/dist/tui/layout.js +140 -0
- package/dist/tui/markdown.js +238 -0
- package/dist/tui/read-model-worker.js +24 -0
- package/dist/tui/read-model.js +502 -0
- package/dist/tui/snapshot.js +434 -0
- package/dist/tui/state.js +229 -0
- package/dist/tui/terminal.js +475 -0
- package/dist/tui/theme.js +86 -0
- package/package.json +16 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createOpsStatusReport = createOpsStatusReport;
|
|
7
|
+
exports.formatOpsStatusReport = formatOpsStatusReport;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const active_run_state_1 = require("./active-run-state");
|
|
11
|
+
const operational_debt_1 = require("./operational-debt");
|
|
12
|
+
const project_read_model_1 = require("./project-read-model");
|
|
13
|
+
const task_capsule_1 = require("../task/task-capsule");
|
|
14
|
+
function createOpsStatusReport(projectRoot) {
|
|
15
|
+
const sources = (0, project_read_model_1.readProjectSources)(projectRoot);
|
|
16
|
+
const tasks = (0, task_capsule_1.listTaskCapsules)(projectRoot);
|
|
17
|
+
const taskCounts = countTaskStatuses(tasks);
|
|
18
|
+
const handoffSections = {
|
|
19
|
+
currentState: extractListSection(sources.handoff.content, '## Current State'),
|
|
20
|
+
knownProblems: extractListSection(sources.handoff.content, '## Current Known Problems'),
|
|
21
|
+
nextRecommendedStep: extractListSection(sources.handoff.content, '## Next Recommended Step')
|
|
22
|
+
};
|
|
23
|
+
const validation = {
|
|
24
|
+
latestFullCheck: extractValidationLine(sources.handoff.content, 'Latest full check') ?? extractValidationHistoryLine(sources.validationHistory.content, 'Docker check'),
|
|
25
|
+
latestDoneLevelValidation: extractValidationLine(sources.handoff.content, 'Latest done-level validation') ??
|
|
26
|
+
extractValidationHistoryLine(sources.validationHistory.content, 'harness validate')
|
|
27
|
+
};
|
|
28
|
+
const activeRun = (0, active_run_state_1.safeCreateActiveRunProjection)(projectRoot);
|
|
29
|
+
const debt = (0, operational_debt_1.createOperationalDebtReport)(projectRoot);
|
|
30
|
+
const issues = [...collectIssues(sources, validation), ...activeRun.issues];
|
|
31
|
+
return {
|
|
32
|
+
schemaVersion: 'hadara.ops.status.v1',
|
|
33
|
+
command: 'ops.status',
|
|
34
|
+
ok: true,
|
|
35
|
+
health: issues.some((issue) => issue.severity === 'error') ? 'error' : issues.length > 0 ? 'degraded' : 'ok',
|
|
36
|
+
project: {
|
|
37
|
+
branch: readGitBranch(projectRoot),
|
|
38
|
+
phase: extractProjectPhase(sources.projectState.content)
|
|
39
|
+
},
|
|
40
|
+
tasks: {
|
|
41
|
+
counts: taskCounts.counts,
|
|
42
|
+
rawStatusCounts: taskCounts.rawStatusCounts,
|
|
43
|
+
normalizedStatusCounts: taskCounts.normalizedStatusCounts,
|
|
44
|
+
lastCompleted: extractLastCompletedTaskIds(sources.handoff.content),
|
|
45
|
+
nextRecommended: handoffSections.nextRecommendedStep[0] ?? null
|
|
46
|
+
},
|
|
47
|
+
handoff: handoffSections,
|
|
48
|
+
validation,
|
|
49
|
+
activeRun,
|
|
50
|
+
debt: debt.aggregate,
|
|
51
|
+
mcp: {
|
|
52
|
+
defaultMode: 'read-only',
|
|
53
|
+
evidenceAttach: {
|
|
54
|
+
enabledByDefault: false,
|
|
55
|
+
requiresFlag: '--enable-evidence-attach',
|
|
56
|
+
requiresApproval: true,
|
|
57
|
+
audited: true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
issues
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function formatOpsStatusReport(report) {
|
|
64
|
+
const counts = Object.entries(report.tasks.counts)
|
|
65
|
+
.map(([status, count]) => `${status}: ${count}`)
|
|
66
|
+
.join(', ');
|
|
67
|
+
return [
|
|
68
|
+
'[HADARA] Operations Status',
|
|
69
|
+
`phase: ${report.project.phase}`,
|
|
70
|
+
`branch: ${report.project.branch}`,
|
|
71
|
+
`tasks: ${counts}`,
|
|
72
|
+
`debt: open ${report.debt.open}, highOpen ${report.debt.highOpen}`,
|
|
73
|
+
`lastCompleted: ${report.tasks.lastCompleted.join(', ') || 'none'}`,
|
|
74
|
+
`nextRecommended: ${report.tasks.nextRecommended ?? 'none'}`
|
|
75
|
+
].join('\n');
|
|
76
|
+
}
|
|
77
|
+
function readGitBranch(projectRoot) {
|
|
78
|
+
const headPath = node_path_1.default.join(projectRoot, '.git', 'HEAD');
|
|
79
|
+
if (!node_fs_1.default.existsSync(headPath))
|
|
80
|
+
return 'unknown';
|
|
81
|
+
const head = node_fs_1.default.readFileSync(headPath, 'utf8').trim();
|
|
82
|
+
const refPrefix = 'ref: refs/heads/';
|
|
83
|
+
if (head.startsWith(refPrefix))
|
|
84
|
+
return head.slice(refPrefix.length);
|
|
85
|
+
return head.length > 0 ? 'detached' : 'unknown';
|
|
86
|
+
}
|
|
87
|
+
function extractProjectPhase(projectState) {
|
|
88
|
+
const section = (0, project_read_model_1.extractSection)(projectState, '## Current Phase');
|
|
89
|
+
const line = section
|
|
90
|
+
.split(/\r?\n/)
|
|
91
|
+
.map((value) => value.trim())
|
|
92
|
+
.find(Boolean);
|
|
93
|
+
if (!line)
|
|
94
|
+
return 'unknown';
|
|
95
|
+
const explicit = line.match(/^Phase:\s*(.+)$/i);
|
|
96
|
+
if (explicit)
|
|
97
|
+
return explicit[1].trim();
|
|
98
|
+
if (/Phase 0\s*\/\s*Phase 1 boundary/i.test(line))
|
|
99
|
+
return 'bootstrap-development';
|
|
100
|
+
return line;
|
|
101
|
+
}
|
|
102
|
+
function countTaskStatuses(tasks) {
|
|
103
|
+
const counts = {
|
|
104
|
+
done: 0,
|
|
105
|
+
draft: 0,
|
|
106
|
+
partial: 0,
|
|
107
|
+
superseded: 0,
|
|
108
|
+
inProgress: 0,
|
|
109
|
+
unknown: 0
|
|
110
|
+
};
|
|
111
|
+
const rawStatusCounts = {};
|
|
112
|
+
const normalizedStatusCounts = {};
|
|
113
|
+
for (const task of tasks) {
|
|
114
|
+
const rawStatus = readTaskStatus(task);
|
|
115
|
+
const normalizedStatus = normalizeStatus(rawStatus);
|
|
116
|
+
const aggregate = aggregateStatus(normalizedStatus);
|
|
117
|
+
counts[aggregate] += 1;
|
|
118
|
+
rawStatusCounts[rawStatus] = (rawStatusCounts[rawStatus] ?? 0) + 1;
|
|
119
|
+
normalizedStatusCounts[normalizedStatus] = (normalizedStatusCounts[normalizedStatus] ?? 0) + 1;
|
|
120
|
+
}
|
|
121
|
+
return { counts, rawStatusCounts, normalizedStatusCounts };
|
|
122
|
+
}
|
|
123
|
+
function readTaskStatus(task) {
|
|
124
|
+
const taskPath = node_path_1.default.join(task.dir, 'TASK.md');
|
|
125
|
+
if (!node_fs_1.default.existsSync(taskPath))
|
|
126
|
+
return 'Unknown';
|
|
127
|
+
const content = node_fs_1.default.readFileSync(taskPath, 'utf8');
|
|
128
|
+
const match = content.match(/^## Status\s*\n+([\s\S]*?)(?:\n## |\s*$)/m);
|
|
129
|
+
return match?.[1]?.trim().split(/\r?\n/)[0]?.trim() || 'Unknown';
|
|
130
|
+
}
|
|
131
|
+
function normalizeStatus(status) {
|
|
132
|
+
const value = status.trim().toLowerCase().replace(/[\s_-]+(.)/g, (_match, letter) => letter.toUpperCase());
|
|
133
|
+
return value || 'unknown';
|
|
134
|
+
}
|
|
135
|
+
function aggregateStatus(status) {
|
|
136
|
+
if (status === 'done')
|
|
137
|
+
return 'done';
|
|
138
|
+
if (status === 'draft')
|
|
139
|
+
return 'draft';
|
|
140
|
+
if (status === 'partial')
|
|
141
|
+
return 'partial';
|
|
142
|
+
if (status === 'superseded')
|
|
143
|
+
return 'superseded';
|
|
144
|
+
if (status === 'inProgress' || status === 'active' || status === 'doing')
|
|
145
|
+
return 'inProgress';
|
|
146
|
+
return 'unknown';
|
|
147
|
+
}
|
|
148
|
+
function extractLastCompletedTaskIds(handoff) {
|
|
149
|
+
return extractListSection(handoff, '## Last 3 Completed Tasks')
|
|
150
|
+
.map((line) => line.match(/^(T-\d{4})\b/)?.[1])
|
|
151
|
+
.filter((value) => Boolean(value));
|
|
152
|
+
}
|
|
153
|
+
function extractValidationLine(handoff, label) {
|
|
154
|
+
const validation = extractListSection(handoff, '## Validation Baseline');
|
|
155
|
+
const prefix = `${label}:`;
|
|
156
|
+
const line = validation.find((item) => item.startsWith(prefix));
|
|
157
|
+
return line ? line.slice(prefix.length).trim().replace(/\.$/, '') : null;
|
|
158
|
+
}
|
|
159
|
+
function extractValidationHistoryLine(validationHistory, pattern) {
|
|
160
|
+
const lines = validationHistory
|
|
161
|
+
.split(/\r?\n/)
|
|
162
|
+
.map((line) => line.trim().replace(/^[-*]\s+/, ''))
|
|
163
|
+
.filter((line) => line.includes(pattern));
|
|
164
|
+
return lines.at(-1)?.replace(/\.$/, '') ?? null;
|
|
165
|
+
}
|
|
166
|
+
function collectIssues(sources, validation) {
|
|
167
|
+
const issues = [];
|
|
168
|
+
if (!sources.projectState.exists)
|
|
169
|
+
issues.push(warning('PROJECT_STATE_MISSING', 'docs/PROJECT_STATE.md is missing.'));
|
|
170
|
+
if (!sources.handoff.exists)
|
|
171
|
+
issues.push(warning('AGENT_HANDOFF_MISSING', 'docs/AGENT_HANDOFF.md is missing.'));
|
|
172
|
+
if (!sources.taskBoard.exists)
|
|
173
|
+
issues.push(warning('TASK_BOARD_MISSING', 'docs/TASK_BOARD.md is missing.'));
|
|
174
|
+
if (!sources.developmentSlices.exists)
|
|
175
|
+
issues.push(warning('DEVELOPMENT_SLICES_MISSING', 'docs/DEVELOPMENT_SLICES.md is missing.'));
|
|
176
|
+
if (!validation.latestFullCheck && !validation.latestDoneLevelValidation) {
|
|
177
|
+
issues.push(warning('VALIDATION_BASELINE_MISSING', 'No latest validation baseline was found in handoff or validation history.'));
|
|
178
|
+
}
|
|
179
|
+
return issues;
|
|
180
|
+
}
|
|
181
|
+
function warning(code, message) {
|
|
182
|
+
return {
|
|
183
|
+
severity: 'warning',
|
|
184
|
+
code,
|
|
185
|
+
message
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function extractListSection(content, heading) {
|
|
189
|
+
return (0, project_read_model_1.extractSection)(content, heading)
|
|
190
|
+
.split(/\r?\n/)
|
|
191
|
+
.map((line) => line.trim())
|
|
192
|
+
.filter(Boolean)
|
|
193
|
+
.map((line) => line.replace(/^[-*]\s+/, '').replace(/^\d+\.\s+/, '').trim())
|
|
194
|
+
.filter(Boolean);
|
|
195
|
+
}
|