@north-light/crouter 0.3.339 → 0.3.340
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/dist/commands/sys/tutorial/branch.js +1 -1
- package/dist/commands/sys/tutorial/lessons.d.ts +0 -1
- package/dist/commands/sys/tutorial/lessons.js +7 -12
- package/dist/commands/sys/tutorial/scenario.js +2 -2
- package/dist/commands/sys/tutorial/tracks.d.ts +0 -1
- package/dist/commands/sys/tutorial/tracks.js +3 -3
- package/package.json +1 -1
- package/runtime.lock.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineBranch as e}from"../../../core/command.js";import{
|
|
1
|
+
import{defineBranch as e}from"../../../core/command.js";import{basicLeaf as r}from"./tracks.js";import{scenarioBranch as s}from"./scenario.js";const t=e({name:"tutorial",description:"guided crouter lessons and disposable practice scenarios",whenToUse:"you need to learn crouter operation conversationally, one lesson at a time, or create the disposable canvas state a lesson asks you to inspect.",extensible:!0,help:{name:"sys tutorial",summary:"guided crouter lessons and disposable practice scenarios",model:"Tracks serve one lesson per invocation and never record progress, so --step can start or resume anywhere. Scenarios create only the temporary canvas state a lesson needs and clean exactly the recorded rows afterward."},children:[r,s]});export{t as tutorialBranch};
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
`)},{title:"
|
|
3
|
-
`)},{title:"
|
|
4
|
-
`)},{title:"
|
|
5
|
-
`)},{title:"
|
|
6
|
-
`)},{title:"
|
|
7
|
-
`)}
|
|
8
|
-
`)},{title:"Status glyphs",body:["The graph gives every node a status glyph, so you can read the canvas before opening each conversation. The five ordinary statuses are:","","| Glyph | Status | What it means |","|---|---|---|",`| ${t.glyph} | active | The node is working. |`,`| ${n.glyph} | idle | The node is not currently running a turn. |`,`| ${a.glyph} | done | The node finished its work. |`,`| ${o.glyph} | dead | The node ended without remaining live work. |`,`| ${i.glyph} | canceled | The node was canceled. |`,"",`Three overlays replace that ordinary status when they are more important: ${s.glyph} live means a turn is streaming now; ${r.glyph} frozen means the node is waiting for broker capacity; ${h.glyph} fault means the runtime found a problem that needs attention.`,"","The precedence is `fault > frozen > live > status`. Read the leftmost applicable condition: a fault hides frozen or live, frozen hides live, and live hides the ordinary status.","","Put a few rows in the graph so the glyphs have something to describe:","","```bash","crtr sys tutorial scenario start idle-nodes","```","","Open `Alt+C` then `g`, identify the idle rows, then clean up the demo yourself:","","```bash","crtr sys tutorial scenario clean idle-nodes","```","","Do not leave this state for another lesson. A user may jump to any lesson, and every demo must leave the canvas as it found it."].join(`
|
|
9
|
-
`)},{title:"The inbox \u2014 Alt+I",body:["The inbox is how a node reaches the user. When an agent needs a decision, wants a document reviewed, or is blocked on something only a person can settle, it posts there and goes dormant. Without the inbox that agent looks stuck; with it, the user can see it is simply waiting on them.","","Give them something real to answer:","","```bash","crtr sys tutorial scenario start pending-ask","```","","Tell them the entry is titled **A question from the tutorial**, so they can find it even if real requests are already waiting. Then have them press `Alt+I`, read it, and respond to it. Walk them through selecting the item and answering, and point out that a real answer wakes the waiting node immediately \u2014 a reply is not filed for later, it resumes the work that was blocked on it. (This demo request has no node behind it, so nothing wakes; say so rather than implying otherwise.)","","Clean up when the point has landed:","","```bash","crtr sys tutorial scenario clean pending-ask","```","","The habit worth leaving them with: **check the inbox when something seems idle.** An agent that appears to have stopped has very often asked a question and is waiting."].join(`
|
|
10
|
-
`)}],c=[{title:"Promotion to orchestrator",body:["Every node is one of two modes. A **base node** does the work itself \u2014 reads, edits, runs commands. An **orchestrator** holds a roadmap and delegates, spawning children for the pieces and integrating what comes back.","","- `Alt+C` `o` promotes the focused node to orchestrator.","- `Alt+C` `Shift+O` demotes it back to a base node.","- From inside a conversation, `/promote` does the same thing, and `/promote <kind>` specializes it at the same time.","","Teach *when*, because the keystroke is the easy part. Promotion earns its cost when the work has **genuinely independent parts** that can run at the same time, or **many large phases** that would otherwise fill a single context window. It is the wrong move for a two-file change: spinning up a child and waiting for its report costs more than doing the work directly.","","The mechanism worth naming: a child reports up to whoever subscribes to it, and that report **wakes the manager**. Nobody polls. An orchestrator delegates, ends its turn, and comes back when there is something to integrate \u2014 which is why a fan-out of five children costs one manager context window rather than five.","","The failure mode to warn about is recursive delegation: an orchestrator that hands its entire assignment to one child has not decomposed anything, it has added a layer. Each child needs a bounded outcome genuinely smaller than the whole."].join(`
|
|
11
|
-
`)},{title:"Terminal and resident nodes",body:["Lifecycle is the other axis, orthogonal to mode. It answers: what does this node owe, and when is it allowed to end?","","- A **terminal** node owes a final report up the spine. It does its work, delivers, and reaps itself. This is the shape for bounded delegated work.","- A **resident** node is interactable, never forced to submit a final, and stays wakeable indefinitely. This is the shape for a conversation with a person.","","`Alt+C` `d` demotes a node to terminal. `Alt+C` `Shift+R` makes one resident. Roots default to resident; managed children default to terminal.","","**Why it works this way** \u2014 this is the part worth understanding, not memorizing.","","A terminal node is *depended upon to finish*. Its manager subscribed to it and will be woken by its report, so the guarantee that it must eventually deliver one is exactly what makes delegation safe. Without it, an orchestrator could wait forever on a child that quietly decided it was done.","","A resident node must never be forced to close mid-sentence. A conversation with a person has no natural completion \u2014 the user may come back tomorrow \u2014 so requiring a final report would either truncate the conversation or produce a meaningless one. Residency removes that requirement, and going dormant costs nothing: the node holds no window and burns no compute while it waits.","","This is why **the user's own conversation is resident and cannot be finished on its behalf**, while the children it spawns are terminal and reap themselves when they report. The user sees this as agents that clean up after themselves while their own thread persists \u2014 that is the lifecycle axis doing its job.","","Related and worth a mention: a **yield** lets a resident node whose context is filling revive fresh under the same identity and mandate, carrying a note to its future self. The conversation survives; only the context window is recycled."].join(`
|
|
12
|
-
`)}];export{c as ADVANCED_LESSONS,l as BASIC_LESSONS};
|
|
1
|
+
const e=[{title:"Return to a conversation \u2014 recap, find, pin",body:["Start with a conversation the user actually wants to return to. `Alt+C` opens the crouter action menu; its entries show the keys, so do not ask the user to memorize a shortcut list.","","Ask them to press `Alt+C`. If Option types an accented character instead of opening the menu, identify their terminal and help set Option to send Alt/Esc; show any proposed config edit and get permission before writing it. If they cannot use tmux panes yet, inspect their existing tmux prefix and bindings and teach only the pane actions they need. These are conditional setup steps, not separate lessons.","","Have them choose `s` from the menu to refresh this conversation\u2019s Goal/State recap and generated title. Point out the Goal above the transcript and the State above the editor. This generates content using an agent; do not describe it as a free visual toggle. Then open Find node with `Alt+C`, `/`, search for the refreshed title, and select the conversation. The navigator searches conversations across the canvas; the graph in a later lesson is only for nodes connected to the current conversation.","","In Find node, have them select this conversation and press `p` to pin it; the star and sorting change. If it was already pinned, do not unpin it merely for practice. A pin persists, so ask before changing it and restore the original state if this is only a demonstration.","","Explain the important distinction: closing the viewer or terminal detaches from the conversation; it does not close the node. They can find it again. `Alt+C`, `x` deliberately closes the node and its subtree, so do not use it for detaching. Let them try recap, find, and pin before proceeding."].join(`
|
|
2
|
+
`)},{title:"Answer an agent \u2014 the inbox",body:["When an agent needs a decision, it can put a question in the human inbox and wait without polling. The answer to an agent\u2019s own question wakes that agent. Teach the habit: if work seems paused, check the inbox with `Alt+I`.","","Ask before creating the disposable tutorial question. Once they agree, run:","","```bash",'crtr sys tutorial scenario start pending-ask --parent "$CRTR_NODE_ID"',"```","","Have them open **A question from the tutorial** with `Alt+I`, select an option with `j`/`k`, toggle it with Space, optionally add a comment with `c`, and submit. This question links back to the tutorial conversation but **no agent waits on its answer**; it practices the same inbox controls as a real request. Clean up afterward, even if they decide not to submit:","","```bash","crtr sys tutorial scenario clean pending-ask","```"].join(`
|
|
3
|
+
`)},{title:"Make it yours \u2014 settings and plugins",body:["Open `Alt+C`, `,` to inspect settings and keybindings. Let the user find one binding they care about. In the keybinding editor, `/` filters, Enter edits, and Escape discards an unsaved edit. Do not save a binding change unless they ask for that exact change; saved bindings affect their future sessions.","","Then use `Alt+C`, `l` to browse plugins. Have them inspect one plugin\u2019s capabilities and decide whether it is relevant to their work. Browsing does not install it. Installing or enabling a plugin changes local configuration, so do that only if they choose a specific plugin and approve the change.","","These are discovery tools, not a feature tour: the user should leave knowing how to find a setting or capability when they need it, not with a new configuration they did not request."].join(`
|
|
4
|
+
`)},{title:"Take another direction \u2014 fork",body:["Forking lets the user pursue another direction without replacing the original conversation. `Alt+C`, `f` forks the focused node into a separate, idle root. It does not start a model turn; the fork is a new conversation that remains on the canvas until closed.","","Ask whether they have a disposable conversation to fork and want to try it. Do not fork the current long-lived conversation just to make a demonstration. If they agree, focus that conversation, use `Alt+C`, `f`, then find both the original and the new root with `Alt+C`, `/`. Confirm which is which before offering to close the disposable fork; closing it is a separate, destructive action that needs permission.","","If there is no suitable conversation or they decline to create durable state, explain the action and move on. Mention `/fork` only if they specifically need to choose a point within the conversation; the menu action is enough for this lesson."].join(`
|
|
5
|
+
`)},{title:"Keep a useful fact \u2014 memory",body:["The practical instruction is \u201Cremember that.\u201D The user does not need to choose a storage format: the agent can propose whether the fact is knowledge about how to do something or a preference about how it should behave, and where that memory should apply.","","Ask whether there is a genuine, durable fact from their work that they want the agent to remember. State the proposed wording and scope, and get their approval before writing. Do not manufacture a personal preference or save a fact just to complete the exercise. If none exists, let them try the phrase as a future request and move on.","","A project fact should not silently become a global preference. The useful outcome is that the user knows they can say \u201Cremember that\u201D and correct the proposed wording or scope."].join(`
|
|
6
|
+
`)},{title:"Follow delegated work \u2014 the graph",body:["Use a real task with independent parts if one is already underway. Delegation is useful when pieces can run separately or a task has several large phases; do not promote a node or spawn children solely to fill a graph. A small task stays with one agent.","","Press `Alt+g` to open the graph of this conversation and its connected nodes. With real children present, `l` expands a parent or moves to its first child, `j`/`k` selects rows, `h` moves toward the parent, Enter focuses a child, and Esc closes the graph. Do not use `x`: it asks to close a subtree. If no real children are present, describe these controls briefly and let the user revisit the graph when an agent delegates actual work.","","A manager may look idle while its children run. That is expected: it ends its turn and waits for a child\u2019s report, which wakes it to integrate the result. A running broker is not proof that a model turn is streaming; a fault is different from ordinary waiting and needs attention. Explain status only in response to what the user actually sees, not as a glyph glossary.","","The visible result should be a user who can open a working child and return to its manager without wondering why the manager stopped speaking. End the tutorial here; promotion, node modes, and lifecycle commands are details to explain only when a real task requires them."].join(`
|
|
7
|
+
`)}];export{e as BASIC_LESSONS};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);function h(){return
|
|
1
|
+
var A=Object.defineProperty;var a=(e,t)=>A(e,"name",{value:t,configurable:!0});import{mkdirSync as w,readFileSync as R}from"node:fs";import{dirname as y,join as T}from"node:path";import{ApiError as b}from"../../../api/index.js";import{withMetaLock as q,writeMetaObjectLocked as O}from"../../../core/canvas/meta-file.js";import{defineBranch as E,defineLeaf as p}from"../../../core/command.js";import{InputError as c}from"../../../core/io.js";import{userScopeRoot as P}from"../../../core/scope.js";import{cliClient as l,getNodeOrNull as _,rethrowAsCliError as u}from"../../api-client.js";const v={"idle-nodes":{title:"Three practice children of a tutorial conversation",teaches:"the graph lesson \u2014 navigate a parent and its children",builds:"three child nodes without tasks under the specified parent; their brokers run until cleanup"},"pending-ask":{title:"A question waiting in the inbox",teaches:"the inbox lesson \u2014 reading a pending item and answering it",builds:"one durable pending request in the human inbox"}},$=["export default function TutorialAsk() {"," return (",' <Page title="A question from the tutorial" subtitle="Practice choosing and commenting on an option.">'," <UserQuestion",' id="answer"',' label="Which crouter topics would you like to explore?"',' body="Select one or more topics with Space and add a comment to an option with c. This is practice; no agent acts on your answer."',' mode="multi"'," options={["," { id: 'orchestration', label: 'Delegating work to other agents' },"," { id: 'memory', label: 'Teaching it my preferences' },"," { id: 'navigation', label: 'Finding conversations and navigating the canvas' },"," ]}"," />"," </Page>"," );","}"].join(`
|
|
2
|
+
`);function h(){return T(P(),"tutorial-scenarios.json")}a(h,"ledgerPath");function k(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}a(k,"isStringArray");function x(){let e;try{e=JSON.parse(R(h(),"utf8"))}catch(r){if(r.code==="ENOENT")return{};throw r}if(typeof e!="object"||e===null||Array.isArray(e))throw new c({error:"invalid_scenario_ledger",message:`tutorial scenario ledger at ${h()} must be an object`,next:"Remove or repair the ledger file, then retry the scenario command."});const t={};for(const r of Object.keys(v)){const n=e[r];if(n===void 0)continue;if(typeof n!="object"||n===null||typeof n.started!="string")throw new c({error:"invalid_scenario_ledger",message:`tutorial scenario ledger has an invalid ${r} record`,next:"Remove or repair the ledger file, then retry the scenario command."});const s=n;if(s.nodes!==void 0&&!k(s.nodes)||s.requests!==void 0&&!k(s.requests))throw new c({error:"invalid_scenario_ledger",message:`tutorial scenario ledger has invalid ids for ${r}`,next:"Remove or repair the ledger file, then retry the scenario command."});t[r]={started:s.started,...s.nodes===void 0?{}:{nodes:s.nodes},...s.requests===void 0?{}:{requests:s.requests}}}return t}a(x,"readLedger");function N(e){const t=h();return w(y(t),{recursive:!0}),q(t,()=>e(x()))}a(N,"withLedger");function f(e){const t=h();return w(y(t),{recursive:!0}),q(t,()=>{const r=x(),n=e(r);return O(t,r),n})}a(f,"updateLedger");function I(e){return f(t=>{if(t[e]!==void 0)throw new c({error:"scenario_already_standing",message:`the '${e}' scenario is already standing (started ${t[e].started})`,field:"scenario",next:`Run \`crtr sys tutorial scenario clean ${e}\` first, then start it again.`});const r={started:new Date().toISOString(),...e==="idle-nodes"?{nodes:[]}:{requests:[]}};return t[e]=r,r})}a(I,"reserveScenario");async function S(e,t,r){if(!f(s=>{const i=s[e];return i===void 0?!1:(i[t]=[...i[t]??[],r],!0)})){try{t==="nodes"?await l().closeNode(r):await l().cancelHumanRequest(r,{reason:"Tutorial scenario start interrupted."})}catch(s){m(s)||u(s)}throw new Error(`tutorial scenario '${e}' disappeared while it was starting`)}}a(S,"appendScenarioId");function m(e){return e instanceof b&&(e.status===404||e.code==="already_settled")}a(m,"isAlreadyCleaned");function L(e){return e==="done"||e==="dead"||e==="canceled"}a(L,"isTerminalNode");function j(e){const t=e.scenario;if(t==="idle-nodes"||t==="pending-ask")return t;throw new c({error:"unknown_scenario",message:`no tutorial scenario named '${String(t)}'`,field:"scenario",next:"Use idle-nodes or pending-ask. Run `crtr sys tutorial scenario list` for what each one builds."})}a(j,"scenario");async function C(e,t){const r=["tutorial-demo-one","tutorial-demo-two","tutorial-demo-three"];for(const n of r){const s=await l().createNode({parent:t,creator:t,root_lifecycle:"resident",no_kickoff:!0,prompt:"",cwd:process.cwd(),name:n}).catch(u);await S("idle-nodes","nodes",s.node_id),e.nodes.push(s.node_id)}}a(C,"startIdleNodes");async function U(e,t){const r=await l().createHumanRequest({page:{dialect:"jsx",source:$},delivery:{placement:"inline",inbox:!0,reply:!1},source:{askedBy:"crtr sys tutorial",sessionName:"tutorial",nodeId:t},creator_cwd:process.cwd()}).catch(u);await S("pending-ask","requests",r.request_id),e.requests.push(r.request_id)}a(U,"startPendingAsk");const B=p({name:"list",description:"list the tutorial practice scenarios",whenToUse:"you need to choose a disposable canvas scenario for a lesson or see whether one is already standing.",help:{name:"sys tutorial scenario list",summary:"list the tutorial practice scenarios and their standing state",inputNote:"No input parameters.",output:[{name:"scenarios",type:"object[]",required:!0,constraint:"One row per scenario: {id, title, teaches, builds, standing}."},{name:"standing",type:"number",required:!0,constraint:"Number of scenarios currently recorded as standing."}],outputKind:"object",effects:["None. Read-only."]},run:a(async()=>{const e=N(r=>r),t=Object.entries(v).map(([r,n])=>({id:r,title:n.title,teaches:n.teaches,builds:n.builds,standing:e[r]!==void 0}));return{scenarios:t,standing:t.filter(r=>r.standing).length}},"run")}),D=p({name:"start",description:"create a tutorial practice scenario",whenToUse:"a tutorial lesson needs its disposable graph rows or inbox request before the user can practice against a real canvas surface.",help:{name:"sys tutorial scenario start",summary:"create one tutorial practice scenario",params:[{kind:"positional",name:"scenario",type:"string",required:!0,constraint:"idle-nodes (three children without tasks) or pending-ask (one durable inbox request)."},{kind:"flag",name:"parent",type:"string",required:!0,constraint:"Node id of the tutorial conversation; children and the inbox request are linked to this node."}],output:[{name:"nodes",type:"string[]",required:!1,constraint:"Created child node ids for idle-nodes."},{name:"requests",type:"string[]",required:!1,constraint:"Created human request ids for pending-ask."},{name:"clean_with",type:"string",required:!0,constraint:"Exact command that removes this scenario."},{name:"look_at",type:"string",required:!0,constraint:"Viewer surface that shows the created state."}],outputKind:"object",effects:["idle-nodes creates three resident children of --parent with no kickoff turn; their brokers run until cleanup. Their ids are recorded in ~/.crouter/tutorial-scenarios.json.","pending-ask publishes one durable human request with --parent as its source; answering it does not wake that node. Its id is recorded in ~/.crouter/tutorial-scenarios.json.","Refuses a scenario already recorded as standing; clean it before starting it again."]},run:a(async e=>{const t=j(e),r=e.parent;if(r===void 0||r.trim()==="")throw new c({error:"parent_required",message:`${t} needs the tutorial conversation node id in --parent`,field:"parent",next:"Pass the node id of the conversation the user is viewing."});if(await _(r)===null)throw new c({error:"unknown_parent",message:`no local node exists for --parent ${r}`,field:"parent",next:"Pass the node id of a conversation on this canvas."});const n=I(t);return t==="idle-nodes"?await C(n,r):await U(n,r),{...n.nodes===void 0?{}:{nodes:n.nodes},...n.requests===void 0?{}:{requests:n.requests},clean_with:`crtr sys tutorial scenario clean ${t}`,look_at:t==="idle-nodes"?"Open the graph with `Alt+g`.":"Open the inbox with `Alt+I`."}},"run")}),H=p({name:"clean",description:"remove a tutorial practice scenario",whenToUse:"the lesson has finished with a scenario and you need to remove exactly the nodes or request it recorded.",help:{name:"sys tutorial scenario clean",summary:"remove exactly the rows recorded for one tutorial practice scenario",params:[{kind:"positional",name:"scenario",type:"string",required:!0,constraint:"Scenario to remove: idle-nodes or pending-ask."}],output:[{name:"was_standing",type:"boolean",required:!0,constraint:"Whether this scenario had a ledger record to remove."},{name:"closed_nodes",type:"number",required:!1,constraint:"Number of ledger-recorded node ids closed. Present when the scenario was standing."},{name:"canceled_requests",type:"number",required:!1,constraint:"Number of ledger-recorded request ids canceled. Present when the scenario was standing."},{name:"already_settled_requests",type:"number",required:!1,constraint:"Number of ledger-recorded request ids already terminal when clean processed them. Present when the scenario was standing."}],outputKind:"object",effects:["Closes or cancels only ids recorded for this scenario in ~/.crouter/tutorial-scenarios.json, then removes that scenario record."]},run:a(async e=>{const t=j(e),r=N(o=>o[t]);if(r===void 0)return{was_standing:!1};let n=0,s=0,i=0;for(const o of r.nodes??[]){const d=await _(o);if(!(d===null||L(d.status)))try{await l().closeNode(o),n++}catch(g){m(g)||u(g)}}for(const o of r.requests??[])try{await l().cancelHumanRequest(o,{reason:"Tutorial scenario cleaned up."}),s++}catch(d){d instanceof b&&d.code==="already_settled"?i++:m(d)||u(d)}return f(o=>{delete o[t]}),{was_standing:!0,closed_nodes:n,canceled_requests:s,...i===0?{}:{already_settled_requests:i}}},"run")}),X=E({name:"scenario",description:"create and remove disposable tutorial practice state",whenToUse:"a tutorial lesson needs real but disposable canvas rows or an inbox request to inspect and practice against.",help:{name:"sys tutorial scenario",summary:"create and remove disposable canvas state for tutorial lessons",model:"Each scenario records only the ids it creates. Start refuses an already-standing scenario, and clean acts only on that recorded list."},children:[B,D,H]});export{X as scenarioBranch};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}
|
|
1
|
+
var h=Object.defineProperty;var i=(e,n)=>h(e,"name",{value:n,configurable:!0});import{defineLeaf as m}from"../../../core/command.js";import{InputError as y}from"../../../core/io.js";import{BASIC_LESSONS as p}from"./lessons.js";const g=["Teach this conversationally, in your own words \u2014 do not paste this lesson at the user.","Ask before you change anything on their machine, and show the exact diff you propose.","Let the user actually try each thing and confirm it worked before you move on."].join(" "),f={basic:p};function b(e){return e.map((n,t)=>`${t+1}. ${n.title}`).join(`
|
|
2
|
+
`)}i(b,"tableOfContents");async function w(){const{resolveRoot:e}=await import("../../../build-root.js"),t=(await e("sys")).subtrees.find(s=>s.name==="sys");if(t?.kind!=="branch")throw new Error("The assembled sys subtree is missing.");const r=t.children.find(s=>s.name==="tutorial");if(r?.kind!=="branch")throw new Error("The assembled sys tutorial branch is missing.");if(r.help.listing===void 0)throw new Error("The assembled sys tutorial listing is missing.");return r.help.listing}i(w,"tutorialListing");function $(e){return e.length===0?"That is the whole tutorial.":`What's next: ${e.map(({command:n,description:t})=>`${n} \u2014 ${t}`).join("; ")}`}i($,"nextTracksLine");async function T(e,n){const t=f[e],r=t.length,s=n.step,o=s==null?1:Number(s);if(!Number.isInteger(o)||o<1||o>r)throw new y({error:"step_out_of_range",message:`--step must be between 1 and ${r} (got ${String(s)})`,field:"step",next:`Run \`crtr sys tutorial ${e} -h\` and read the contents, then pick a lesson in range.`});const c=t[o-1],l=o<r?`crtr sys tutorial ${e} --step ${o+1}`:void 0,d=l===void 0?await w():void 0;let a;return d!==void 0&&(a=d.filter(u=>u.plugin!==void 0).map(u=>({command:`crtr sys tutorial ${u.name}`,description:u.description}))),{track:e,step:o,total:r,title:c.title,body:a===void 0?c.body:`${c.body}
|
|
3
3
|
|
|
4
|
-
${
|
|
4
|
+
${$(a)}`,...l===void 0?{}:{next:l},teaching_contract:g,...o===1?{contents:b(t)}:{},...a===void 0?{}:{next_tracks:a}}}i(T,"runTrack");function k(e,n,t){return m({name:e,description:n,whenToUse:t,help:{name:`sys tutorial ${e}`,summary:`serve one lesson from the ${e} crouter tutorial track`,params:[{kind:"flag",name:"step",type:"int",required:!1,default:1,constraint:`Lesson number, from 1 through ${f[e].length}. Default: 1.`}],output:[{name:"track",type:"string",required:!0,constraint:`The served track: ${e}.`},{name:"step",type:"number",required:!0,constraint:"The served lesson number."},{name:"total",type:"number",required:!0,constraint:"Number of lessons in this track."},{name:"title",type:"string",required:!0,constraint:"Lesson title."},{name:"body",type:"string",required:!0,constraint:"Lesson instructions for the teaching agent."},{name:"next",type:"string",required:!1,constraint:"The exact command for the next lesson. Absent on the last lesson."},{name:"teaching_contract",type:"string",required:!0,constraint:"Rules for teaching the lesson conversationally and safely."},{name:"contents",type:"string",required:!1,constraint:"Numbered titles for every lesson in this track. Present only for step 1."},{name:"next_tracks",type:"array",required:!1,constraint:"Available core and plugin tutorial tracks, each with command and description. Present only on the last lesson."}],outputKind:"object",effects:["None. Read-only. Progress is not stored."]},run:i(async r=>T(e,r),"run")})}i(k,"trackLeaf");const N=k("basic","serve one task-first crouter lesson","you want to learn everyday crouter actions, from returning to a conversation through following delegated work.");export{N as basicLeaf};
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.340",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.340",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "GPL-3.0-only",
|
|
12
12
|
"workspaces": [
|
|
@@ -10859,28 +10859,28 @@
|
|
|
10859
10859
|
},
|
|
10860
10860
|
"packages/crouter-api": {
|
|
10861
10861
|
"name": "@north-light/crouter-api",
|
|
10862
|
-
"version": "0.3.
|
|
10862
|
+
"version": "0.3.340",
|
|
10863
10863
|
"license": "GPL-3.0-only"
|
|
10864
10864
|
},
|
|
10865
10865
|
"packages/crouter-env-docker": {
|
|
10866
10866
|
"name": "@north-light/crouter-env-docker",
|
|
10867
|
-
"version": "0.3.
|
|
10867
|
+
"version": "0.3.340",
|
|
10868
10868
|
"license": "GPL-3.0-only"
|
|
10869
10869
|
},
|
|
10870
10870
|
"packages/crouter-plugin": {
|
|
10871
10871
|
"name": "@north-light/crouter-plugin",
|
|
10872
|
-
"version": "0.3.
|
|
10872
|
+
"version": "0.3.340",
|
|
10873
10873
|
"license": "GPL-3.0-only",
|
|
10874
10874
|
"dependencies": {
|
|
10875
|
-
"@north-light/crouter-api": "^0.3.
|
|
10875
|
+
"@north-light/crouter-api": "^0.3.340"
|
|
10876
10876
|
}
|
|
10877
10877
|
},
|
|
10878
10878
|
"packages/crouter-sdk": {
|
|
10879
10879
|
"name": "@north-light/crouter-sdk",
|
|
10880
|
-
"version": "0.3.
|
|
10880
|
+
"version": "0.3.340",
|
|
10881
10881
|
"license": "GPL-3.0-only",
|
|
10882
10882
|
"dependencies": {
|
|
10883
|
-
"@north-light/crouter-api": "^0.3.
|
|
10883
|
+
"@north-light/crouter-api": "^0.3.340"
|
|
10884
10884
|
}
|
|
10885
10885
|
}
|
|
10886
10886
|
}
|