@khoavu882/doflow 2.0.0-beta.4 → 2.0.0-beta.5
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/core/.antigravity-plugin/plugin.json +0 -1
- package/core/.claude-plugin/plugin.json +1 -1
- package/core/.codex-plugin/plugin.json +1 -1
- package/core/.plugin/plugin.json +1 -1
- package/core/harnesses/claude/hooks/mcp-tool-guard.sh +7 -17
- package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
- package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
- package/core/harnesses/claude/hooks/session-start.sh +5 -3
- package/core/harnesses/claude/hooks/stop-check.sh +5 -3
- package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
- package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
- package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
- package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
- package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
- package/core/harnesses/codex/hooks/session-start.sh +5 -3
- package/core/harnesses/codex/hooks/stop-check.sh +6 -5
- package/core/harnesses/codex/hooks/subagent-audit.sh +17 -6
- package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
- package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +7 -18
- package/core/harnesses/gemini/hooks/pre-bash-guard.sh +7 -18
- package/core/harnesses/gemini/hooks/pre-implement-gate.sh +7 -19
- package/core/harnesses/gemini/hooks/session-start.sh +5 -3
- package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +20 -5
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +20 -5
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +20 -5
- package/core/harnesses/kiro/hooks/session-start.sh +11 -5
- package/core/harnesses/kiro/hooks/stop-check.sh +21 -30
- package/core/harnesses/pi/extensions/doflow-guard.js +159 -0
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -11
- package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
- package/core/harnesses/shared/hooks/bridge/bridge.sh +184 -0
- package/core/harnesses/shared/hooks/bridge/envelope.jq +60 -0
- package/core/harnesses/shared/hooks/bridge/respond.sh +62 -0
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +4 -2
- package/core/harnesses/shared/hooks/policies/contract.sh +75 -0
- package/core/harnesses/shared/hooks/policies/deny-json.sh +39 -4
- package/core/harnesses/shared/hooks/policies/lib.sh +4 -2
- package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +46 -34
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +75 -25
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +67 -73
- package/core/harnesses/shared/hooks/policies/session-context.sh +37 -7
- package/core/harnesses/shared/hooks/policies/stop-check.sh +42 -15
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +35 -5
- package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +40 -7
- package/core/harnesses/shared/hooks/stream-hook-runner.js +69 -181
- package/core/registry/assets.json +19 -0
- package/core/registry/contracts.json +2 -2
- package/core/registry/harnesses.json +196 -10
- package/core/registry/lifecycle.json +2626 -7
- package/core/registry/storage.json +24 -1
- package/core/shared/scripts/doflow/bin/doflow-run +10 -6
- package/core/shared/skills/do-design/SKILL.md +6 -6
- package/core/shared/skills/do-execute-plan/SKILL.md +11 -10
- package/core/shared/skills/do-execute-plan/references/readiness_gate.md +2 -0
- package/core/shared/skills/do-implement/SKILL.md +3 -2
- package/core/shared/skills/do-plan/SKILL.md +7 -8
- package/package.json +1 -1
- package/src/adapters/antigravity/index.js +83 -47
- package/src/adapters/claude/index.js +15 -1
- package/src/adapters/codex/hooks.js +40 -5
- package/src/adapters/codex/index.js +52 -9
- package/src/adapters/copy-tree.js +4 -4
- package/src/adapters/gemini/hooks.js +57 -16
- package/src/adapters/gemini/index.js +57 -18
- package/src/adapters/kiro/index.js +15 -1
- package/src/adapters/pi/hooks.js +119 -0
- package/src/adapters/pi/index.js +34 -9
- package/src/cli/commands/install.js +1 -1
- package/src/cli/commands/update.js +1 -1
- package/src/cli/index.js +17 -5
- package/src/cli/runtime-commands.js +51 -12
- package/src/lifecycle/coverage.js +57 -0
- package/src/lifecycle/hook-step.js +61 -0
- package/src/lifecycle/index.js +28 -14
- package/src/registry/index.js +136 -7
- package/src/runtime/candidate.js +505 -0
- package/src/runtime/claims.js +14 -5
- package/src/runtime/cli-result.js +11 -4
- package/src/runtime/cli.js +35 -268
- package/src/runtime/context/budget.js +203 -0
- package/src/runtime/context/compose.js +1367 -0
- package/src/runtime/context/delivery-store.js +102 -0
- package/src/runtime/context/mandatory.js +594 -0
- package/src/runtime/context/pointer.js +142 -0
- package/src/runtime/context-pack.js +1029 -244
- package/src/runtime/evidence-fields.js +39 -0
- package/src/runtime/evidence-ledger.js +7 -0
- package/src/runtime/freshness.js +44 -7
- package/src/runtime/outcome.js +1 -1
- package/src/runtime/readiness.js +83 -13
- package/src/runtime/retrieval-plan.js +422 -73
- package/src/runtime/retrieval-record.js +223 -0
- package/src/runtime/scaffold/artifacts.js +3 -0
- package/src/runtime/source-version.js +289 -0
- package/src/runtime/task-attempts.js +1 -1
- package/src/runtime/task-scope.js +28 -3
- package/src/runtime/task-state.js +72 -7
- package/core/.antigravity-plugin/hooks.json +0 -39
- package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
- package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
- package/core/harnesses/shared/hooks/hooks.json +0 -47
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// TypeScript migration: run directly by Node native type-stripping.
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
const crypto = require('node:crypto');
|
|
7
|
+
|
|
8
|
+
function sha256(text ) {
|
|
9
|
+
return `sha256:${crypto.createHash('sha256').update(text, 'utf8').digest('hex')}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function inside(root , file , fsImpl = fs) {
|
|
13
|
+
const absolute = path.resolve(file);
|
|
14
|
+
let realRoot ;
|
|
15
|
+
let realFile ;
|
|
16
|
+
try {
|
|
17
|
+
realRoot = fsImpl.realpathSync(path.resolve(root));
|
|
18
|
+
realFile = fsImpl.realpathSync(absolute);
|
|
19
|
+
} catch { return null; }
|
|
20
|
+
const relative = path.relative(realRoot, realFile);
|
|
21
|
+
if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) return null;
|
|
22
|
+
const normalized = relative.split(path.sep).join('/');
|
|
23
|
+
if (normalized.split('/').includes('state')) return null;
|
|
24
|
+
return normalized;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function lineSlice(lines , startLine , endLine ) {
|
|
28
|
+
return lines.slice(startLine - 1, endLine).join('\n') + '\n';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function rangesFor(file , text , requirement ) {
|
|
32
|
+
const lines = text.split(/\r?\n/);
|
|
33
|
+
const result = [];
|
|
34
|
+
if (requirement) {
|
|
35
|
+
let section = '';
|
|
36
|
+
for (let i = 0; i < lines.length; i++) {
|
|
37
|
+
const heading = lines[i].match(/^##\s+(.*)$/);
|
|
38
|
+
if (heading) section = heading[1];
|
|
39
|
+
if (!/^##\s+[34](?:[.)]|\s|$)/.test(lines[i])) continue;
|
|
40
|
+
let end = i + 1;
|
|
41
|
+
while (end < lines.length && !/^##\s+/.test(lines[end])) end++;
|
|
42
|
+
for (let j = i + 1; j < end; j++) {
|
|
43
|
+
if (!/^\s*\*\*Detail:?\*\*/i.test(lines[j])) continue;
|
|
44
|
+
let blockEnd = j + 1;
|
|
45
|
+
while (blockEnd < end && !/^\s*\*\*[A-Za-z][^*]*:?\*\*/.test(lines[blockEnd])) blockEnd++;
|
|
46
|
+
result.push({ startLine: j + 1, endLine: blockEnd, heading: section || null });
|
|
47
|
+
j = blockEnd - 1;
|
|
48
|
+
}
|
|
49
|
+
i = end - 1;
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
let start = -1;
|
|
54
|
+
let title = null;
|
|
55
|
+
const flush = (end ) => {
|
|
56
|
+
if (start >= 0 && end >= start) result.push({ startLine: start + 1, endLine: end, heading: title });
|
|
57
|
+
};
|
|
58
|
+
for (let i = 0; i < lines.length; i++) {
|
|
59
|
+
const heading = lines[i].match(/^##\s+(.+)$/);
|
|
60
|
+
if (heading) {
|
|
61
|
+
flush(i);
|
|
62
|
+
start = i;
|
|
63
|
+
title = heading[1].trim();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
flush(lines.length);
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function createPointer({ path: rel, heading, range, slice } ) {
|
|
71
|
+
const bytes = Buffer.byteLength(slice, 'utf8');
|
|
72
|
+
return {
|
|
73
|
+
id: `ptr:${rel}:${range.startLine}-${range.endLine}`,
|
|
74
|
+
path: rel,
|
|
75
|
+
heading,
|
|
76
|
+
range,
|
|
77
|
+
digest: sha256(slice),
|
|
78
|
+
bytes,
|
|
79
|
+
tokensEst: { value: Math.ceil(bytes / 4), basis: 'estimated:bytes/4' },
|
|
80
|
+
inlineBytes: Buffer.byteLength(`- ptr:${rel}:${range.startLine}-${range.endLine} ${rel}:${range.startLine}-${range.endLine} ${bytes} B\n`, 'utf8'),
|
|
81
|
+
load: `read ${rel} lines ${range.startLine}-${range.endLine}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function sourceFiles({ projectRoot, feature, fsImpl = fs } ) {
|
|
86
|
+
const root = path.resolve(projectRoot);
|
|
87
|
+
const featureDir = feature?.featureDir ? path.resolve(feature.featureDir) : null;
|
|
88
|
+
const candidates = [];
|
|
89
|
+
const add = (file , requirement = false) => {
|
|
90
|
+
if (!file) return;
|
|
91
|
+
const absolute = path.isAbsolute(file) ? file : path.resolve(feature?.repoRoot || root, file);
|
|
92
|
+
let stat ;
|
|
93
|
+
try { stat = fsImpl.statSync(absolute); } catch { return; }
|
|
94
|
+
if (!inside(root, absolute, fsImpl) || !stat.isFile()) return;
|
|
95
|
+
if (!candidates.some((item) => item.absolute === absolute)) candidates.push({ absolute, requirement });
|
|
96
|
+
};
|
|
97
|
+
if (featureDir) {
|
|
98
|
+
add(feature.paths?.requirement || path.join(featureDir, 'intention', 'requirement.md'), true);
|
|
99
|
+
for (const file of [
|
|
100
|
+
feature.paths?.design,
|
|
101
|
+
feature.paths?.plan,
|
|
102
|
+
path.join(featureDir, 'design', 'design.md'),
|
|
103
|
+
path.join(featureDir, 'design', 'specs.md'),
|
|
104
|
+
path.join(featureDir, 'design', 'data-model.md'),
|
|
105
|
+
path.join(featureDir, 'plan', 'plan.md'),
|
|
106
|
+
path.join(featureDir, 'design.md'),
|
|
107
|
+
path.join(featureDir, 'plan.md'),
|
|
108
|
+
]) add(file);
|
|
109
|
+
}
|
|
110
|
+
return candidates;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function collectPointers({ projectRoot, feature, fsImpl = fs } ) {
|
|
114
|
+
const root = path.resolve(projectRoot);
|
|
115
|
+
const pointers = [];
|
|
116
|
+
for (const source of sourceFiles({ projectRoot: root, feature, fsImpl })) {
|
|
117
|
+
const rel = inside(root, source.absolute, fsImpl);
|
|
118
|
+
if (!rel) continue;
|
|
119
|
+
let text ;
|
|
120
|
+
try { text = fsImpl.readFileSync(source.absolute, 'utf8'); } catch { continue; }
|
|
121
|
+
const lines = text.split(/\r?\n/);
|
|
122
|
+
for (const range of rangesFor(rel, text, source.requirement)) {
|
|
123
|
+
const slice = lineSlice(lines, range.startLine, range.endLine);
|
|
124
|
+
if (!slice.trim()) continue;
|
|
125
|
+
pointers.push(createPointer({ path: rel, heading: range.heading, range: { startLine: range.startLine, endLine: range.endLine }, slice }));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return pointers;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function readPointerSlice({ projectRoot, pointer, fsImpl = fs } ) {
|
|
132
|
+
const rel = inside(projectRoot, path.resolve(projectRoot, pointer.path), fsImpl);
|
|
133
|
+
if (!rel || rel !== pointer.path) return null;
|
|
134
|
+
const file = path.resolve(projectRoot, rel);
|
|
135
|
+
try {
|
|
136
|
+
const lines = fsImpl.readFileSync(file, 'utf8').split(/\r?\n/);
|
|
137
|
+
const slice = lineSlice(lines, pointer.range.startLine, pointer.range.endLine);
|
|
138
|
+
return { slice, digest: sha256(slice) };
|
|
139
|
+
} catch { return null; }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = { collectPointers, createPointer, readPointerSlice, sha256 };
|