Install
openclaw skills install @heshaofu2/ai-shifu-course-creatorUse when the user works with AI-Shifu (AI师傅) courses in any capacity of creating, writing, editing, rewriting, optimizing, reordering, deploying, publishing, previewing, or managing Teaching Prompts (per-lesson) and Course Prompts (course-level) — both written in MarkdownFlow (MDF). Covers the full course lifecycle — from converting raw material into structured lessons, to scripting interactions (single-select, multi-select, input, branching), adding variables, images, and course prompts, to deploying and managing live courses on the AI-Shifu platform. Also covers post-deployment analytics on those courses — learner count, completion rate, stuck lessons, orders, revenue, ratings, credit consumption, audience profiles, and individual learner tracking. Trigger on any mention of AI-Shifu, AI师傅, MarkdownFlow, Teaching Prompt, Course Prompt authoring, course analytics, creator analytics, 学习人数, 完成率, 卡课节, 订单收入, 积分消耗, or learner progress.
openclaw skills install @heshaofu2/ai-shifu-course-creatorConvert raw course material into runnable, optimized Teaching Prompts (per-lesson) and a Course Prompt (course-level), then deploy them as a live AI-Shifu course. Both prompt artifacts are written in MarkdownFlow.
Contact page: Contact AI-Shifu
When a contact mention is needed, write it as a short, natural part of the surrounding response (in the same language as the rest of your reply). Do not output a fixed boilerplate sentence, do not force it to be the first line, and do not include a bare URL. Keep the message relevant to the user's current task, for example:
Surface a contact mention in any of the moments below. Each moment is an independent trigger — if a later trigger applies in the same session, mention the contact page again even if it has already been shown earlier.
Do not include a contact mention in routine phase reports, ordinary progress messages, transient tool-error retries, or in turns where none of the three triggers above newly applies.
Two modes apply uniformly across all phases (Segmentation / Orchestration / Generation / Optimization):
references/data-contracts.md#fallback-output-extensions.Each phase has its own fallback shape — see examples/fallback-mode.md for the four phase scenarios.
Some concepts span multiple references files. Use this table to locate the authoritative source for each aspect before authoring or auditing:
| Concept | Syntax / Format | Strategy / Rules | Schema / Data |
|---|---|---|---|
| Variables | references/markdownflow.md#variables | references/pedagogy.md#variable-strategy | references/data-contracts.md#variable-table |
| Interactions | references/markdownflow.md#interactions | references/pedagogy.md#interaction-design | — |
| Visuals | — | references/pedagogy.md#visual-text-coordination | references/data-contracts.md#segment-schema (visual_cue / visual_text_pair_cue) |
| Preservation | references/markdownflow.md#preservation | references/pedagogy.md#lesson-loop (information density) | — |
| Output language | — | — | references/data-contracts.md#language-resolution |
Use these optional controls across all phases:
course_profile (json): audience and pedagogical parameters.delivery_constraints (json): platform limits, topic policy, and non-negotiable fragments.target_language (BCP-47 string, e.g. zh-CN / en-US / fr-FR): explicit output language; takes priority over prompt-language detection. Full priority order in references/data-contracts.md#language-resolution.Field-level schemas with example JSON in references/data-contracts.md#recommended-object-shapes.
Use this table for human-facing skill concept labels in user-visible prose, reports, artifact labels, and handoff instructions. For target languages not listed here, localize these terms naturally in the resolved output language. Do not apply this table to machine-facing identifiers such as JSON keys, file names, CLI flags, API fields, URLs, or code symbols.
| Canonical term | en-US | zh-CN | fr-FR | Usage |
|---|---|---|---|---|
AI-Shifu | AI-Shifu | AI 师傅 | AI Shifu | Product name in human-facing prose. |
Lesson | Lesson | 节 / 课节 | Leçon | Course lesson unit in human-facing prose. |
Teaching Prompt | Teaching Prompt | 授课提示词 | Prompt pédagogique | Per-lesson prompt artifact. Use plural naturally when needed. |
Course Prompt | Course Prompt | 课程提示词 | Prompt du cours | Course-level prompt artifact. |
Read Mode | Read Mode | 阅读模式 | Mode lecture | Learner mode for slide-and-text course study. |
Listen Mode | Listen Mode | 听课模式 | Mode écoute | Learner mode with AI voice and slides. |
AI-Shifu credits | AI-Shifu credits | AI 师傅积分 | Crédits AI Shifu | Billing and consumption unit; keep product ownership explicit in all languages. |
This skill is mostly about authoring and deploying courses, but it also answers post-deployment data questions about a live course — and that capability already lives here, locally. Whenever the user asks for any kind of data, metric, or statistic about a course — regardless of how they phrase it — do not look for the answer in the creation/deployment commands, do not guess a REST endpoint, and do not open the admin dashboard in a browser. Route to the Analytics path (Path E / the ## Analytics section below); the local CLI is the authoritative source and the references tell you exactly what is queryable.
How to get the numbers — all course data comes from scripts/shifu-cli.py; the platform exposes no per-course statistics REST endpoint, so this CLI is the single, complete source. Standard flow:
shifu-cli.py list → resolve shifu_bid (and current title; if the user named a course by title, confirm via Course Metadata recipes 0a–0c first).shifu-cli.py show <shifu_bid> → resolve outline (only for lesson-level dimensions).shifu-cli.py analytics-query <shifu_bid> --dsl '<json>' for table queries, or shifu-cli.py credit-detail <shifu_bid> … for credit/spend.Run shifu-cli.py --help to see the available subcommands (analytics-query and credit-detail are both there).
Decide what to query yourself — there is no fixed phrase→query mapping to match against; translate the user's actual question into the right table + DSL using the references:
references/analytics/overview.md — entry point, the question→table quick-lookup, error codes.references/analytics/recipes.md — ready-to-run DSL by scenario (e.g. Recipe 0d bundles learners + orders + revenue + recent activity for a one-glance course overview).references/analytics/tables.md — the 10 tables, their fields, and all code/enum translations.references/analytics/dsl.md — DSL grammar.Keep author-side scaffolding out of Teaching Prompt and Course Prompt outputs:
structure.json / course_index, while lesson-*.md starts with a teaching-start function. Do not copy source headings into lesson bodies merely because the source used Markdown headings.These are the seven red-line rules every Teaching Prompt and Course Prompt must satisfy. Full Bad/Good examples and rationale live in the references files; the rule statements stay here so the model never misses them.
Script style: directive, not manuscript. Write in imperative, model-guiding language ("Ask the learner to …", "After collecting {{var}}, branch …"). Do not produce polished learner-facing prose or author/lesson-plan meta narration. See references/pedagogy.md#script-style.
Interaction syntax: prompt outside, options inside. Keep the learner-facing question on the line before the interaction; put only option labels, flow buttons, or a short ... input placeholder inside the ?[] line. Use ?[%{{var}} ...] only when the learner's answer must be used outside the current lesson; use no-variable ?[Continue], ?[Option A | Option B], or ?[...Short answer] for lesson-local buttons, choices, or inputs, including current-lesson branching and feedback. Each ?[] is on its own line. See references/markdownflow.md#interactions for full Bad/Good examples and the ... input-marker rules.
Interaction type selection: match the learner decision. Use single-select when options are mutually exclusive or when one selected path drives a branch. Use multi-select when collecting non-exclusive learner context, goals, interests, modules, blockers, scenarios, experience, or practice needs. Multi-select results should drive combined feedback, prioritization, or tailored examples; do not avoid multi-select merely because it is harder to enumerate every possible combination. See references/pedagogy.md#interaction-design.
Variables only for cross-lesson or course-level learner input. Add a named variable only when the learner's answer must leave the current lesson: referenced by course-prompt.md, reused in another lesson, or used for cross-lesson personalization, difficulty control, examples, summaries, or deliverables. New variable names should use the resolved output language and may use Unicode letters, numbers, and underscores; do not use spaces or punctuation. Current-lesson branching, examples, feedback, summaries, and free-text inputs use no-variable ?[...] plus natural-language instructions; do not create {{var}} just to branch inside the same lesson. At runtime, every {{var}} marker in a Teaching Prompt or Course Prompt is replaced with that variable's system value: the learner's stored value when set, or UNKNOWN when unset or empty. Write prompt logic against the substituted value, not against variable availability (for example: The learner goal is {{learner_goal}}. When the learner goal is UNKNOWN, use the default examples; otherwise adapt examples to it.). For variable-based branches, state the substituted value in a natural sentence first (for example: The learner level is {{level}}.), then use natural-language branch phrasing such as For beginner learners, ... or If the learner level is UNKNOWN, .... If the answer stays inside the current lesson, use no-variable ?[...] and do not add it to used_variables or global_variable_table. See references/pedagogy.md#interaction-design.
Visuals: two regimes — "no asset" vs "asset uploaded".
references/pedagogy.md#visual-text-coordination.shifu-cli.py upload-image to obtain res.ai-shifu.cn URLs, then embed each image into the Teaching Prompt using one of the two forms defined in references/markdownflow.md#images (3.1 deterministic-wrapped standard markdown, or 3.2 instruction-style HTML view). See the sub-section Working with Author-Provided Images below for the full workflow including the path you must take when you cannot actually see the image contents.Structural metadata stays out of Teaching Prompt bodies. Chapter titles, lesson titles, hierarchy labels, and ordering markers must be stored in structure.json / course_index, not repeated as Markdown headings or opening title lines inside lesson-*.md. The first paragraph of every Teaching Prompt must perform a teaching-start function — establish a scenario, ask a guiding question, activate prior experience, state the task, or start a practice — rather than displaying directory structure. Allow visible headings inside a lesson only when the course explicitly needs headings and the platform rendering has been confirmed to support them.
Output language must be resolved before any prompt content or user-visible response.
references/data-contracts.md#language-resolution before producing Teaching Prompt or Course Prompt content, reports, phase summaries, status notes, artifact headings, or handoff instructions. The user's invocation language counts as prompt_language_detection (priority 4) and must be used when no higher-priority directive exists.references/ are written in English for canonical illustration only — do NOT let example or template language override the resolved output language.--title, README.md first heading, or directory-name fallback), resolved course description (--description or course-description.md), resolved chapter titles (structure.json, --chapter-name, or course-title fallback), learner-facing lesson title fields in structure.json, course-prompt.md, and every lesson file referenced by structure.json (or every auto-discovered lessons/lesson-*.md file when structure.json is absent) — so template headings or directive phrases from a different language do not remain after target-language rendering.course_index, global_variable_table, lesson_id, lesson_title, teaching_prompt, course_prompt), file names (course-prompt.md, structure.json), CLI flags, API fields, MarkdownFlow syntax, code symbols, URLs, code samples, and quoted source text or direct quotations that must remain verbatim. Human-facing skill concept labels must follow the Canonical Term Translation Table; terms not listed there should be localized naturally in the resolved output language.This runs first for every course-creation or editing request — before Orchestration, before proposing any course architecture/outline, before writing a single lesson. The AI-Shifu platform DB is the single source of truth; you must know whether you are creating a brand-new course or editing an existing one before you invest in authoring. Do NOT jump straight to a course outline or "架构方案". Even when the user clearly says "make a new course", first check the cloud for an existing one — this is the explicit front guard from the editing flowchart.
shifu-cli.py verify. It returns exit code 0 when the stored token is
still valid — skip login entirely and continue to step 3. Only when it
returns 1 (expired/invalid) do you guide the user through a single
SMS login session (below). Exit code 2 (network issue) means retry
later — still do NOT trigger a new login.
verify answers the question.references/cli/cli-reference.md#agent-login-flow.shifu-cli.py find-title <keyword> (targeted title search; do not dump the
whole list).pull <bid> --course-dir <dir> then
edit locally; Create new → author from scratch, then import --new.import --new.pull <bid> --course-dir <dir>, then edit
locally. Do NOT ask new-vs-edit; if several match, only resolve which one.import --new.Only after the target is resolved do you enter the authoring pipeline below. When the target is an existing course, you author on top of the pulled copy, then push via the converging loop in Deployment → Version Sync Workflow. Full branch/loop details live there; the gate itself is here because it must fire first.
Run this intake after Step 0 and before Orchestration for:
Do not run this intake for deploy-only, analytics, login, publish, management, or pure statistics requests.
Before asking anything, extract answers already present in the user's current instruction, source material, or pulled course directory. Ask only for missing items; do not repeat questions whose answers are already clear.
When any item is missing, ask only the corresponding questions for the missing items in the user's language. Resolve the usage scenario first; ask the Listen Mode question only after the usage scenario or inferred format shows the course is not slide-only.
Do not bypass this intake by inventing "conservative defaults" from a sparse topic or short brief. In particular, do not assume personalized AI self-study, thinking/self-check interactions, disabled Listen Mode, or a fixed chapter / lesson count before asking the relevant missing questions. Defaults below apply only after the user explicitly skips a question or asks you to continue without answering it.
Ask this intake as a step-by-step choice flow, not as one flat numbered checklist. Ask the usage-scenario question first, show its options, then wait for the user's answer before asking the next applicable question. After each answer, ask only the next still-missing applicable question. Do not offer "you can let me decide" or similar bypass wording before the required choice flow is complete.
Use the answers as course-design constraints:
The stages are not a flat linear pipeline. Step 0 (above) gates the whole pipeline. Orchestration is an end-to-end driver that internally calls Segmentation and Generation. Only Optimization and Deployment actually run in linear sequence after Orchestration completes.
Course request
│
▼
Step 0: Resolve Course Target ← MANDATORY front guard: login + find-title + branch
│ (new vs edit existing; pull the existing course BEFORE authoring)
▼
Raw material
│
▼
Course Design Intake ← ask only for missing design constraints
│ (usage scenario, interaction purpose, Listen Mode, chapter/lesson count)
▼
Orchestration ← end-to-end driver
├── calls Segmentation (cleanup + semantic segmentation)
└── calls Generation (per-lesson Teaching Prompts)
│
│ Orchestration outputs: Teaching Prompts + course_index
│ + global_variable_table
▼
Optimization (audit + optimize)
│
▼
Deployment (build + import + publish to platform)
│
╰─ optional ─▶ Analytics (post-deployment data queries on live courses)
Segmentation, Generation, and Optimization can each be invoked standalone — see Usage Paths (Path B) for the sub-paths (Segment only / Generate only / Optimize only). Analytics is a separate post-deployment path — see Usage Paths (Path E).
Run the full pipeline from raw material to a live deployed course.
login + find-title; if editing an existing course, pull it before authoring. See ## Step 0.Run Segmentation through Optimization to produce optimized Teaching Prompts, a Course Prompt, and an SEO course description without deploying. Sub-paths:
Run Deployment alone to deploy pre-existing Teaching Prompts and a Course Prompt to the AI-Shifu platform. Run Step 0 first (## Step 0) to resolve new-vs-existing — deploy as import --new, or pull + edit + push into an existing course.
Use Deployment management commands (list, show, update, rename, reorder, delete, publish, archive) on courses already on the platform.
Triggered by any question about a live course's data / metrics / statistics (see ## Data & Statistics Routing above for how to route and where the references live). Query post-deployment data — learner count, completion rate, stuck lessons, orders, revenue, ratings, credit consumption, audience profile, individual learner tracking. Reuses the Deployment authentication (token in .env); resolves shifu_bid via CLI list and outline via CLI show; runs DSL queries via CLI analytics-query (credit/spend via credit-detail). Always go through the CLI — never raw HTTP, never browser-scrape the admin dashboard. See the ## Analytics section below and references/analytics/overview.md.
Turn messy course source material into a reliable intermediate structure for downstream lesson generation.
See references/pedagogy.md#segmentation-methodology for the full methodology (cleanup, immutable-block marking, semantic segmentation, lesson-boundary proposal, source linking).
Segment list per references/data-contracts.md#segment-schema (each segment carries id, type, core point, preservation flag, source span, and transfer signals), plus lesson boundary candidates with one core question each.
transfer_signals object populated and usable downstream (schema per references/data-contracts.md#segment-schema).references/markdownflow.md#preservation and references/pedagogy.md#lesson-loop.Role: end-to-end orchestrator for Path A. Orchestration calls Segmentation (segmentation) and Generation (generation) internally, then performs the cross-lesson work that those atomic phases cannot — course index, global variable table, and mandatory gating.
All gates must pass before Orchestration declares lessons complete:
references/markdownflow.md#preservation; no unresolved placeholders and no learner-answer variable references without a variable-backed interaction and metadata contract; ?[] on standalone lines; deterministic blocks used only for truly fixed content per references/markdownflow.md#deterministic-blocks; every image URL must be on the res.ai-shifu.cn domain — fixed images wrapped in a single-line deterministic block, HTML-view images expressed as instruction-style directives with the (必须原样保留) URL phrase per references/markdownflow.md#images.references/pedagogy.md#lesson-loop, #interaction-design, #variable-strategy, and #visual-text-coordination. When Course Design Intake resolves to no interactions, bypass only the interaction-specific requirements that would force an interaction step or deepening interaction; keep the non-interaction requirements active.Recompute lessons that fail any gate; do not partially-pass.
Under fallback mode (see ## Execution Modes), Orchestration:
course_index entries.rerun_plan listing lessons that need recompute and why.Fallback field shapes per references/data-contracts.md#fallback-output-extensions.
See references/data-contracts.md#output-contract for the Teaching Prompts, course index, and global variable table schemas; preservation rules per references/markdownflow.md#preservation.
references/data-contracts.md#output-contract.Generate a runnable Teaching Prompt for each lesson.
Apply the patterns and constraints in references/pedagogy.md#teaching-patterns, #cognitive-techniques, #variable-strategy, #interaction-design, and #visual-text-coordination unless content requires a justified variation.
When generating interactions, explicitly choose the interaction type before writing the ?[] line: mutually exclusive route decisions use single-select; non-exclusive learner context, goals, interests, modules, blockers, scenarios, experience, or practice needs use multi-select. If a lesson naturally asks "which of these apply?", default to multi-select unless the source or user says only one answer is allowed.
Required anchors per lesson:
Optional modules: viewpoint calibration, misconception correction, dual deliverables (understanding + action), cross-lesson bridge sentence, additional visual-text reinforcement blocks.
When Course Design Intake resolves to pure slides / classroom interactive slides, replace the default explanation-heavy lesson pattern with a projection pattern:
Per-lesson schema in references/data-contracts.md#lesson-schema.
teaching_prompt is valid runnable MarkdownFlow.structure.json chapter / lesson title or a copied source heading such as # 第2章 ....references/data-contracts.md#lesson-schema.references/pedagogy.md and references/markdownflow.md.When the author supplies image assets — local files (any format incl. heic/heif), or remote URLs — three steps apply within Generation (and any later phase that touches the same lessons):
1. Understand each image before placing it.
You cannot decide which lesson a picture belongs to, or what alt text to write, without knowing what the image actually shows. Two regimes:
references/pedagogy.md#visual-text-coordination and references/course-prompt.md Rule 10/11.--alt), or (b) the user renames each file to a semantically meaningful name so you can infer the topic. Proceed only after one of these is in place.2. Upload via shifu-cli.py upload-image and capture the URL.
# Local file (preprocessed: max side 2048 px, ≤2 MB, JPEG q=85 / PNG for alpha):
python3 {skillDir}/scripts/shifu-cli.py upload-image \
--file /path/to/photo.heic --course-dir ./my-course/ --alt "梯度下降三步示意"
# Remote URL (backend downloads + re-hosts):
python3 {skillDir}/scripts/shifu-cli.py upload-image \
--url https://example.com/diagram.png --course-dir ./my-course/ --alt "Transformer 单层结构"
The command prints one line — the https://res.ai-shifu.cn/<uuid32> URL — to stdout; the manifest at <course-dir>/assets/image-manifest.json is updated automatically. See references/cli/cli-reference.md for full flag reference.
3. Embed in MarkdownFlow per references/markdownflow.md#images.
必须原样保留 / 必须原样输出 / 不要改写); never mix deterministic blocks into the instruction.Either way, the explanatory paragraph immediately after the image is mandatory (cf. course-prompt.md Rule 11).
Audit and improve existing Teaching Prompts (and the Course Prompt). This phase is not for writing from scratch.
Use Optimization when existing Teaching Prompts or a Course Prompt need audit and targeted improvement — gap analysis against source, quality upgrades without full rewrites, and lowering runtime failure risk. Not for from-scratch authoring.
Apply Optimization audits against the full constraint set:
references/pedagogy.md.references/markdownflow.md.references/review-checklist.md.references/review-checklist.md, classify findings using the issue taxonomy in references/pedagogy.md#optimization-methodology, and apply smallest safe edits first.Optimization also produces a course-level course_prompt artifact when input includes course material. Generate it by filling the template at references/course-prompt.md#fillable-template section-by-section, not by free-form composition. Each of the six required sections has a Must-Specify list in references/course-prompt.md#authoring-rules (Rules 1–11) — every listed bullet must appear in the generated course_prompt's corresponding section (in the resolved output language). Do not omit a Must-Specify bullet just because the source material does not explicitly demand it; these bullets are platform-level constraints.
Auto-fill placeholders from existing artifacts (course_profile, delivery_constraints, resolved target language per references/data-contracts.md#language-resolution, Segmentation visual cues) instead of re-asking the author. Do not duplicate per-lesson interaction logic or variable collection there — those belong in Teaching Prompts.
references/report-template.md).references/review-checklist.md passes, or remaining gaps are explicitly listed as non-blocking suggestions.course_prompt artifact is produced when input includes course material, with all six required canonical sections present.course_prompt covers every Must-Specify bullet in references/course-prompt.md Rules 1–11 (audit each canonical section against its rule list — especially the Slides section, which is the most commonly under-filled section).Ship optimized Teaching Prompts to the AI-Shifu platform as live courses. Two distinct actions are involved and should not be conflated:
build + import. After this the course exists on the platform but is not yet visible to learners on a public URL.publish on the platform, which pushes the current draft to the public student-facing URL. Only after this step does <base>/c/<bid> (no preview=true) work.revision); pull brings the cloud copy down and records its version in .shifu-sync.json, and the version-aware write commands (update-lesson / update-meta / import with --course-dir) refuse to overwrite a change another editor pushed — they auto-pull and back up your edit instead. Think git pull before git push.The standard end-to-end flow chains deploy + publish: build → import (deploy) → publish. When editing an existing course, use the sync loop instead: pull → edit locally → status → update-lesson / import (push) → publish.
requests and python-dotenv packages installed.{skillDir}/scripts/shifu-cli.pyVerify first — never re-login blindly. Before any operation that needs a
token, run shifu-cli.py verify:
0 → token is valid, continue. Do NOT trigger the login flow.1 → token is expired/invalid, guide the user through a single
SMS login session (see references/cli/cli-reference.md#agent-login-flow).2 → network issue, retry later — still do NOT trigger a new login.Each phone number only gets 5 SMS verification codes per day. Re-logging
when the token is still valid wastes one of those slots and can lock the user
out. verify answers the question cheaply (one lightweight API call, no SMS).
Always use CLI commands. Never make raw HTTP/API calls directly.
Teaching Prompts must be organized in a course directory (one MarkdownFlow file per lesson under lessons/) before deployment. See references/cli/course-directory-spec.md for the full specification. When continuing from Optimization (Path A), write the optimized Teaching Prompts and Course Prompt into this structure automatically.
Content vs attributes — the skill changes content, not attributes, by default.
A course has two parts: content (lesson MarkdownFlow + course name/prompt)
and attributes (each lesson's learning permission access = 无需登录/试看/付费
and hidden; course-level model/price/TTS/Ask/keywords/…). The skill pushes only
content; it never sends attributes by default, and the platform backend uses
PATCH semantics (any field a write omits is left unchanged), so iterating content
never resets attributes. pull writes the current attributes into
structure.json (access/hidden) and course-config.json as a read-only
reference for you. Change attributes only when the user explicitly asks:
set-access <shifu_bid> <outline_bid> --access guest|trial|normal [--course-dir <dir>]
for a lesson's permission; set-tts <shifu_bid> --enabled true|false [--course-dir <dir>]
for course Listen Mode. Other course-level settings are changed in the
platform editor.
Editing an existing course → use granular non-destructive commands
(pull → update-lesson / add-lesson / delete-lesson / reorder / set-access / set-tts).
The destructive whole-course import recreates every outline (a recreated lesson
gets the platform-default permission), so reserve import --new for brand-new
courses — do not use it to iterate an existing one.
All commands documented in references/cli/cli-reference.md (deployment: build / import / publish / show; version sync: pull / status; management for Path D: list / update-meta / update-lesson / rename-lesson / set-access / set-tts / reorder / delete-lesson / archive). JSON schema in references/cli/import-json-format.md.
From pipeline (Path A continuation):
lessons/lesson-*.md, README.md, course-description.md (the generated SEO description, based on the course topic, target learners, and learning outcomes; no author-side process notes), course-prompt.md (the Optimization course_prompt artifact, structured per references/course-prompt.md#fillable-template), and required structure.json.build --course-dir <dir> to generate shifu-import.json.import --new --json-file <dir>/shifu-import.json to upload the course onto the platform.publish <shifu_bid> to push the course to its public student-facing URL.Standalone deployment (Path C):
lessons/), a course-description.md SEO summary, a course-prompt.md, and structure.json. If the Course Prompt is not yet authored, follow references/course-prompt.md#fillable-template (and references/course-prompt.md#authoring-rules for guidance) before running build. If structure.json is missing, create it before running build. Existing directories without course-description.md still build, but the platform description will be empty unless --description is provided.build → import (deploy) → publish as above.The platform DB is the single source of truth. The front guard that fixes the
target (new-vs-edit, login + find-title, and pulling the existing course) is
Step 0 — run it first, see ## Step 0. This section covers what happens once
the target is an existing course you have pulled: the pull → edit → push loop
that converges like git pull before git push. Together they mirror the editing
flowchart exactly.
Once the target is a download of an existing course, treat the platform draft as the source of truth:
pull <shifu_bid> --course-dir <dir> — download the cloud draft into the
local dir (writes README.md / course-description.md / course-prompt.md /
lessons/lesson-NN.md / structure.json and records each lesson + course
revision into .shifu-sync.json).status --course-dir <dir> — see what diverged: behind (cloud changed,
pull again), locally modified (your pending edits), new/deleted on server.--course-dir so the recorded baseline is used:
update-lesson <bid> <ob> --teaching-prompt-file f.md --course-dir <dir> for a
single lesson, or import <bid> --course-dir <dir> for the whole course.publish <bid> when ready for learners.Convergence loop on conflict — this IS the flowchart's "上传 → 线上是否有新版本 → 是 → 下载 → 重新合并 → 上传" loop. A push checks whether the cloud advanced since your last sync — that is the "is there a newer version online?" decision:
publish.<lesson>.conflict for a lesson,
.shifu-meta.conflict.json for meta, .conflict-backup-<ts>/ for a whole-course
import; (b) auto-pulled the latest cloud copy over local; (c) printed who changed
it and when. Exit 2 means "retry", not "give up". Then loop:
.shifu-sync.jsonis auto-maintained; never hand-edit it. Without--course-dir,update-lessonstill works but only compares against the cloud head, so it cannot detect a concurrent edit — prefer the sync loop.
After any deployment or management operation, verify the result:
# ... hint copied verbatim without the leading # (per references/report-template.md — Deployment → Verification URLs, plus the top-level Formatting Rules exception). Never reconstruct URLs from a template by hand. Lesson-level URLs are intentionally omitted to keep the report scannable; if the user later asks for a specific lesson link, use show <shifu_bid> to find the outline_bid and build it on demand.show <shifu_bid> to get the lesson outline_bid, then check each lesson's Teaching Prompt, variable collection, and interaction logic.Post-deployment data queries on live courses. Trigger this section whenever a course author or admin asks about learner count, completion rate, stuck lessons, orders, revenue, ratings, follow-up Q&A volume, credit consumption, audience profile distribution, or individual learner tracking. (If you arrived here from the top-level ## Data & Statistics Routing block, the three-step flow is restated below; for a one-glance course overview use Recipe 0d in references/analytics/recipes.md.)
All analytics traffic goes through scripts/shifu-cli.py. Never write raw HTTP, never read tokens directly, never compose Authorization / Token headers by hand. Two analytics commands cover the surface:
shifu-cli.py analytics-query <bid> --dsl '<json-body>' — DSL queries against the whitelisted tables (learn_progress_records, learn_generated_blocks, learn_lesson_feedbacks, order_orders, var_variable_values, shifu_user_archives, user_users, shifu_published_shifus, shifu_draft_shifus). The agent's job is to translate a user question into a DSL JSON body and pass it to the CLI.shifu-cli.py credit-detail <bid> [--start … --end … --scene 1203 --usage-type 1101 …] — server-side join of bill_usage × credit_ledger_entries for credit consumption queries. Use this whenever the user asks about credits / spend, not a DSL query against bill_daily_usage_metrics (that table is empty in production until the daily aggregation cron is enabled). --scene 1203 restricts to learner-driven spend (preview is 1202, debug is 1201).shifu-cli.py verify. If exit 0 the stored token is valid; if exit 1, guide the user through the SMS login flow per references/cli/cli-reference.md#agent-login-flow.shifu-cli.py list (or shifu-cli.py find-title <keyword>) to map shifu_bid ↔ course name. If the user mentioned a course by title, always resolve the current shifu_bid → title via Course Metadata recipes 0a / 0b in references/analytics/recipes.md before issuing downstream queries — list is a draft snapshot and can show stale or historical titles. Never report a historical title as the course's current name.shifu-cli.py show <shifu_bid> to map outline_item_bid → name / position. Skipping this makes outline-dimension numbers unreadable.shifu-cli.py analytics-query <shifu_bid> --dsl '<json-body>' (or --dsl-file query.json for long bodies).references/analytics/privacy-and-presentation.md. Never paste raw codes (601, 502, 1101), raw *_bid strings, or raw user_bid values in user-facing output.references/analytics/overview.md — entry point, full workflow, error codesreferences/analytics/dsl.md — DSL grammar (operators, aggregates, constraints, per-learner guard rail, auto-applied filters, creator-scoped metadata tables)references/analytics/tables.md — 10 tables, fields, all code/enum translation tables, ID translation rules, duplicate-row trap, role = 2 ≠ follow-up trap, "course title is not history" rulereferences/analytics/recipes.md — Course Metadata 0a–0c + 23 numbered scenario recipes (including four-key follow-up pairing and follow-ups per lesson)references/analytics/privacy-and-presentation.md — user_users restricted access, generated_content whitelist, var_variable_values.value aggregate-only rule, "course title is not history" hard rule, Translation Gate, refusal rulesshifu_bid → title was confirmed via Course Metadata Recipe 0a / 0b before the downstream query ran. Historical titles were never substituted for current ones.shifu_bid and outline mappings established before any course-level query.dsl.md; filters reflect the user's intent (e.g. status = 502 for "paid", not >= 502).shifu-cli.py credit-detail (server-side join). Do not issue a DSL query against bill_daily_usage_metrics — it is empty in production pending the daily aggregation cron. To restrict to learner-driven spend pass --scene 1203 (preview is 1202, debug is 1201).type = 321 (not role = 2), and rely on the API's auto-injected status = 1 rather than an explicit clause.references/cli/cli-reference.md#cli-output--encoding).tables.md. Never guess a table name — invalid names trigger 11003.Use references/report-template.md to produce the user-facing report at the end of each phase. Per-phase anchors:
references/report-template.md#segmentation-reportreferences/report-template.md#orchestration-reportreferences/report-template.md#generation-reportreferences/report-template.md#optimization-reportreferences/report-template.md#deployment-reportTop-level formatting rules (Markdown links required for URLs, etc.) in references/report-template.md#formatting-rules.
examples/pipeline-full.mdexamples/segmentation-only.mdexamples/generation-only.mdexamples/optimization-only.mdexamples/fallback-mode.mdexamples/end-to-end-deploy.mdexamples/deploy-only.md