@curdx/flow 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 +21 -87
- package/LICENSE +1 -1
- package/README.md +28 -129
- package/dist/index.mjs +995 -0
- package/package.json +33 -44
- package/.claude-plugin/marketplace.json +0 -48
- package/.claude-plugin/plugin.json +0 -52
- package/agent-preamble/preamble.md +0 -314
- package/agents/flow-adversary.md +0 -203
- package/agents/flow-architect.md +0 -198
- package/agents/flow-brownfield-analyst.md +0 -143
- package/agents/flow-debugger.md +0 -321
- package/agents/flow-edge-hunter.md +0 -289
- package/agents/flow-executor.md +0 -269
- package/agents/flow-orchestrator.md +0 -145
- package/agents/flow-planner.md +0 -247
- package/agents/flow-product-designer.md +0 -159
- package/agents/flow-qa-engineer.md +0 -282
- package/agents/flow-researcher.md +0 -166
- package/agents/flow-reviewer.md +0 -304
- package/agents/flow-security-auditor.md +0 -401
- package/agents/flow-triage-analyst.md +0 -272
- package/agents/flow-ui-researcher.md +0 -230
- package/agents/flow-ux-designer.md +0 -221
- package/agents/flow-verifier.md +0 -350
- package/bin/curdx-flow +0 -5
- package/bin/curdx-flow-state +0 -104
- package/bin/curdx-flow.js +0 -54
- package/cli/README.md +0 -104
- package/cli/doctor-workflow.js +0 -483
- package/cli/doctor.js +0 -73
- package/cli/help.js +0 -59
- package/cli/install-bundled-mcps.js +0 -37
- package/cli/install-companions.js +0 -19
- package/cli/install-context7-config.js +0 -80
- package/cli/install-curdx-plugin.js +0 -96
- package/cli/install-language.js +0 -35
- package/cli/install-next-steps.js +0 -29
- package/cli/install-options.js +0 -9
- package/cli/install-paths.js +0 -52
- package/cli/install-recommended-plugins.js +0 -104
- package/cli/install-required-plugins.js +0 -57
- package/cli/install-self-update.js +0 -62
- package/cli/install-workflow.js +0 -209
- package/cli/install.js +0 -101
- package/cli/lib/claude-commands.js +0 -41
- package/cli/lib/claude-ops.js +0 -47
- package/cli/lib/claude.js +0 -183
- package/cli/lib/config.js +0 -24
- package/cli/lib/doctor-claude-settings.js +0 -1186
- package/cli/lib/doctor-report.js +0 -978
- package/cli/lib/doctor-runtime-environment.js +0 -196
- package/cli/lib/frontmatter.js +0 -44
- package/cli/lib/json-schema.js +0 -57
- package/cli/lib/logging.js +0 -25
- package/cli/lib/process.js +0 -60
- package/cli/lib/prompts.js +0 -135
- package/cli/lib/runtime.js +0 -107
- package/cli/lib/semver.js +0 -109
- package/cli/lib/version.js +0 -12
- package/cli/protocols-body.md +0 -22
- package/cli/protocols.js +0 -162
- package/cli/registry.js +0 -123
- package/cli/router.js +0 -49
- package/cli/uninstall-actions.js +0 -360
- package/cli/uninstall-workflow.js +0 -146
- package/cli/uninstall.js +0 -42
- package/cli/upgrade-workflow.js +0 -80
- package/cli/upgrade.js +0 -91
- package/cli/utils.js +0 -40
- package/gates/adversarial-review-gate.md +0 -219
- package/gates/coverage-audit-gate.md +0 -182
- package/gates/devex-gate.md +0 -254
- package/gates/edge-case-gate.md +0 -194
- package/gates/karpathy-gate.md +0 -130
- package/gates/security-gate.md +0 -218
- package/gates/tdd-gate.md +0 -182
- package/gates/test-quality-gate.md +0 -59
- package/gates/verification-gate.md +0 -179
- package/hooks/hooks.json +0 -130
- package/hooks/scripts/common.sh +0 -237
- package/hooks/scripts/config-change-guard.sh +0 -94
- package/hooks/scripts/flow-context-watch.sh +0 -94
- package/hooks/scripts/inject-karpathy.sh +0 -53
- package/hooks/scripts/quick-mode-guard.sh +0 -69
- package/hooks/scripts/session-start.sh +0 -94
- package/hooks/scripts/session-title.sh +0 -87
- package/hooks/scripts/stop-watcher.sh +0 -231
- package/hooks/scripts/subagent-artifact-guard.sh +0 -92
- package/hooks/scripts/subagent-statusline.sh +0 -111
- package/hooks/scripts/task-lifecycle-guard.sh +0 -106
- package/hooks/scripts/teammate-idle-guard.sh +0 -83
- package/knowledge/artifact-output-discipline.md +0 -24
- package/knowledge/artifact-summary-contracts.md +0 -50
- package/knowledge/atomic-commits.md +0 -262
- package/knowledge/claude-code-runtime-contracts.md +0 -240
- package/knowledge/epic-decomposition.md +0 -307
- package/knowledge/execution-strategies.md +0 -303
- package/knowledge/karpathy-guidelines.md +0 -219
- package/knowledge/planning-reviews.md +0 -211
- package/knowledge/poc-first-workflow.md +0 -223
- package/knowledge/review-feedback-intake.md +0 -57
- package/knowledge/spec-driven-development.md +0 -180
- package/knowledge/systematic-debugging.md +0 -378
- package/knowledge/two-stage-review.md +0 -249
- package/knowledge/wave-execution.md +0 -403
- package/monitors/monitors.json +0 -8
- package/monitors/scripts/flow-state-monitor.sh +0 -102
- package/output-styles/curdx-evidence-first.md +0 -34
- package/output-styles/curdx-fast-mode.md +0 -42
- package/output-styles/curdx-spec-mode.md +0 -46
- package/schemas/agent-frontmatter.schema.json +0 -66
- package/schemas/config.schema.json +0 -134
- package/schemas/gate-frontmatter.schema.json +0 -30
- package/schemas/hooks.schema.json +0 -115
- package/schemas/output-style-frontmatter.schema.json +0 -22
- package/schemas/plugin-manifest.schema.json +0 -436
- package/schemas/plugin-settings.schema.json +0 -29
- package/schemas/skill-frontmatter.schema.json +0 -177
- package/schemas/spec-frontmatter.schema.json +0 -42
- package/schemas/spec-state.schema.json +0 -165
- package/settings.json +0 -8
- package/skills/brownfield-index/SKILL.md +0 -53
- package/skills/brownfield-index/references/applicability.md +0 -12
- package/skills/brownfield-index/references/handoff.md +0 -8
- package/skills/brownfield-index/references/index-contract.md +0 -10
- package/skills/browser-qa/SKILL.md +0 -39
- package/skills/browser-qa/references/handoff.md +0 -6
- package/skills/browser-qa/references/prerequisites.md +0 -10
- package/skills/browser-qa/references/qa-contract.md +0 -20
- package/skills/cancel/SKILL.md +0 -41
- package/skills/cancel/references/destructive-mode.md +0 -17
- package/skills/cancel/references/reporting.md +0 -18
- package/skills/cancel/references/state-recovery.md +0 -30
- package/skills/cancel/references/target-resolution.md +0 -7
- package/skills/debug/SKILL.md +0 -45
- package/skills/debug/references/context-gathering.md +0 -11
- package/skills/debug/references/failure-guard.md +0 -25
- package/skills/debug/references/intake.md +0 -12
- package/skills/debug/references/phase-workflow.md +0 -34
- package/skills/debug/references/reporting.md +0 -20
- package/skills/epic/SKILL.md +0 -39
- package/skills/epic/references/epic-artifacts.md +0 -20
- package/skills/epic/references/epic-intake.md +0 -9
- package/skills/epic/references/slice-handoff.md +0 -16
- package/skills/fast/SKILL.md +0 -62
- package/skills/fast/references/applicability.md +0 -25
- package/skills/fast/references/clarification.md +0 -20
- package/skills/fast/references/execution-contract.md +0 -56
- package/skills/help/SKILL.md +0 -55
- package/skills/help/references/dispatch.md +0 -20
- package/skills/help/references/overview.md +0 -39
- package/skills/help/references/troubleshoot.md +0 -47
- package/skills/help/references/workflow.md +0 -37
- package/skills/implement/SKILL.md +0 -104
- package/skills/implement/references/error-recovery.md +0 -36
- package/skills/implement/references/linear-execution.md +0 -43
- package/skills/implement/references/native-task-sync.md +0 -107
- package/skills/implement/references/preflight.md +0 -43
- package/skills/implement/references/progress-contract.md +0 -36
- package/skills/implement/references/state-init.md +0 -36
- package/skills/implement/references/stop-hook-execution.md +0 -50
- package/skills/implement/references/strategy-router.md +0 -38
- package/skills/implement/references/subagent-execution.md +0 -57
- package/skills/implement/references/wave-execution.md +0 -180
- package/skills/init/SKILL.md +0 -49
- package/skills/init/references/gitignore-and-health.md +0 -26
- package/skills/init/references/next-steps.md +0 -22
- package/skills/init/references/preflight.md +0 -15
- package/skills/init/references/scaffold-contract.md +0 -27
- package/skills/review/SKILL.md +0 -82
- package/skills/review/references/optional-passes.md +0 -48
- package/skills/review/references/preflight.md +0 -38
- package/skills/review/references/report-contract.md +0 -49
- package/skills/review/references/reporting.md +0 -20
- package/skills/review/references/stage-execution.md +0 -32
- package/skills/security-audit/SKILL.md +0 -47
- package/skills/security-audit/references/audit-contract.md +0 -21
- package/skills/security-audit/references/gate-handoff.md +0 -8
- package/skills/security-audit/references/scope-and-depth.md +0 -9
- package/skills/spec/SKILL.md +0 -100
- package/skills/spec/references/artifact-landing.md +0 -31
- package/skills/spec/references/phase-execution.md +0 -50
- package/skills/spec/references/planning-review.md +0 -31
- package/skills/spec/references/preflight-and-routing.md +0 -46
- package/skills/spec/references/reporting.md +0 -21
- package/skills/start/SKILL.md +0 -84
- package/skills/start/references/branch-routing.md +0 -51
- package/skills/start/references/mode-semantics.md +0 -12
- package/skills/start/references/preflight.md +0 -13
- package/skills/start/references/reporting.md +0 -20
- package/skills/start/references/state-seeding.md +0 -44
- package/skills/start/references/workflow-handoff.md +0 -26
- package/skills/status/SKILL.md +0 -41
- package/skills/status/references/gather-contract.md +0 -30
- package/skills/status/references/health-rules.md +0 -27
- package/skills/status/references/output-contract.md +0 -25
- package/skills/status/references/preflight.md +0 -10
- package/skills/status/references/recovery-hints.md +0 -18
- package/skills/ui-sketch/SKILL.md +0 -39
- package/skills/ui-sketch/references/brief-intake.md +0 -10
- package/skills/ui-sketch/references/iteration-handoff.md +0 -5
- package/skills/ui-sketch/references/variant-contract.md +0 -15
- package/skills/verify/SKILL.md +0 -56
- package/skills/verify/references/evidence-workflow.md +0 -39
- package/skills/verify/references/output-contract.md +0 -23
- package/skills/verify/references/preflight.md +0 -11
- package/skills/verify/references/report-handoff.md +0 -35
- package/skills/verify/references/strict-mode.md +0 -12
- package/templates/CONTEXT.md.tmpl +0 -53
- package/templates/PROJECT.md.tmpl +0 -59
- package/templates/ROADMAP.md.tmpl +0 -50
- package/templates/STATE.md.tmpl +0 -49
- package/templates/config.json.tmpl +0 -51
- package/templates/design.md.tmpl +0 -83
- package/templates/progress.md.tmpl +0 -77
- package/templates/requirements.md.tmpl +0 -76
- package/templates/research.md.tmpl +0 -83
- package/templates/tasks.md.tmpl +0 -107
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# CurDX-Flow SubagentStop Hook
|
|
3
|
-
# Blocks successful subagent completion if the expected artifact never landed on disk.
|
|
4
|
-
#
|
|
5
|
-
# Why:
|
|
6
|
-
# - long markdown/report-writing agents can truncate near the end of a run
|
|
7
|
-
# - users then see a cheerful success summary but the actual file is missing or tiny
|
|
8
|
-
# - latest Claude Code hooks expose SubagentStop with agent_type + last_assistant_message,
|
|
9
|
-
# which lets us guard only "success-looking" exits while allowing genuine precondition failures
|
|
10
|
-
|
|
11
|
-
set -u
|
|
12
|
-
|
|
13
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
-
. "$SCRIPT_DIR/common.sh"
|
|
15
|
-
|
|
16
|
-
INPUT="$(cat 2>/dev/null || echo "{}")"
|
|
17
|
-
FLOW_ROOT="$(resolve_flow_root 2>/dev/null || true)"
|
|
18
|
-
|
|
19
|
-
if ! has_python3; then
|
|
20
|
-
# Without JSON parsing, fail open rather than blocking subagents blindly.
|
|
21
|
-
exit 0
|
|
22
|
-
fi
|
|
23
|
-
|
|
24
|
-
export SUBAGENT_GUARD_INPUT="$INPUT"
|
|
25
|
-
|
|
26
|
-
AGENT_TYPE="$(python3 -c 'import json, os
|
|
27
|
-
try:
|
|
28
|
-
data = json.loads(os.environ["SUBAGENT_GUARD_INPUT"])
|
|
29
|
-
print(data.get("agent_type", ""))
|
|
30
|
-
except Exception:
|
|
31
|
-
print("")
|
|
32
|
-
' 2>/dev/null)"
|
|
33
|
-
|
|
34
|
-
LAST_MESSAGE="$(python3 -c 'import json, os
|
|
35
|
-
try:
|
|
36
|
-
data = json.loads(os.environ["SUBAGENT_GUARD_INPUT"])
|
|
37
|
-
print((data.get("last_assistant_message") or "").strip())
|
|
38
|
-
except Exception:
|
|
39
|
-
print("")
|
|
40
|
-
' 2>/dev/null)"
|
|
41
|
-
|
|
42
|
-
looks_like_success() {
|
|
43
|
-
local msg="${1:-}"
|
|
44
|
-
printf '%s' "$msg" | grep -Eq '(^✓| generated$| generated\n|Wrote |Review complete|Requirements done|Research complete|UI Sketch generation complete|Report:|Next:|TASK_COMPLETE|ALL_TASKS_COMPLETE)'
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
completed_task_id() {
|
|
48
|
-
local msg="${1:-}"
|
|
49
|
-
printf '%s' "$msg" | sed -nE 's/.*TASK_COMPLETE:[[:space:]]*([0-9]+(\.([0-9]+|VF|X(\+[0-9]+)?))*).*/\1/p' | head -1
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
artifact_target=""
|
|
53
|
-
minimum_size=200
|
|
54
|
-
|
|
55
|
-
case "$AGENT_TYPE" in
|
|
56
|
-
flow-executor)
|
|
57
|
-
curdx_resolve_artifact_contract "$AGENT_TYPE" "$LAST_MESSAGE" "$FLOW_ROOT" || exit 0
|
|
58
|
-
artifact_target="$CURDX_ARTIFACT_TARGET"
|
|
59
|
-
minimum_size="$CURDX_ARTIFACT_MIN_SIZE"
|
|
60
|
-
if printf '%s' "$LAST_MESSAGE" | grep -q 'ALL_TASKS_COMPLETE'; then
|
|
61
|
-
exit 0
|
|
62
|
-
fi
|
|
63
|
-
task_id="$(completed_task_id "$LAST_MESSAGE")"
|
|
64
|
-
[ -z "$task_id" ] && exit 0
|
|
65
|
-
if grep -Eq "^- \\[x\\] \\*\\*${task_id//./\\.}\\*\\*" "$artifact_target" 2>/dev/null; then
|
|
66
|
-
exit 0
|
|
67
|
-
fi
|
|
68
|
-
emit_subagentstop_block "[CurDX-Flow subagent-artifact-guard] flow-executor emitted TASK_COMPLETE: ${task_id}, but ${artifact_target} does not mark that task as [x]. Update tasks.md and the spec progress/state before stopping."
|
|
69
|
-
exit 0
|
|
70
|
-
;;
|
|
71
|
-
*)
|
|
72
|
-
curdx_resolve_artifact_contract "$AGENT_TYPE" "$LAST_MESSAGE" "$FLOW_ROOT" || exit 0
|
|
73
|
-
artifact_target="$CURDX_ARTIFACT_TARGET"
|
|
74
|
-
minimum_size="$CURDX_ARTIFACT_MIN_SIZE"
|
|
75
|
-
;;
|
|
76
|
-
esac
|
|
77
|
-
|
|
78
|
-
if [ -f "$artifact_target" ]; then
|
|
79
|
-
size="$(wc -c < "$artifact_target" 2>/dev/null | tr -d ' ')"
|
|
80
|
-
if [ "${size:-0}" -ge "$minimum_size" ]; then
|
|
81
|
-
exit 0
|
|
82
|
-
fi
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
if ! looks_like_success "$LAST_MESSAGE"; then
|
|
86
|
-
# The subagent appears to be stopping because of a real precondition failure,
|
|
87
|
-
# clarification request, or other non-success path. Let that response through.
|
|
88
|
-
exit 0
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
emit_subagentstop_block "[CurDX-Flow subagent-artifact-guard] ${AGENT_TYPE} is stopping with a success summary, but ${artifact_target} is missing or too small. Write the full artifact to disk first, then respond with the minimal completion summary only."
|
|
92
|
-
exit 0
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# CurDX-Flow subagentStatusLine command.
|
|
3
|
-
# Reads the official subagent status-line JSON payload from stdin and emits
|
|
4
|
-
# one JSON line per CurDX-Flow subagent row that should be overridden.
|
|
5
|
-
|
|
6
|
-
set -u
|
|
7
|
-
|
|
8
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
-
. "$SCRIPT_DIR/common.sh"
|
|
10
|
-
|
|
11
|
-
INPUT="$(cat 2>/dev/null || echo "{}")"
|
|
12
|
-
|
|
13
|
-
if ! has_python3; then
|
|
14
|
-
exit 0
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
export CURDX_SUBAGENT_STATUSLINE_INPUT="$INPUT"
|
|
18
|
-
|
|
19
|
-
python3 <<'PY'
|
|
20
|
-
import json
|
|
21
|
-
import os
|
|
22
|
-
from pathlib import Path
|
|
23
|
-
|
|
24
|
-
try:
|
|
25
|
-
data = json.loads(os.environ.get("CURDX_SUBAGENT_STATUSLINE_INPUT", "{}"))
|
|
26
|
-
except Exception:
|
|
27
|
-
raise SystemExit(0)
|
|
28
|
-
|
|
29
|
-
columns = data.get("columns")
|
|
30
|
-
try:
|
|
31
|
-
columns = int(columns)
|
|
32
|
-
except Exception:
|
|
33
|
-
columns = 100
|
|
34
|
-
columns = max(40, columns)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def flow_type(task):
|
|
38
|
-
raw = str(task.get("type") or task.get("name") or task.get("label") or "")
|
|
39
|
-
if raw.startswith("curdx-flow:"):
|
|
40
|
-
raw = raw.split(":", 1)[1]
|
|
41
|
-
return raw
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def is_flow_task(task):
|
|
45
|
-
values = [
|
|
46
|
-
task.get("type"),
|
|
47
|
-
task.get("name"),
|
|
48
|
-
task.get("label"),
|
|
49
|
-
task.get("description"),
|
|
50
|
-
]
|
|
51
|
-
return any(str(value or "").startswith(("flow-", "curdx-flow:flow-")) for value in values)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def active_spec(cwd):
|
|
55
|
-
if not cwd:
|
|
56
|
-
return ""
|
|
57
|
-
try:
|
|
58
|
-
current = Path(cwd).resolve()
|
|
59
|
-
except Exception:
|
|
60
|
-
return ""
|
|
61
|
-
for candidate in [current, *current.parents]:
|
|
62
|
-
try:
|
|
63
|
-
value = (candidate / ".flow" / ".active-spec").read_text(encoding="utf-8").strip()
|
|
64
|
-
except Exception:
|
|
65
|
-
continue
|
|
66
|
-
return value[:40]
|
|
67
|
-
return ""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def token_label(value):
|
|
71
|
-
try:
|
|
72
|
-
count = int(value)
|
|
73
|
-
except Exception:
|
|
74
|
-
return ""
|
|
75
|
-
if count >= 1000:
|
|
76
|
-
return f"{count / 1000:.1f}k tok"
|
|
77
|
-
return f"{count} tok"
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def clamp(text):
|
|
81
|
-
if len(text) <= columns:
|
|
82
|
-
return text
|
|
83
|
-
if columns <= 4:
|
|
84
|
-
return text[:columns]
|
|
85
|
-
return text[: columns - 3] + "..."
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
for task in data.get("tasks") or []:
|
|
89
|
-
if not isinstance(task, dict) or not is_flow_task(task):
|
|
90
|
-
continue
|
|
91
|
-
|
|
92
|
-
task_id = task.get("id")
|
|
93
|
-
if not task_id:
|
|
94
|
-
continue
|
|
95
|
-
|
|
96
|
-
parts = ["[curdx-flow]", flow_type(task) or "flow-agent"]
|
|
97
|
-
|
|
98
|
-
status = str(task.get("status") or "").strip()
|
|
99
|
-
if status:
|
|
100
|
-
parts.append(status)
|
|
101
|
-
|
|
102
|
-
spec = active_spec(task.get("cwd"))
|
|
103
|
-
if spec:
|
|
104
|
-
parts.append(f"spec:{spec}")
|
|
105
|
-
|
|
106
|
-
tokens = token_label(task.get("tokenCount"))
|
|
107
|
-
if tokens:
|
|
108
|
-
parts.append(tokens)
|
|
109
|
-
|
|
110
|
-
print(json.dumps({"id": str(task_id), "content": clamp(" | ".join(parts))}, ensure_ascii=True))
|
|
111
|
-
PY
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
set -u
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
. "$SCRIPT_DIR/common.sh"
|
|
7
|
-
|
|
8
|
-
INPUT="$(cat 2>/dev/null || echo "{}")"
|
|
9
|
-
|
|
10
|
-
if ! has_python3; then
|
|
11
|
-
exit 0
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
export CURDX_TASK_GUARD_INPUT="$INPUT"
|
|
15
|
-
|
|
16
|
-
read_json_field() {
|
|
17
|
-
local field="$1"
|
|
18
|
-
python3 - "$field" <<'PY' 2>/dev/null
|
|
19
|
-
import json
|
|
20
|
-
import os
|
|
21
|
-
import sys
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
data = json.loads(os.environ.get("CURDX_TASK_GUARD_INPUT", "{}"))
|
|
25
|
-
except Exception:
|
|
26
|
-
data = {}
|
|
27
|
-
|
|
28
|
-
field = sys.argv[1]
|
|
29
|
-
value = data.get(field, "")
|
|
30
|
-
if isinstance(value, str):
|
|
31
|
-
value = value.strip()
|
|
32
|
-
elif value is None:
|
|
33
|
-
value = ""
|
|
34
|
-
print(value)
|
|
35
|
-
PY
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
HOOK_EVENT_NAME="$(read_json_field hook_event_name)"
|
|
39
|
-
TASK_SUBJECT="$(read_json_field task_subject)"
|
|
40
|
-
TASK_DESCRIPTION="$(read_json_field task_description)"
|
|
41
|
-
|
|
42
|
-
FLOW_ROOT="$(resolve_flow_root 2>/dev/null || true)"
|
|
43
|
-
[ -n "$FLOW_ROOT" ] || exit 0
|
|
44
|
-
|
|
45
|
-
ACTIVE_SPEC="$(cat "$FLOW_ROOT/.flow/.active-spec" 2>/dev/null || true)"
|
|
46
|
-
[ -n "$ACTIVE_SPEC" ] || exit 0
|
|
47
|
-
|
|
48
|
-
TASKS_FILE="$FLOW_ROOT/.flow/specs/$ACTIVE_SPEC/tasks.md"
|
|
49
|
-
[ -f "$TASKS_FILE" ] || exit 0
|
|
50
|
-
|
|
51
|
-
extract_curdx_task_id() {
|
|
52
|
-
python3 <<'PY' 2>/dev/null
|
|
53
|
-
import os
|
|
54
|
-
import re
|
|
55
|
-
|
|
56
|
-
subject = os.environ.get("CURDX_TASK_GUARD_SUBJECT", "").strip()
|
|
57
|
-
patterns = [
|
|
58
|
-
r'^\[P\]\s+([0-9]+(?:\.([0-9]+|VF|X(\+[0-9]+)?))*)\b',
|
|
59
|
-
r'^\[VERIFY\]\s+([0-9]+(?:\.([0-9]+|VF|X(\+[0-9]+)?))*)\b',
|
|
60
|
-
r'^([0-9]+(?:\.([0-9]+|VF|X(\+[0-9]+)?))*)\b',
|
|
61
|
-
]
|
|
62
|
-
for pattern in patterns:
|
|
63
|
-
match = re.match(pattern, subject)
|
|
64
|
-
if match:
|
|
65
|
-
print(match.group(1))
|
|
66
|
-
break
|
|
67
|
-
PY
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export CURDX_TASK_GUARD_SUBJECT="$TASK_SUBJECT"
|
|
71
|
-
CURDX_TASK_ID="$(extract_curdx_task_id)"
|
|
72
|
-
[ -n "$CURDX_TASK_ID" ] || exit 0
|
|
73
|
-
|
|
74
|
-
task_exists() {
|
|
75
|
-
local escaped_id
|
|
76
|
-
escaped_id="$(printf '%s' "$1" | sed 's/[.[\*^$()+?{|]/\\&/g')"
|
|
77
|
-
grep -Eq "^- \\[[ xX]\\] \\*\\*${escaped_id}\\*\\*" "$TASKS_FILE" 2>/dev/null
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
task_completed() {
|
|
81
|
-
local escaped_id
|
|
82
|
-
escaped_id="$(printf '%s' "$1" | sed 's/[.[\*^$()+?{|]/\\&/g')"
|
|
83
|
-
grep -Eq "^- \\[[xX]\\] \\*\\*${escaped_id}\\*\\*" "$TASKS_FILE" 2>/dev/null
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if ! task_exists "$CURDX_TASK_ID"; then
|
|
87
|
-
printf '%s\n' "[CurDX-Flow task-lifecycle-guard] Native task '${TASK_SUBJECT}' references CurDX task ${CURDX_TASK_ID}, but ${TASKS_FILE} does not contain that task id. Rebuild native tasks from tasks.md before proceeding." >&2
|
|
88
|
-
exit 2
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
case "$HOOK_EVENT_NAME" in
|
|
92
|
-
TaskCreated)
|
|
93
|
-
if [ -z "$TASK_DESCRIPTION" ]; then
|
|
94
|
-
printf '%s\n' "[CurDX-Flow task-lifecycle-guard] Native task '${TASK_SUBJECT}' is missing a description. Include a compact description derived from 'Done when' and 'Verify' so the task list mirrors tasks.md faithfully." >&2
|
|
95
|
-
exit 2
|
|
96
|
-
fi
|
|
97
|
-
;;
|
|
98
|
-
TaskCompleted)
|
|
99
|
-
if ! task_completed "$CURDX_TASK_ID"; then
|
|
100
|
-
printf '%s\n' "[CurDX-Flow task-lifecycle-guard] Native task '${TASK_SUBJECT}' cannot be marked completed before ${TASKS_FILE} marks ${CURDX_TASK_ID} as [x]. Update tasks.md and disk-backed state first, then complete the native task." >&2
|
|
101
|
-
exit 2
|
|
102
|
-
fi
|
|
103
|
-
;;
|
|
104
|
-
esac
|
|
105
|
-
|
|
106
|
-
exit 0
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# CurDX-Flow TeammateIdle Hook
|
|
3
|
-
# Keeps artifact-producing CurDX teammates from idling before their disk artifact lands.
|
|
4
|
-
|
|
5
|
-
set -u
|
|
6
|
-
|
|
7
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
-
. "$SCRIPT_DIR/common.sh"
|
|
9
|
-
|
|
10
|
-
INPUT="$(cat 2>/dev/null || echo "{}")"
|
|
11
|
-
FLOW_ROOT="$(resolve_flow_root 2>/dev/null || true)"
|
|
12
|
-
|
|
13
|
-
[ -n "$FLOW_ROOT" ] || exit 0
|
|
14
|
-
has_python3 || exit 0
|
|
15
|
-
|
|
16
|
-
export CURDX_TEAMMATE_IDLE_INPUT="$INPUT"
|
|
17
|
-
|
|
18
|
-
read_json_field() {
|
|
19
|
-
local field="$1"
|
|
20
|
-
python3 - "$field" <<'PY' 2>/dev/null
|
|
21
|
-
import json
|
|
22
|
-
import os
|
|
23
|
-
import sys
|
|
24
|
-
|
|
25
|
-
try:
|
|
26
|
-
data = json.loads(os.environ.get("CURDX_TEAMMATE_IDLE_INPUT", "{}"))
|
|
27
|
-
except Exception:
|
|
28
|
-
data = {}
|
|
29
|
-
|
|
30
|
-
value = data.get(sys.argv[1], "")
|
|
31
|
-
if isinstance(value, str):
|
|
32
|
-
value = value.strip()
|
|
33
|
-
elif value is None:
|
|
34
|
-
value = ""
|
|
35
|
-
print(value)
|
|
36
|
-
PY
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
TEAM_NAME="$(read_json_field team_name)"
|
|
40
|
-
TEAMMATE_NAME="$(read_json_field teammate_name)"
|
|
41
|
-
|
|
42
|
-
[ -n "$TEAM_NAME" ] || exit 0
|
|
43
|
-
[ -n "$TEAMMATE_NAME" ] || exit 0
|
|
44
|
-
|
|
45
|
-
TEAM_CONFIG="${HOME}/.claude/teams/${TEAM_NAME}/config.json"
|
|
46
|
-
[ -f "$TEAM_CONFIG" ] || exit 0
|
|
47
|
-
|
|
48
|
-
export CURDX_TEAM_CONFIG="$TEAM_CONFIG"
|
|
49
|
-
export CURDX_TEAMMATE_NAME="$TEAMMATE_NAME"
|
|
50
|
-
|
|
51
|
-
AGENT_TYPE="$(python3 <<'PY' 2>/dev/null
|
|
52
|
-
import json
|
|
53
|
-
import os
|
|
54
|
-
|
|
55
|
-
try:
|
|
56
|
-
data = json.load(open(os.environ["CURDX_TEAM_CONFIG"]))
|
|
57
|
-
except Exception:
|
|
58
|
-
raise SystemExit(0)
|
|
59
|
-
|
|
60
|
-
name = os.environ["CURDX_TEAMMATE_NAME"]
|
|
61
|
-
for member in data.get("members", []) or []:
|
|
62
|
-
if isinstance(member, dict) and (member.get("name") or "").strip() == name:
|
|
63
|
-
print((member.get("agent_type") or "").strip())
|
|
64
|
-
break
|
|
65
|
-
PY
|
|
66
|
-
)"
|
|
67
|
-
|
|
68
|
-
[ -n "$AGENT_TYPE" ] || exit 0
|
|
69
|
-
|
|
70
|
-
curdx_resolve_artifact_contract "$AGENT_TYPE" "" "$FLOW_ROOT" || exit 0
|
|
71
|
-
|
|
72
|
-
artifact_target="$CURDX_ARTIFACT_TARGET"
|
|
73
|
-
minimum_size="$CURDX_ARTIFACT_MIN_SIZE"
|
|
74
|
-
|
|
75
|
-
if [ -f "$artifact_target" ]; then
|
|
76
|
-
size="$(wc -c < "$artifact_target" 2>/dev/null | tr -d ' ')"
|
|
77
|
-
if [ "${size:-0}" -ge "$minimum_size" ]; then
|
|
78
|
-
exit 0
|
|
79
|
-
fi
|
|
80
|
-
fi
|
|
81
|
-
|
|
82
|
-
printf '%s\n' "[CurDX-Flow teammate-idle-guard] Teammate '${TEAMMATE_NAME}' (${AGENT_TYPE}) is about to go idle, but ${artifact_target} is missing or too small. Write the required CurDX artifact to disk before idling." >&2
|
|
83
|
-
exit 2
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Artifact Output Discipline
|
|
2
|
-
|
|
3
|
-
Use this discipline for artifact-producing agents that write canonical files
|
|
4
|
-
such as `research.md`, `requirements.md`, `design.md`, `tasks.md`, or
|
|
5
|
-
`codebase-index.md`.
|
|
6
|
-
|
|
7
|
-
## Core Rules
|
|
8
|
-
|
|
9
|
-
1. Write the artifact first. The first substantive action should be the `Write`
|
|
10
|
-
tool call for the final file content.
|
|
11
|
-
2. Do not preview or paraphrase the artifact inline. The file is the
|
|
12
|
-
deliverable.
|
|
13
|
-
3. Keep status updates minimal: short bullets or fixed summary lines only.
|
|
14
|
-
4. End with the exact compact output contract defined by the agent-specific
|
|
15
|
-
section. No extra explanation before or after it.
|
|
16
|
-
5. If something blocks the write, report the blocker directly instead of
|
|
17
|
-
emitting a fake success summary.
|
|
18
|
-
|
|
19
|
-
## Why
|
|
20
|
-
|
|
21
|
-
- Prevents context waste from duplicating the artifact in chat
|
|
22
|
-
- Makes the written file the canonical output surface
|
|
23
|
-
- Keeps artifact-producing subagents consistent across research, product,
|
|
24
|
-
architecture, planning, and brownfield mapping
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Artifact Summary Contracts
|
|
2
|
-
|
|
3
|
-
Use these compact summary contracts after an artifact lands successfully. Pair
|
|
4
|
-
them with `artifact-output-discipline.md`: write first, no preview, then emit
|
|
5
|
-
the exact contract below and stop.
|
|
6
|
-
|
|
7
|
-
## research.md
|
|
8
|
-
|
|
9
|
-
```text
|
|
10
|
-
✓ research.md generated
|
|
11
|
-
Recommendations: N
|
|
12
|
-
Next: /curdx-flow:spec --phase=requirements
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## requirements.md
|
|
16
|
-
|
|
17
|
-
```text
|
|
18
|
-
✓ requirements.md generated
|
|
19
|
-
User stories: N
|
|
20
|
-
Functional requirements: N
|
|
21
|
-
Next: /curdx-flow:spec --phase=design
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## design.md
|
|
25
|
-
|
|
26
|
-
```text
|
|
27
|
-
✓ design.md generated
|
|
28
|
-
Architecture decisions: N
|
|
29
|
-
Components: N
|
|
30
|
-
Next: /curdx-flow:spec --phase=tasks
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## tasks.md
|
|
34
|
-
|
|
35
|
-
```text
|
|
36
|
-
✓ tasks.md generated
|
|
37
|
-
Total tasks: N
|
|
38
|
-
Coverage audit: PASS
|
|
39
|
-
Phases: 1-5
|
|
40
|
-
Next: /curdx-flow:implement
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## codebase-index.md
|
|
44
|
-
|
|
45
|
-
```text
|
|
46
|
-
✓ codebase-index.md generated
|
|
47
|
-
Modules: N
|
|
48
|
-
Entry points: N
|
|
49
|
-
Next: /curdx-flow:start <feature-name>
|
|
50
|
-
```
|