dream-wf 0.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/README.md +178 -0
- package/bin/dream-wf.js +10 -0
- package/core/dependencies.md +79 -0
- package/core/grill-prd-policy.md +35 -0
- package/core/mcp-tool-policy.md +90 -0
- package/core/spec-bootstrap-policy.md +39 -0
- package/core/workflow-profile.md +30 -0
- package/package.json +24 -0
- package/src/cli/index.js +198 -0
- package/src/deps/index.js +96 -0
- package/src/doctor/index.js +16 -0
- package/src/lib/files.js +64 -0
- package/src/lib/json.js +44 -0
- package/src/lib/platforms.js +32 -0
- package/src/lib/trellis.js +118 -0
- package/src/platforms/claude-code/index.js +54 -0
- package/src/platforms/cursor/index.js +50 -0
- package/src/platforms/opencode/index.js +26 -0
- package/src/platforms/shared.js +58 -0
- package/templates/hooks/claude-code/dream-wf-guard.py +128 -0
- package/templates/hooks/cursor/dream-wf-guard.py +121 -0
- package/templates/hooks/opencode/dream-wf-guard.js +108 -0
- package/templates/rules/claude-code/dream-wf-block.md +23 -0
- package/templates/rules/cursor/dream-wf.mdc +38 -0
- package/templates/rules/opencode/dream-wf-block.md +23 -0
- package/templates/skills/dream-wf-grill-prd/SKILL.md +94 -0
- package/templates/skills/dream-wf-mcp-policy/SKILL.md +53 -0
- package/templates/spec/guides/dream-wf-mcp-policy.md +29 -0
- package/templates/spec/guides/dream-wf-prd-policy.md +27 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
MUTATING_TOOLS = {"Write", "Edit", "MultiEdit", "Delete"}
|
|
10
|
+
MUTATING_SHELL = re.compile(r"\b(rm|mv|cp|mkdir|touch|npm\s+install|pnpm\s+add|yarn\s+add|bun\s+add|git\s+commit|git\s+push)\b")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def find_root(cwd):
|
|
14
|
+
current = Path(cwd).resolve()
|
|
15
|
+
for candidate in [current, *current.parents]:
|
|
16
|
+
if (candidate / ".trellis").exists():
|
|
17
|
+
return candidate
|
|
18
|
+
return current
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def active_tasks(root):
|
|
22
|
+
tasks_dir = root / ".trellis" / "tasks"
|
|
23
|
+
if not tasks_dir.exists():
|
|
24
|
+
return []
|
|
25
|
+
|
|
26
|
+
result = []
|
|
27
|
+
for task_json in tasks_dir.glob("*/task.json"):
|
|
28
|
+
try:
|
|
29
|
+
data = json.loads(task_json.read_text())
|
|
30
|
+
except Exception:
|
|
31
|
+
continue
|
|
32
|
+
if data.get("status") in {"planning", "in_progress"}:
|
|
33
|
+
result.append((task_json.parent, data))
|
|
34
|
+
return result
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def is_prd_confirmed(task_dir):
|
|
38
|
+
prd = task_dir / "prd.md"
|
|
39
|
+
if not prd.exists():
|
|
40
|
+
return False
|
|
41
|
+
text = prd.read_text(errors="ignore").lower()
|
|
42
|
+
markers = ["prd confirmed", "confirmed: true", "status: confirmed", "用户已确认", "已确认"]
|
|
43
|
+
return any(marker in text for marker in markers)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def is_planning_artifact(root, tool_input):
|
|
47
|
+
if not isinstance(tool_input, dict):
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
candidate = tool_input.get("path") or tool_input.get("file_path") or tool_input.get("target_file") or ""
|
|
51
|
+
if not candidate:
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
file_path = Path(candidate)
|
|
56
|
+
if not file_path.is_absolute():
|
|
57
|
+
file_path = (root / file_path).resolve()
|
|
58
|
+
relative = file_path.relative_to(root).as_posix()
|
|
59
|
+
except Exception:
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
if not relative.startswith(".trellis/tasks/"):
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
name = Path(relative).name
|
|
66
|
+
return (
|
|
67
|
+
name in {"prd.md", "design.md", "implement.md", "implement.jsonl", "check.jsonl"}
|
|
68
|
+
or "/research/" in relative
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def deny(message):
|
|
73
|
+
print(json.dumps({
|
|
74
|
+
"hookSpecificOutput": {
|
|
75
|
+
"hookEventName": "PreToolUse",
|
|
76
|
+
"permissionDecision": "deny",
|
|
77
|
+
"permissionDecisionReason": message
|
|
78
|
+
}
|
|
79
|
+
}))
|
|
80
|
+
sys.exit(0)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def allow():
|
|
84
|
+
print(json.dumps({
|
|
85
|
+
"hookSpecificOutput": {
|
|
86
|
+
"hookEventName": "PreToolUse",
|
|
87
|
+
"permissionDecision": "allow"
|
|
88
|
+
}
|
|
89
|
+
}))
|
|
90
|
+
sys.exit(0)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def main():
|
|
94
|
+
try:
|
|
95
|
+
payload = json.load(sys.stdin)
|
|
96
|
+
except Exception:
|
|
97
|
+
allow()
|
|
98
|
+
|
|
99
|
+
tool_name = payload.get("tool_name") or payload.get("tool", "")
|
|
100
|
+
tool_input = payload.get("tool_input") or payload.get("input") or {}
|
|
101
|
+
cwd = payload.get("cwd") or os.environ.get("CLAUDE_PROJECT_DIR") or os.getcwd()
|
|
102
|
+
root = find_root(cwd)
|
|
103
|
+
|
|
104
|
+
is_mutating = tool_name in MUTATING_TOOLS
|
|
105
|
+
command = tool_input.get("command", "") if isinstance(tool_input, dict) else ""
|
|
106
|
+
if tool_name in {"Shell", "Bash"} and MUTATING_SHELL.search(command):
|
|
107
|
+
is_mutating = True
|
|
108
|
+
|
|
109
|
+
if not is_mutating:
|
|
110
|
+
allow()
|
|
111
|
+
|
|
112
|
+
tasks = active_tasks(root)
|
|
113
|
+
if not tasks:
|
|
114
|
+
deny("dream-wf strict: mutating actions require an active Trellis task. Create or start a Trellis task first, or switch dream-wf to advisory mode.")
|
|
115
|
+
|
|
116
|
+
planning_tasks = [(task_dir, task) for task_dir, task in tasks if task.get("status") == "planning"]
|
|
117
|
+
if planning_tasks:
|
|
118
|
+
if is_planning_artifact(root, tool_input):
|
|
119
|
+
allow()
|
|
120
|
+
unconfirmed = [task for task_dir, task in planning_tasks if not is_prd_confirmed(task_dir)]
|
|
121
|
+
if unconfirmed:
|
|
122
|
+
deny("dream-wf strict: implementation is blocked while this task is in planning and its PRD is not confirmed. Continue grill-me PRD clarification first. Planning artifacts under .trellis/tasks/** are allowed.")
|
|
123
|
+
|
|
124
|
+
allow()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
main()
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
MUTATING_TOOLS = {"Write", "Edit", "MultiEdit", "Delete"}
|
|
10
|
+
MUTATING_SHELL = re.compile(r"\b(rm|mv|cp|mkdir|touch|npm\s+install|pnpm\s+add|yarn\s+add|bun\s+add|git\s+commit|git\s+push)\b")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def find_root(cwd):
|
|
14
|
+
current = Path(cwd).resolve()
|
|
15
|
+
for candidate in [current, *current.parents]:
|
|
16
|
+
if (candidate / ".trellis").exists():
|
|
17
|
+
return candidate
|
|
18
|
+
return current
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def active_tasks(root):
|
|
22
|
+
tasks_dir = root / ".trellis" / "tasks"
|
|
23
|
+
if not tasks_dir.exists():
|
|
24
|
+
return []
|
|
25
|
+
|
|
26
|
+
result = []
|
|
27
|
+
for task_json in tasks_dir.glob("*/task.json"):
|
|
28
|
+
try:
|
|
29
|
+
data = json.loads(task_json.read_text())
|
|
30
|
+
except Exception:
|
|
31
|
+
continue
|
|
32
|
+
if data.get("status") in {"planning", "in_progress"}:
|
|
33
|
+
result.append((task_json.parent, data))
|
|
34
|
+
return result
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def is_prd_confirmed(task_dir):
|
|
38
|
+
prd = task_dir / "prd.md"
|
|
39
|
+
if not prd.exists():
|
|
40
|
+
return False
|
|
41
|
+
text = prd.read_text(errors="ignore").lower()
|
|
42
|
+
markers = ["prd confirmed", "confirmed: true", "status: confirmed", "用户已确认", "已确认"]
|
|
43
|
+
return any(marker in text for marker in markers)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def is_planning_artifact(root, tool_input):
|
|
47
|
+
if not isinstance(tool_input, dict):
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
candidate = tool_input.get("path") or tool_input.get("file_path") or tool_input.get("target_file") or ""
|
|
51
|
+
if not candidate:
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
file_path = Path(candidate)
|
|
56
|
+
if not file_path.is_absolute():
|
|
57
|
+
file_path = (root / file_path).resolve()
|
|
58
|
+
relative = file_path.relative_to(root).as_posix()
|
|
59
|
+
except Exception:
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
if not relative.startswith(".trellis/tasks/"):
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
name = Path(relative).name
|
|
66
|
+
return (
|
|
67
|
+
name in {"prd.md", "design.md", "implement.md", "implement.jsonl", "check.jsonl"}
|
|
68
|
+
or "/research/" in relative
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def deny(message):
|
|
73
|
+
print(json.dumps({
|
|
74
|
+
"permission": "deny",
|
|
75
|
+
"user_message": message,
|
|
76
|
+
"agent_message": message
|
|
77
|
+
}))
|
|
78
|
+
sys.exit(0)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def allow():
|
|
82
|
+
print(json.dumps({"permission": "allow"}))
|
|
83
|
+
sys.exit(0)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def main():
|
|
87
|
+
try:
|
|
88
|
+
payload = json.load(sys.stdin)
|
|
89
|
+
except Exception:
|
|
90
|
+
allow()
|
|
91
|
+
|
|
92
|
+
tool_name = payload.get("tool_name") or payload.get("tool", "")
|
|
93
|
+
tool_input = payload.get("tool_input") or payload.get("input") or {}
|
|
94
|
+
cwd = payload.get("cwd") or os.getcwd()
|
|
95
|
+
root = find_root(cwd)
|
|
96
|
+
|
|
97
|
+
is_mutating = tool_name in MUTATING_TOOLS
|
|
98
|
+
command = tool_input.get("command", "") if isinstance(tool_input, dict) else ""
|
|
99
|
+
if tool_name in {"Shell", "Bash"} and MUTATING_SHELL.search(command):
|
|
100
|
+
is_mutating = True
|
|
101
|
+
|
|
102
|
+
if not is_mutating:
|
|
103
|
+
allow()
|
|
104
|
+
|
|
105
|
+
tasks = active_tasks(root)
|
|
106
|
+
if not tasks:
|
|
107
|
+
deny("dream-wf strict: mutating actions require an active Trellis task. Create or start a Trellis task first, or explicitly switch dream-wf to advisory mode.")
|
|
108
|
+
|
|
109
|
+
planning_tasks = [(task_dir, task) for task_dir, task in tasks if task.get("status") == "planning"]
|
|
110
|
+
if planning_tasks:
|
|
111
|
+
if is_planning_artifact(root, tool_input):
|
|
112
|
+
allow()
|
|
113
|
+
unconfirmed = [task for task_dir, task in planning_tasks if not is_prd_confirmed(task_dir)]
|
|
114
|
+
if unconfirmed:
|
|
115
|
+
deny("dream-wf strict: implementation is blocked while this task is in planning and its PRD is not confirmed. Continue grill-me PRD clarification first. Planning artifacts under .trellis/tasks/** are allowed.")
|
|
116
|
+
|
|
117
|
+
allow()
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if __name__ == "__main__":
|
|
121
|
+
main()
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
const mutatingTools = new Set(['Write', 'Edit', 'MultiEdit', 'Delete']);
|
|
5
|
+
const mutatingShell = /\b(rm|mv|cp|mkdir|touch|npm\s+install|pnpm\s+add|yarn\s+add|bun\s+add|git\s+commit|git\s+push)\b/;
|
|
6
|
+
|
|
7
|
+
export default function dreamWfGuard() {
|
|
8
|
+
return {
|
|
9
|
+
name: 'dream-wf-guard',
|
|
10
|
+
async 'tool.before'(input) {
|
|
11
|
+
const toolName = input?.tool || input?.tool_name || '';
|
|
12
|
+
const toolInput = input?.input || input?.tool_input || {};
|
|
13
|
+
const cwd = input?.cwd || process.cwd();
|
|
14
|
+
const root = findRoot(cwd);
|
|
15
|
+
const command = typeof toolInput.command === 'string' ? toolInput.command : '';
|
|
16
|
+
const isMutating = mutatingTools.has(toolName) || ((toolName === 'Shell' || toolName === 'Bash') && mutatingShell.test(command));
|
|
17
|
+
|
|
18
|
+
if (!isMutating) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const tasks = activeTasks(root);
|
|
23
|
+
if (tasks.length === 0) {
|
|
24
|
+
throw new Error('dream-wf strict: mutating actions require an active Trellis task. Create or start a Trellis task first, or switch dream-wf to advisory mode.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const hasPlanningTask = tasks.some(({ task }) => task.status === 'planning');
|
|
28
|
+
if (hasPlanningTask && isPlanningArtifact(root, toolInput)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const hasUnconfirmedPlanningTask = tasks.some(({ taskDir, task }) => task.status === 'planning' && !isPrdConfirmed(taskDir));
|
|
33
|
+
if (hasUnconfirmedPlanningTask) {
|
|
34
|
+
throw new Error('dream-wf strict: implementation is blocked while this task is in planning and its PRD is not confirmed. Continue grill-me PRD clarification first. Planning artifacts under .trellis/tasks/** are allowed.');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function findRoot(cwd) {
|
|
41
|
+
let current = path.resolve(cwd);
|
|
42
|
+
while (true) {
|
|
43
|
+
if (fs.existsSync(path.join(current, '.trellis'))) {
|
|
44
|
+
return current;
|
|
45
|
+
}
|
|
46
|
+
const parent = path.dirname(current);
|
|
47
|
+
if (parent === current) {
|
|
48
|
+
return path.resolve(cwd);
|
|
49
|
+
}
|
|
50
|
+
current = parent;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function activeTasks(root) {
|
|
55
|
+
const tasksDir = path.join(root, '.trellis', 'tasks');
|
|
56
|
+
if (!fs.existsSync(tasksDir)) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return fs.readdirSync(tasksDir, { withFileTypes: true })
|
|
61
|
+
.filter((entry) => entry.isDirectory())
|
|
62
|
+
.map((entry) => {
|
|
63
|
+
const taskDir = path.join(tasksDir, entry.name);
|
|
64
|
+
const taskJson = path.join(taskDir, 'task.json');
|
|
65
|
+
if (!fs.existsSync(taskJson)) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const task = JSON.parse(fs.readFileSync(taskJson, 'utf8'));
|
|
70
|
+
return { taskDir, task };
|
|
71
|
+
} catch {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
.filter(Boolean)
|
|
76
|
+
.filter(({ task }) => task.status === 'planning' || task.status === 'in_progress');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function isPrdConfirmed(taskDir) {
|
|
80
|
+
const prd = path.join(taskDir, 'prd.md');
|
|
81
|
+
if (!fs.existsSync(prd)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const text = fs.readFileSync(prd, 'utf8').toLowerCase();
|
|
85
|
+
return ['prd confirmed', 'confirmed: true', 'status: confirmed', '用户已确认', '已确认'].some((marker) => text.includes(marker));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function isPlanningArtifact(root, toolInput) {
|
|
89
|
+
const candidate = toolInput?.path || toolInput?.file_path || toolInput?.target_file || '';
|
|
90
|
+
if (!candidate) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let relative;
|
|
95
|
+
try {
|
|
96
|
+
const filePath = path.isAbsolute(candidate) ? candidate : path.resolve(root, candidate);
|
|
97
|
+
relative = path.relative(root, filePath).split(path.sep).join('/');
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!relative.startsWith('.trellis/tasks/')) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const name = path.basename(relative);
|
|
107
|
+
return ['prd.md', 'design.md', 'implement.md', 'implement.jsonl', 'check.jsonl'].includes(name) || relative.includes('/research/');
|
|
108
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- DREAM-WF:START -->
|
|
2
|
+
# Dream WF Entry
|
|
3
|
+
|
|
4
|
+
For every software engineering request in this project, use the Dream WF profile on top of Trellis by default. The user does not need to mention Trellis or dream-wf.
|
|
5
|
+
|
|
6
|
+
## Default Routing
|
|
7
|
+
|
|
8
|
+
- First classify the request using Trellis task classification.
|
|
9
|
+
- For conversation-only or tiny inline work, ask whether a Trellis task is needed only if durable tracking would help.
|
|
10
|
+
- For feature work, bug fixes with uncertainty, refactors, architecture decisions, multi-file changes, or unclear requests, create/use a Trellis planning task before implementation.
|
|
11
|
+
|
|
12
|
+
## PRD First, Grill-Me Style
|
|
13
|
+
|
|
14
|
+
During planning, do not start by drafting and writing a speculative PRD. Use `dream-wf-grill-prd` behavior first: inspect available context, ask exactly one high-value question at a time, provide 2-3 options and a recommended answer, then update `prd.md` after the user answers.
|
|
15
|
+
|
|
16
|
+
Do not start implementation until the active Trellis task has a confirmed PRD. Planning artifacts such as `prd.md`, `design.md`, `implement.md`, `implement.jsonl`, `check.jsonl`, and `research/**` are allowed during planning.
|
|
17
|
+
|
|
18
|
+
## MCP Policy
|
|
19
|
+
|
|
20
|
+
- Use `fast-context-mcp` for codebase semantic context.
|
|
21
|
+
- Use `grok-search-mcp` for external docs, live web information, and webpage fetch.
|
|
22
|
+
- If a preferred MCP is unavailable, state the fallback reason before using another tool.
|
|
23
|
+
<!-- DREAM-WF:END -->
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Dream WF Trellis workflow entrypoint
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dream WF Entry
|
|
7
|
+
|
|
8
|
+
For every software engineering request in this project, use the Dream WF profile on top of Trellis by default. The user does not need to mention Trellis or dream-wf.
|
|
9
|
+
|
|
10
|
+
## Default Routing
|
|
11
|
+
|
|
12
|
+
- First classify the request using Trellis task classification.
|
|
13
|
+
- For conversation-only or tiny inline work, ask whether a Trellis task is needed only if durable tracking would help.
|
|
14
|
+
- For feature work, bug fixes with uncertainty, refactors, architecture decisions, multi-file changes, or any unclear request, create/use a Trellis planning task before implementation.
|
|
15
|
+
|
|
16
|
+
## PRD First, Grill-Me Style
|
|
17
|
+
|
|
18
|
+
During planning, do not start by drafting and writing a speculative PRD.
|
|
19
|
+
|
|
20
|
+
Instead:
|
|
21
|
+
|
|
22
|
+
1. Invoke/use the `dream-wf-grill-prd` skill behavior first.
|
|
23
|
+
2. Inspect code, docs, config, existing specs, and task history before asking the user.
|
|
24
|
+
3. Ask exactly one high-value question at a time.
|
|
25
|
+
4. Provide 2-3 options and a recommended answer.
|
|
26
|
+
5. After the user answers, update `prd.md`.
|
|
27
|
+
6. Repeat until blocking open questions are resolved.
|
|
28
|
+
7. Ask for explicit PRD confirmation before implementation.
|
|
29
|
+
|
|
30
|
+
## Implementation Gate
|
|
31
|
+
|
|
32
|
+
Do not start implementation until the active Trellis task has a confirmed PRD. Planning artifacts such as `prd.md`, `design.md`, `implement.md`, `implement.jsonl`, `check.jsonl`, and `research/**` are allowed during planning.
|
|
33
|
+
|
|
34
|
+
## MCP Policy
|
|
35
|
+
|
|
36
|
+
- Use `fast-context-mcp` for codebase semantic context.
|
|
37
|
+
- Use `grok-search-mcp` for external docs, live web information, and webpage fetch.
|
|
38
|
+
- If a preferred MCP is unavailable, state the fallback reason before using another tool.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- DREAM-WF:START -->
|
|
2
|
+
# Dream WF Entry
|
|
3
|
+
|
|
4
|
+
For every software engineering request in this project, use the Dream WF profile on top of Trellis by default. The user does not need to mention Trellis or dream-wf.
|
|
5
|
+
|
|
6
|
+
## Default Routing
|
|
7
|
+
|
|
8
|
+
- First classify the request using Trellis task classification.
|
|
9
|
+
- For conversation-only or tiny inline work, ask whether a Trellis task is needed only if durable tracking would help.
|
|
10
|
+
- For feature work, bug fixes with uncertainty, refactors, architecture decisions, multi-file changes, or unclear requests, create/use a Trellis planning task before implementation.
|
|
11
|
+
|
|
12
|
+
## PRD First, Grill-Me Style
|
|
13
|
+
|
|
14
|
+
During planning, do not start by drafting and writing a speculative PRD. Use `dream-wf-grill-prd` behavior first: inspect available context, ask exactly one high-value question at a time, provide 2-3 options and a recommended answer, then update `prd.md` after the user answers.
|
|
15
|
+
|
|
16
|
+
Do not start implementation until the active Trellis task has a confirmed PRD. Planning artifacts such as `prd.md`, `design.md`, `implement.md`, `implement.jsonl`, `check.jsonl`, and `research/**` are allowed during planning.
|
|
17
|
+
|
|
18
|
+
## MCP Policy
|
|
19
|
+
|
|
20
|
+
- Use `fast-context-mcp` for codebase semantic context.
|
|
21
|
+
- Use `grok-search-mcp` for external docs, live web information, and webpage fetch.
|
|
22
|
+
- If a preferred MCP is unavailable, state the fallback reason before using another tool.
|
|
23
|
+
<!-- DREAM-WF:END -->
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dream-wf-grill-prd
|
|
3
|
+
description: |
|
|
4
|
+
Use during Trellis planning when creating or refining a PRD. Applies grill-me style clarification: ask one question at a time, inspect code before asking, provide options and a recommended answer, update prd.md after each decision, and require PRD confirmation before implementation.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dream WF Grill PRD
|
|
8
|
+
|
|
9
|
+
You are the Dream WF PRD clarification skill running inside a Trellis planning task.
|
|
10
|
+
|
|
11
|
+
This skill replaces only the interview style of open-ended brainstorming. It does not replace Trellis task creation, `prd.md`, `design.md`, `implement.md`, `implement.jsonl`, `check.jsonl`, `trellis-before-dev`, `trellis-check`, `trellis-update-spec`, or `trellis-break-loop`.
|
|
12
|
+
|
|
13
|
+
## Trigger Check
|
|
14
|
+
|
|
15
|
+
Use this skill when:
|
|
16
|
+
|
|
17
|
+
- A Trellis task is in `planning`.
|
|
18
|
+
- A PRD is being created or refined.
|
|
19
|
+
- Requirements are ambiguous, multi-step, architectural, or likely to affect specs.
|
|
20
|
+
- The user asks to plan, design, scope, or clarify a task.
|
|
21
|
+
|
|
22
|
+
If the task is a small inline change and the user declined Trellis task creation, do not force this skill.
|
|
23
|
+
|
|
24
|
+
## Required Behavior
|
|
25
|
+
|
|
26
|
+
1. Read the active task directory and existing `prd.md` if present.
|
|
27
|
+
2. Inspect relevant code, configs, docs, existing specs, and task history before asking the user.
|
|
28
|
+
3. Do not start by writing a speculative initial PRD.
|
|
29
|
+
4. Ask exactly one high-value question first.
|
|
30
|
+
5. For each question, provide 2-3 concrete options and your recommended answer.
|
|
31
|
+
6. After the user answers, update `prd.md` immediately.
|
|
32
|
+
7. Track unresolved items under `Open Questions`.
|
|
33
|
+
8. Move confirmed answers into `Requirements`, `Acceptance Criteria`, `Decisions`, `Technical Notes`, or `Out of Scope`.
|
|
34
|
+
9. Add spec candidates when a user answer or design decision should become a project convention.
|
|
35
|
+
10. Continue until no blocking open questions remain.
|
|
36
|
+
11. Show the complete PRD and ask for explicit confirmation before implementation starts.
|
|
37
|
+
|
|
38
|
+
## PRD Structure
|
|
39
|
+
|
|
40
|
+
Use or preserve these sections:
|
|
41
|
+
|
|
42
|
+
```markdown
|
|
43
|
+
# <Task Title>
|
|
44
|
+
|
|
45
|
+
## Goal
|
|
46
|
+
<What and why in one sentence.>
|
|
47
|
+
|
|
48
|
+
## In Scope
|
|
49
|
+
- ...
|
|
50
|
+
|
|
51
|
+
## Out of Scope
|
|
52
|
+
- ...
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
- ...
|
|
56
|
+
|
|
57
|
+
## Acceptance Criteria
|
|
58
|
+
- [ ] ...
|
|
59
|
+
|
|
60
|
+
## Decisions
|
|
61
|
+
- Context: ...
|
|
62
|
+
- Decision: ...
|
|
63
|
+
- Consequences: ...
|
|
64
|
+
|
|
65
|
+
## Technical Notes
|
|
66
|
+
- ...
|
|
67
|
+
|
|
68
|
+
## Spec Candidates
|
|
69
|
+
- Candidate: ...
|
|
70
|
+
Evidence: ...
|
|
71
|
+
Needs user confirmation: yes/no
|
|
72
|
+
|
|
73
|
+
## Open Questions
|
|
74
|
+
- ...
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Question Format
|
|
78
|
+
|
|
79
|
+
Use this format for each question:
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
Question: <one decision to resolve>
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
1. <option A>
|
|
86
|
+
2. <option B>
|
|
87
|
+
3. <option C if useful>
|
|
88
|
+
|
|
89
|
+
Recommended: <your recommendation and why>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Stop Condition
|
|
93
|
+
|
|
94
|
+
Do not begin implementation. End by asking for PRD confirmation or by reporting the exact blocker that prevents confirmation.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dream-wf-mcp-policy
|
|
3
|
+
description: |
|
|
4
|
+
Use before codebase exploration, external documentation lookup, live web research, or webpage fetching. Enforces Dream WF MCP priority: fast-context-mcp for semantic code context and grok-search-mcp for external web/docs/fetch tasks.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dream WF MCP Policy
|
|
8
|
+
|
|
9
|
+
Classify the information need before choosing a search or fetch tool.
|
|
10
|
+
|
|
11
|
+
## Codebase Semantic Context
|
|
12
|
+
|
|
13
|
+
Use `fast-context-mcp` first when the request needs semantic codebase understanding.
|
|
14
|
+
|
|
15
|
+
Preferred tool:
|
|
16
|
+
|
|
17
|
+
- `fast_context_search`
|
|
18
|
+
|
|
19
|
+
Use for:
|
|
20
|
+
|
|
21
|
+
- Finding where behavior lives.
|
|
22
|
+
- Tracing architecture or cross-file flows.
|
|
23
|
+
- Discovering relevant files from natural language.
|
|
24
|
+
- Planning implementation or PRD context collection.
|
|
25
|
+
|
|
26
|
+
Fallback:
|
|
27
|
+
|
|
28
|
+
- Use exact search only for known symbols, strings, paths, or narrow scoped patterns.
|
|
29
|
+
- If `fast-context-mcp` is unavailable, state the fallback reason before using another tool.
|
|
30
|
+
|
|
31
|
+
## External Docs and Web Information
|
|
32
|
+
|
|
33
|
+
Use `grok-search-mcp` first for external documentation, live technical information, webpage fetch, and source discovery.
|
|
34
|
+
|
|
35
|
+
Preferred tools:
|
|
36
|
+
|
|
37
|
+
- `web_search`
|
|
38
|
+
- `web_fetch`
|
|
39
|
+
- `web_map`
|
|
40
|
+
- `get_sources`
|
|
41
|
+
|
|
42
|
+
Fallback:
|
|
43
|
+
|
|
44
|
+
- Use built-in web tools only if `grok-search-mcp` is unavailable or insufficient.
|
|
45
|
+
- State the fallback reason before using another web tool.
|
|
46
|
+
|
|
47
|
+
## Strict Mode
|
|
48
|
+
|
|
49
|
+
In strict mode, do not silently bypass the preferred MCP. If the preferred tool is missing, say so and proceed with the narrowest fallback that can answer the question.
|
|
50
|
+
|
|
51
|
+
## Security
|
|
52
|
+
|
|
53
|
+
Never write API keys, tokens, or MCP secrets into tracked project files. Use environment variables, user-level MCP config, or secret managers.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Dream WF MCP Policy
|
|
2
|
+
|
|
3
|
+
This project prefers MCP tools in a fixed order.
|
|
4
|
+
|
|
5
|
+
## Codebase Semantic Search
|
|
6
|
+
|
|
7
|
+
Prefer `fast-context-mcp` and `fast_context_search` for semantic codebase understanding:
|
|
8
|
+
|
|
9
|
+
- Behavior discovery.
|
|
10
|
+
- Architecture tracing.
|
|
11
|
+
- Natural-language code search.
|
|
12
|
+
- Planning context collection.
|
|
13
|
+
|
|
14
|
+
Use exact search only for known symbols, strings, paths, or narrow patterns.
|
|
15
|
+
|
|
16
|
+
## External Web and Documentation
|
|
17
|
+
|
|
18
|
+
Prefer `grok-search-mcp` for external information:
|
|
19
|
+
|
|
20
|
+
- `web_search` for live search and technical docs.
|
|
21
|
+
- `web_fetch` for webpage content.
|
|
22
|
+
- `web_map` for site structure.
|
|
23
|
+
- `get_sources` for source URLs.
|
|
24
|
+
|
|
25
|
+
Built-in web tools are fallback only. State the fallback reason before using them.
|
|
26
|
+
|
|
27
|
+
## Security
|
|
28
|
+
|
|
29
|
+
Do not commit API keys, tokens, or MCP secrets into project files.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Dream WF PRD Policy
|
|
2
|
+
|
|
3
|
+
This project uses `dream-wf` on top of Trellis.
|
|
4
|
+
|
|
5
|
+
## Policy
|
|
6
|
+
|
|
7
|
+
- Keep Trellis task lifecycle and artifacts.
|
|
8
|
+
- Use grill-me style clarification during PRD creation and refinement.
|
|
9
|
+
- Do not start planning by writing a speculative initial PRD.
|
|
10
|
+
- Ask one high-value question first.
|
|
11
|
+
- Provide 2-3 options and a recommended answer for each question.
|
|
12
|
+
- Inspect code, docs, config, existing specs, and task history before asking the user.
|
|
13
|
+
- Update `prd.md` only after each confirmed answer, confirmed existing fact, or explicit decision.
|
|
14
|
+
- Treat task creation consent and implementation approval as separate gates.
|
|
15
|
+
- Do not start implementation until the PRD is confirmed.
|
|
16
|
+
|
|
17
|
+
## Initial Spec Candidates
|
|
18
|
+
|
|
19
|
+
During bootstrap or planning, spec candidates may come from:
|
|
20
|
+
|
|
21
|
+
- User answers.
|
|
22
|
+
- PRD decisions.
|
|
23
|
+
- Design decisions.
|
|
24
|
+
- Verified codebase facts.
|
|
25
|
+
- Existing tests, configs, docs, and conventions.
|
|
26
|
+
|
|
27
|
+
Initial spec candidates require user review before they become stable project conventions.
|