fdeops 3.22.1 → 3.22.2
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/bin/fde.js +37 -15
- package/mcp/fdeops-ingest/package.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
package/bin/fde.js
CHANGED
|
@@ -1610,20 +1610,38 @@ function smartProposeText(input) {
|
|
|
1610
1610
|
return out.join('\n') + (out.length ? '\n' : '')
|
|
1611
1611
|
}
|
|
1612
1612
|
|
|
1613
|
-
//
|
|
1614
|
-
//
|
|
1615
|
-
//
|
|
1616
|
-
const
|
|
1613
|
+
// Kickoff English, not only "signer: Priya". "Helena signs off", "Anand Mehta
|
|
1614
|
+
// has final say", "Finance controller (Helena) signs off" all have to fill
|
|
1615
|
+
// success.md - that is the line Monday's RECORD reads.
|
|
1616
|
+
const SIGNER_VERB = '(?:signs?(?:\\s+off)?|approves|has (?:the )?final say|can say yes|owns the decision|is the (?:sponsor|signer|decision[- ]maker))'
|
|
1617
|
+
const SIGNER_NAME = '([A-Z][\\w.\'-]+(?:\\s+[A-Z][\\w.\'-]+){0,3})'
|
|
1618
|
+
const NOT_A_PERSON = /^(The|This|That|It|We|They|She|He|Staging|Budget|Prod|Production|Nobody|Someone|Everyone|Finance|Legal|Security|Platform|Engineering)\b/
|
|
1619
|
+
const ROLE_TOKEN = /\b(VP|SVP|EVP|CTO|CFO|COO|CEO|CISO|Eng|Engineer|Director|Lead|Head|Manager|Controller|Ops|Legal|Finance|Sponsor)\b/i
|
|
1620
|
+
|
|
1621
|
+
function looksLikePersonName(s) {
|
|
1622
|
+
const t = String(s || '').trim()
|
|
1623
|
+
if (!t || NOT_A_PERSON.test(t) || ROLE_TOKEN.test(t)) return false
|
|
1624
|
+
return /^[A-Z][\w.'-]+(?:\s+[A-Z][\w.'-]+){0,2}$/.test(t)
|
|
1625
|
+
}
|
|
1617
1626
|
|
|
1618
1627
|
function signerFromLine(text) {
|
|
1619
|
-
const t = String(text || '').trim()
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1628
|
+
const t = String(text || '').replace(/^[-*+]\s+/, '').trim()
|
|
1629
|
+
if (!t) return ''
|
|
1630
|
+
// "Priya (VP Eng) signs off" → Priya. "Finance controller (Helena) signs off" → Helena.
|
|
1631
|
+
const titled = t.match(new RegExp('\\b' + SIGNER_NAME + '\\s+\\(' + SIGNER_NAME + '\\)\\s+' + SIGNER_VERB + '\\b'))
|
|
1632
|
+
if (titled) {
|
|
1633
|
+
const before = titled[1].trim()
|
|
1634
|
+
const inside = titled[2].trim()
|
|
1635
|
+
if (looksLikePersonName(before) && ROLE_TOKEN.test(inside)) return before
|
|
1636
|
+
if (looksLikePersonName(inside)) return inside
|
|
1637
|
+
if (looksLikePersonName(before)) return before
|
|
1638
|
+
}
|
|
1639
|
+
const paren = t.match(new RegExp('\\(' + SIGNER_NAME + '\\)\\s+' + SIGNER_VERB + '\\b'))
|
|
1640
|
+
if (paren && looksLikePersonName(paren[1])) return paren[1].trim()
|
|
1641
|
+
const named = t.match(new RegExp('\\b' + SIGNER_NAME + '\\s+' + SIGNER_VERB + '\\b'))
|
|
1642
|
+
if (!named) return ''
|
|
1643
|
+
const who = named[1].trim()
|
|
1644
|
+
return looksLikePersonName(who) ? who : ''
|
|
1627
1645
|
}
|
|
1628
1646
|
|
|
1629
1647
|
function setSigner(eng, who) {
|
|
@@ -2134,7 +2152,7 @@ function cmdReceipts(args) {
|
|
|
2134
2152
|
agreed.map(h => (h.match(/^\s*([^:]+):/) || [])[1]).filter(f => f && dirtySet.has(f))
|
|
2135
2153
|
)]
|
|
2136
2154
|
if (agreed.length) {
|
|
2137
|
-
console.log('ON RECORD (dated
|
|
2155
|
+
console.log('ON RECORD (dated):')
|
|
2138
2156
|
agreed.forEach(h => {
|
|
2139
2157
|
const file = (h.match(/^\s*([^:]+):/) || [])[1]
|
|
2140
2158
|
console.log(h + (file && dirtySet.has(file) ? ' ⚠ dirty file' : ''))
|
|
@@ -2620,7 +2638,7 @@ function hasValueBucket(eng) {
|
|
|
2620
2638
|
// "pending review", "TBD.", "n/a (blocked)" and "..." are all the same thing an
|
|
2621
2639
|
// FDE means by an empty cell - nagging about them teaches people to ignore doctor.
|
|
2622
2640
|
const PENDING_CELL_RE =
|
|
2623
|
-
/^(?:pending|tbd|to ?be ?(?:measured|confirmed|determined)|n\s*\/\s*a|na|none|unknown|not
|
|
2641
|
+
/^(?:pending|tbd|to ?be ?(?:measured|confirmed|determined)|n\s*\/\s*a|na|none|unknown|not(?:\s+yet)?\s+measured|unmeasured|awaiting|\?+|\.{2,}|…|-+)(?:[^\w].*)?$/i
|
|
2624
2642
|
|
|
2625
2643
|
function parseValueLedger(eng) {
|
|
2626
2644
|
// Last section with actual rows, not merely the last non-empty one: a template
|
|
@@ -2704,7 +2722,7 @@ function engagementTouchesAI(eng) {
|
|
|
2704
2722
|
].join('\n'))
|
|
2705
2723
|
// No bare "prompt": "prompt response" / "prompt payment" is ordinary delivery
|
|
2706
2724
|
// English and would fail every non-AI ship on a missing eval receipt.
|
|
2707
|
-
return /\b(llm|rag|embedding|model card|model output|model drift|agentic|openai|anthropic|vector database|vector db|fine-tun\w*|hallucinat\w*)\b|\bmodel inference\b|\binference (?:api|endpoint|server|engine)\b|\b(?:system|model|user)\s+prompts?\b|\bprompt (?:engineering|injection|template)/i.test(blob)
|
|
2725
|
+
return /\bAI in scope\b|\b(llm|rag|embedding|model card|model output|model drift|agentic|openai|anthropic|vector database|vector db|fine-tun\w*|hallucinat\w*)\b|\bmodel inference\b|\binference (?:api|endpoint|server|engine)\b|\b(?:system|model|user)\s+prompts?\b|\bprompt (?:engineering|injection|template)/i.test(blob)
|
|
2708
2726
|
}
|
|
2709
2727
|
|
|
2710
2728
|
// The repo says AI even when the record does not. Read-only, capped, local: the
|
|
@@ -3618,6 +3636,10 @@ function printUsage() {
|
|
|
3618
3636
|
}
|
|
3619
3637
|
|
|
3620
3638
|
const [cmd, ...args] = process.argv.slice(2)
|
|
3639
|
+
if (args.includes('--help') || args.includes('-h') || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
3640
|
+
printUsage()
|
|
3641
|
+
process.exit(0)
|
|
3642
|
+
}
|
|
3621
3643
|
switch (cmd) {
|
|
3622
3644
|
case 'demo': cmdDemo(args); break
|
|
3623
3645
|
case 'scan': cmdScan(); break
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fdeops",
|
|
3
|
-
"version": "3.22.
|
|
3
|
+
"version": "3.22.2",
|
|
4
4
|
"description": "Forward deployed engineering skills for AI coding agents. One @fde skill for the client work around the code: who can say yes, what went live, whether they signed off. Dated markdown on your laptop. You confirm each write.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fdeops": "bin/install.js",
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "fdeops",
|
|
4
|
-
"version": "3.22.
|
|
4
|
+
"version": "3.22.2",
|
|
5
5
|
"description": "Forward deployed engineering skills for AI coding agents. One @fde skill for the client work around the code. You confirm; then it lands in .fde/ on your laptop.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Subash Natarajan",
|