@deftai/directive-content 0.73.0 → 0.73.1
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/package.json +1 -1
- package/tasks/engine.yml +170 -5
- package/tasks/ts.yml +9 -6
- package/templates/agents-entry.md +5 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive-content",
|
|
3
|
-
"version": "0.73.
|
|
3
|
+
"version": "0.73.1",
|
|
4
4
|
"description": "Shippable Directive framework content in the consumer .deft/core/ layout (C1 flatten), plus the engine surfaces (.githooks/, Taskfile.yml, tasks/) the deposit wires. Python-free per #2022 Phase 3. Refs #11, #1669, #1967.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
package/tasks/engine.yml
CHANGED
|
@@ -10,6 +10,67 @@ vars:
|
|
|
10
10
|
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
11
11
|
|
|
12
12
|
tasks:
|
|
13
|
+
pm-run:
|
|
14
|
+
internal: true
|
|
15
|
+
desc: "Run a package.json script via pnpm (bare or Corepack pin) or explicit DEFT_PACKAGE_MANAGER=npm (#2410)."
|
|
16
|
+
dir: '{{.DEFT_ROOT}}'
|
|
17
|
+
cmds:
|
|
18
|
+
- |
|
|
19
|
+
set -eu
|
|
20
|
+
node -e "
|
|
21
|
+
const {execFileSync}=require('child_process');
|
|
22
|
+
const fs=require('fs');
|
|
23
|
+
const root=process.argv[1];
|
|
24
|
+
const script=process.argv[2];
|
|
25
|
+
const pkgPath=root+'/package.json';
|
|
26
|
+
if(!fs.existsSync(pkgPath)){
|
|
27
|
+
console.error('deft: package.json missing at '+root);
|
|
28
|
+
process.exit(2);
|
|
29
|
+
}
|
|
30
|
+
const pkg=JSON.parse(fs.readFileSync(pkgPath,'utf8'));
|
|
31
|
+
const hasCmd=(name)=>{
|
|
32
|
+
try{
|
|
33
|
+
execFileSync('sh',['-c','command -v '+name],{stdio:'ignore'});
|
|
34
|
+
return true;
|
|
35
|
+
}catch{
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const run=(cmd,args)=>{
|
|
40
|
+
execFileSync(cmd,args,{cwd:root,stdio:'inherit',shell:true});
|
|
41
|
+
};
|
|
42
|
+
const trySteps=(steps)=>{
|
|
43
|
+
for(const [cmd,args] of steps){
|
|
44
|
+
try{
|
|
45
|
+
run(cmd,args);
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}catch{
|
|
48
|
+
// fall through to Corepack / next resolver
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const envPm=String(process.env.DEFT_PACKAGE_MANAGER||'').trim().toLowerCase();
|
|
53
|
+
if(envPm==='npm'){
|
|
54
|
+
run('npm',['run',script]);
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
const pin=String(pkg.packageManager||'').trim();
|
|
58
|
+
const match=pin.match(/^pnpm@(.+)$/);
|
|
59
|
+
const steps=[];
|
|
60
|
+
if(hasCmd('pnpm')) steps.push(['pnpm',['run',script]]);
|
|
61
|
+
if(hasCmd('corepack')&&match) steps.push(['corepack',['pnpm@'+match[1],'run',script]]);
|
|
62
|
+
if(hasCmd('corepack')) steps.push(['corepack',['pnpm','run',script]]);
|
|
63
|
+
trySteps(steps);
|
|
64
|
+
console.error('deft: neither pnpm nor corepack is available to run \"'+script+'\".');
|
|
65
|
+
if(pin){
|
|
66
|
+
console.error(' Enable Corepack for the pinned manager: corepack enable && corepack prepare '+pin+' --activate');
|
|
67
|
+
}else{
|
|
68
|
+
console.error(' Install pnpm or enable Corepack (see package.json#packageManager).');
|
|
69
|
+
}
|
|
70
|
+
console.error(' Or set DEFT_PACKAGE_MANAGER=npm for an explicit npm build path.');
|
|
71
|
+
process.exit(127);
|
|
72
|
+
" "{{.DEFT_ROOT}}" "{{.PM_SCRIPT}}"
|
|
73
|
+
|
|
13
74
|
_ts-build:
|
|
14
75
|
internal: true
|
|
15
76
|
desc: "Build CLI dist from the framework source checkout; no-op on npm consumer deposits that ship no packages/ source (#2022 Phase 3 / #2126)."
|
|
@@ -32,12 +93,60 @@ tasks:
|
|
|
32
93
|
if [ -f "{{.DEFT_ROOT}}/packages/cli/package.json" ] \
|
|
33
94
|
&& [ -f "{{.DEFT_ROOT}}/package.json" ] \
|
|
34
95
|
&& node -e "const fs=require('fs');const j=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));process.exit(j.scripts&&j.scripts.build?0:1)" "{{.DEFT_ROOT}}/package.json"; then
|
|
35
|
-
|
|
96
|
+
node -e "
|
|
97
|
+
const {execFileSync}=require('child_process');
|
|
98
|
+
const fs=require('fs');
|
|
99
|
+
const root=process.argv[1];
|
|
100
|
+
const script='build';
|
|
101
|
+
const pkgPath=root+'/package.json';
|
|
102
|
+
const pkg=JSON.parse(fs.readFileSync(pkgPath,'utf8'));
|
|
103
|
+
const hasCmd=(name)=>{
|
|
104
|
+
try{
|
|
105
|
+
execFileSync('sh',['-c','command -v '+name],{stdio:'ignore'});
|
|
106
|
+
return true;
|
|
107
|
+
}catch{
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const run=(cmd,args)=>{
|
|
112
|
+
execFileSync(cmd,args,{cwd:root,stdio:'inherit',shell:true});
|
|
113
|
+
};
|
|
114
|
+
const trySteps=(steps)=>{
|
|
115
|
+
for(const [cmd,args] of steps){
|
|
116
|
+
try{
|
|
117
|
+
run(cmd,args);
|
|
118
|
+
process.exit(0);
|
|
119
|
+
}catch{
|
|
120
|
+
// fall through to Corepack / next resolver
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const envPm=String(process.env.DEFT_PACKAGE_MANAGER||'').trim().toLowerCase();
|
|
125
|
+
if(envPm==='npm'){
|
|
126
|
+
run('npm',['run',script]);
|
|
127
|
+
process.exit(0);
|
|
128
|
+
}
|
|
129
|
+
const pin=String(pkg.packageManager||'').trim();
|
|
130
|
+
const match=pin.match(/^pnpm@(.+)$/);
|
|
131
|
+
const steps=[];
|
|
132
|
+
if(hasCmd('pnpm')) steps.push(['pnpm',['run',script]]);
|
|
133
|
+
if(hasCmd('corepack')&&match) steps.push(['corepack',['pnpm@'+match[1],'run',script]]);
|
|
134
|
+
if(hasCmd('corepack')) steps.push(['corepack',['pnpm','run',script]]);
|
|
135
|
+
trySteps(steps);
|
|
136
|
+
console.error('deft: neither pnpm nor corepack is available to run \"'+script+'\".');
|
|
137
|
+
if(pin){
|
|
138
|
+
console.error(' Enable Corepack for the pinned manager: corepack enable && corepack prepare '+pin+' --activate');
|
|
139
|
+
}else{
|
|
140
|
+
console.error(' Install pnpm or enable Corepack (see package.json#packageManager).');
|
|
141
|
+
}
|
|
142
|
+
console.error(' Or set DEFT_PACKAGE_MANAGER=npm for an explicit npm build path.');
|
|
143
|
+
process.exit(127);
|
|
144
|
+
" "{{.DEFT_ROOT}}"
|
|
36
145
|
fi
|
|
37
146
|
|
|
38
147
|
invoke:
|
|
39
148
|
internal: true
|
|
40
|
-
desc: "Run a deft-ts verb from vendored bin.js (source checkout) or global deft (npm consumer deposit
|
|
149
|
+
desc: "Run a deft-ts verb from vendored bin.js (source checkout) or global deft (npm consumer deposit / runtime fallback #2409). Runtime/session verbs must not trigger engine:_ts-build / pnpm (#2181)."
|
|
41
150
|
# Run from the operator project root so deft verbs resolve USER_WORKING_DIR
|
|
42
151
|
# correctly; without this, included engine.yml defaults cwd to tasks/ (#2022).
|
|
43
152
|
dir: '{{.USER_WORKING_DIR}}'
|
|
@@ -69,11 +178,67 @@ tasks:
|
|
|
69
178
|
fi
|
|
70
179
|
node "$bin" {{.ENGINE_CMD}}
|
|
71
180
|
elif [ "$is_buildable_source" = 1 ]; then
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
181
|
+
engine_cmd='{{.ENGINE_CMD}}'
|
|
182
|
+
first_token="${engine_cmd%% *}"
|
|
183
|
+
is_runtime_verb=0
|
|
184
|
+
case " ${first_token} " in
|
|
185
|
+
" session:start "|" session-start "|\
|
|
186
|
+
" verify:session-ritual "|" verify-session-ritual "|\
|
|
187
|
+
" verify:tools "|" verify-tools "|\
|
|
188
|
+
" triage:summary "|" triage-summary "|\
|
|
189
|
+
" triage:welcome "|" triage-welcome "|\
|
|
190
|
+
" verify:cache-fresh "|" verify-cache-fresh "|\
|
|
191
|
+
" preflight-cache ")
|
|
192
|
+
is_runtime_verb=1
|
|
193
|
+
;;
|
|
194
|
+
esac
|
|
195
|
+
if [ "${DEFT_USE_GLOBAL_CLI:-}" = "1" ]; then
|
|
196
|
+
is_runtime_verb=1
|
|
197
|
+
fi
|
|
198
|
+
global_cli=""
|
|
199
|
+
if command -v deft >/dev/null 2>&1; then
|
|
200
|
+
global_cli=deft
|
|
201
|
+
elif command -v directive >/dev/null 2>&1; then
|
|
202
|
+
global_cli=directive
|
|
203
|
+
fi
|
|
204
|
+
if [ "$is_runtime_verb" = 1 ] && [ -n "$global_cli" ]; then
|
|
205
|
+
node -e "
|
|
206
|
+
const {execFileSync}=require('child_process');
|
|
207
|
+
const root=process.argv[1];
|
|
208
|
+
const cli=process.argv[2];
|
|
209
|
+
let srcVer='0.0.0-dev';
|
|
210
|
+
try{
|
|
211
|
+
if(process.env.DEFT_RELEASE_VERSION){
|
|
212
|
+
srcVer=process.env.DEFT_RELEASE_VERSION;
|
|
213
|
+
}else{
|
|
214
|
+
srcVer=execFileSync('git',['describe','--tags','--abbrev=0'],{cwd:root,encoding:'utf8'}).trim().replace(/^v/,'');
|
|
215
|
+
}
|
|
216
|
+
}catch{}
|
|
217
|
+
let globalVer='unknown';
|
|
218
|
+
try{
|
|
219
|
+
globalVer=execFileSync(cli,['--version'],{encoding:'utf8'}).trim();
|
|
220
|
+
}catch{}
|
|
221
|
+
const m=globalVer.match(/@([0-9]+\\.[0-9]+\\.[0-9]+)/)||globalVer.match(/([0-9]+\\.[0-9]+\\.[0-9]+)/);
|
|
222
|
+
const gv=m?m[1]:globalVer;
|
|
223
|
+
if(srcVer!=='0.0.0-dev'&&gv!=='unknown'&&gv!==srcVer){
|
|
224
|
+
console.error('deft: using global '+cli+' ('+gv+'); source checkout is v'+srcVer+' — run task build for a local engine match.');
|
|
225
|
+
}
|
|
226
|
+
" "{{.DEFT_ROOT}}" "$global_cli" >&2 || true
|
|
227
|
+
"$global_cli" {{.ENGINE_CMD}}
|
|
228
|
+
else
|
|
229
|
+
echo "deft: CLI artifact missing at {{.DEFT_ROOT}}/packages/cli/dist/bin.js" >&2
|
|
230
|
+
if [ "$is_runtime_verb" = 1 ]; then
|
|
231
|
+
echo " Install global deft: npm i -g @deftai/directive" >&2
|
|
232
|
+
echo " Or run \`task build\` first (framework source checkout)." >&2
|
|
233
|
+
else
|
|
234
|
+
echo " Run \`task build\` first (framework source checkout)." >&2
|
|
235
|
+
fi
|
|
236
|
+
exit 2
|
|
237
|
+
fi
|
|
75
238
|
elif command -v deft >/dev/null 2>&1; then
|
|
76
239
|
deft {{.ENGINE_CMD}}
|
|
240
|
+
elif command -v directive >/dev/null 2>&1; then
|
|
241
|
+
directive {{.ENGINE_CMD}}
|
|
77
242
|
else
|
|
78
243
|
echo "deft: neither {{.DEFT_ROOT}}/packages/cli/dist/bin.js nor a global deft command is available." >&2
|
|
79
244
|
echo " Install with: npm i -g @deftai/directive" >&2
|
package/tasks/ts.yml
CHANGED
|
@@ -8,21 +8,24 @@ vars:
|
|
|
8
8
|
tasks:
|
|
9
9
|
build:
|
|
10
10
|
desc: "Build the TypeScript engine monorepo (tsc -b project references, #1717)"
|
|
11
|
-
dir: '{{.DEFT_ROOT}}'
|
|
12
11
|
cmds:
|
|
13
|
-
-
|
|
12
|
+
- task: :engine:pm-run
|
|
13
|
+
vars:
|
|
14
|
+
PM_SCRIPT: build
|
|
14
15
|
|
|
15
16
|
test:
|
|
16
17
|
desc: "Run the TypeScript engine test suite with coverage (vitest, #1717)"
|
|
17
|
-
dir: '{{.DEFT_ROOT}}'
|
|
18
18
|
cmds:
|
|
19
|
-
-
|
|
19
|
+
- task: :engine:pm-run
|
|
20
|
+
vars:
|
|
21
|
+
PM_SCRIPT: test
|
|
20
22
|
|
|
21
23
|
lint:
|
|
22
24
|
desc: "Lint + format-check the TypeScript engine (biome, #1717)"
|
|
23
|
-
dir: '{{.DEFT_ROOT}}'
|
|
24
25
|
cmds:
|
|
25
|
-
-
|
|
26
|
+
- task: :engine:pm-run
|
|
27
|
+
vars:
|
|
28
|
+
PM_SCRIPT: lint
|
|
26
29
|
|
|
27
30
|
check-lane:
|
|
28
31
|
desc: "Run the TS lane (lint+build+test) when a Node toolchain is present; skip with a notice otherwise (#1530, #1790)."
|
|
@@ -96,23 +96,21 @@ Projects on the legacy `vbrief/` tree are still read-accepted; run `deft migrate
|
|
|
96
96
|
|
|
97
97
|
## Umbrella status reading (#1152 / #2066)
|
|
98
98
|
|
|
99
|
-
Rationale + cross-references: `.deft/core/docs/analysis/2026-07-02-agents-md-incident-rule-rationale.md` § Umbrella current-shape convention (#1152).
|
|
100
|
-
|
|
101
99
|
- ! Fetch issue comments via REST (`gh api repos/<owner>/<repo>/issues/<N>/comments`), read the `## Current shape (as of pass-N)` comment, and any linked context or `LockedDecisions` xBRIEF referenced there — following the reading order body -> current-shape comment -> amendment comments (claim-cites-state-surface, #2066). Prefer the deterministic read path: `deft umbrella:current-shape <N>` (or `task umbrella:current-shape <N>`) — it locates the canonical comment, validates #1152 sections, and never falls back to the issue body.
|
|
102
100
|
- ⊗ Conclude umbrella or epic status from the issue body alone. Any "X is done" / "X is the blocker" assertion about an umbrella MUST cite the current-shape comment or another state artifact, not the body.
|
|
103
101
|
|
|
104
102
|
## Deterministic questions runtime obligation (#1470)
|
|
105
103
|
|
|
106
|
-
Rationale + cross-references: `.deft/core/
|
|
104
|
+
Rationale + cross-references: `.deft/core/contracts/deterministic-questions.md` (#767); closes the agent-runtime enforcement gap on issue #1470.
|
|
107
105
|
|
|
108
|
-
- ! ANY agent-initiated structured question — whether via host `ask_user_question` / `AskQuestion` tooling or a numbered menu rendered in chat — inside OR outside any skill flow MUST include `Discuss` and `Back` as the final two options, in that order, and MUST obey the Discuss-pause semantic documented verbatim in `.deft/core/
|
|
106
|
+
- ! ANY agent-initiated structured question — whether via host `ask_user_question` / `AskQuestion` tooling or a numbered menu rendered in chat — inside OR outside any skill flow MUST include `Discuss` and `Back` as the final two options, in that order, and MUST obey the Discuss-pause semantic documented verbatim in `.deft/core/contracts/deterministic-questions.md`.
|
|
109
107
|
- ! Before emitting any structured or numbered question, self-check: confirm `Discuss` and `Back` are present as the final two options; if not, add them before calling the tool or rendering the menu. Host-native `Other` / free-text affordances are NOT substitutes for `Discuss` (#767 / #431).
|
|
110
108
|
- ⊗ Emit a structured or numbered question without `Discuss` and `Back` as the final two options — including ad-hoc orchestration approvals, dispatch confirmations, and decision walkthroughs outside interview/setup/refinement skills.
|
|
111
109
|
- ⊗ Treat the host UI's automatic `Other` option as the stop-and-discuss escape hatch — `Other` widens the answer space; `Discuss` exits the deterministic flow entirely (see contract).
|
|
112
110
|
|
|
113
111
|
## Issue body→comments reading (#2143)
|
|
114
112
|
|
|
115
|
-
Rationale + cross-references:
|
|
113
|
+
Rationale + cross-references: preamble § 5.6 in `.deft/core/templates/agent-prompt-preamble.md` (#2143).
|
|
116
114
|
|
|
117
115
|
- ! Fetch both the issue body and `repos/<owner>/<repo>/issues/<N>/comments` via REST before concluding what the issue asks for or building a worker dispatch envelope. Read body first, then the comment thread in chronological order.
|
|
118
116
|
- ! `deft issue:ingest` / `task issue:ingest` fetches `/comments` by default and folds the thread into the ingested overview (#2143).
|
|
@@ -192,7 +190,7 @@ Override paths (`deft policy:show` / `deft policy:enforce-branches` / `deft poli
|
|
|
192
190
|
|
|
193
191
|
## Platform-conditional rules (PowerShell / Windows)
|
|
194
192
|
|
|
195
|
-
Platform/tool/runtime-specific rules are lazy-loaded, not rendered here, so they don't crowd context for sessions that can't trigger them (#2157 / #1882). If your session matches a trigger below, load `.deft/core/
|
|
193
|
+
Platform/tool/runtime-specific rules are lazy-loaded, not rendered here, so they don't crowd context for sessions that can't trigger them (#2157 / #1882). If your session matches a trigger below, load `.deft/core/scm/github.md` § "PowerShell platform-conditional rules for agents" **before** the risky operation:
|
|
196
194
|
|
|
197
195
|
- ! Editing files with non-ASCII glyphs from PowerShell (especially PS 5.1) -- enforced at commit by `deft verify:encoding` (#798).
|
|
198
196
|
- ! Running shell commands under the Grok Build Windows + pwsh 7+ runtime -- piped/redirected commands leak wrapper text (#1353); PTY-based Warp + Claude are exempt.
|
|
@@ -222,7 +220,7 @@ Platform/tool/runtime-specific rules are lazy-loaded, not rendered here, so they
|
|
|
222
220
|
|
|
223
221
|
## Commands
|
|
224
222
|
|
|
225
|
-
Directive product commands use the `/deft:directive:*` namespace (#418 / #1670). Prior `/deft:*` product forms remain as deprecation-warning aliases — see
|
|
223
|
+
Directive product commands use the `/deft:directive:*` namespace (#418 / #1670). Prior `/deft:*` product forms remain as deprecation-warning aliases — see `.deft/core/commands.md` for the full alias table. Cross-product session commands stay at the umbrella `/deft:*` level.
|
|
226
224
|
|
|
227
225
|
**Directive product (`/deft:directive:*`):**
|
|
228
226
|
|