From mst
Parallel AI agents autonomously explore the codebase in background to locate specific code or information, synthesizing results into an explore-report.md. Triggers on 'νμ', 'μ½λ μ°Ύμμ€', etc., or /mst:explore.
npx claudepluginhub myrtlepn/gran-maestro --plugin mstThis skill uses the workspace's default tool permissions.
μ€μ λ AI νμλ€μ΄ **λ³λ ¬λ‘ μ½λλ² μ΄μ€λ₯Ό νμ**νκ³ PM(Claude)μ΄ κ²°κ³Όλ₯Ό ν©μ³ μ’ ν© νμ 리ν¬νΈλ₯Ό μμ±ν©λλ€.
Orchestrates multi-wave parallel agent exploration for large-scale codebase research (>25 files) and complex cross-domain systems, outputting unified reports with completeness scores.
Orchestrates parallel agents to find all query-relevant files in codebase with orthogonal exploration. Delivers topic overview + file lists with line ranges. Scales thoroughness from quick single-agent to multi-wave thorough searches.
Executes structured deep codebase exploration and synthesis using Agent Teams with dynamic planning, reconnaissance, parallel workers, and hub-and-spoke coordination. Activates on 'deep analysis', 'analyze codebase', or similar requests.
Share bugs, ideas, or general feedback.
μ€μ λ AI νμλ€μ΄ λ³λ ¬λ‘ μ½λλ² μ΄μ€λ₯Ό νμνκ³ PM(Claude)μ΄ κ²°κ³Όλ₯Ό ν©μ³ μ’ ν© νμ 리ν¬νΈλ₯Ό μμ±ν©λλ€.
| νλͺ© | debug | explore |
|---|---|---|
| μ‘°μ¬μ ν€ | investigators | explorers |
| κ°λ³ μ°μΆλ¬Ό | finding-{key}.md | explore-{key}.md |
| μ’ ν© λ¦¬ν¬νΈ | debug-report.md | explore-report.md |
| claude μ°Έμ¬ λ°©μ | investigatorλ‘ μ§μ μ°Έμ¬ κ°λ₯ | explorersμμ μ μΈ, claude_synthesisλ‘λ§ μ’ ν© |
κ²½λ‘ κ·μΉ (MANDATORY): μ΄ μ€ν¬μ λͺ¨λ
.gran-maestro/κ²½λ‘λ μ λκ²½λ‘λ‘ μ¬μ©ν©λλ€. μ€ν¬ μ€ν μμ μPROJECT_ROOTλ₯Ό μ·¨λνκ³ , μ΄ν λͺ¨λ κ²½λ‘μ{PROJECT_ROOT}/μ λμ¬λ₯Ό λΆμ λλ€.PROJECT_ROOT=$(pwd)
{PLUGIN_ROOT}λ μ΄ μ€ν¬μ "Base directory"μμskills/{μ€ν¬λͺ }/μ μ κ±°ν μ λκ²½λ‘μ λλ€. μλκ²½λ‘(.claude/...)λ μ λ μ¬μ©νμ§ μμ΅λλ€.
~/.claude/user-profile.json (AskUserQuestion 컨ν
μ€νΈ, λΉμ°¨λ¨)~/.claude/user-profile.jsonμ Readνλ€.
user_profile_context = nullλ‘ μ²λ¦¬νκ³ κΈ°μ‘΄ λμμ μ μ§νλ€ (graceful fallback).role (string)experience_level (string)domain_knowledge (string[])communication_style (string)user_profile_context = nullλ‘ μ²λ¦¬νλ€ (μν¬νλ‘μ° μ°¨λ¨ κΈμ§).communication_styleμ μ΅μ°μ λ°μνλ€.experience_level/domain_knowledgeμ λ§μΆ° μ©μ΄ μμ€κ³Ό μ€λͺ
κΉμ΄λ₯Ό μ‘°μ νλ€.archive.auto_archive_on_create=true μ EXP-* μΈμ
μ νμΈ β max_active_sessions μ΄κ³Ό μ μλ£ μΈμ
μμΉ΄μ΄λΈ ν μ§ν
{PROJECT_ROOT}/.gran-maestro/explore/ λλ ν 리 μ‘΄μ¬ νμΈ, μμΌλ©΄ μμ±python3 {PLUGIN_ROOT}/scripts/mst.py counter next --type expEXP-EXP- μ΄μ€ μ λμ¬ κ°μ§ μ sanitize β λ¨μΌ EXP-λ§ μ μ§ (μ΅μ°μ )EXP-NNN ννλ©΄ μ ν¨μ± νμΈ ν κ·Έλλ‘ μ¬μ©EXP-{zero-padded}λ‘ 1νλ§ μ λμ¬ λΆμ¬mst.py counter next --type expλ μ΄λ―Έ EXP- μ λμ¬λ₯Ό ν¬ν¨νμ¬ λ°νν©λλ€. λ°νκ°μ μλμΌλ‘ EXP-λ₯Ό μΆκ°νλ©΄ EXP-EXP- μ΄μ€ μ λμ¬κ° λ°μν©λλ€. λ°νκ°μ κ·Έλλ‘ μ¬μ©νλ, μ κ²μ¦λ§ μννμΈμ.{PROJECT_ROOT}/.gran-maestro/explore/counter.json Readnext_id = last_id + 1EXP-* λλ ν 리/μμΉ΄μ΄λΈλ₯Ό μ€μΊν΄ max λ²νΈλ₯Ό 볡ꡬνκ³ counter.json μμ±{PROJECT_ROOT}/.gran-maestro/explore/EXP-NNN/ λλ ν 리 μμ±session.json μμ±β±οΈ νμμ€ν¬ν μ·¨λ (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)μ λͺ λ Ή μ€ν¨ μ ν΄λ°±:python3 -c "from datetime import datetime, timezone; print(datetime.now(timezone.utc).isoformat())"μΆλ ₯κ°μcreated_atνλμ κΈ°μ νλ€. λ μ§λ§ κΈ°μ κΈμ§.
{
"schema_version": "1.0",
"id": "EXP-NNN",
"goal": "{μ¬μ©μ νμ λͺ©ν}",
"focus": "{--focus κ° λλ null}",
"status": "exploring",
"created_at": "{TS β mst.py timestamp now μΆλ ₯κ°}",
"dispatch_started_at": null,
"merge_completed_at": null,
"completed_at": null,
"failed_at": null,
"explorers": {
"codex": {
"role": "",
"status": "pending",
"provider": "codex",
"tier": "default",
"started_at": null,
"completed_at": null,
"output_file": "explore-codex.md",
"task_id": null,
"exit_code": null
},
"gemini": {
"role": "",
"status": "pending",
"provider": "gemini",
"tier": "default",
"started_at": null,
"completed_at": null,
"output_file": "explore-gemini.md",
"task_id": null,
"exit_code": null
}
},
"claude_synthesis": {
"status": "pending",
"started_at": null,
"completed_at": null,
"output_file": "explore-report.md"
},
"participant_config": {
"codex": { "count": 1, "tier": "default" },
"gemini": { "count": 1, "tier": "default" },
"claude": { "count": 1, "tier": "default" }
},
"merge_wait_ms": 60000,
"error": null
}
explorersλ configμ explore.agentsλ₯Ό μ½μ΄ λμ μμ±ν©λλ€.
codex, gemini, claude)λ³ count/tierλ₯Ό μ½μ΄ participant_configλ₯Ό {provider: {count, tier}} κ΅¬μ‘°λ‘ κΈ°λ‘claudeλ explorers μμ± λμμμ νμ μ μΈνκ³ claude_synthesisλ‘λ§ μ¬μ©{provider}{provider}, {provider}-2, {provider}-3... μμΌλ‘ μμ±provider λ° tier νλλ₯Ό κΈ°λ‘ (tierλ configμ explore.agents.{provider}.tier κ°μ μ ν, λ―Έμ€μ μ "default")explore.agentsκ° μμΌλ©΄ κΈ°λ³Έκ° { codex:1, gemini:1, claude:1 }μ μ¬μ©ν©λλ€.
schema_versionμ΄ μλ μΈμ
μ legacyλ‘ κ°μ£Όνκ³ , Read μ canonical ννλ‘ normalizeνλ€.schema_version, explorers=object, participant_config={provider:{count,tier}})λ‘λ§ μννλ€.νλλ³ λ³ν ν μ΄λΈ:
| λ κ±°μ νν | canonical λ³ν |
|---|---|
participant_config.{provider}: number (μ: "codex": 2) | { "count": 2, "tier": "default" } |
participant_config.{provider}: string (μ: "codex_model": "...") | { "count": 1, "tier": "default" } (λͺ¨λΈλͺ
μ 무μ) |
claude_synthesis: true | { "status": "done", "started_at": null, "completed_at": null, "output_file": "explore-report.md" } |
claude_synthesis: false | { "status": "pending", "started_at": null, "completed_at": null, "output_file": "explore-report.md" } |
claude_synthesis: { ... } (object, νλ λλ½) | λλ½ νλλ₯Ό κΈ°λ³Έκ°μΌλ‘ 보μ (status: "pending", output_file: "explore-report.md") |
explorers: [array] (λ°°μ΄ νν) | κ° νλͺ©μ key νλλ₯Ό object ν€λ‘ μ¬μ©νμ¬ objectλ‘ λ³ν |
explorers[].tier νλ λλ½ | "tier": "default" 보μ |
μΈμ ꡬ쑰:
EXP-NNN/session.jsonEXP-NNN/prompts/explore-{explorerKey}-prompt.mdEXP-NNN/prompts/synthesis-prompt.mdEXP-NNN/explore-{explorerKey}.mdEXP-NNN/explore-report.mdPM(Claude)μ΄ νμ λͺ©νλ₯Ό λΆμνμ¬ explorers μλ§νΌ μν μ λ°°μ ν©λλ€.
session.json μ
λ°μ΄νΈ:
explorers[key].role κΈ°λ‘status: "dispatching"μΌλ‘ μ μ΄μ΄ μ€ν¬μ λͺ¨λ Stepμ μ¬μ©μ μ λ ₯ μμ΄ μμ¨μ μΌλ‘ μ§νν©λλ€.
- λ°±κ·ΈλΌμ΄λ μμ μλ£ μ μ¬μ©μ νμΈ μ§λ¬Έ κΈμ§
- Step 2~5λ μμ μλ μ§ν
- μμ μ€ν¨ μμλ κ°λ₯ν λ²μκΉμ§ μλ 볡ꡬ/ν©μ± ν μνλ₯Ό μ’ λ£(
completedλλfailed)νλ€- λ¨, Step 5 μ’ λ£ λ³΄κ³ μ§ν λ€μ λ¨κ³ μ νμ
AskUserQuestionμΌλ‘ μ²λ¦¬νλ€ (AUTO-CONTINUE μμΈ)
λ 립 νμΌ Writeλ νλμ μλ΅μμ λμμ μνν©λλ€.
session.json + μ¬λ¬ ν둬ννΈ νμΌ λμ μμ±/μ
λ°μ΄νΈexplorers ν€λ₯Ό μννμ¬ providerλ³λ‘ λμ μ€νν©λλ€.
Claude λͺ¨λΈ κ²°μ :
Bash(python3 {PLUGIN_ROOT}/scripts/mst.py config get explore.agents.claude.tier models.providers.claude.default_tier)λ‘ tierλ₯Ό ꡬν λ€models.providers.claude[{tier}]λ‘ resolve (λ―Έμ€μ μ"sonnet"ν΄λ°±).
config νμΈ:
python3 {PLUGIN_ROOT}/scripts/mst.py config get prompt_builder.enabled prompt_builder.fallback_on_error
.gran-maestro/tmp/ctx-{session_id}.mdλ‘ Writedispatch-input.json Write:
{
"format": "mst.dispatch",
"schema_version": 1,
"common": {
"topic": "{EXP-NNN νμ λͺ©ν}",
"constraints": ["μ½κΈ° μ μ© νμλ§ μν, νμΌ μμ /μμ± κΈμ§", "..."],
"reference_context_file": ".gran-maestro/tmp/ctx-{session_id}.md"
},
"tasks": [
{"role": "explore-{explorerKey}", "angle": "{role}", "ask": "νμ μ§μΉ¨ β€200μ λλ ask_file"}
]
}
tasks[]λ explorers ν€λ₯Ό μννμ¬ μμ±role κ°μ "explore-{explorerKey}"λ‘ μ€μ (split κ²°κ³Ό νμΌμ΄ explore-{explorerKey}-prompt.mdλ‘ μμ±λμ΄ κΈ°μ‘΄ dispatch κ²½λ‘ νΈν)ask_file κ²½λ‘λ‘ λΆλ¦¬python3 {PLUGIN_ROOT}/scripts/mst.py prompt build --input {absolute_path}/dispatch-input.json --out-dir {absolute_path}/prompts --sid {session_id}python3 {PLUGIN_ROOT}/scripts/mst.py session split-prompts --dir {absolute_path}/prompts νΈμΆ β prompts/explore-{explorerKey}-prompt.md κ°λ³ νμΌ μμ± β κΈ°μ‘΄ dispatch (2b λ¨κ³) κ·Έλλ‘ μ€νfallback_on_error=trueμΌ λ)fallback_on_error=falseμ΄λ©΄ μν¬νλ‘μ° μ€λ¨ + μ¬μ©μ μμ€μ»¬λ μ΄μ
mst.py prompt buildλ μ€λ₯ λ°νλ§ λ΄λΉ, repair 1ν/fallback μ νμ λ³Έ μ€ν¬(explore)μ μ±
μμ΄λ€explorers ν€λ₯Ό μννμ¬ prompts/explore-{explorerKey}-prompt.mdλ₯Ό νλμ λ©μμ§μμ λμμ Writeν©λλ€.
ν둬ννΈμλ λ°λμ **"μ½κΈ° μ μ© νμλ§ μν, νμΌ μμ /μμ± κΈμ§"**λ₯Ό λͺ
μνκ³ κ²°κ³Όλ₯Ό explore-{explorerKey}.mdμ μμ±νλλ‘ μ§μ ν©λλ€.
--from EXP-NNN μμ½ μ£Όμ
κ·μΉ (μ΅μ
)--from EXP-NNNμ΄ μ§μ λλ©΄ {PROJECT_ROOT}/.gran-maestro/explore/EXP-NNN/explore-report.mdμμ νμ νμμ© μμ½ μΉμ
λ§ μΆμΆνλ€.μ΄μ μΈμ
μμ½ μ»¨ν
μ€νΈ λΈλ‘μΌλ‘ μ½μ
νκ³ , μκ±°λ μΆμΆ μ€ν¨ μ ν΄λΉ λΈλ‘μ μλ΅νλ€.# μ½λλ² μ΄μ€ νμ μμ²
<!-- @include _shared/skill-execution-marker.md -->
## μ€ν¬ μ€ν λ§μ»€ (MANDATORY)
- λͺ¨λ μλ΅μ 첫 μ€ λλ κ° Step μμ μ€μ μλ λ§μ»€λ₯Ό μΆλ ₯νλ€.
- κΈ°λ³Έ λ§μ»€ ν¬λ§·: `[MST skill={name} step={N}/{M} return_to={parent_skill/step | null}]`
- νλ κ·μΉ:
- `skill`: νμ¬ μ€ν μ€μΈ μ€ν¬ μ΄λ¦
- `step`: νμ¬ λ¨κ³(`N/M`) λλ μλΈμ€ν¬ μ’
λ£ μ `returned`
- `return_to`: μ΅μμ μ€ν¬μ΄λ©΄ `null`, μλΈμ€ν¬μ΄λ©΄ `{parent_skill}/{step_number}`
- μλΈμ€ν¬ μ’
λ£ λ§μ»€: `[MST skill={subskill} step=returned return_to={parent/step}]`
- C/D λΆλ¦¬ λ§μ»€ κ·μΉμ μΆκ°λ‘ μ¬μ©νμ§ μλλ€. λ°λμ λ¨μΌ MST λ§μ»€λ§ μ¬μ©νλ€.
- μμ:
- `[MST skill={name} step=1/3 return_to=null]`
- `[MST skill={subskill} step=returned return_to={parent_skill}/{step_number}]`
<!-- @end-include -->
## νμ λͺ©ν
{μ¬μ©μ νμ λͺ©ν μ 체 λ΄μ©}
## λΉμ μ μν
λΉμ μ {provider} νμμμ
λλ€. λ΄λΉ κ°λ: **{role}**
## μ‘°μ¬ μ§μΉ¨
1. μ½λλ² μ΄μ€λ₯Ό μ½κΈ° μ μ©μΌλ‘ νμνκ³ μ¦κ±°λ₯Ό μμ§νλ€.
2. νμΌ κ²½λ‘, μ¬λ³Όλͺ
, λΌμΈ λ²νΈλ₯Ό κ°λ₯ν ν ꡬ체μ μΌλ‘ μ μνλ€.
3. μΆλ‘ κ³Ό μ¬μ€μ ꡬλΆν΄ μμ±νλ€.
4. μμ¬ μ§μ μ νμΈμ΄ νμν μ΄μ λ₯Ό ν¨κ» μ λλ€.
5. νμΌ μμ /μμ±/μμ λ μ λ μννμ§ μλλ€.
## μ§μ€ μμ
{--focus κ°μ΄ μμΌλ©΄ ν΄λΉ ν¨ν΄, μμΌλ©΄ "μ½λλ² μ΄μ€ μ 체"}
## μ΄μ μΈμ
μμ½ μ»¨ν
μ€νΈ (μ ν)
{--fromμ΄ μμΌλ©΄ EXP-NNNμ "νμ νμμ© μμ½"λ§ 500ν ν° μ΄λ΄λ‘ μ£Όμ
, μμΌλ©΄ μ΄ μΉμ
μλ΅}
## μΆλ ₯ νμ
μλ΅μ `{output_file}`μ λ§ν¬λ€μ΄μΌλ‘ μμ±νκ³ μλ μΉμ
μ ν¬ν¨νλ€.
- **νμ λ²μ**: μ€μ λ‘ νμΈν νμΌ/λͺ¨λ/μ¬λ³Ό λ²μ
- **λ°κ²¬ μ¬ν**: νμΈλ μ¬μ€/ν¨ν΄ λͺ©λ‘ (`νμΌ:λΌμΈ` νκΈ°)
- **ꡬ쑰μ κ΄κ³**: λͺ¨λ/νΈμΆ/λ°μ΄ν° νλ¦ κ΄κ³
- **λ―Ένμ μμ**: μμ§ νμΈνμ§ λͺ»νκ±°λ μ¦κ±°κ° λΆμ‘±ν μμ
- **νμ νμ μ μ**: λ€μ νμ μ°μ μμμ μ μ κ²½λ‘
κΈμ μ μ ν: `{config.collaborative_explore.finding_char_limit}`μ μ΄λ΄
λͺ¨λ νΈμΆμ
Task(run_in_background: true)λ‘ μ€νν©λλ€.
provider: "codex":
Bash(
run_in_background: true,
command: "codex exec --full-auto -m $(python3 {PLUGIN_ROOT}/scripts/mst.py resolve-model codex explore 2>/dev/null || echo \"gpt-5.3-codex\") -C $(pwd) \"$(cat {absolute_path}/prompts/explore-{explorerKey}-prompt.md)\" > {absolute_path}/explore-{explorerKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/explore-{explorerKey}.md; exit $EC"
)
provider: "gemini":
Bash(
run_in_background: true,
command: "gemini -p \"$(cat {absolute_path}/prompts/explore-{explorerKey}-prompt.md)\" --model {config.models.providers.gemini[explore.agents.gemini.tier || default_tier]} --approval-mode yolo --sandbox=false > {absolute_path}/explore-{explorerKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/explore-{explorerKey}.md; exit $EC"
)
κ° νΈμΆμ background task IDλ₯Ό session.jsonμ κΈ°λ‘ν©λλ€.
β±οΈ νμμ€ν¬ν μ·¨λ (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)μ€ν¨ μ UTC ISO ν΄λ°±μΌλ‘ μμ±νλ€.
session.json μ
λ°μ΄νΈ:
status: "waiting"dispatch_started_at: "{TS}"explorers[key].status: "in_progress"explorers[key].started_at: "{TS}"explorersλ₯Ό μννμ¬ explore-{explorerKey}.md μ‘΄μ¬ μ¬λΆ/λ΄μ©μ νμΈ:
EXIT_CODE: μ‘΄μ¬ β ν보 μν done λλ failed(exit code κΈ°λ°)EXIT_CODE: λ―ΈκΈ°λ‘ β in_progressλͺ¨λ explorerκ° μλ£ μνλ©΄ μ¦μ Step 3cλ‘ μ§ν.
in_progress explorerκ° μμΌλ©΄ μλ λͺ
λ ΉμΌλ‘ λκΈ°:
python3 {PLUGIN_ROOT}/scripts/mst.py wait-files \
--timeout {config.collaborative_explore.merge_wait_msλ₯Ό 1000μΌλ‘ λλ κ°, κΈ°λ³Έ 60} \
{in_progress explorerλ€μ {absolute_path}/explore-{explorerKey}.md μ λ κ²½λ‘ λͺ©λ‘}
λΆκΈ° μ²λ¦¬:
ALL_READYλ©΄ μ¦μ Step 3c μ§νTIMEOUTμ΄λ©΄ μλ£λ κ²°κ³Όλ§ μ¬μ©νκ³ λ―Έμλ£ explorerλ timeoutμΌλ‘ κΈ°λ‘ ν Step 3c μ§νβ±οΈ νμμ€ν¬ν μ·¨λ (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)μ λͺ λ Ή μ€ν¨ μ ν΄λ°±:python3 -c "from datetime import datetime, timezone; print(datetime.now(timezone.utc).isoformat())"μΆλ ₯κ°μmerge_completed_atνλμ κΈ°μ νλ€. λ μ§λ§ κΈ°μ κΈμ§.
{
"status": "synthesizing",
"explorers": {
"codex": { "status": "done", "completed_at": "{TS}", "exit_code": 0 },
"gemini": { "status": "timeout", "completed_at": null, "exit_code": null }
},
"merge_completed_at": "{TS β mst.py timestamp now μΆλ ₯κ°}"
}
status in ["done"]μΈ explore-{explorerKey}.mdλ§ μ
λ ₯μΌλ‘ μ¬μ©prompts/synthesis-prompt.md μμ± ν Claudeλ‘ μ’
ν© μ€νexplore-report.mdλ‘ μ μ₯ (μλ νμ€ μΉμ
μ λ°λμ μ μ§)claude_synthesis.status κ°±μ :
donefailed + μμΈ κΈ°λ‘explore-report.md νμ€ μΉμ
:
--from μ£Όμ
μ μ© μμ½)status: "completed"status: "failed"completedλ©΄ completed_at νμfailedλ©΄ failed_at νμexplore-report.md μμ½κ³Ό κ²½λ‘λ₯Ό νμνμ ν¬λ§·:
## EXP-NNN νμ 리ν¬νΈ
### μ°Έμ¬ νμμ
- {explorerKey} ({role}, {provider}): {status}
### ν΅μ¬ λ°κ²¬
{μ λ’°λ λμ λ°κ²¬ 1~3κ°}
### μ°Έκ³ κ²½λ‘
- μμΈ λ¦¬ν¬νΈ: {PROJECT_ROOT}/.gran-maestro/explore/EXP-NNN/explore-report.md
AskUserQuestionμΌλ‘ λ€μ λ¨κ³λ₯Ό μλ΄νλ€.
Skill(skill: "mst:explore", args: "--from {EXP-NNN} {μ¬μ©μ νμ νμ μ§λ¬Έ}")--fromμ μλ ν¬ν¨νλ€.Skill(skill: "mst:request", args: "--from-explore {EXP-NNN} {νμ λͺ©ν μ 50μ}")Skill(skill: "mst:plan", args: "--from-explore {EXP-NNN} {νμ λͺ©ν μ 50μ}")exploring β dispatching β waiting β synthesizing β completed
β failed
| νμ¬ μν | νμ© μ μ΄ λμ |
|---|---|
exploring | dispatching, failed |
dispatching | waiting, failed |
waiting | synthesizing, failed |
synthesizing | completed, failed |
completed | (ν°λ―Έλ β μ μ΄ λΆκ°) |
failed | (ν°λ―Έλ β μ μ΄ λΆκ°) |
failedλ‘ μ μ΄ κ°λ₯: * β failedfailed μ μ΄ μ λ°λμ failed_at νμμ€ν¬νλ₯Ό κΈ°λ‘νλ€.completed β (any non-terminal): μ λ κΈμ§. μλ£λ μΈμ
μ λ€μ μ΄ μ μλ€.failed β (any non-terminal): μ λ κΈμ§. μ€ν¨ν μΈμ
μ λ€μ μ΄ μ μλ€.completed, failed)λ λΆλ³μ΄λ€. μ¬μλκ° νμνλ©΄ μ μΈμ
μ μμ±νλ€.μ€κ° μ€ν¨κ° μμ΄λ μνλ₯Ό μ΄λ¦° μ±λ‘ λμ§ μμ΅λλ€. λ°λμ completed λλ failedλ‘ λ«μ΅λλ€.
[MST skill={name} step={N}/{M} return_to={parent_skill/step | null}]skill: νμ¬ μ€ν μ€μΈ μ€ν¬ μ΄λ¦step: νμ¬ λ¨κ³(N/M) λλ μλΈμ€ν¬ μ’
λ£ μ returnedreturn_to: μ΅μμ μ€ν¬μ΄λ©΄ null, μλΈμ€ν¬μ΄λ©΄ {parent_skill}/{step_number}[MST skill={subskill} step=returned return_to={parent/step}][MST skill={name} step=1/3 return_to=null][MST skill={subskill} step=returned return_to={parent_skill}/{step_number}]explore-* κ²°κ³Όλ‘ μ μ ν©μ± μ§νcompleted κ°λ₯completed, ν©μ± μ€ν¨ μ failedstatus: "failed" + failed_at + error κΈ°λ‘skippedλ‘ νμνκ³ κ³μ μ§νfailedmst.py counter next --type exp μ€ν¨
EXP-EXP λ°©μ§failedλ‘ μ’
λ£failed μ’
λ£.gran-maestro/explore/EXP-NNN/
βββ session.json
βββ prompts/
β βββ explore-{explorerKey}-prompt.md
β βββ synthesis-prompt.md
βββ explore-{explorerKey}.md
βββ explore-report.md
--focus {νμΌν¨ν΄|κ΄μ ν€μλ}: νμ λ²μλ₯Ό νμΌ ν¨ν΄ λλ κ΄μ ν€μλλ‘ μ§μ (μ: src/auth/**/*.ts, architecture, data-flow, security-surface)--from EXP-NNN: μ΄μ νμ μΈμ
μ νμ νμμ© μμ½λ§(μ΅λ 500ν ν°) μ£Όμ
ν΄ μ°μ νμμ μν/mst:explore "λ‘κ·ΈμΈ νλ¦μμ ν ν° κ²μ¦ κ²½λ‘λ₯Ό μ°Ύμμ€"
/mst:explore --focus src/api/**/*.ts "API λΌμ°ν
κ³Ό μλ¬ μ²λ¦¬ νλ¦μ μ 리ν΄μ€"
/mst:explore --from EXP-012 --focus data-flow "κ²°μ μΉμΈ μ΄ν μ μ°κΉμ§ λ°μ΄ν° νλ¦μ μ΄μ΄μ μΆμ ν΄μ€"
/mst:explore "μ΄ μ μ₯μμμ κ²°μ λͺ¨λμ΄ μ΄λμ μμλλμ§ μΆμ ν΄μ€"
--from, μ°μΆλ¬Ό νμ€ν, λ€μ λ¨κ³ μλ΄, --focus κ΄μ ν€μλ)μ μΆκ° ν¬ν¨ν©λλ€.explorersλ object canonical μ€ν€λ§λ₯Ό μ¬μ©νλ©° λ°°μ΄ ννμ κΈμ§ν©λλ€.