/os-tk-plan
Inputs
- •Request text (from
$ARGUMENTS) - •Optional
--mode greenfield|brownfield - •Optional
--interviewto run interview mode first - •Optional
--no-interviewto explicitly skip interview mode - •Optional
--max-questions Nto limit interview questions - •Optional
--needs-reviewto mark this plan as requiring review - •Optional
--plan-id <id>to associate a plan id for review tracking
Determine mode
- •If
--modeprovided, use it. - •Else: if repo has real code/config (
src/,app/,lib/,package.json,pyproject.toml,go.mod,Cargo.toml, etc.), treat as brownfield. Otherwise greenfield.
Interview mode (NEW)
If --interview is provided (or if enabled in config):
- •Run
os-tk-interviewersubagent to collect requirements - •Save interview output to
INTERVIEW_OUTPUT - •Update request with interview context:
REQUEST_WITH_CONTEXT="${REQUEST}\n\n## Interview Context\n${INTERVIEW_OUTPUT}" - •Pass
REQUEST_WITH_CONTEXTto planner chain - •Note that interview was run in dev notes (if enabled)
If --no-interview is provided:
- •Skip interview mode, use original request directly
- •Set
REQUEST_WITH_CONTEXT="$REQUEST"(no interview context)
If neither flag provided:
- •Check config for default interview setting (optional future enhancement)
- •Default to no interview (backward compatible)
- •Set
REQUEST_WITH_CONTEXT="$REQUEST"(no interview context)
Execution:
bash
# Parse flags
INTERVIEW_MODE=false
NO_INTERVIEW_MODE=false
NEEDS_REVIEW=false
PLAN_ID=""
while [[ $# -gt 0 ]]; do
case "$1" in
--interview)
INTERVIEW_MODE=true
shift
;;
--no-interview)
NO_INTERVIEW_MODE=true
shift
;;
--needs-review)
NEEDS_REVIEW=true
shift
;;
--plan-id)
PLAN_ID="$2"
shift 2
;;
*)
REQUEST="$*"
break
;;
esac
done
# Auto-generate plan id when needs-review is set
if [[ "$NEEDS_REVIEW" == "true" ]] && [[ -z "$PLAN_ID" ]]; then
PLAN_ID="plan-$(date +%Y%m%d-%H%M%S)"
echo "Auto-generated plan id: $PLAN_ID"
fi
# If plan id is set, ensure it's persisted and shown to the user later
# (Plan ID will be added to final plan output and dev notes)
# Check if interview mode is active
if [[ "$INTERVIEW_MODE" == "true" ]] && [[ "$NO_INTERVIEW_MODE" != "true" ]]; then
echo "=== Interview Mode ==="
echo "Collecting requirements through questions..."
echo ""
# Run interviewer agent
INTERVIEW_OUTPUT=$(subagent({
"agent": "os-tk-interviewer",
"task": "Conduct interview for request: $REQUEST"
}))
# Check if interview succeeded
if [[ -z "$INTERVIEW_OUTPUT" ]]; then
echo "ERROR: Interview failed to complete"
exit 1
fi
# Save interview to dev notes (if enabled)
CONFIG_FILE=".os-tk/config.json"
if [[ -f "$CONFIG_FILE" ]]; then
DEV_NOTES_ENABLED=$(jq -r '.devNotes.enabled // false' "$CONFIG_FILE" 2>/dev/null || echo "false")
else
DEV_NOTES_ENABLED="false"
fi
if [[ "$DEV_NOTES_ENABLED" == "true" ]]; then
SUMMARY="<summary bullets from interview>" REQUEST="$REQUEST" bash pi/skills/os-tk-interview/scripts/save-interview.sh
fi
echo ""
echo "=== Interview Complete ==="
echo "Proceeding to planning with interview context..."
echo ""
# Update request with interview context
REQUEST_WITH_CONTEXT="${REQUEST}\n\n## Interview Context\n${INTERVIEW_OUTPUT}"
else
# No interview mode
REQUEST_WITH_CONTEXT="$REQUEST"
fi
Parallel scouting + planning (single subagent chain)
Use pi-async-subagents tool subagent with a parallel-in-chain fan-out/fan-in.
Important:
- •The planner must NOT spawn any subagents.
- •This chain is sync (
async: false) because it includes a parallel step.
js
subagent({
"agentScope": "both",
"async": false,
"chain": [
{
"parallel": [
{
"agent": "os-tk-repo-scout",
"task": "(If this is a greenfield repo / no relevant code, say so quickly.)\n\nFind existing patterns, conventions, related code paths, and test patterns relevant to: " + (REQUEST_WITH_CONTEXT || "{task}") + ""
},
{
"agent": "os-tk-librarian",
"task": "DOCS mode: Find official docs, breaking changes, and examples relevant to: " + (REQUEST_WITH_CONTEXT || "{task}") + ""
}
],
"concurrency": 2,
"failFast": false
},
{
"agent": "os-tk-planner",
"task": "Create a concise plan.\n\nRequest: " + (REQUEST_WITH_CONTEXT || "{task}") + "\nMode: <greenfield|brownfield> (infer from repo if not provided)\n\nScout findings:\n{previous}\n\nOutput MUST follow this template:\n# Plan (mode: <greenfield|brownfield>)\n\nContext (brownfield only):\n- ...\n\nSteps:\n1. ...\n\nRisks/Unknowns/Deps:\n- risk: ...\n- unknown: ...\n- dep: ...\n\nValidation:\n- ...\n\nUnresolved questions:\n- ...\n\nRules: extreme concision, numbered steps, include validation commands."
},
{
"agent": "os-tk-gap-analyst",
"task": "Review the plan for gaps. Request: " + (REQUEST_WITH_CONTEXT || "{task}") + ". Plan:\n{previous}"
},
{
"agent": "os-tk-planner",
"output": "final-plan.md",
"task": "Revise the plan to address the gap analysis below.\n\nRequest: " + (REQUEST_WITH_CONTEXT || "{task}") + "\n\nGap analysis:\n{previous}\n\nWrite the FINAL plan (same template as before). Also write it to the chain output file per instructions."
}
]
})
Return final plan to the user
The chain tool returns a summary including the chain directory, e.g.:
- •
📁 Artifacts: /tmp/pi-chain-runs/<runId>
After the chain completes:
- •Extract the chain dir from the tool output.
- •Read
${CHAIN_DIR}/final-plan.md. - •If
PLAN_IDis set, rename, annotate, and persist the plan file:
bash
# Rename file to plan-<id>.md
PLAN_PATH=$(bash "pi/skills/os-tk-plan/scripts/rename-plan-file.sh" \
--plan-id "$PLAN_ID" \
--plan-file "${CHAIN_DIR}/final-plan.md")
# Annotate plan file with Plan ID
bash "pi/skills/os-tk-plan/scripts/annotate-plan-id.sh" \
--plan-id "$PLAN_ID" \
--plan-file "$PLAN_PATH"
# Persist to .os-tk/plans/
PLAN_PATH=$(bash "pi/skills/os-tk-plan/scripts/persist-plan-file.sh" \
--plan-file "$PLAN_PATH")
- •Return contents (now including
Plan ID: ...) as the/os-tk-planoutput.
Dev notes (mandatory when enabled)
If .os-tk/config.json has devNotes.enabled=true:
- •Create
.os-tk/dev-notes/plan-<YYYYMMDD-HHMMSS>.mdcontaining:- •Request
- •Final plan
- •Snippets (validated) (if any)
- •Open questions
- •Plan ID (if available)
- •Append a one-line entry to
.os-tk/dev-notes/INDEX.mdlinking the plan note.
If PLAN_ID is set and dev notes file exists, annotate it:
bash
bash "pi/skills/os-tk-plan/scripts/annotate-plan-id.sh" \
--plan-id "$PLAN_ID" \
--plan-file "$PLAN_PATH" \
--dev-notes "${DEV_NOTES_FILE}"
Plan storage:
- •Final plan file is persisted to
.os-tk/plans/<plan-id>.md - •
/os-tk-proposal --plan-id <id>will load this file automatically
Mark plan as requiring review (NEW)
If --needs-review is provided:
- •
--plan-id <id>is optional; if omitted, it auto-generatesplan-YYYYMMDD-HHMMSS - •Mark plan as pending review in
.os-tk/plan-approvals.json - •Run:
bash
bash "pi/skills/os-tk-plan/scripts/mark-plan-needs-review.sh" --plan-id "$PLAN_ID"
This sets:
- •
status: pending - •
requestedByandrequestedAt
The proposal gate will block until plan is approved.
Stop condition
STOP after printing the final plan and (if enabled) writing dev-notes. Ask for answers to unresolved questions.
Prohibited
- •No product code changes.
- •No ticket creation.