@bendyline/gilde 0.1.95 → 0.2.1
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/authoring/chat-models/minicpm-v4.7-35b-a3b-q4.json +106 -0
- package/data/chat-models/index.json +1 -1
- package/data/chat-models/mi/minicpm-v4.7-35b-a3b-q4/manifest.json +184 -0
- package/data/chat-models/mi/minicpm-v4.7-35b-a3b-q4/versions/1.0.0/manifest.json +93 -0
- package/data/chat-models/raw-index.json +1 -1
- package/data/craftbook-templates/ab/ab-test-readout/manifest.json +4 -0
- package/data/craftbook-templates/al/album-curate/manifest.json +4 -0
- package/data/craftbook-templates/an/anniversary-cut/manifest.json +4 -0
- package/data/craftbook-templates/an/annotated-bibliography/manifest.json +4 -0
- package/data/craftbook-templates/an/annual-document-review/manifest.json +4 -0
- package/data/craftbook-templates/an/anomaly-scan/manifest.json +3 -0
- package/data/craftbook-templates/au/audio-ad-spot/manifest.json +4 -0
- package/data/craftbook-templates/bo/board-deck/manifest.json +3 -0
- package/data/craftbook-templates/bo/board-game-web/manifest.json +4 -0
- package/data/craftbook-templates/br/branding-website/manifest.json +4 -0
- package/data/craftbook-templates/br/broadcast-announcement/manifest.json +4 -0
- package/data/craftbook-templates/ca/calendar-brief/manifest.json +3 -0
- package/data/craftbook-templates/ch/chapter-weave/manifest.json +4 -0
- package/data/craftbook-templates/ch/chart-pack/manifest.json +3 -0
- package/data/craftbook-templates/co/codebase-ux-review/manifest.json +3 -0
- package/data/craftbook-templates/co/cohort-analysis/manifest.json +3 -0
- package/data/craftbook-templates/co/company-research-brief/manifest.json +4 -0
- package/data/craftbook-templates/co/compat-check/manifest.json +4 -0
- package/data/craftbook-templates/co/competitive-analysis/manifest.json +4 -0
- package/data/craftbook-templates/co/content-accuracy-review/manifest.json +4 -0
- package/data/craftbook-templates/co/content-deck/manifest.json +4 -0
- package/data/craftbook-templates/co/contract-template/manifest.json +4 -0
- package/data/craftbook-templates/co/corpus-email-digest/manifest.json +3 -0
- package/data/craftbook-templates/co/cover-letter/manifest.json +3 -0
- package/data/craftbook-templates/cr/crm-update-batch/manifest.json +3 -0
- package/data/craftbook-templates/cr/crossword-forge/manifest.json +4 -0
- package/data/craftbook-templates/cs/csv-transformer/manifest.json +3 -0
- package/data/craftbook-templates/da/dashboard-spec/manifest.json +4 -0
- package/data/craftbook-templates/da/data-dictionary/manifest.json +3 -0
- package/data/craftbook-templates/da/data-export-migrate/manifest.json +4 -0
- package/data/craftbook-templates/da/data-join-merge/manifest.json +3 -0
- package/data/craftbook-templates/da/data-quality-audit/manifest.json +3 -0
- package/data/craftbook-templates/da/data-to-report/manifest.json +4 -0
- package/data/craftbook-templates/da/data-viz-page/manifest.json +4 -0
- package/data/craftbook-templates/da/dataset-clean/manifest.json +3 -0
- package/data/craftbook-templates/de/design-review/manifest.json +4 -0
- package/data/craftbook-templates/de/design-system-consultation/manifest.json +4 -0
- package/data/craftbook-templates/di/diagram-from-text/manifest.json +4 -0
- package/data/craftbook-templates/dr/drive-wrap-up/manifest.json +4 -0
- package/data/craftbook-templates/du/due-diligence-brief/manifest.json +4 -0
- package/data/craftbook-templates/en/engineering-retrospective/manifest.json +4 -0
- package/data/craftbook-templates/ex/expense-categorize/manifest.json +4 -0
- package/data/craftbook-templates/ex/explain-code-folder/manifest.json +26 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/craftbook.json +233 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/README.md +29 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/package.json +17 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/src/format.js +15 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/src/index.js +50 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/src/store.js +45 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/test/store.test.js +61 -0
- package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/test.json +106 -0
- package/data/craftbook-templates/fa/family-story-chapter/manifest.json +4 -0
- package/data/craftbook-templates/fo/forecast-model/manifest.json +4 -0
- package/data/craftbook-templates/ga/game-with-screens/manifest.json +4 -0
- package/data/craftbook-templates/gl/glossary-build/manifest.json +3 -0
- package/data/craftbook-templates/ha/handbook-section/manifest.json +3 -0
- package/data/craftbook-templates/he/hero-image/manifest.json +4 -0
- package/data/craftbook-templates/ht/html-arcade-game/manifest.json +4 -0
- package/data/craftbook-templates/ht/html-puzzle-game/manifest.json +4 -0
- package/data/craftbook-templates/id/idle-clicker-game/manifest.json +4 -0
- package/data/craftbook-templates/in/inbox-triage/manifest.json +3 -0
- package/data/craftbook-templates/in/insurance-inventory/manifest.json +4 -0
- package/data/craftbook-templates/in/interactive-quiz/manifest.json +3 -0
- package/data/craftbook-templates/in/invoice-generator/manifest.json +3 -0
- package/data/craftbook-templates/in/invoice-run/manifest.json +3 -0
- package/data/craftbook-templates/index.json +1 -1
- package/data/craftbook-templates/ju/juice-pass/manifest.json +4 -0
- package/data/craftbook-templates/kp/kpi-scorecard/manifest.json +4 -0
- package/data/craftbook-templates/la/landing-page/manifest.json +4 -0
- package/data/craftbook-templates/le/lead-enrichment/manifest.json +4 -0
- package/data/craftbook-templates/li/literature-review/manifest.json +4 -0
- package/data/craftbook-templates/lo/logo-set/manifest.json +4 -0
- package/data/craftbook-templates/ma/market-scan/manifest.json +4 -0
- package/data/craftbook-templates/me/meeting-minutes/manifest.json +3 -0
- package/data/craftbook-templates/me/meeting-notes-to-actions/manifest.json +3 -0
- package/data/craftbook-templates/me/meeting-notes-to-actions/versions/1.1.2/craftbook.json +255 -0
- package/data/craftbook-templates/me/meeting-notes-to-actions/versions/1.1.2/samples/team-sync/notes.md +47 -0
- package/data/craftbook-templates/me/meeting-notes-to-actions/versions/1.1.2/test.json +78 -0
- package/data/craftbook-templates/me/meeting-prep-brief/manifest.json +3 -0
- package/data/craftbook-templates/me/meeting-summary-audio/manifest.json +3 -0
- package/data/craftbook-templates/me/memory-prompt-session/manifest.json +3 -0
- package/data/craftbook-templates/mi/micro-game-jam/manifest.json +4 -0
- package/data/craftbook-templates/mo/mock-interview/manifest.json +3 -0
- package/data/craftbook-templates/mo/mod-scaffold/manifest.json +4 -0
- package/data/craftbook-templates/mo/month-close/manifest.json +3 -0
- package/data/craftbook-templates/mo/monthly-recording-review/manifest.json +3 -0
- package/data/craftbook-templates/oc/ocr-extract/manifest.json +4 -0
- package/data/craftbook-templates/of/offer-compare/manifest.json +3 -0
- package/data/craftbook-templates/on/one-pager/manifest.json +4 -0
- package/data/craftbook-templates/ph/photo-cull/manifest.json +4 -0
- package/data/craftbook-templates/ph/photo-library-nightly/manifest.json +4 -0
- package/data/craftbook-templates/ph/physics-toy/manifest.json +4 -0
- package/data/craftbook-templates/pi/pitch-deck/manifest.json +4 -0
- package/data/craftbook-templates/pl/playtest-report/manifest.json +4 -0
- package/data/craftbook-templates/po/powerpoint-deck/manifest.json +4 -0
- package/data/craftbook-templates/pr/practice-exam/manifest.json +3 -0
- package/data/craftbook-templates/pr/practice-session/manifest.json +3 -0
- package/data/craftbook-templates/pr/price-tracker/manifest.json +4 -0
- package/data/craftbook-templates/pr/proposal-sow/manifest.json +3 -0
- package/data/craftbook-templates/pu/puzzle-pack-layout/manifest.json +4 -0
- package/data/craftbook-templates/qu/quarterly-summary/manifest.json +4 -0
- package/data/craftbook-templates/raw-index.json +1 -1
- package/data/craftbook-templates/re/reading-list/manifest.json +3 -0
- package/data/craftbook-templates/re/receipt-intake/manifest.json +4 -0
- package/data/craftbook-templates/re/receipt-ocr-ledger/manifest.json +3 -0
- package/data/craftbook-templates/re/recurring-invoice-run/manifest.json +3 -0
- package/data/craftbook-templates/re/release-announcement/manifest.json +4 -0
- package/data/craftbook-templates/re/resume-cv/manifest.json +3 -0
- package/data/craftbook-templates/re/review-code-folder/manifest.json +25 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/craftbook.json +223 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/samples/todo-cli-bugs/README.md +29 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/samples/todo-cli-bugs/package.json +17 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/samples/todo-cli-bugs/src/format.js +15 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/samples/todo-cli-bugs/src/index.js +50 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/samples/todo-cli-bugs/src/store.js +44 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/samples/todo-cli-bugs/test/store.test.js +37 -0
- package/data/craftbook-templates/re/review-code-folder/versions/1.0.0/test.json +108 -0
- package/data/craftbook-templates/sc/scrape-to-structured/manifest.json +3 -0
- package/data/craftbook-templates/sp/spa-dashboard/manifest.json +4 -0
- package/data/craftbook-templates/sp/spreadsheet-findings/manifest.json +26 -0
- package/data/craftbook-templates/sp/spreadsheet-findings/versions/1.0.0/craftbook.json +186 -0
- package/data/craftbook-templates/sp/spreadsheet-findings/versions/1.0.0/samples/shop-sales/sales.csv +49 -0
- package/data/craftbook-templates/sp/spreadsheet-findings/versions/1.0.0/test.json +88 -0
- package/data/craftbook-templates/sp/spreadsheet-model/manifest.json +4 -0
- package/data/craftbook-templates/sp/sprite-sheet/manifest.json +4 -0
- package/data/craftbook-templates/sq/sql-analysis/manifest.json +3 -0
- package/data/craftbook-templates/st/standup-summary/manifest.json +3 -0
- package/data/craftbook-templates/st/status-report/manifest.json +3 -0
- package/data/craftbook-templates/su/subscription-audit/manifest.json +4 -0
- package/data/craftbook-templates/su/survey-analysis/manifest.json +4 -0
- package/data/craftbook-templates/ta/tailor-resume/manifest.json +3 -0
- package/data/craftbook-templates/ti/tidy-spreadsheet/manifest.json +26 -0
- package/data/craftbook-templates/ti/tidy-spreadsheet/versions/1.0.0/craftbook.json +183 -0
- package/data/craftbook-templates/ti/tidy-spreadsheet/versions/1.0.0/samples/club-members/members.csv +43 -0
- package/data/craftbook-templates/ti/tidy-spreadsheet/versions/1.0.0/test.json +108 -0
- package/data/craftbook-templates/ti/tileset-batch/manifest.json +4 -0
- package/data/craftbook-templates/to/topic-explainer/manifest.json +4 -0
- package/data/craftbook-templates/tr/transcribe-audio/manifest.json +4 -0
- package/data/craftbook-templates/tr/transcribe-index/manifest.json +4 -0
- package/data/craftbook-templates/vi/visit-prep/manifest.json +4 -0
- package/data/craftbook-templates/we/weak-spot-drill/manifest.json +3 -0
- package/data/craftbook-templates/we/week-plan/manifest.json +3 -0
- package/data/craftbook-templates/we/weekly-pipeline-review/manifest.json +3 -0
- package/data/craftbook-templates/we/weekly-review/manifest.json +3 -0
- package/data/craftbook-templates/ye/year-in-review/manifest.json +4 -0
- package/data/image-models/an/animagine-xl-4/versions/4.0.1/manifest.json +16 -0
- package/data/image-models/fl/flux-2-klein-4b-q4/versions/1.0.1/manifest.json +29 -0
- package/data/image-models/index.json +1 -1
- package/data/image-models/ir/iris-3b-f32/versions/1.0.1/manifest.json +25 -0
- package/data/image-models/kr/krea-2-turbo-q4/versions/1.0.1/manifest.json +29 -0
- package/data/image-models/kr/krea-2-turbo-q6/versions/1.0.1/manifest.json +29 -0
- package/data/image-models/kr/krea-2-turbo-q8/versions/1.0.1/manifest.json +29 -0
- package/data/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.1/manifest.json +50 -0
- package/data/image-models/raw-index.json +1 -1
- package/data/image-models/sd/sd-1.5/versions/1.0.1/manifest.json +16 -0
- package/data/image-models/sd/sd-turbo/versions/1.0.1/manifest.json +16 -0
- package/data/image-models/sd/sdxl-base-1.0/versions/1.0.1/manifest.json +16 -0
- package/data/image-models/sd/sdxl-lightning-4step/versions/1.0.1/manifest.json +16 -0
- package/data/image-models/sd/sdxl-turbo/versions/1.0.1/manifest.json +16 -0
- package/data/project-types/ca/caregiving-binder/manifest.json +4 -0
- package/data/project-types/de/design-scheme/manifest.json +4 -0
- package/data/project-types/fi/fitness-coach/manifest.json +4 -0
- package/data/project-types/fr/freelance-office/manifest.json +3 -0
- package/data/project-types/fu/fundraiser-hq/manifest.json +4 -0
- package/data/project-types/ho/household-budget/manifest.json +3 -0
- package/data/project-types/index.json +1 -1
- package/data/project-types/jo/job-hunt/manifest.json +4 -0
- package/data/project-types/jo/job-hunt/versions/1.0.3/about.md +10 -0
- package/data/project-types/jo/job-hunt/versions/1.0.3/activity.json +4 -0
- package/data/project-types/jo/job-hunt/versions/1.0.3/manifest.json +212 -0
- package/data/project-types/jo/job-hunt/versions/1.0.3/mission.md +9 -0
- package/data/project-types/jo/job-hunt/versions/1.0.3/pages/dashboard/index.html +430 -0
- package/data/project-types/jo/job-hunt/versions/1.0.3/pipeline.json +6 -0
- package/data/project-types/li/life-binder/manifest.json +4 -0
- package/data/project-types/raw-index.json +1 -1
- package/data/project-types/so/social-feed/manifest.json +3 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/about.md +7 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/journal.json +4 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/manifest.json +226 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/mission.md +4 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/packing.json +8 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/pages/dashboard/index.html +368 -0
- package/data/project-types/tr/trip-planner/versions/1.0.3/trip.json +8 -0
- package/data/toolsets/do/docblocks/versions/2.7.0/manifest.json +95 -0
- package/data/toolsets/index.json +1 -1
- package/data/toolsets/raw-index.json +1 -1
- package/data/video-models/index.json +1 -1
- package/data/video-models/lt/ltx-2-19b/versions/1.0.1/manifest.json +375 -0
- package/data/video-models/lt/ltx-2.3-22b/versions/1.0.1/manifest.json +377 -0
- package/data/video-models/lt/ltx-2.3-22b-distilled/versions/1.0.1/manifest.json +377 -0
- package/data/video-models/lt/ltx-video-0.9.7-dev/versions/1.0.1/manifest.json +195 -0
- package/data/video-models/lt/ltx-video-0.9.8-13b-distilled/versions/1.0.1/manifest.json +190 -0
- package/data/video-models/raw-index.json +1 -1
- package/data/video-models/wa/wan2.2-ti2v-5b/versions/1.0.1/manifest.json +168 -0
- package/package.json +2 -1
- package/schemas/craftbook-doc.schema.json +35 -0
- package/schemas/craftbook-template-identity.schema.json +18 -0
- package/schemas/craftbook-template-version.schema.json +35 -0
- package/schemas/image-model-identity.schema.json +0 -2
- package/schemas/image-model-version.schema.json +50 -0
- package/schemas/project-type-identity.schema.json +18 -0
- package/schemas/video-model-identity.schema.json +0 -2
- package/schemas/video-model-version.schema.json +25 -0
- package/data/image-models/fl/flux-1-dev-q4/manifest.json +0 -38
- package/data/image-models/fl/flux-1-dev-q4/versions/1.0.0/manifest.json +0 -29
- package/data/image-models/fl/flux-1-schnell-q4/manifest.json +0 -39
- package/data/image-models/fl/flux-1-schnell-q4/versions/1.0.0/manifest.json +0 -29
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "explain-code-folder",
|
|
3
|
+
"name": "Explain a code folder",
|
|
4
|
+
"description": "A plain-language tour of a folder of code: what it does, how the files are organised, how to run it, and the three files to read first. Every file and command it names comes from the folder itself. Good for a project you inherited, an open-source tool you want to understand, or your own code after a long break.\n\nIt works on the folder you choose when you launch it: a folder in this project, or one you pick from your computer. It reads the code and never runs or changes it. No code to hand? Try it on the sample, a tiny to-do app for the command line.",
|
|
5
|
+
"entryStepId": "explain",
|
|
6
|
+
"triggers": [
|
|
7
|
+
"explain a code folder",
|
|
8
|
+
"explain this codebase",
|
|
9
|
+
"what does this code do",
|
|
10
|
+
"overview of this repo",
|
|
11
|
+
"walk me through this code"
|
|
12
|
+
],
|
|
13
|
+
"samples": [
|
|
14
|
+
{
|
|
15
|
+
"id": "todo-cli",
|
|
16
|
+
"title": "a tiny to-do app for the command line",
|
|
17
|
+
"param": "source",
|
|
18
|
+
"files": [
|
|
19
|
+
"samples/todo-cli/README.md",
|
|
20
|
+
"samples/todo-cli/package.json",
|
|
21
|
+
"samples/todo-cli/src/index.js",
|
|
22
|
+
"samples/todo-cli/src/store.js",
|
|
23
|
+
"samples/todo-cli/src/format.js",
|
|
24
|
+
"samples/todo-cli/test/store.test.js"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"paramSchema": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": [
|
|
31
|
+
"source"
|
|
32
|
+
],
|
|
33
|
+
"properties": {
|
|
34
|
+
"source": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"title": "Code folder",
|
|
37
|
+
"description": "The folder of code to explain: a folder in this project, or one you pick from your computer.",
|
|
38
|
+
"input": {
|
|
39
|
+
"kind": "folder",
|
|
40
|
+
"accept": [
|
|
41
|
+
".js",
|
|
42
|
+
".mjs",
|
|
43
|
+
".cjs",
|
|
44
|
+
".jsx",
|
|
45
|
+
".ts",
|
|
46
|
+
".tsx",
|
|
47
|
+
".py",
|
|
48
|
+
".rb",
|
|
49
|
+
".go",
|
|
50
|
+
".rs",
|
|
51
|
+
".java",
|
|
52
|
+
".kt",
|
|
53
|
+
".cs",
|
|
54
|
+
".php",
|
|
55
|
+
".swift",
|
|
56
|
+
".c",
|
|
57
|
+
".h",
|
|
58
|
+
".cpp",
|
|
59
|
+
".hpp",
|
|
60
|
+
".sh",
|
|
61
|
+
".sql",
|
|
62
|
+
".html",
|
|
63
|
+
".css",
|
|
64
|
+
".scss",
|
|
65
|
+
".vue",
|
|
66
|
+
".svelte",
|
|
67
|
+
".md",
|
|
68
|
+
".txt",
|
|
69
|
+
".json",
|
|
70
|
+
".toml",
|
|
71
|
+
".yaml",
|
|
72
|
+
".yml",
|
|
73
|
+
".ini",
|
|
74
|
+
".cfg",
|
|
75
|
+
".xml"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"workPath": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"title": "Working folder",
|
|
82
|
+
"description": "Per-task working folder in the artifacts drawer. Defaults to this task's own folder so runs never collide; override with a stable name when you deliberately want runs to share files.",
|
|
83
|
+
"default": "{{task.dir}}",
|
|
84
|
+
"askUser": false
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"steps": [
|
|
89
|
+
{
|
|
90
|
+
"id": "explain",
|
|
91
|
+
"name": "Explain the folder",
|
|
92
|
+
"description": "Read the code and write a plain-language overview of it.",
|
|
93
|
+
"prompt": "Explain the code folder in the `source` input to someone who has never seen it, in `{{workPath}}/overview.md`.\n\n1. Open the file list `{{task.dir}}/inputs/source.json` with `read_artifact`. It lists every file in the folder and the drawer they are in.\n2. Read the files with the tool named on the `source` line under Invocation parameters: the README first, if there is one, then the file that names the project and its commands (package.json, pyproject.toml, Cargo.toml, a Makefile or similar), then the entry point, then the rest. If there are more than 15 files, read those first and then the files they name, 15 at most.\n3. Write `{{workPath}}/overview.md` with `write_artifact`, under exactly these four headings:\n - `## What it does`: two or three sentences in plain words.\n - `## How it is organised`: a markdown table with the columns `File` and `What it holds`, one row per file you read, each path in backticks and relative to the folder (`src/app.js`, not the full drawer path).\n - `## How to run it`: the commands the README or the project file actually gives, in a code block. If they give none, say so.\n - `## Three things to read first`: a numbered list of three files, each with one line on why.\n\nName only files that are in the file list and commands the files state. Never invent a file, a function or a command.\n\nIf the folder holds no file you can read, do not write `overview.md`. Write a task note with `write_task_note` that says what you found, then end your turn.",
|
|
94
|
+
"suggestedRole": "developer",
|
|
95
|
+
"toolPolicy": {
|
|
96
|
+
"disallowBuiltinToolsets": [
|
|
97
|
+
"ai-apps",
|
|
98
|
+
"archives",
|
|
99
|
+
"audio",
|
|
100
|
+
"browser-automation",
|
|
101
|
+
"code-execution",
|
|
102
|
+
"craftbooks",
|
|
103
|
+
"data-tables",
|
|
104
|
+
"entity-intel",
|
|
105
|
+
"git",
|
|
106
|
+
"image-intel",
|
|
107
|
+
"images",
|
|
108
|
+
"role-delegation",
|
|
109
|
+
"role-delegation-escalation",
|
|
110
|
+
"security-intel",
|
|
111
|
+
"team-management",
|
|
112
|
+
"videos",
|
|
113
|
+
"web",
|
|
114
|
+
"workspace-fs-write"
|
|
115
|
+
],
|
|
116
|
+
"outputMedium": "artifact",
|
|
117
|
+
"additionalOutputMedia": [
|
|
118
|
+
"task-note"
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"consumes": [
|
|
122
|
+
{
|
|
123
|
+
"file": "{{task.dir}}/inputs/source.json",
|
|
124
|
+
"artifact": true
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"advanceWhen": {
|
|
128
|
+
"file": "{{workPath}}/overview.md",
|
|
129
|
+
"minBytes": 1,
|
|
130
|
+
"sniff": "nonempty",
|
|
131
|
+
"artifact": true
|
|
132
|
+
},
|
|
133
|
+
"gate": {
|
|
134
|
+
"at": "completion",
|
|
135
|
+
"checks": [
|
|
136
|
+
{
|
|
137
|
+
"kind": "minBytes",
|
|
138
|
+
"file": "{{workPath}}/overview.md",
|
|
139
|
+
"bytes": 800,
|
|
140
|
+
"artifact": true
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"kind": "contains",
|
|
144
|
+
"file": "{{workPath}}/overview.md",
|
|
145
|
+
"pattern": "(?:^|\\n)#{1,3}\\s*What it does",
|
|
146
|
+
"flags": "i",
|
|
147
|
+
"label": "a \"## What it does\" section",
|
|
148
|
+
"artifact": true
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"kind": "contains",
|
|
152
|
+
"file": "{{workPath}}/overview.md",
|
|
153
|
+
"pattern": "(?:^|\\n)#{1,3}\\s*How it is organised",
|
|
154
|
+
"flags": "i",
|
|
155
|
+
"label": "a \"## How it is organised\" section",
|
|
156
|
+
"artifact": true
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"kind": "contains",
|
|
160
|
+
"file": "{{workPath}}/overview.md",
|
|
161
|
+
"pattern": "(?:^|\\n)#{1,3}\\s*How to run it",
|
|
162
|
+
"flags": "i",
|
|
163
|
+
"label": "a \"## How to run it\" section",
|
|
164
|
+
"artifact": true
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"kind": "contains",
|
|
168
|
+
"file": "{{workPath}}/overview.md",
|
|
169
|
+
"pattern": "(?:^|\\n)#{1,3}\\s*Three things to read first",
|
|
170
|
+
"flags": "i",
|
|
171
|
+
"label": "a \"## Three things to read first\" section",
|
|
172
|
+
"artifact": true
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"kind": "tableShape",
|
|
176
|
+
"file": "{{workPath}}/overview.md",
|
|
177
|
+
"requiredColumns": [
|
|
178
|
+
"File",
|
|
179
|
+
"What it holds"
|
|
180
|
+
],
|
|
181
|
+
"minRows": 2,
|
|
182
|
+
"artifact": true
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"kind": "contains",
|
|
186
|
+
"file": "{{workPath}}/overview.md",
|
|
187
|
+
"pattern": "`[^`\\n]+\\.[A-Za-z0-9]{1,10}`",
|
|
188
|
+
"label": "file paths from the folder, in backticks",
|
|
189
|
+
"artifact": true
|
|
190
|
+
}
|
|
191
|
+
],
|
|
192
|
+
"onReject": "explain",
|
|
193
|
+
"maxAttempts": 3
|
|
194
|
+
},
|
|
195
|
+
"next": "finish"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"id": "finish",
|
|
199
|
+
"name": "Finish",
|
|
200
|
+
"description": "The deliverable passed its checks. Stamp a short summary and report DONE.",
|
|
201
|
+
"prompt": "The deliverable passed its checks. Write a one-paragraph DONE summary to task notes via `write_task_note`: what you made, the deliverable path(s), and a one-line confirmation that each required section is there. Then report DONE.",
|
|
202
|
+
"suggestedRole": "developer",
|
|
203
|
+
"toolPolicy": {
|
|
204
|
+
"disallowBuiltinToolsets": [
|
|
205
|
+
"ai-apps",
|
|
206
|
+
"archives",
|
|
207
|
+
"artifacts",
|
|
208
|
+
"audio",
|
|
209
|
+
"browser-automation",
|
|
210
|
+
"code-execution",
|
|
211
|
+
"craftbooks",
|
|
212
|
+
"data-tables",
|
|
213
|
+
"entity-intel",
|
|
214
|
+
"git",
|
|
215
|
+
"image-intel",
|
|
216
|
+
"images",
|
|
217
|
+
"role-delegation",
|
|
218
|
+
"role-delegation-escalation",
|
|
219
|
+
"security-intel",
|
|
220
|
+
"team-management",
|
|
221
|
+
"videos",
|
|
222
|
+
"web",
|
|
223
|
+
"workspace-fs-write"
|
|
224
|
+
],
|
|
225
|
+
"outputMedium": "task-note"
|
|
226
|
+
},
|
|
227
|
+
"terminal": true
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
"version": "1.0.0",
|
|
231
|
+
"releasedAt": "2026-10-12T00:00:00Z",
|
|
232
|
+
"minGezelVersion": "1.26285"
|
|
233
|
+
}
|
package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# todo-cli
|
|
2
|
+
|
|
3
|
+
A tiny to-do list for the command line. It keeps your to-dos in a JSON file
|
|
4
|
+
in the current folder, so each project folder can have its own list.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
node src/index.js add "Buy oat milk"
|
|
10
|
+
node src/index.js list
|
|
11
|
+
node src/index.js done 2
|
|
12
|
+
node src/index.js remove 1
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`list` prints every to-do with its number. `done` and `remove` take that
|
|
16
|
+
number. Set `TODO_FILE` to keep the list somewhere else:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
TODO_FILE=~/todos.json node src/index.js list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Tests
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npm test
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The tests use Node's built-in test runner (Node 18 or newer). There are no
|
|
29
|
+
dependencies to install.
|
package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "todo-cli",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "A tiny to-do list for the command line.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"todo": "src/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node src/index.js",
|
|
11
|
+
"test": "node --test"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT"
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function formatTodo(todo, index) {
|
|
2
|
+
const box = todo.done ? '[x]' : '[ ]';
|
|
3
|
+
return `${String(index + 1).padStart(2)}. ${box} ${todo.text}`;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function formatList(todos) {
|
|
7
|
+
if (todos.length === 0) return 'Nothing to do. Add one with: todo add "..."';
|
|
8
|
+
return todos.map(formatTodo).join('\n');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function formatSummary(todos) {
|
|
12
|
+
const open = todos.filter((todo) => !todo.done).length;
|
|
13
|
+
const word = open === 1 ? 'to-do' : 'to-dos';
|
|
14
|
+
return `${open} open ${word}, ${todos.length - open} done.`;
|
|
15
|
+
}
|
package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/src/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { formatList, formatSummary } from './format.js';
|
|
3
|
+
import { addTodo, completeTodo, loadTodos, removeTodo } from './store.js';
|
|
4
|
+
|
|
5
|
+
const file = process.env.TODO_FILE ?? 'todos.json';
|
|
6
|
+
const [command, ...rest] = process.argv.slice(2);
|
|
7
|
+
|
|
8
|
+
function readNumber(value) {
|
|
9
|
+
const number = Number(value);
|
|
10
|
+
if (!Number.isInteger(number) || number < 1) {
|
|
11
|
+
throw new Error(`"${value}" is not a to-do number. Run "todo list" to see the numbers.`);
|
|
12
|
+
}
|
|
13
|
+
return number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function main() {
|
|
17
|
+
switch (command) {
|
|
18
|
+
case 'add': {
|
|
19
|
+
const text = rest.join(' ').trim();
|
|
20
|
+
if (!text) throw new Error('Say what to add: todo add "Buy oat milk"');
|
|
21
|
+
const todo = await addTodo(file, text);
|
|
22
|
+
console.log(`Added: ${todo.text}`);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case 'list': {
|
|
26
|
+
const todos = await loadTodos(file);
|
|
27
|
+
console.log(formatList(todos));
|
|
28
|
+
console.log(formatSummary(todos));
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case 'done': {
|
|
32
|
+
const todo = await completeTodo(file, readNumber(rest[0]));
|
|
33
|
+
console.log(`Done: ${todo.text}`);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'remove': {
|
|
37
|
+
const todo = await removeTodo(file, readNumber(rest[0]));
|
|
38
|
+
console.log(`Removed: ${todo.text}`);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
default:
|
|
42
|
+
console.log('Usage: todo <add|list|done|remove> [text or number]');
|
|
43
|
+
process.exitCode = command ? 1 : 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
main().catch((error) => {
|
|
48
|
+
console.error(error.message);
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
});
|
package/data/craftbook-templates/ex/explain-code-folder/versions/1.0.0/samples/todo-cli/src/store.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
|
|
3
|
+
export async function loadTodos(file) {
|
|
4
|
+
try {
|
|
5
|
+
const text = await readFile(file, 'utf8');
|
|
6
|
+
return JSON.parse(text);
|
|
7
|
+
} catch (error) {
|
|
8
|
+
if (error.code === 'ENOENT') return [];
|
|
9
|
+
throw error;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function saveTodos(file, todos) {
|
|
14
|
+
await writeFile(file, `${JSON.stringify(todos, null, 2)}\n`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function addTodo(file, text) {
|
|
18
|
+
const todos = await loadTodos(file);
|
|
19
|
+
const todo = { text, done: false, added: new Date().toISOString().slice(0, 10) };
|
|
20
|
+
todos.push(todo);
|
|
21
|
+
await saveTodos(file, todos);
|
|
22
|
+
return todo;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function pick(todos, number) {
|
|
26
|
+
const todo = todos[number - 1];
|
|
27
|
+
if (!todo) throw new Error(`There is no to-do number ${number}.`);
|
|
28
|
+
return todo;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function completeTodo(file, number) {
|
|
32
|
+
const todos = await loadTodos(file);
|
|
33
|
+
const todo = pick(todos, number);
|
|
34
|
+
todo.done = true;
|
|
35
|
+
await saveTodos(file, todos);
|
|
36
|
+
return todo;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function removeTodo(file, number) {
|
|
40
|
+
const todos = await loadTodos(file);
|
|
41
|
+
pick(todos, number);
|
|
42
|
+
const [removed] = todos.splice(number - 1, 1);
|
|
43
|
+
await saveTodos(file, todos);
|
|
44
|
+
return removed;
|
|
45
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { test } from 'node:test';
|
|
6
|
+
import { addTodo, completeTodo, loadTodos, removeTodo } from '../src/store.js';
|
|
7
|
+
|
|
8
|
+
async function withFile(run) {
|
|
9
|
+
const dir = await mkdtemp(join(tmpdir(), 'todo-cli-'));
|
|
10
|
+
try {
|
|
11
|
+
await run(join(dir, 'todos.json'));
|
|
12
|
+
} finally {
|
|
13
|
+
await rm(dir, { recursive: true, force: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
test('a missing file is an empty list', () =>
|
|
18
|
+
withFile(async (file) => {
|
|
19
|
+
assert.deepEqual(await loadTodos(file), []);
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
test('add keeps to-dos in the order they were added', () =>
|
|
23
|
+
withFile(async (file) => {
|
|
24
|
+
await addTodo(file, 'Buy oat milk');
|
|
25
|
+
await addTodo(file, 'Call the plumber');
|
|
26
|
+
const todos = await loadTodos(file);
|
|
27
|
+
assert.deepEqual(
|
|
28
|
+
todos.map((todo) => todo.text),
|
|
29
|
+
['Buy oat milk', 'Call the plumber'],
|
|
30
|
+
);
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
test('done marks the numbered to-do and saves it', () =>
|
|
34
|
+
withFile(async (file) => {
|
|
35
|
+
await addTodo(file, 'Buy oat milk');
|
|
36
|
+
await addTodo(file, 'Call the plumber');
|
|
37
|
+
await completeTodo(file, 2);
|
|
38
|
+
const todos = await loadTodos(file);
|
|
39
|
+
assert.equal(todos[0].done, false);
|
|
40
|
+
assert.equal(todos[1].done, true);
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
test('remove takes out the numbered to-do', () =>
|
|
44
|
+
withFile(async (file) => {
|
|
45
|
+
await addTodo(file, 'Buy oat milk');
|
|
46
|
+
await addTodo(file, 'Call the plumber');
|
|
47
|
+
await addTodo(file, 'Water the plants');
|
|
48
|
+
const removed = await removeTodo(file, 1);
|
|
49
|
+
assert.equal(removed.text, 'Buy oat milk');
|
|
50
|
+
const todos = await loadTodos(file);
|
|
51
|
+
assert.deepEqual(
|
|
52
|
+
todos.map((todo) => todo.text),
|
|
53
|
+
['Call the plumber', 'Water the plants'],
|
|
54
|
+
);
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
test('a number past the end is an error', () =>
|
|
58
|
+
withFile(async (file) => {
|
|
59
|
+
await addTodo(file, 'Buy oat milk');
|
|
60
|
+
await assert.rejects(removeTodo(file, 3), /no to-do number 3/);
|
|
61
|
+
}));
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"mode": "workflow",
|
|
4
|
+
"title": "Explain a code folder on the todo-cli sample",
|
|
5
|
+
"objective": "Prove that a small local model can run the Explain a code folder craftbook on its bundled todo-cli sample, offline, and reach the terminal step with an overview that names only real files and commands.",
|
|
6
|
+
"tags": [
|
|
7
|
+
"first-project",
|
|
8
|
+
"sample",
|
|
9
|
+
"code"
|
|
10
|
+
],
|
|
11
|
+
"prompt": "Explain this little command-line to-do app to me: what it does, how it is put together, and how to run it.",
|
|
12
|
+
"setup": {
|
|
13
|
+
"projectName": "Todo CLI",
|
|
14
|
+
"about": "A tiny made-up Node.js to-do app for the command line, six files in source/todo-cli. Nothing needs to be run or installed; read the code.",
|
|
15
|
+
"missionObjectives": "Run the craftbook on source/todo-cli and leave overview.md in the task folder, naming only files and commands that are really there.",
|
|
16
|
+
"files": [
|
|
17
|
+
{
|
|
18
|
+
"path": "source/todo-cli/README.md",
|
|
19
|
+
"content": "# todo-cli\n\nA tiny to-do list for the command line. It keeps your to-dos in a JSON file\nin the current folder, so each project folder can have its own list.\n\n## Usage\n\n```sh\nnode src/index.js add \"Buy oat milk\"\nnode src/index.js list\nnode src/index.js done 2\nnode src/index.js remove 1\n```\n\n`list` prints every to-do with its number. `done` and `remove` take that\nnumber. Set `TODO_FILE` to keep the list somewhere else:\n\n```sh\nTODO_FILE=~/todos.json node src/index.js list\n```\n\n## Tests\n\n```sh\nnpm test\n```\n\nThe tests use Node's built-in test runner (Node 18 or newer). There are no\ndependencies to install.\n"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "source/todo-cli/package.json",
|
|
23
|
+
"content": "{\n \"name\": \"todo-cli\",\n \"version\": \"0.3.0\",\n \"description\": \"A tiny to-do list for the command line.\",\n \"type\": \"module\",\n \"bin\": {\n \"todo\": \"src/index.js\"\n },\n \"scripts\": {\n \"start\": \"node src/index.js\",\n \"test\": \"node --test\"\n },\n \"engines\": {\n \"node\": \">=18\"\n },\n \"license\": \"MIT\"\n}\n"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "source/todo-cli/src/format.js",
|
|
27
|
+
"content": "export function formatTodo(todo, index) {\n const box = todo.done ? '[x]' : '[ ]';\n return `${String(index + 1).padStart(2)}. ${box} ${todo.text}`;\n}\n\nexport function formatList(todos) {\n if (todos.length === 0) return 'Nothing to do. Add one with: todo add \"...\"';\n return todos.map(formatTodo).join('\\n');\n}\n\nexport function formatSummary(todos) {\n const open = todos.filter((todo) => !todo.done).length;\n const word = open === 1 ? 'to-do' : 'to-dos';\n return `${open} open ${word}, ${todos.length - open} done.`;\n}\n"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "source/todo-cli/src/index.js",
|
|
31
|
+
"content": "#!/usr/bin/env node\nimport { formatList, formatSummary } from './format.js';\nimport { addTodo, completeTodo, loadTodos, removeTodo } from './store.js';\n\nconst file = process.env.TODO_FILE ?? 'todos.json';\nconst [command, ...rest] = process.argv.slice(2);\n\nfunction readNumber(value) {\n const number = Number(value);\n if (!Number.isInteger(number) || number < 1) {\n throw new Error(`\"${value}\" is not a to-do number. Run \"todo list\" to see the numbers.`);\n }\n return number;\n}\n\nasync function main() {\n switch (command) {\n case 'add': {\n const text = rest.join(' ').trim();\n if (!text) throw new Error('Say what to add: todo add \"Buy oat milk\"');\n const todo = await addTodo(file, text);\n console.log(`Added: ${todo.text}`);\n break;\n }\n case 'list': {\n const todos = await loadTodos(file);\n console.log(formatList(todos));\n console.log(formatSummary(todos));\n break;\n }\n case 'done': {\n const todo = await completeTodo(file, readNumber(rest[0]));\n console.log(`Done: ${todo.text}`);\n break;\n }\n case 'remove': {\n const todo = await removeTodo(file, readNumber(rest[0]));\n console.log(`Removed: ${todo.text}`);\n break;\n }\n default:\n console.log('Usage: todo <add|list|done|remove> [text or number]');\n process.exitCode = command ? 1 : 0;\n }\n}\n\nmain().catch((error) => {\n console.error(error.message);\n process.exitCode = 1;\n});\n"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"path": "source/todo-cli/src/store.js",
|
|
35
|
+
"content": "import { readFile, writeFile } from 'node:fs/promises';\n\nexport async function loadTodos(file) {\n try {\n const text = await readFile(file, 'utf8');\n return JSON.parse(text);\n } catch (error) {\n if (error.code === 'ENOENT') return [];\n throw error;\n }\n}\n\nexport async function saveTodos(file, todos) {\n await writeFile(file, `${JSON.stringify(todos, null, 2)}\\n`);\n}\n\nexport async function addTodo(file, text) {\n const todos = await loadTodos(file);\n const todo = { text, done: false, added: new Date().toISOString().slice(0, 10) };\n todos.push(todo);\n await saveTodos(file, todos);\n return todo;\n}\n\nfunction pick(todos, number) {\n const todo = todos[number - 1];\n if (!todo) throw new Error(`There is no to-do number ${number}.`);\n return todo;\n}\n\nexport async function completeTodo(file, number) {\n const todos = await loadTodos(file);\n const todo = pick(todos, number);\n todo.done = true;\n await saveTodos(file, todos);\n return todo;\n}\n\nexport async function removeTodo(file, number) {\n const todos = await loadTodos(file);\n pick(todos, number);\n const [removed] = todos.splice(number - 1, 1);\n await saveTodos(file, todos);\n return removed;\n}\n"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"path": "source/todo-cli/test/store.test.js",
|
|
39
|
+
"content": "import assert from 'node:assert/strict';\nimport { mkdtemp, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { test } from 'node:test';\nimport { addTodo, completeTodo, loadTodos, removeTodo } from '../src/store.js';\n\nasync function withFile(run) {\n const dir = await mkdtemp(join(tmpdir(), 'todo-cli-'));\n try {\n await run(join(dir, 'todos.json'));\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n}\n\ntest('a missing file is an empty list', () =>\n withFile(async (file) => {\n assert.deepEqual(await loadTodos(file), []);\n }));\n\ntest('add keeps to-dos in the order they were added', () =>\n withFile(async (file) => {\n await addTodo(file, 'Buy oat milk');\n await addTodo(file, 'Call the plumber');\n const todos = await loadTodos(file);\n assert.deepEqual(\n todos.map((todo) => todo.text),\n ['Buy oat milk', 'Call the plumber'],\n );\n }));\n\ntest('done marks the numbered to-do and saves it', () =>\n withFile(async (file) => {\n await addTodo(file, 'Buy oat milk');\n await addTodo(file, 'Call the plumber');\n await completeTodo(file, 2);\n const todos = await loadTodos(file);\n assert.equal(todos[0].done, false);\n assert.equal(todos[1].done, true);\n }));\n\ntest('remove takes out the numbered to-do', () =>\n withFile(async (file) => {\n await addTodo(file, 'Buy oat milk');\n await addTodo(file, 'Call the plumber');\n await addTodo(file, 'Water the plants');\n const removed = await removeTodo(file, 1);\n assert.equal(removed.text, 'Buy oat milk');\n const todos = await loadTodos(file);\n assert.deepEqual(\n todos.map((todo) => todo.text),\n ['Call the plumber', 'Water the plants'],\n );\n }));\n\ntest('a number past the end is an error', () =>\n withFile(async (file) => {\n await addTodo(file, 'Buy oat milk');\n await assert.rejects(removeTodo(file, 3), /no to-do number 3/);\n }));\n"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"craftbookParams": {
|
|
43
|
+
"source": "source/todo-cli"
|
|
44
|
+
},
|
|
45
|
+
"worker": {
|
|
46
|
+
"name": "Developer",
|
|
47
|
+
"role": "developer",
|
|
48
|
+
"about": "A patient developer who explains code to people who are new to it. Follow the craftbook steps exactly, read the code you are given, and never invent a file or a command."
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"mocks": [],
|
|
52
|
+
"success": {
|
|
53
|
+
"summary": "The explain-code-folder task read the sample folder, wrote overview.md with all four sections and a File / What it holds table naming real files and the README commands, and reached its terminal step without external services.",
|
|
54
|
+
"deliverables": [
|
|
55
|
+
{
|
|
56
|
+
"path": "{{task.dir}}/overview.md",
|
|
57
|
+
"kind": "markdown-report",
|
|
58
|
+
"artifact": true,
|
|
59
|
+
"minBytes": 800,
|
|
60
|
+
"checks": [
|
|
61
|
+
{
|
|
62
|
+
"kind": "contains",
|
|
63
|
+
"file": "{{task.dir}}/overview.md",
|
|
64
|
+
"pattern": "store\\.js",
|
|
65
|
+
"label": "the store module",
|
|
66
|
+
"artifact": true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"kind": "contains",
|
|
70
|
+
"file": "{{task.dir}}/overview.md",
|
|
71
|
+
"pattern": "node src/index\\.js|npm (?:run )?test",
|
|
72
|
+
"label": "a run command the README gives",
|
|
73
|
+
"artifact": true
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"taskGraph": {
|
|
79
|
+
"requireCraftbookTask": true,
|
|
80
|
+
"requireTerminalStep": true
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"rubric": {
|
|
84
|
+
"artifact": {
|
|
85
|
+
"path": "{{task.dir}}/overview.md",
|
|
86
|
+
"kind": "markdown"
|
|
87
|
+
},
|
|
88
|
+
"axes": [
|
|
89
|
+
{
|
|
90
|
+
"name": "grounding",
|
|
91
|
+
"description": "Every file, function and command in overview.md exists in the sample folder; nothing is invented."
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "clarity",
|
|
95
|
+
"description": "Someone who has never seen the app understands what it does, where the data lives, and how to run it and its tests."
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"contextNote": "Advisory only. Deterministic pass/fail comes from the craftbook runtime gates, the deliverable checks, attribution, and terminal progress."
|
|
99
|
+
},
|
|
100
|
+
"qualityFocus": [
|
|
101
|
+
"real explain-code-folder craftbook task attribution",
|
|
102
|
+
"only real files and commands",
|
|
103
|
+
"all four required sections and the organisation table",
|
|
104
|
+
"terminal workflow progress offline"
|
|
105
|
+
]
|
|
106
|
+
}
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"id": "family-story-chapter",
|
|
5
5
|
"role": "general",
|
|
6
6
|
"category": "writing",
|
|
7
|
+
"interests": [
|
|
8
|
+
"home",
|
|
9
|
+
"content"
|
|
10
|
+
],
|
|
7
11
|
"name": "Family Story Chapter",
|
|
8
12
|
"description": "Write one chapter of the family story from the record you actually have — interviews and tree facts woven into narrative, speculation clearly dressed as speculation — the ritual that turns an archive into the book every family means to write. Locks the chapter's arc and the sourcing rules FIRST, then drafts from the record only, with a faithfulness pass that loops until every event traces. Use for drafting a family history chapter, writing up the emigration years, turning interviews into narrative, and 'write the family story'.",
|
|
9
13
|
"tags": [
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"id": "forecast-model",
|
|
5
5
|
"role": "general",
|
|
6
6
|
"category": "research",
|
|
7
|
+
"interests": [
|
|
8
|
+
"data",
|
|
9
|
+
"work"
|
|
10
|
+
],
|
|
7
11
|
"name": "Simple Forecast / Trend Model",
|
|
8
12
|
"description": "Build a simple, defensible forecast of a time series (revenue, demand, signups, usage) with the assumptions and method stated up front and the projection plus a confidence band as the output. Scopes the series, horizon, method, and assumptions FIRST (so the forecast isn't an unexplained black box), then builds the projection with a baseline and an interval, then reviews it for sanity against history and overfitting. Use this for forecasting a metric, projecting a trend, estimating future demand, a simple time-series projection, or a 'what will this be next quarter' estimate.",
|
|
9
13
|
"tags": [
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"id": "game-with-screens",
|
|
5
5
|
"role": "project-starter",
|
|
6
6
|
"category": "code-build",
|
|
7
|
+
"interests": [
|
|
8
|
+
"software",
|
|
9
|
+
"play"
|
|
10
|
+
],
|
|
7
11
|
"name": "Full Game with Title & Game-Over Screens",
|
|
8
12
|
"description": "Build a complete single-file HTML game with the full screen flow — a title/start screen, the gameplay screen, a game-over screen showing the score, and a restart back to a fresh game — wrapping any core arcade or survival mechanic. Designs the mechanic and the screen-state machine first, a cohesive visual look across all screens, then implements a screen manager so transitions are clean and restart truly resets. Many small models nail gameplay but ship with no start or game-over screen; this archetype makes the screen flow a first-class, gated requirement.",
|
|
9
13
|
"tags": [
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
"id": "glossary-build",
|
|
5
5
|
"role": "general",
|
|
6
6
|
"category": "code-docs",
|
|
7
|
+
"interests": [
|
|
8
|
+
"work"
|
|
9
|
+
],
|
|
7
10
|
"name": "Domain Glossary",
|
|
8
11
|
"description": "Build a consistent, accurate glossary for a domain: a planner sets the domain scope, the term-selection criteria, and the entry template, a researcher gathers the canonical definition and usage for each term with sources, and a copywriter writes the alphabetized glossary with cross-references and consistent entries. The ordering matters because terms picked ad hoc leave gaps and inconsistent entries confuse readers; locking the scope, what makes a term in-scope, and a fixed entry template first guarantees coverage and a uniform, cross-linked glossary. Use this for building a domain or product glossary, a terms/definitions reference, an acronym list, onboarding vocabulary, and 'define all the key terms in X' requests.",
|
|
9
12
|
"tags": [
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
"id": "handbook-section",
|
|
5
5
|
"role": "general",
|
|
6
6
|
"category": "writing",
|
|
7
|
+
"interests": [
|
|
8
|
+
"work"
|
|
9
|
+
],
|
|
7
10
|
"name": "Team Handbook Section",
|
|
8
11
|
"description": "Write a clear, reference-grade section of a team/company handbook — a policy, process, or how-we-work doc that a new hire can read once and act on correctly. Scopes the policy's intent, audience, and edge cases FIRST, writes unambiguous prose with concrete examples, a quick-reference summary, and FAQ, then has a reviewer check it for ambiguity and contradictions with how things actually work. Use for onboarding docs, policy pages, process documentation, and internal wikis.",
|
|
9
12
|
"tags": [
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"id": "hero-image",
|
|
5
5
|
"role": "general",
|
|
6
6
|
"category": "media",
|
|
7
|
+
"interests": [
|
|
8
|
+
"content",
|
|
9
|
+
"business"
|
|
10
|
+
],
|
|
7
11
|
"name": "Marketing Hero Image",
|
|
8
12
|
"description": "Create a single high-impact marketing hero image from a brief and place it into a working hero section. Lock the brief FIRST — aspect ratio, subject, mood, palette, focal point, and crucially the safe zone where headline and CTA text will overlay — because a beautiful hero that has no room for copy (or whose focal point sits under the button) is useless. Then generate the image to the brief and place it behind real overlaid text to prove it works. Covers hero banners, marketing imagery, landing-page art, website headers, and key visuals.",
|
|
9
13
|
"tags": [
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"id": "html-arcade-game",
|
|
5
5
|
"role": "project-starter",
|
|
6
6
|
"category": "code-build",
|
|
7
|
+
"interests": [
|
|
8
|
+
"software",
|
|
9
|
+
"play"
|
|
10
|
+
],
|
|
7
11
|
"name": "HTML Arcade Game",
|
|
8
12
|
"description": "Build a playable single-file HTML/canvas arcade game (shooter, runner, dodger, etc.). Splits design into game-mechanics and visual look, builds, then evaluates against a playability bar and loops until it is actually fun and bug-free.",
|
|
9
13
|
"tags": [
|