devflow-kit 3.0.0 → 3.1.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 +22 -0
- package/dist/agents/git.md +2 -2
- package/dist/cli/agents-view/index.js +1 -1
- package/dist/cli/agents-view/render.js +2 -2
- package/dist/cli/agents-view/state.js +2 -2
- package/dist/cli/agents-view/terminal.js +5 -5
- package/dist/cli/commands/agents.js +7 -6
- package/dist/cli/commands/ambient.js +1 -1
- package/dist/cli/commands/attribution-prompts.js +8 -8
- package/dist/cli/commands/capture.js +1 -1
- package/dist/cli/commands/compliance-prompts.js +8 -8
- package/dist/cli/commands/compliance.js +8 -7
- package/dist/cli/commands/flags.js +33 -31
- package/dist/cli/commands/hud.js +1 -1
- package/dist/cli/commands/init-seed.js +9 -9
- package/dist/cli/commands/init.js +34 -32
- package/dist/cli/commands/install-report.js +10 -10
- package/dist/cli/commands/learning.js +267 -129
- package/dist/cli/commands/memory.js +1 -1
- package/dist/cli/commands/proxy.js +23 -23
- package/dist/cli/commands/rules.js +6 -5
- package/dist/cli/commands/tracker-prompts.js +6 -6
- package/dist/cli/commands/tracker.js +9 -9
- package/dist/cli/commands/uninstall.js +20 -20
- package/dist/cli/flags-view/render.js +5 -5
- package/dist/cli/flags-view/state.js +9 -9
- package/dist/cli/flags-view/terminal.js +4 -4
- package/dist/cli/tui/cells.js +1 -1
- package/dist/cli/tui/terminal.js +6 -6
- package/dist/commands/dynamic-build.md +18 -4
- package/dist/commands/dynamic-plan.md +19 -5
- package/dist/commands/dynamic-profile.md +17 -3
- package/dist/commands/dynamic-tickets.md +18 -4
- package/dist/commands/release.md +15 -1
- package/dist/commands/research.md +1 -1
- package/dist/commands/resolve.md +8 -9
- package/dist/core/agent-frontmatter.js +3 -3
- package/dist/core/agent-models.js +6 -6
- package/dist/core/agent-state.js +2 -2
- package/dist/core/ansi.js +2 -2
- package/dist/core/cache.js +7 -8
- package/dist/core/codex-auth-inspect.js +4 -4
- package/dist/core/compliance-compose.js +3 -3
- package/dist/core/compliance.js +3 -4
- package/dist/core/evidence-policy.js +14 -13
- package/dist/core/external-models.js +1 -1
- package/dist/core/feature-config.js +3 -3
- package/dist/core/feature-switch.js +3 -3
- package/dist/core/flags.js +25 -25
- package/dist/core/fs-atomic.js +6 -7
- package/dist/core/learning-queue-cleanup.js +16 -80
- package/dist/core/learning-store.js +61 -0
- package/dist/core/manifest.js +5 -5
- package/dist/core/mds-variants.js +13 -13
- package/dist/core/model-discovery.js +8 -8
- package/dist/core/observations.js +17 -101
- package/dist/core/orphan-sweep.js +4 -4
- package/dist/core/plugins.js +4 -5
- package/dist/core/project-paths.js +9 -13
- package/dist/core/proxy-log.js +8 -8
- package/dist/core/proxy-state.js +3 -3
- package/dist/core/reference-sweep.js +6 -6
- package/dist/core/teammate-mode-cleanup.js +1 -1
- package/dist/core/tracker.js +14 -14
- package/dist/hud/colors.js +2 -2
- package/dist/hud/components/learning-counts.js +2 -16
- package/dist/hud/components/version-badge.js +1 -1
- package/dist/skills/git/references/pr/resolve-review-threads.md +2 -2
- package/dist/targets/claude-code/compliance-install.js +17 -15
- package/dist/targets/claude-code/hooks.js +2 -2
- package/dist/targets/claude-code/installer.js +24 -24
- package/dist/targets/claude-code/legacy.js +1 -1
- package/dist/targets/claude-code/post-install.js +25 -11
- package/dist/targets/claude-code/tracker-install.js +2 -2
- package/package.json +1 -1
- package/src/assets/agents/code.md +1 -4
- package/src/assets/agents/design.md +2 -2
- package/src/assets/agents/diagnose.md +1 -1
- package/src/assets/agents/git.mds +2 -2
- package/src/assets/agents/knowledge.md +3 -3
- package/src/assets/agents/learning.md +281 -196
- package/src/assets/agents/research.md +1 -1
- package/src/assets/agents/review.md +3 -3
- package/src/assets/agents/scrutinize.md +1 -1
- package/src/assets/agents/skim.md +1 -1
- package/src/assets/agents/triage.md +9 -9
- package/src/assets/commands/_partials/_decisions.mds +8 -3
- package/src/assets/commands/_partials/_docs_root.mds +3 -3
- package/src/assets/commands/_partials/_engine.mds +1 -1
- package/src/assets/commands/_partials/_preamble.mds +6 -2
- package/src/assets/commands/_partials/_settings.mds +2 -2
- package/src/assets/commands/dynamic-build.mds +1 -1
- package/src/assets/commands/dynamic-plan.mds +3 -3
- package/src/assets/commands/dynamic-profile.mds +1 -1
- package/src/assets/commands/dynamic-tickets.mds +2 -2
- package/src/assets/commands/release.md +15 -1
- package/src/assets/commands/research.mds +1 -1
- package/src/assets/commands/resolve.mds +8 -9
- package/src/assets/mds/git/_pr.mds +3 -3
- package/src/assets/mds/tracker/_common.mds +1 -1
- package/src/assets/mds/tracker/_github.mds +1 -1
- package/src/assets/mds/tracker/_jira.mds +1 -1
- package/src/assets/mds/tracker/_linear.mds +1 -1
- package/src/assets/mds/tracker/_mcp.mds +6 -5
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +1 -0
- package/src/assets/scripts/hooks/background-memory-update +28 -22
- package/src/assets/scripts/hooks/capture-turn +1 -17
- package/src/assets/scripts/hooks/ensure-devflow-init +1 -1
- package/src/assets/scripts/hooks/ensure-proxy +5 -6
- package/src/assets/scripts/hooks/ensure-root-gitignore +1 -1
- package/src/assets/scripts/hooks/is-hex-sha +1 -1
- package/src/assets/scripts/hooks/json-helper.cjs +348 -814
- package/src/assets/scripts/hooks/json-parse +3 -2
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +205 -156
- package/src/assets/scripts/hooks/lib/learning-store.cjs +3102 -0
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +7 -5
- package/src/assets/scripts/hooks/lib/project-paths.cjs +13 -19
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +253 -226
- package/src/assets/scripts/hooks/queue-append +2 -2
- package/src/assets/scripts/hooks/resolve-project-root +3 -4
- package/src/assets/scripts/hooks/session-start-context +40 -18
- package/src/assets/scripts/lib/project-config.cjs +2 -2
- package/src/assets/scripts/pr-evidence.cjs +3 -3
- package/src/assets/scripts/redact-secrets.cjs +20 -20
- package/src/assets/scripts/release-trace.cjs +1 -1
- package/src/assets/scripts/resolve-evidence-policy.cjs +3 -3
- package/src/assets/scripts/resolve-settings.cjs +3 -3
- package/src/assets/scripts/verify-evidence.cjs +2 -2
- package/src/assets/skills/apply-decisions/SKILL.md +37 -17
- package/src/assets/skills/docs-framework/SKILL.md +2 -2
- package/src/assets/skills/feature-knowledge/SKILL.md +6 -5
- package/src/targets/claude-code/templates/managed-settings.json +3 -3
- package/dist/core/observation-io.js +0 -50
- package/src/assets/scripts/hooks/decisions-usage-scan.cjs +0 -131
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// D29: Scanner runs after queue append, not before.
|
|
5
|
-
// D19: Citation scanner is a separate .cjs module — independently testable.
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const { getMemoryDir, getDecisionsUsagePath, getDecisionsUsageLockDir } = require('./lib/project-paths.cjs');
|
|
10
|
-
|
|
11
|
-
// Parse --cwd argument
|
|
12
|
-
const cwdIdx = process.argv.indexOf('--cwd');
|
|
13
|
-
const rawCwd = cwdIdx !== -1 && process.argv[cwdIdx + 1] ? process.argv[cwdIdx + 1] : null;
|
|
14
|
-
if (!rawCwd) process.exit(0); // silent fail
|
|
15
|
-
|
|
16
|
-
// Security: reject relative input BEFORE resolving (prevents CWE-23 path traversal).
|
|
17
|
-
// path.resolve() unconditionally returns an absolute path, so checking isAbsolute *after*
|
|
18
|
-
// resolving is a no-op. We must reject relative inputs first, then resolve to normalise
|
|
19
|
-
// traversal sequences (e.g. /foo/../bar → /bar).
|
|
20
|
-
// All legitimate callers (stop-hook) pass an absolute $CWD from bash.
|
|
21
|
-
if (!path.isAbsolute(rawCwd)) {
|
|
22
|
-
console.error('cwd must be absolute, got:', rawCwd);
|
|
23
|
-
process.exit(2);
|
|
24
|
-
}
|
|
25
|
-
const cwd = path.resolve(rawCwd);
|
|
26
|
-
|
|
27
|
-
const memoryDir = getMemoryDir(cwd);
|
|
28
|
-
if (!fs.existsSync(memoryDir)) process.exit(0); // no .devflow/memory dir — nothing to scan
|
|
29
|
-
|
|
30
|
-
// Read stdin synchronously
|
|
31
|
-
let input = '';
|
|
32
|
-
try {
|
|
33
|
-
input = fs.readFileSync(0, 'utf8'); // fd 0 = stdin
|
|
34
|
-
} catch {
|
|
35
|
-
process.exit(0); // no stdin — nothing to scan
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (!input) process.exit(0);
|
|
39
|
-
|
|
40
|
-
// Scan for ADR-NNN or PF-NNN citations
|
|
41
|
-
const pattern = /(ADR|PF)-\d{3}/g;
|
|
42
|
-
const matches = new Set();
|
|
43
|
-
let match;
|
|
44
|
-
while ((match = pattern.exec(input)) !== null) {
|
|
45
|
-
matches.add(match[0]);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (matches.size === 0) process.exit(0);
|
|
49
|
-
|
|
50
|
-
// Read usage file
|
|
51
|
-
const usagePath = getDecisionsUsagePath(cwd);
|
|
52
|
-
const lockDir = getDecisionsUsageLockDir(cwd);
|
|
53
|
-
|
|
54
|
-
// Yield the current thread for the given number of milliseconds without spinning.
|
|
55
|
-
// Atomics.wait on a freshly allocated SharedArrayBuffer never resolves (value never
|
|
56
|
-
// changes), so it blocks the synchronous thread for exactly `ms` milliseconds with
|
|
57
|
-
// zero CPU usage — unlike a busy-wait loop.
|
|
58
|
-
function syncSleep(ms) {
|
|
59
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Simple mkdir-based lock with 2s timeout
|
|
63
|
-
function acquireLock() {
|
|
64
|
-
const deadline = Date.now() + 2000;
|
|
65
|
-
while (Date.now() < deadline) {
|
|
66
|
-
try {
|
|
67
|
-
fs.mkdirSync(lockDir);
|
|
68
|
-
return true;
|
|
69
|
-
} catch (e) {
|
|
70
|
-
if (e.code !== 'EEXIST') return false;
|
|
71
|
-
// Check for stale lock (>5s old)
|
|
72
|
-
try {
|
|
73
|
-
const stat = fs.statSync(lockDir);
|
|
74
|
-
if (Date.now() - stat.mtimeMs > 5000) {
|
|
75
|
-
try { fs.rmdirSync(lockDir); } catch { /* race */ }
|
|
76
|
-
}
|
|
77
|
-
} catch { /* stat failed — retry */ }
|
|
78
|
-
// Yield for 10 ms instead of busy-spinning to avoid pegging the CPU.
|
|
79
|
-
syncSleep(10);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function releaseLock() {
|
|
86
|
-
try { fs.rmdirSync(lockDir); } catch { /* already released */ }
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!acquireLock()) process.exit(0); // can't acquire lock — skip silently
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
let data = { version: 1, entries: {} };
|
|
93
|
-
try {
|
|
94
|
-
const raw = fs.readFileSync(usagePath, 'utf8');
|
|
95
|
-
const parsed = JSON.parse(raw);
|
|
96
|
-
if (parsed && parsed.version === 1 && typeof parsed.entries === 'object') {
|
|
97
|
-
data = parsed;
|
|
98
|
-
}
|
|
99
|
-
} catch { /* ENOENT or malformed — use default */ }
|
|
100
|
-
|
|
101
|
-
const now = new Date().toISOString();
|
|
102
|
-
let changed = false;
|
|
103
|
-
|
|
104
|
-
for (const id of matches) {
|
|
105
|
-
// Only increment existing entries (D19: ignores unregistered IDs)
|
|
106
|
-
if (data.entries[id]) {
|
|
107
|
-
data.entries[id].cites = (data.entries[id].cites || 0) + 1;
|
|
108
|
-
data.entries[id].last_cited = now;
|
|
109
|
-
changed = true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (changed) {
|
|
114
|
-
// PID-scope the tmp name so concurrent writers from different processes
|
|
115
|
-
// never collide on the same .tmp path. mirrors fs-atomic.ts and proxy-log.ts.
|
|
116
|
-
const tmp = usagePath + '.tmp.' + process.pid;
|
|
117
|
-
const content = JSON.stringify(data, null, 2) + '\n';
|
|
118
|
-
// Use wx (O_EXCL) to reject any pre-existing file or symlink at the .tmp path,
|
|
119
|
-
// preventing TOCTOU symlink-follow attacks. On EEXIST, unlink and retry once.
|
|
120
|
-
try {
|
|
121
|
-
fs.writeFileSync(tmp, content, { flag: 'wx' });
|
|
122
|
-
} catch (err) {
|
|
123
|
-
if (err.code !== 'EEXIST') throw err;
|
|
124
|
-
try { fs.unlinkSync(tmp); } catch { /* race — already removed */ }
|
|
125
|
-
fs.writeFileSync(tmp, content, { flag: 'wx' });
|
|
126
|
-
}
|
|
127
|
-
fs.renameSync(tmp, usagePath);
|
|
128
|
-
}
|
|
129
|
-
} finally {
|
|
130
|
-
releaseLock();
|
|
131
|
-
}
|