codemble 0.6.3__tar.gz → 0.7.0__tar.gz
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.
- {codemble-0.6.3 → codemble-0.7.0}/.gitignore +1 -0
- {codemble-0.6.3 → codemble-0.7.0}/CHANGELOG.md +122 -0
- {codemble-0.6.3 → codemble-0.7.0}/CLAUDE.md +70 -4
- {codemble-0.6.3 → codemble-0.7.0}/PKG-INFO +31 -14
- {codemble-0.6.3 → codemble-0.7.0}/README.md +30 -13
- {codemble-0.6.3 → codemble-0.7.0}/codemble/__init__.py +1 -1
- {codemble-0.6.3 → codemble-0.7.0}/codemble/checks/service.py +14 -8
- {codemble-0.6.3 → codemble-0.7.0}/codemble/lens/python.py +6 -1
- {codemble-0.6.3 → codemble-0.7.0}/codemble/progress/store.py +44 -7
- {codemble-0.6.3 → codemble-0.7.0}/codemble/server/project_selection.py +16 -1
- codemble-0.6.3/codemble/web_dist/assets/index-CnZFAhwF.js → codemble-0.7.0/codemble/web_dist/assets/index-CMsEPFpK.js +1 -1
- codemble-0.7.0/codemble/web_dist/assets/index-CU2GP4jq.css +1 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/index.html +2 -2
- codemble-0.7.0/docs/releases/v0.6.4.md +89 -0
- codemble-0.7.0/docs/releases/v0.7.0.md +64 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/package.json +1 -1
- codemble-0.7.0/docs-site/public/shots/easy-mode.png +0 -0
- codemble-0.7.0/docs-site/public/shots/galaxy-lit.png +0 -0
- codemble-0.7.0/docs-site/public/shots/galaxy.png +0 -0
- codemble-0.7.0/docs-site/public/shots/map-architecture.png +0 -0
- codemble-0.7.0/docs-site/public/shots/map-workflow.png +0 -0
- codemble-0.7.0/docs-site/public/shots/study-panel.png +0 -0
- codemble-0.7.0/docs-site/public/shots/system.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/checks-and-lighting.md +13 -6
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/quickstart.md +15 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/study-panel.md +16 -7
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/the-galaxy.md +53 -17
- {codemble-0.6.3 → codemble-0.7.0}/pyproject.toml +1 -1
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_checks.py +29 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_progress.py +55 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_project_selection.py +34 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/package-lock.json +2 -2
- {codemble-0.6.3 → codemble-0.7.0}/web/package.json +2 -2
- codemble-0.7.0/web/scripts/check_galaxy_effects.mjs +89 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_graph_data.mjs +126 -2
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_learner_projection.mjs +103 -1
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_learner_session.mjs +2 -2
- codemble-0.7.0/web/scripts/check_map_viewport.mjs +84 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/App.jsx +342 -71
- {codemble-0.6.3 → codemble-0.7.0}/web/src/GalaxyCanvas.jsx +25 -2
- {codemble-0.6.3 → codemble-0.7.0}/web/src/MapView.jsx +139 -12
- {codemble-0.6.3 → codemble-0.7.0}/web/src/StudyPanel.jsx +53 -5
- {codemble-0.6.3 → codemble-0.7.0}/web/src/galaxyEffects.js +8 -4
- {codemble-0.6.3 → codemble-0.7.0}/web/src/graphData.js +110 -8
- {codemble-0.6.3 → codemble-0.7.0}/web/src/learnerProjection.js +55 -9
- {codemble-0.6.3 → codemble-0.7.0}/web/src/learnerSession.js +14 -0
- codemble-0.7.0/web/src/mapViewport.js +86 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/styles.css +205 -33
- {codemble-0.6.3 → codemble-0.7.0}/web/src/tokens.css +27 -0
- codemble-0.6.3/codemble/web_dist/assets/index-CDRcoar-.css +0 -1
- codemble-0.6.3/docs-site/public/shots/easy-mode.png +0 -0
- codemble-0.6.3/docs-site/public/shots/galaxy-lit.png +0 -0
- codemble-0.6.3/docs-site/public/shots/galaxy.png +0 -0
- codemble-0.6.3/docs-site/public/shots/map-architecture.png +0 -0
- codemble-0.6.3/docs-site/public/shots/map-workflow.png +0 -0
- codemble-0.6.3/docs-site/public/shots/study-panel.png +0 -0
- codemble-0.6.3/docs-site/public/shots/system.png +0 -0
- codemble-0.6.3/web/scripts/check_map_viewport.mjs +0 -38
- codemble-0.6.3/web/src/mapViewport.js +0 -45
- {codemble-0.6.3 → codemble-0.7.0}/.env.example +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.gitattributes +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/ISSUE_TEMPLATE/early_tester.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/dependabot.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/workflows/ci.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/workflows/pages.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/.github/workflows/publish-pypi.yml +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/AGENTS.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/CODE_OF_CONDUCT.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/CONTEXT.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/CONTRIBUTING.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/LICENSE +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/NOTICE +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/SECURITY.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/TESTING.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/assets/demo.gif +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/base.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/discovery.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/parse_progress.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/project.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/python_ast.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/adapters/typescript_tree_sitter.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/checks/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/cli.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/graph/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/graph/finalize.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/graph/layout.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/graph/mapview.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/lens/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/lens/javascript_typescript.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/llm/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/llm/local_status.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/llm/providers.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/llm/structural.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/llm/study.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/paths.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/progress/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/server/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/server/app.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/server/parse_job.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/server/project_activation.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/server/runtime.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/shippori-mincho-latin-500-normal-C-QwvIb3.woff +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/shippori-mincho-latin-500-normal-XI1O8euf.woff2 +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/shippori-mincho-latin-700-normal-CkoCYOiI.woff +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/shippori-mincho-latin-700-normal-DHcmzUO5.woff2 +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/zen-kaku-gothic-new-latin-400-normal-BEdayliK.woff2 +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/codemble/web_dist/assets/zen-kaku-gothic-new-latin-400-normal-CPSmNJAU.woff +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/adr/README.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/2026-07-19-audience-modes-and-local-narration-design.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/2026-07-19-audience-modes-backend-plan.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/2026-07-19-audience-modes-frontend-plan.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/2026-07-19-install-ux-folder-picker-design.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/2026-07-19-install-ux-folder-picker-plan.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/2026-07-20-oss-inspired-map-and-constellations.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/README.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/plans/phase-1.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/checklist.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.1.0.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.2.0.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.4.0.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.5.0.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.5.1.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.5.2.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.5.3.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.6.1.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.6.2.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/releases/v0.6.3.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/research/2026-07-20-opensource-graph-architecture-inspiration.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/research/README.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/superpowers/plans/2026-07-19-galaxy-ux-phase-a.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/superpowers/plans/2026-07-19-galaxy-ux-phase-b.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/superpowers/plans/2026-07-19-galaxy-ux-phase-c.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/superpowers/plans/2026-07-19-galaxy-ux-shared-contract.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/superpowers/specs/2026-07-19-galaxy-ux-overhaul-design.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs/superpowers/specs/2026-07-21-navigation-design-clarity-design.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/.gitignore +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/astro.config.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/design.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/favicon-16.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/favicon-32.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/icon-180.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/icon-192.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/icon-512.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/icon.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/icons/asterism.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/icons/install.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/mark-animated.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/mark.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/hero-chart.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/hero-field.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/hero-gold.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/kasumi-rule.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/plate-galaxy.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/plate-study.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/plate-system.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/brand/plates/seal.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/favicon.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/public/shots/loading.png +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/scripts/build-plates.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/assets/codemble-mark-dark.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/assets/codemble-mark-light.svg +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/components/Search.astro +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/components/Tatebanko.astro +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/architecture.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/build-from-source.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/contributing.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/correctness.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/early-testing.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/installation.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/introduction.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m1-parser.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m10-polyglot-release.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m12-galaxy-look.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m13-scale.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m2-galaxy.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m3-study.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m4-lens.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m5-checks.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m6-release.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m8-typescript.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/progress/m9-typescript-lens.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/roadmap.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content/docs/star-chart.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/content.config.ts +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/pages/index.astro +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/styles/custom.css +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/styles/landing.css +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/docs-site/src/styles/tokens.css +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/scripts/dev.sh +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/scripts/record_demo.sh +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/conftest.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/check_suites.json +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/concepts_sample.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/impact/alpha.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/impact/beta.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/impact/gamma.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/impact/helpers.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/impact/noisy.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/python_worker.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/broken.ts +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/legacy.js +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/local.js +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/main.ts +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/reexport.ts +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/util.ts +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/polyglot/src/widget.tsx +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/repeated_calls.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/.gitignore +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/ambiguous.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/api.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/app.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/broken.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/cli.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/pkg/__init__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/pkg/helpers.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/pkg/service.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/pkg/util.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/runner/__main__.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/fixtures/sampleproj/shared.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_dependency_compatibility.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_graph_finalization.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_mapview.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_parse_job.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_parse_progress.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_project_activation.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_project_parser.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_providers.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_python_ast.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_server.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_smoke.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_structural.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_study.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/tests/test_typescript_tree_sitter.py +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/README.md +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/index.html +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/benchmark_learner_projection.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_focus_handoffs.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_mode_gate_portal.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_name_atlas.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_orbit_pointer_guard.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/check_project_mapping.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/scripts/record_demo.mjs +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/GuidanceLayer.jsx +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/ModeControl.jsx +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/galaxyMaterials.js +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/main.jsx +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/nameAtlas.js +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/orbitPointerGuard.js +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/src/projectMapping.js +0 -0
- {codemble-0.6.3 → codemble-0.7.0}/web/vite.config.js +0 -0
|
@@ -5,6 +5,128 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.7.0] - 2026-07-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Constellations you can tell apart.** Every parser-proven import community
|
|
12
|
+
now wears one of eight traditional Japanese colour families (seiji, fuji,
|
|
13
|
+
koke, asagi, toki, umenezumi, wakatake, kikyō), assigned deterministically
|
|
14
|
+
from the community id — same code, same sky, same colours. Galaxy stars keep
|
|
15
|
+
centrality as lightness inside the family hue, planets inherit their
|
|
16
|
+
system's family, and Architecture boxes tint toward it. Every hue is
|
|
17
|
+
lightness-capped beneath the unlit ceiling and the amber band is excluded
|
|
18
|
+
from the wheel, so a lit star stays the brightest object in the sky and
|
|
19
|
+
nothing unproven can read as understood. The Key gains a colour-family row.
|
|
20
|
+
- **A counted shelf for unreachable modules.** On the Architecture map, modules
|
|
21
|
+
with no import route from Home fold away behind their exact count with a
|
|
22
|
+
**Show them** control (auto-folded above eight). On this repository that
|
|
23
|
+
turns a 1:3.2-tall drawing dominated by 80 test fixtures into a readable
|
|
24
|
+
connected core — with nothing hidden from the count and every module still
|
|
25
|
+
one click away.
|
|
26
|
+
- **Class rings.** A structure the parser knows is a class wears a thin ring in
|
|
27
|
+
the system view — parser fact, not decoration.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- **Connections are visible.** Routes on both layers used to borrow the border
|
|
31
|
+
hairline at ~1.6:1 contrast — and the galaxy multiplied it to 32% opacity —
|
|
32
|
+
so the relationships the app teaches were its least visible marks. Both
|
|
33
|
+
layers now draw a dedicated route ink (4.0:1), arrowheads included, and a
|
|
34
|
+
*possible* relationship stays deliberately the more visible claim, dashed on
|
|
35
|
+
the map as before.
|
|
36
|
+
- **The map's language stripe actually renders.** It set its colour through an
|
|
37
|
+
SVG presentation attribute, where `var()` is invalid, and silently fell back
|
|
38
|
+
to the box navy — the Key advertised Python/JS/TS colours the map never
|
|
39
|
+
drew. The stripe now paints through a style property.
|
|
40
|
+
- **The nebula dawn no longer corrupts the lit system's name plate.** The
|
|
41
|
+
animation snapshotted one scale axis and restored all three from it, so the
|
|
42
|
+
celebration squashed the plate into a blurry square until a level change
|
|
43
|
+
rebuilt it. It now restores the full vector — the one bold moment ends
|
|
44
|
+
crisp.
|
|
45
|
+
- **Escape steps back from anywhere on the Map.** The handler listened only
|
|
46
|
+
inside the stage, and the most common Easy path leaves focus on the page
|
|
47
|
+
body, so the documented recovery silently did nothing; the study exit also
|
|
48
|
+
said "Back to system" on the Diagram. Escape is now a window-level handler
|
|
49
|
+
(with dialog and typing guards) and the exit says "Back to the module".
|
|
50
|
+
- **A resize cannot strand you in empty space.** Restored map viewports are
|
|
51
|
+
replayed only while they still show your focus; shrinking a desktop window
|
|
52
|
+
to phone width used to keep the desktop scroll and show empty layer bands.
|
|
53
|
+
Both the restore path and live resizes now re-centre on the parser-backed
|
|
54
|
+
target.
|
|
55
|
+
- **Fit lands on something readable.** On tall drawings a true fit reached 7% —
|
|
56
|
+
a thumbnail with no names — so Fit now fits the width and lets the height
|
|
57
|
+
scroll when the whole shape would be unreadable, and keeps whole-shape fit
|
|
58
|
+
otherwise. The open Key also no longer covers the zoom controls, and the
|
|
59
|
+
region panel's actions no longer clip at desktop heights.
|
|
60
|
+
- **Easy mode speaks its own register end to end.** "parser rank 0" became
|
|
61
|
+
"candidate 1", the checks header reads "Quiz · answers come from your code,
|
|
62
|
+
not AI", the lit celebration explains what the source hash means instead of
|
|
63
|
+
naming it, study metadata reads "What it is / Length / Evidence", and the
|
|
64
|
+
chrome attributes fixture errors to their shared directory ("2 could not be
|
|
65
|
+
read · all under tests/"). Expert keeps every precise term.
|
|
66
|
+
- **Guidance stops sending beginners into tests first.** The nearest-unlit
|
|
67
|
+
ranking now charges test-scoped paths a bounded +1.5-hop penalty — a real
|
|
68
|
+
source module one hop farther wins the tie, an all-tests project is still
|
|
69
|
+
guided, and the displayed hop count stays the real one. On this repository
|
|
70
|
+
the second stop changed from `tests.test_python_ast` to
|
|
71
|
+
`codemble.adapters.project`.
|
|
72
|
+
- **The study panel's connection diagram names its dots.** Six anonymous dots
|
|
73
|
+
used to decorate the labelled list below; each now carries its structure's
|
|
74
|
+
own (tail-truncated) name.
|
|
75
|
+
|
|
76
|
+
## [0.6.4] - 2026-07-21
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
- **A missed check no longer hands back its own answer.** Getting a question
|
|
80
|
+
wrong printed the parser answer and its evidence, and the same question then
|
|
81
|
+
accepted that answer — so a region could light without understanding. A miss
|
|
82
|
+
now returns neither the answer nor the citations (an importer check's
|
|
83
|
+
evidence *is* its answer); both appear once the learner has proven it.
|
|
84
|
+
- **The Map can show you the code it is asking about.** Easy mode lands on the
|
|
85
|
+
Map, which offered checks but no way to read a module. Region focus now
|
|
86
|
+
carries **Read the source** beside **Prove understanding**, and Easy guidance
|
|
87
|
+
recommends reading before proving instead of sending the learner to another
|
|
88
|
+
layer. Escape steps back a level on the Map, as it always has in the Galaxy.
|
|
89
|
+
- **The checks panel is usable from the keyboard.** Opening it hands focus to
|
|
90
|
+
the panel instead of leaving it on the trigger behind ~114 tab stops, and
|
|
91
|
+
submitting keeps focus on the result rather than dropping it to the document.
|
|
92
|
+
- **Enter opens the structure the arrow keys selected.** At study level the
|
|
93
|
+
canvas announced a sibling while the panel kept showing the old one; Enter
|
|
94
|
+
was a no-op despite the view's own instructions.
|
|
95
|
+
- **Guidance is docked, and waits its turn.** The hint chip took its own strip
|
|
96
|
+
above the footer instead of floating over captions, name plates and its own
|
|
97
|
+
button, and it no longer appears during the audience, Home and coach steps —
|
|
98
|
+
where it used to recommend a target "because no import route reaches it from
|
|
99
|
+
Home" while no Home existed.
|
|
100
|
+
- **Compact Map controls no longer stack.** At 375 px the Key button covered
|
|
101
|
+
40% of the "What runs first" tab and the zoom pill covered the top row of
|
|
102
|
+
boxes. Measured at 320 and 375: zero overlapping interactive rectangles.
|
|
103
|
+
- **The study panel stops contradicting itself.** Easy mode showed "Used by 0"
|
|
104
|
+
above a summary saying five other parts use the file; the call-edge stat is
|
|
105
|
+
now "Called by", leaving "use" to imports.
|
|
106
|
+
- **The audience question is asked once per learner, not once per project.**
|
|
107
|
+
A new project inherits the last answer; the header toggle still overrides any
|
|
108
|
+
single project.
|
|
109
|
+
- **Home calibration is navigable on real projects.** It is now a modal sized
|
|
110
|
+
to the window rather than a card capped to a short stage, states how many
|
|
111
|
+
candidates exist, groups them by their real top-level scope (so test fixtures
|
|
112
|
+
no longer sit unmarked beside your entrypoint), and keeps "Explore without
|
|
113
|
+
Home" on screen instead of thousands of pixels below the fold.
|
|
114
|
+
- **The star chart is reachable from anywhere and closes with Escape.** It kept
|
|
115
|
+
its header slot at every level instead of surrendering it to the level-return
|
|
116
|
+
button, and every exit now names the layer it returns to.
|
|
117
|
+
- **Galaxy plates are named by path tail**, the rule the Map's boxes already
|
|
118
|
+
use, so two different `__init__.py` modules no longer wear identical names.
|
|
119
|
+
- **Find opens on Home and the most-used modules** instead of a screen of
|
|
120
|
+
identical `__init__.py` rows.
|
|
121
|
+
- **Easy guidance prefers a substantive module** when several sit the same
|
|
122
|
+
number of import hops from Home, instead of the alphabetically-first
|
|
123
|
+
four-line package init.
|
|
124
|
+
- **The exception-handling lens note is true of `raise`,** not only of
|
|
125
|
+
`try`/`except`, since the parser files all three under one concept.
|
|
126
|
+
- **Counts of one read as one** ("1 structure", not "1 structures").
|
|
127
|
+
- **The picker opens beside your last project** rather than at your home
|
|
128
|
+
directory every time.
|
|
129
|
+
|
|
8
130
|
## [0.6.3] - 2026-07-21
|
|
9
131
|
|
|
10
132
|
### Fixed
|
|
@@ -167,9 +167,57 @@ Polish, then the coordinated launch (Show HN / X; lit-galaxy GIF as hero).
|
|
|
167
167
|
|
|
168
168
|
## Current State **[AGENT-MAINTAINED]**
|
|
169
169
|
|
|
170
|
-
**Current milestone: Phase 1 tester evidence** · Last updated: 2026-07-
|
|
171
|
-
Session note: v0.
|
|
172
|
-
user-flow audit.
|
|
170
|
+
**Current milestone: Phase 1 tester evidence** · Last updated: 2026-07-22 ·
|
|
171
|
+
Session note: v0.7.0 implements all fourteen findings of a fresh evidence-based
|
|
172
|
+
user-flow audit of the served v0.6.4 build (run as a first-run Easy learner on
|
|
173
|
+
this repository at 1280/375/320, with before/after screenshots) plus the
|
|
174
|
+
approved D1 design direction: parser-proven import communities now wear eight
|
|
175
|
+
deterministic traditional Japanese colour families (galaxy stars, planets, and
|
|
176
|
+
Architecture-box tints), lightness-capped beneath the unlit ceiling with the
|
|
177
|
+
amber band excluded so understanding stays the brightest claim in the sky.
|
|
178
|
+
Routes on both layers moved from the 1.6:1 border hairline to a dedicated
|
|
179
|
+
4.0:1 route ink (possible relationships stay dashed and deliberately more
|
|
180
|
+
visible); the Architecture map folds modules with no route from Home into a
|
|
181
|
+
counted shelf behind a Show-them control; Fit fits width when whole-shape fit
|
|
182
|
+
would be unreadable; and Easy guidance charges test-scoped paths a bounded
|
|
183
|
+
+1.5-hop penalty so a learner's own code outranks its test suite at equal
|
|
184
|
+
distance. Mechanical fixes: the nebula dawn restores sprite scale as a vector
|
|
185
|
+
(it squashed the lit system's name plate square), the map's language stripe
|
|
186
|
+
paints via a style property (an SVG fill attribute cannot resolve var() and
|
|
187
|
+
silently rendered navy), Escape on the Map is a window-level handler that
|
|
188
|
+
works with focus on body, stale map viewports re-centre on the focus point on
|
|
189
|
+
restore and on live resizes, the open Key stacks below the zoom controls, the
|
|
190
|
+
region panel's actions no longer clip, study connection dots carry names, and
|
|
191
|
+
the Easy register replaces parser vocabulary end to end ("candidate 1",
|
|
192
|
+
"Quiz · answers come from your code, not AI", "What it is / Length /
|
|
193
|
+
Evidence", fixture errors attributed "all under tests/"). Parser, graph,
|
|
194
|
+
checks, progress, provider, and HTTP contracts are byte-unchanged; the suite
|
|
195
|
+
grew a nebula-dawn scale-restore check plus community-colour, viewport, and
|
|
196
|
+
guidance-penalty contract assertions (241 pytest, ruff clean, 12 frontend
|
|
197
|
+
checks, rebuilt web_dist). Full planet realism explicitly remains a Phase 3
|
|
198
|
+
decision under the game-art Non-Goal. The milestone does not advance: issue
|
|
199
|
+
#13 still requires human tester evidence. Previously: v0.6.4 closes all twenty findings of a fresh end-to-end user-flow
|
|
200
|
+
audit run against the served build on three real projects (Codemble, Golavo,
|
|
201
|
+
FolioOrb) at 1280/375/320 px with a keyboard pass. The headline fix is a
|
|
202
|
+
Correctness Contract one: a missed check printed the parser answer and its
|
|
203
|
+
evidence and then accepted that answer, so a region could light without
|
|
204
|
+
understanding; a miss now returns neither, and both appear only after the
|
|
205
|
+
learner proves it. The Easy default layer gained the reading path it never had
|
|
206
|
+
(**Read the source** on the Map, guidance that says read-before-prove, Escape
|
|
207
|
+
stepping back a level), the checks panel became keyboard-usable (focus handoff
|
|
208
|
+
on open, focus preserved across submits), Enter now opens the arrow-selected
|
|
209
|
+
structure at study level, and the guidance chip is docked into its own strip
|
|
210
|
+
and hidden until the first-run decisions finish. Home calibration is now a
|
|
211
|
+
viewport-sized modal that states its candidate count, groups candidates by
|
|
212
|
+
their real scope, and keeps its escape hatch on screen; the audience question
|
|
213
|
+
is asked once per learner instead of once per project; the star chart is
|
|
214
|
+
reachable from every level and closes with Escape; exits name the layer they
|
|
215
|
+
return to; galaxy plates and the module index use path tails; Find opens on
|
|
216
|
+
Home and the busiest modules; and compact Map controls no longer share touch
|
|
217
|
+
targets (zero overlapping interactive rectangles at 320 and 375). Parser,
|
|
218
|
+
graph, checks, progress, and provider contracts are unchanged except for the
|
|
219
|
+
deliberate withholding of answers on a failed submission. Previously, v0.6.3
|
|
220
|
+
closed the four follow-up findings from the earlier user-flow audit. Easy guidance is now level-aware and never offers an enabled
|
|
173
221
|
no-op; compact Maps open at readable 100% around Home and preserve zoom/pan
|
|
174
222
|
through data refreshes; Switch project confirms on the first compact-Menu click
|
|
175
223
|
without leaking disclosure state across project or breakpoint changes; and Home
|
|
@@ -551,6 +599,15 @@ shows lower repeated-commit work without changing derived values.
|
|
|
551
599
|
| 2026-07-21 | Easy guidance actions are derived from level, region, and layer, then executed by `LearnerSession`; the chip renders no button when the next step is already on screen | React must not guess a structure or own navigation truth, and an enabled action that commits the same state is a false promise. The nearest unlit region remains graph-derived; only the honest route to it changes with the learner's current context |
|
|
552
600
|
| 2026-07-21 | Map zoom/pan is renderer-local state keyed by tab and Home, preserved through transient data remounts but cleared with the project lifecycle; compact Maps start at 100% centred on the parser-backed target | Auto-fitting made 56 px boxes as little as 8–18 px tall and re-ran after check-driven map refreshes. Fit is still a valid explicit overview, while session state stays reserved for graph and learning truth |
|
|
553
601
|
| 2026-07-21 | Responsive disclosures and global surfaces own explicit focus handoffs; compact Menu closes on project exit and when crossing to the desktop rail | DOM focus and disclosure visibility are view concerns, but leaving focus on removed or hidden controls makes a successful navigation indistinguishable from a dead action to a keyboard or screen-reader user |
|
|
602
|
+
| 2026-07-21 | A wrong check submission returns no answer, no answer labels and no evidence; all three are returned only once the learner answers correctly | The response printed the parser answer on every miss and the same question then accepted it, so a region could light on an answer the app itself had just displayed — illumination stopped meaning understanding, the same failure class as the 2026-07-19 "every check needs a wrong option" fix. Evidence is withheld with the answer because an importer check cites exactly the files that *are* its answer |
|
|
603
|
+
| 2026-07-21 | The 2D Map gets a reading path: region focus offers **Read the source** beside the checks, Easy guidance recommends reading before proving, and Escape steps back a level there as it does in the Galaxy | Easy mode lands on the Map, where the only action was a quiz about code the layer could not show. The study panel is layer-neutral (`/api/node/:id/study`), so the Map only needed to select the module node the parser already produced — no new truth, and the audience that most needs to read first stops being sent to another layer to do it |
|
|
604
|
+
| 2026-07-21 | The audience answer is stored per learner as well as per project (`learner.json` beside progress); a fresh bind seeds from it and skips the gate, while the header toggle still overrides one project | The gate asks who the *learner* is, but the answer lived only under the project key, so every new project re-asked an expert whether they were new to coding. The file carries no `schema_version`, which is what keeps recents from reading it as a project |
|
|
605
|
+
| 2026-07-21 | Home calibration is a native modal sized to the viewport, grouped by the candidates' real top-level scope, with the candidate count stated and "Explore without Home" outside the scrolling list | It is the second step of the same required sequence as the audience gate and deserves the same shape. As a card capped to a share of the stage it showed one candidate of eleven with the escape hatch thousands of pixels below the fold, and a flat list put `tests/fixtures/...` beside the learner's entrypoint with nothing to tell them apart. Scope and rank are parser facts already in the payload; the leading group always opens so a project whose best candidate is rank 1 is never met by an all-collapsed list |
|
|
606
|
+
| 2026-07-21 | Galaxy name plates use the same path-tail rule as map schema 3's `short_label`; the shared module index and the command palette use it too, and the palette's unfiltered order is Home → lit → centrality | Basenames collide hard in a Python project — every package carries an `__init__.py` — so identical plates named different modules, which is precisely the wrong a learner cannot detect, and the palette opened on a screen of indistinguishable rows |
|
|
607
|
+
| 2026-07-22 | **Hue means import community.** Each parser-proven community takes one of eight traditional Japanese colour tokens (`--cm-com-0..7`) by `community id mod 8`; stars, planets and Architecture boxes all read the same arithmetic in `graphData.communityShade`. This amends the M2 encoding row: colour was "language", which is now the nebula/stripe channel only | Approved by UD. The sky had one hue for 109 systems, so nothing could be tracked without reading every plate — and the graph had proven communities since schema 5 that nothing rendered. Guardrails that keep the Correctness Contract intact: every token is lightness-tuned to `--cm-ink-2`'s luminance (0.389) so a lit star at 0.598 always wins, the kohaku band (~40°) is excluded so no community can read as "understood", a missing community id falls back to the old neutral ramp rather than borrowing a hue, and the mapping is pure arithmetic on graph truth so the same code always yields the same sky |
|
|
608
|
+
| 2026-07-22 | Routes get their own ink (`--cm-route`, 4.0:1) on both layers, and it sits deliberately BELOW `--cm-route-possible` (6.4:1) | Edges borrowed `--cm-hairline`, the ink of box borders and panel rules, measuring 1.57:1 on the canvas ground — the relationships the product exists to teach were its least visible marks, which is the literal complaint that opened the audit. Ordering the two inks this way keeps the 2026-07-19 rule that an unproven claim must be the more visible one |
|
|
609
|
+
| 2026-07-22 | Architecture-map modules with no import route from Home fold into a counted shelf behind an explicit control (auto-folded above 8), and Fit fits WIDTH when a whole-shape fit would land below 35% | On this repository 80 of 109 boxes are test fixtures and scripts, making the drawing 1:3.2 tall so the connected core fit at an unreadable 7%. Folding is view state, never truth: the note carries the exact count, **Show them** draws every one, and both surfaces still reach every module. Distinct from progressive reveal, which stays galaxy-only |
|
|
610
|
+
| 2026-07-22 | Easy guidance charges test-scoped paths a bounded +1.5-hop penalty; the displayed hop count stays the real one | A CLI's nearest neighbour is usually its own test suite, so pure hop-distance sent a brand-new learner from Home straight into `tests/`. The penalty is bounded so a non-test module one hop farther wins while a distant one does not, and an all-tests project is still guided. Both inputs stay parser truth (the BFS count and the recorded file path); only the ranking key is biased, never the reported fact |
|
|
554
611
|
|
|
555
612
|
## Non-Goals — do NOT build (point here when asked)
|
|
556
613
|
|
|
@@ -563,7 +620,11 @@ shows lower repeated-commit work without changing derived values.
|
|
|
563
620
|
- ❌ Accounts, cloud hosting, multi-user; share link waits for Phase 3
|
|
564
621
|
- ❌ Extra quest types before Phase 3
|
|
565
622
|
- ❌ GitHub-URL ingestion in v1
|
|
566
|
-
- ❌ Elaborate game art before the loop teaches well
|
|
623
|
+
- ❌ Elaborate game art before the loop teaches well — **still holds**: the
|
|
624
|
+
2026-07-22 visual pass shipped only encodings that carry parser facts
|
|
625
|
+
(community hue, class rings). Procedural planet surfaces, atmospheres and
|
|
626
|
+
rotation ("almost real planets, like a game") remain OUT until Phase 1
|
|
627
|
+
tester evidence lands, and would need their own Decision Log entry
|
|
567
628
|
|
|
568
629
|
## Gotchas
|
|
569
630
|
|
|
@@ -591,6 +652,11 @@ shows lower repeated-commit work without changing derived values.
|
|
|
591
652
|
- **Canvas colours must be plain values, never `color-mix()`** — WebGL receives
|
|
592
653
|
a custom property's authored text, so a computed token renders black. Add new
|
|
593
654
|
canvas tokens through `readPalette`, which resolves them.
|
|
655
|
+
- **`var()` never works in an SVG presentation attribute** — `fill="var(--x)"`
|
|
656
|
+
is invalid and falls back to the cascade *silently*, which is how the map's
|
|
657
|
+
language stripe rendered box-navy for a release while the legend advertised
|
|
658
|
+
three colours. Use `style={{ fill: … }}` (a CSS property) for any
|
|
659
|
+
token-driven SVG paint.
|
|
594
660
|
|
|
595
661
|
## Edge cases & limits
|
|
596
662
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codemble
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: A learning game that turns the code AI wrote for you into a galaxy you light up by understanding it.
|
|
5
5
|
Project-URL: Homepage, https://udhawan97.github.io/Codemble/
|
|
6
6
|
Project-URL: Repository, https://github.com/udhawan97/Codemble
|
|
@@ -66,7 +66,7 @@ Description-Content-Type: text/markdown
|
|
|
66
66
|
</p>
|
|
67
67
|
|
|
68
68
|
<p align="center">
|
|
69
|
-
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/galaxy.png" alt="Codemble at galaxy level:
|
|
69
|
+
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/galaxy.png" alt="Codemble at galaxy level: 109 star systems parsed from real source, 23 charted and named by file path, constellations wearing their import-community colour families in traditional Japanese hues around an amber lit Home, with language focus buttons, a Key disclosure, and a notice that two files could not be read — all under tests/" width="960">
|
|
70
70
|
</p>
|
|
71
71
|
|
|
72
72
|
<p align="center"><sub>
|
|
@@ -148,7 +148,7 @@ of your own code becomes a sky you understand.
|
|
|
148
148
|
## What it looks like
|
|
149
149
|
|
|
150
150
|
<p align="center">
|
|
151
|
-
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/system.png" alt="A single star system, codemble.server.app,
|
|
151
|
+
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/system.png" alt="A single star system, codemble.server.app, its functions and classes as planets in the system's own colour family, in call-depth orbits with the call edges between them" width="900">
|
|
152
152
|
</p>
|
|
153
153
|
|
|
154
154
|
<p align="center"><sub>
|
|
@@ -156,7 +156,7 @@ of your own code becomes a sky you understand.
|
|
|
156
156
|
</sub></p>
|
|
157
157
|
|
|
158
158
|
<p align="center">
|
|
159
|
-
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/study-panel.png" alt="The study panel for create_app, showing kind, span,
|
|
159
|
+
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/study-panel.png" alt="The study panel for create_app, showing kind, span, 53 callers, parser-proven resolution, and a structural summary marked no model needed" width="900">
|
|
160
160
|
</p>
|
|
161
161
|
|
|
162
162
|
<p align="center"><sub>
|
|
@@ -188,9 +188,17 @@ computed in the graph layer and served as data.
|
|
|
188
188
|
| **Map · Workflow** | The call tree from your entrypoint, depth by depth | Seeing what runs first |
|
|
189
189
|
|
|
190
190
|
The Map is plain SVG, so it still works on a machine that cannot draw WebGL.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
Click a box and it offers both halves of a step — **Read the source** opens that
|
|
192
|
+
module's real source, lens notes and relationships without leaving the layer,
|
|
193
|
+
and **Prove understanding** starts its checks. Escape steps back a level, as in
|
|
194
|
+
the Galaxy. On a compact screen the Map opens at readable 100% around Home or
|
|
195
|
+
the selected target; **Fit** is an explicit whole-diagram overview. Zoom and pan
|
|
196
|
+
survive Map refreshes and layer switches instead of snapping back after a passed
|
|
197
|
+
check.
|
|
198
|
+
|
|
199
|
+
In Easy mode these surfaces carry plainer labels — the layer is **Diagram** and
|
|
200
|
+
the tabs are **How it fits together** and **What runs first**. Same views, same
|
|
201
|
+
evidence; only the wording follows the audience.
|
|
194
202
|
|
|
195
203
|
## Open a structure, read what the parser knows first
|
|
196
204
|
|
|
@@ -207,10 +215,14 @@ Sections other than the narration never involve a model at all.
|
|
|
207
215
|
A header toggle changes how Codemble talks to you and how much it puts on
|
|
208
216
|
screen: plain language, larger type, the Map by default, and a hint chip naming
|
|
209
217
|
the nearest unlit region to Home — counted in import hops over the graph, not
|
|
210
|
-
chosen by a model
|
|
211
|
-
|
|
212
|
-
than an enabled no-op. It
|
|
213
|
-
|
|
218
|
+
chosen by a model, and broken by parser-proven structure count when several sit
|
|
219
|
+
the same distance away. The hint opens that system, offers to read its source,
|
|
220
|
+
then becomes an instruction rather than an enabled no-op. It waits until the
|
|
221
|
+
first-run choices are done before it appears at all, and it never changes graph
|
|
222
|
+
truth, coordinates, progress, or how a check is scored.
|
|
223
|
+
|
|
224
|
+
Codemble asks which audience you are **once** — the question is about you, not
|
|
225
|
+
about the project — and each project still keeps its own mode.
|
|
214
226
|
|
|
215
227
|
You can also switch project or change Home without leaving the app.
|
|
216
228
|
|
|
@@ -224,6 +236,7 @@ You can also switch project or change Home without leaving the app.
|
|
|
224
236
|
| A route or edge | An import or call; approximate calls are labeled **possible** |
|
|
225
237
|
| Size | Lines of code |
|
|
226
238
|
| Brightness and glow | How many **distinct** structures call it |
|
|
239
|
+
| Colour family | Import community — modules that import each other share one of eight traditional Japanese hues |
|
|
227
240
|
| Nebula tint | Language, at galaxy level |
|
|
228
241
|
| Orbit ring | Call depth — the inner ring runs first |
|
|
229
242
|
| Drifting particles | A call the parser proved; a possible call stays still |
|
|
@@ -231,9 +244,13 @@ You can also switch project or change Home without leaving the app.
|
|
|
231
244
|
|
|
232
245
|
Understanding owns the top of the brightness range: the unlit ramp stops below
|
|
233
246
|
the amber a lit star uses, so a busy module you have not proven can never
|
|
234
|
-
outshine one you have
|
|
235
|
-
amber
|
|
236
|
-
a
|
|
247
|
+
outshine one you have — every community hue is lightness-capped beneath it, and
|
|
248
|
+
the amber band is excluded from the community wheel entirely. Pass a region's
|
|
249
|
+
checks and that system plays a short amber "nebula dawn" — after the light is
|
|
250
|
+
already saved, so the animation marks a fact rather than delivering one. On the
|
|
251
|
+
flat Map, modules with no import route from Home fold into a counted shelf
|
|
252
|
+
(**Show them** draws every one), so test scaffolding never buries the connected
|
|
253
|
+
core it cannot reach.
|
|
237
254
|
|
|
238
255
|
Python-only, JavaScript-only, TypeScript-only, and mixed projects share the same
|
|
239
256
|
graph contract. Language focus changes only what you are looking at; it never
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
</p>
|
|
35
35
|
|
|
36
36
|
<p align="center">
|
|
37
|
-
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/galaxy.png" alt="Codemble at galaxy level:
|
|
37
|
+
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/galaxy.png" alt="Codemble at galaxy level: 109 star systems parsed from real source, 23 charted and named by file path, constellations wearing their import-community colour families in traditional Japanese hues around an amber lit Home, with language focus buttons, a Key disclosure, and a notice that two files could not be read — all under tests/" width="960">
|
|
38
38
|
</p>
|
|
39
39
|
|
|
40
40
|
<p align="center"><sub>
|
|
@@ -116,7 +116,7 @@ of your own code becomes a sky you understand.
|
|
|
116
116
|
## What it looks like
|
|
117
117
|
|
|
118
118
|
<p align="center">
|
|
119
|
-
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/system.png" alt="A single star system, codemble.server.app,
|
|
119
|
+
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/system.png" alt="A single star system, codemble.server.app, its functions and classes as planets in the system's own colour family, in call-depth orbits with the call edges between them" width="900">
|
|
120
120
|
</p>
|
|
121
121
|
|
|
122
122
|
<p align="center"><sub>
|
|
@@ -124,7 +124,7 @@ of your own code becomes a sky you understand.
|
|
|
124
124
|
</sub></p>
|
|
125
125
|
|
|
126
126
|
<p align="center">
|
|
127
|
-
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/study-panel.png" alt="The study panel for create_app, showing kind, span,
|
|
127
|
+
<img src="https://github.com/udhawan97/Codemble/raw/main/docs-site/public/shots/study-panel.png" alt="The study panel for create_app, showing kind, span, 53 callers, parser-proven resolution, and a structural summary marked no model needed" width="900">
|
|
128
128
|
</p>
|
|
129
129
|
|
|
130
130
|
<p align="center"><sub>
|
|
@@ -156,9 +156,17 @@ computed in the graph layer and served as data.
|
|
|
156
156
|
| **Map · Workflow** | The call tree from your entrypoint, depth by depth | Seeing what runs first |
|
|
157
157
|
|
|
158
158
|
The Map is plain SVG, so it still works on a machine that cannot draw WebGL.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
Click a box and it offers both halves of a step — **Read the source** opens that
|
|
160
|
+
module's real source, lens notes and relationships without leaving the layer,
|
|
161
|
+
and **Prove understanding** starts its checks. Escape steps back a level, as in
|
|
162
|
+
the Galaxy. On a compact screen the Map opens at readable 100% around Home or
|
|
163
|
+
the selected target; **Fit** is an explicit whole-diagram overview. Zoom and pan
|
|
164
|
+
survive Map refreshes and layer switches instead of snapping back after a passed
|
|
165
|
+
check.
|
|
166
|
+
|
|
167
|
+
In Easy mode these surfaces carry plainer labels — the layer is **Diagram** and
|
|
168
|
+
the tabs are **How it fits together** and **What runs first**. Same views, same
|
|
169
|
+
evidence; only the wording follows the audience.
|
|
162
170
|
|
|
163
171
|
## Open a structure, read what the parser knows first
|
|
164
172
|
|
|
@@ -175,10 +183,14 @@ Sections other than the narration never involve a model at all.
|
|
|
175
183
|
A header toggle changes how Codemble talks to you and how much it puts on
|
|
176
184
|
screen: plain language, larger type, the Map by default, and a hint chip naming
|
|
177
185
|
the nearest unlit region to Home — counted in import hops over the graph, not
|
|
178
|
-
chosen by a model
|
|
179
|
-
|
|
180
|
-
than an enabled no-op. It
|
|
181
|
-
|
|
186
|
+
chosen by a model, and broken by parser-proven structure count when several sit
|
|
187
|
+
the same distance away. The hint opens that system, offers to read its source,
|
|
188
|
+
then becomes an instruction rather than an enabled no-op. It waits until the
|
|
189
|
+
first-run choices are done before it appears at all, and it never changes graph
|
|
190
|
+
truth, coordinates, progress, or how a check is scored.
|
|
191
|
+
|
|
192
|
+
Codemble asks which audience you are **once** — the question is about you, not
|
|
193
|
+
about the project — and each project still keeps its own mode.
|
|
182
194
|
|
|
183
195
|
You can also switch project or change Home without leaving the app.
|
|
184
196
|
|
|
@@ -192,6 +204,7 @@ You can also switch project or change Home without leaving the app.
|
|
|
192
204
|
| A route or edge | An import or call; approximate calls are labeled **possible** |
|
|
193
205
|
| Size | Lines of code |
|
|
194
206
|
| Brightness and glow | How many **distinct** structures call it |
|
|
207
|
+
| Colour family | Import community — modules that import each other share one of eight traditional Japanese hues |
|
|
195
208
|
| Nebula tint | Language, at galaxy level |
|
|
196
209
|
| Orbit ring | Call depth — the inner ring runs first |
|
|
197
210
|
| Drifting particles | A call the parser proved; a possible call stays still |
|
|
@@ -199,9 +212,13 @@ You can also switch project or change Home without leaving the app.
|
|
|
199
212
|
|
|
200
213
|
Understanding owns the top of the brightness range: the unlit ramp stops below
|
|
201
214
|
the amber a lit star uses, so a busy module you have not proven can never
|
|
202
|
-
outshine one you have
|
|
203
|
-
amber
|
|
204
|
-
a
|
|
215
|
+
outshine one you have — every community hue is lightness-capped beneath it, and
|
|
216
|
+
the amber band is excluded from the community wheel entirely. Pass a region's
|
|
217
|
+
checks and that system plays a short amber "nebula dawn" — after the light is
|
|
218
|
+
already saved, so the animation marks a fact rather than delivering one. On the
|
|
219
|
+
flat Map, modules with no import route from Home fold into a counted shelf
|
|
220
|
+
(**Show them** draws every one), so test scaffolding never buries the connected
|
|
221
|
+
core it cannot reach.
|
|
205
222
|
|
|
206
223
|
Python-only, JavaScript-only, TypeScript-only, and mixed projects share the same
|
|
207
224
|
graph contract. Language focus changes only what you are looking at; it never
|
|
@@ -124,22 +124,28 @@ class CheckService:
|
|
|
124
124
|
if complete:
|
|
125
125
|
self._progress.mark_understood(region_id)
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
option.label for option in check.options if option.id in check.answer_ids
|
|
129
|
-
]
|
|
130
|
-
return {
|
|
127
|
+
result: dict[str, object] = {
|
|
131
128
|
"correct": correct,
|
|
132
129
|
"check_id": check.id,
|
|
133
|
-
"answer_ids": list(check.answer_ids),
|
|
134
|
-
"answer_labels": answer_labels,
|
|
135
|
-
"evidence": list(check.evidence),
|
|
136
130
|
"message": (
|
|
137
131
|
"Correct. That answer is fixed by the parser graph."
|
|
138
132
|
if correct
|
|
139
|
-
else "Not yet. Re-read the
|
|
133
|
+
else "Not yet. Re-read the relationship in your own code and try again."
|
|
140
134
|
),
|
|
141
135
|
"region_understood": complete,
|
|
142
136
|
}
|
|
137
|
+
if not correct:
|
|
138
|
+
# A miss returns no answer and no citations. An importer check
|
|
139
|
+
# cites the very files that are its answer, so handing either back
|
|
140
|
+
# let the next submission replay what the screen had just shown --
|
|
141
|
+
# and a region lit that way proves nothing.
|
|
142
|
+
return result
|
|
143
|
+
result["answer_ids"] = list(check.answer_ids)
|
|
144
|
+
result["answer_labels"] = [
|
|
145
|
+
option.label for option in check.options if option.id in check.answer_ids
|
|
146
|
+
]
|
|
147
|
+
result["evidence"] = list(check.evidence)
|
|
148
|
+
return result
|
|
143
149
|
|
|
144
150
|
def _region_checks(self, region_id: str) -> tuple[Check, ...]:
|
|
145
151
|
if region_id not in self._checks:
|
|
@@ -47,10 +47,15 @@ _PYTHON_NOTES = {
|
|
|
47
47
|
"expert": "Python calls this specially named method through a language protocol such as length, comparison, or display.",
|
|
48
48
|
},
|
|
49
49
|
),
|
|
50
|
+
# One concept id covers `try`, `try*` and `raise` (python_ast visits all
|
|
51
|
+
# three), so the copy has to be true of a line that *signals* a problem as
|
|
52
|
+
# well as one that catches it. The old easy note taught catching only, and
|
|
53
|
+
# anchored to `raise SystemExit(main())` it claimed roughly the opposite of
|
|
54
|
+
# what that line does.
|
|
50
55
|
"exception-handling": (
|
|
51
56
|
"Exception handling",
|
|
52
57
|
{
|
|
53
|
-
"easy": "This
|
|
58
|
+
"easy": "This treats failure as part of the plan: code like this either raises a problem for whoever called it, or catches one so the program can react instead of crashing.",
|
|
54
59
|
"expert": "This construct makes failure part of explicit control flow by catching, grouping, or raising an exception.",
|
|
55
60
|
},
|
|
56
61
|
),
|
|
@@ -12,6 +12,11 @@ from codemble.adapters.base import Graph
|
|
|
12
12
|
from codemble.paths import data_dir
|
|
13
13
|
|
|
14
14
|
_SCHEMA_VERSION = 1
|
|
15
|
+
_MODES = frozenset({"easy", "expert"})
|
|
16
|
+
# The audience answer is about the learner, not the project, so it is also kept
|
|
17
|
+
# once per data directory. Project payloads still win, which is what keeps the
|
|
18
|
+
# header toggle a genuine per-project override.
|
|
19
|
+
_LEARNER_FILE = "learner.json"
|
|
15
20
|
|
|
16
21
|
|
|
17
22
|
class UnknownRegionError(KeyError):
|
|
@@ -26,6 +31,7 @@ class ProgressStore:
|
|
|
26
31
|
self._root = root or data_dir() / "progress"
|
|
27
32
|
project_key = hashlib.sha256(graph.project_root.encode()).hexdigest()[:20]
|
|
28
33
|
self.path = self._root / f"{project_key}.json"
|
|
34
|
+
self._learner_path = self._root / _LEARNER_FILE
|
|
29
35
|
self._signatures = _region_signatures(graph)
|
|
30
36
|
|
|
31
37
|
def understood_regions(self) -> frozenset[str]:
|
|
@@ -72,24 +78,55 @@ class ProgressStore:
|
|
|
72
78
|
def mode(self) -> str:
|
|
73
79
|
"""Return the learner's audience mode; this never affects progress."""
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
value
|
|
77
|
-
|
|
81
|
+
value = self._read().get("mode")
|
|
82
|
+
if value in _MODES:
|
|
83
|
+
return value
|
|
84
|
+
return self._learner_mode() or "easy"
|
|
78
85
|
|
|
79
86
|
def mode_chosen(self) -> bool:
|
|
80
|
-
"""Return whether
|
|
87
|
+
"""Return whether this learner has answered the audience question.
|
|
81
88
|
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
Per project first, then the learner-level answer. The gate asks who
|
|
90
|
+
the *learner* is, so re-asking it on every project would be asking a
|
|
91
|
+
question they have already answered; the header toggle still overrides
|
|
92
|
+
any single project.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
return self._read().get("mode") in _MODES or self._learner_mode() is not None
|
|
84
96
|
|
|
85
97
|
def set_mode(self, mode: str) -> None:
|
|
86
98
|
"""Persist the audience mode beside progress without touching signatures."""
|
|
87
99
|
|
|
88
|
-
if mode not in
|
|
100
|
+
if mode not in _MODES:
|
|
89
101
|
raise ValueError("Mode must be 'easy' or 'expert'.")
|
|
90
102
|
payload = self._read()
|
|
91
103
|
payload["mode"] = mode
|
|
92
104
|
self._write(payload)
|
|
105
|
+
self._write_learner_mode(mode)
|
|
106
|
+
|
|
107
|
+
def _learner_mode(self) -> str | None:
|
|
108
|
+
"""Read the last audience answered on any project in this data dir."""
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
payload = json.loads(self._learner_path.read_text(encoding="utf-8"))
|
|
112
|
+
except (OSError, json.JSONDecodeError, UnicodeDecodeError):
|
|
113
|
+
return None
|
|
114
|
+
if not isinstance(payload, dict):
|
|
115
|
+
return None
|
|
116
|
+
value = payload.get("mode")
|
|
117
|
+
return value if value in _MODES else None
|
|
118
|
+
|
|
119
|
+
def _write_learner_mode(self, mode: str) -> None:
|
|
120
|
+
self._root.mkdir(parents=True, exist_ok=True)
|
|
121
|
+
temporary = self._learner_path.with_suffix(f".{os.getpid()}.tmp")
|
|
122
|
+
try:
|
|
123
|
+
temporary.write_text(
|
|
124
|
+
json.dumps({"mode": mode}, indent=2, sort_keys=True) + "\n",
|
|
125
|
+
encoding="utf-8",
|
|
126
|
+
)
|
|
127
|
+
temporary.replace(self._learner_path)
|
|
128
|
+
finally:
|
|
129
|
+
temporary.unlink(missing_ok=True)
|
|
93
130
|
|
|
94
131
|
def selected_entrypoint(self) -> str | None:
|
|
95
132
|
"""Return the learner's persisted Home choice, if one was stored.
|
|
@@ -69,7 +69,7 @@ class ProjectSelector:
|
|
|
69
69
|
def browse(self, path: str | Path | None = None) -> FolderListing:
|
|
70
70
|
"""List non-hidden child directories for one allowed folder."""
|
|
71
71
|
|
|
72
|
-
resolved = self.resolve(path if path is not None else self.
|
|
72
|
+
resolved = self.resolve(path if path is not None else self._default_start())
|
|
73
73
|
if not resolved.is_dir():
|
|
74
74
|
raise ProjectFolderMissing("That folder does not exist.")
|
|
75
75
|
try:
|
|
@@ -97,6 +97,21 @@ class ProjectSelector:
|
|
|
97
97
|
if self._is_inside_root(Path(str(entry["project_root"])).resolve())
|
|
98
98
|
)
|
|
99
99
|
|
|
100
|
+
def _default_start(self) -> Path:
|
|
101
|
+
"""Open browsing beside the newest remembered project, else at the root.
|
|
102
|
+
|
|
103
|
+
Projects tend to live as siblings, so starting at the browse root made
|
|
104
|
+
every switch re-walk the same folders. Derived from recents rather than
|
|
105
|
+
stored, so it cannot drift, and it stays inside the same jail because
|
|
106
|
+
``recents`` already filtered by it.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
for entry in self.recents():
|
|
110
|
+
parent = Path(str(entry["project_root"])).parent
|
|
111
|
+
if self._is_inside_root(parent) and parent.is_dir():
|
|
112
|
+
return parent
|
|
113
|
+
return self._root
|
|
114
|
+
|
|
100
115
|
def _require_inside_root(self, path: Path) -> None:
|
|
101
116
|
if not self._is_inside_root(path):
|
|
102
117
|
raise ProjectFolderForbidden(
|