18 Commits

Author SHA1 Message Date
przeprogramowani 1ce41e19d2 fix(rules): continue --no-course-rules when markers need repair (#54)
* fix(rules): continue --no-course-rules when markers need repair

Malformed, duplicate, or out-of-order sentinels still fail-close on a
default rules write, but opt-out no longer aborts the whole lesson.
Default get now returns a rules_markers_need_repair envelope instead of
a stack dump.

* chore(release): prepare v1.23.1

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-18 17:21:17 +02:00
przeprogramowani 95fc5f4394 fix(skills): include idea-check in lesson setup (#48)
* fix(skills): include idea-check in lesson setup

* chore(release): prepare v1.22.1

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-15 17:04:35 +02:00
przeprogramowani 56484f5856 feat(skills): guide CLI setup, filtered downloads and safe updates (#41)
* feat(skills): guide CLI setup, named downloads and updates

* fix(skills): bound npm inventory checks on cold Windows runners

* fix(skills): align launch guide with 10xCards PRD journey

* fix(tests): make helper checks portable on Windows

* test(helpers): trace Windows npm pack startup

* fix(helpers): allow bounded Windows npm startup time

* fix(helpers): use released lesson-scoped skill filters

Correct setup/guide examples and sync ownership to match CLI 1.21.
Exercise the documented preview/write commands through CAC and the
real partial writer, preserving all three trees and the PRD schema.

Refs: https://github.com/przeprogramowani/10x-cli/pull/41

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-14 10:51:38 +02:00
przeprogramowani b0c789af70 feat: enable v4 course selection and protected first-week sync (#38)
* docs(10xdevs4-cli-access): record membership gates and bootstrap context (p1)

Add canonical access plan, accepted decisions and supporting context.
Record phase 1 verification, Toolkit revision and remaining evidence gaps.

* docs(10xdevs4-cli-access): record course access gates and scoped review (p2)

Update canonical Progress, change status, evidence and implementation review.
Record Toolkit revisions, inherited typecheck limitation and phase 3 prerequisites.

* docs(10xdevs4-cli-access): persist reviewed revisions and phase 3 boundary

Record final reviewed Toolkit and CLI context revisions.
Persist Progress attribution and unresolved W04/W05/W08 prerequisites.
Keep phases 3–6, phase 7 and Manual criteria open.

* docs(10xdevs4-cli-access): record squash-safe source prerequisite

Record PR #30, verified gates, permanent-pin lessons and the remaining merge dependency.
Keep phase 3 and all manual rollout criteria pending.

* docs(10xdevs4-cli-access): record source prerequisite review

Record independent review of PR #30 and verified CI evidence.
Keep the master pin and delivery phase completion pending.

* docs(10xdevs4-cli-access): distinguish candidate checks from final master pins

Record passing pre-merge v4 checks and defer workflow suspension.
Keep the final v3 maintenance pin dependent on the resulting master SHA.

* feat: prepare v4 course delivery and protected project sync

Capture the reviewed implementation and manual rehearsal for draft PR review. Master source prerequisites, full clean verification and coordinated Windows CI remain open; production rollout is separate.

* fix: keep paid CI evidence private and converge cumulative sync

* docs: record merged source prerequisite and passing clean gate

* fix: preserve generated API type line endings on Windows

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-13 09:24:16 +02:00
psmyrdek 8a6a32aca1 feat(tool-profiles): replace Windsurf with Devin Desktop 2026-08-20 10:21:18 +02:00
“mkczarkowski” 2993481628 fix(disable-course-rules): address impl-review F1/F2
F1: updateToolConfig now throws when the merged config has no `tool`
instead of silently persisting an invalid object a later read rejects
wholesale (dropping lang/acknowledgedOrphans).

F2: add command-level course-rules tests — strip-after-apply with
surrounding-content preservation, the human [removed] rules render
line, and the positive --course-rules CAC parse guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:30:43 +02:00
“mkczarkowski” 6fb6ed6890 feat(disable-course-rules): command wiring, resolution & output (p3)
- src/commands/get.ts: register --no-course-rules, add tri-state
  resolveCourseRulesFlag (argv peek), merge-safe persistence via
  updateToolConfig (folds --lang persist, skips under --dry-run),
  explicit --type rules override, output (counts.rules 0 + [removed] line)
- tests/get-command.test.ts: resolver unit + opt-out/override/persist/dry-run
  integration; runGet mirrors process.argv
- README.md, CLAUDE.md: document the flag, persistence & override precedence

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:30:43 +02:00
“mkczarkowski” e0b122c8a2 test(user-edit-protection): comprehensive behavior tests (p4)
- Conflict detection: clean update, user edit, matching edit, each resolution
- v2 manifest upgrade: false positive on diff, clean match, v3 upgrade, 3-way after upgrade
- Removal tracking: skill/prompt removals, empty on fresh, dry-run populates
- Hash persistence: stored after apply, preserved on skip, updated on overwrite/save_user
- Non-TTY conflict resolver: always skips without prompting
- Update get-command test types for new counts.removals field

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 18:28:52 +02:00
“mkczarkowski” 802ea46a63 feat(user-edit-protection): interactive prompts + output rendering (p3)
- Create conflict-prompt.ts with TTY/non-TTY conflict resolver factory
- Wire createConflictResolver and showUpgradeNotice into get command
- Add v2 manifest upgrade detection before applyBundle
- Render [removed] lines for skill/prompt/config removals
- Render conflict-specific action labels (conflict: overwritten/saved .user/skipped)
- Add removals to JSON output envelope with counts.removals
- Update get-command test for new counts shape

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 18:23:59 +02:00
“mkczarkowski” 3d6aa64040 feat(get): persist --tool choice as user default
When --tool is passed to resolveToolProfile(), save the choice to
config.json so future invocations default to it. Shows a stderr
confirmation on TTY when the default actually changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 13:16:34 +02:00
“mkczarkowski” f05ee31634 fix(windows-compatibility): normalize path separators in test assertions
Use path.join() instead of hardcoded forward slashes for path assertions
that compare absolute paths on Windows (backslash vs forward slash).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:33:02 +02:00
“mkczarkowski” a0832349f0 fix(windows-compatibility): cross-platform config isolation in tests
On Windows, configDir() reads APPDATA, not XDG_CONFIG_HOME. Tests that
only redirected XDG_CONFIG_HOME leaked config state across test files,
causing failures on windows-latest CI. Extract redirectConfigDir/
restoreConfigDir helper that sets both env vars, apply across all 10
test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:31:02 +02:00
“mkczarkowski” fc20d322fb feat(cli): forward ?tool= in fetchLesson to API
Pass the resolved tool profile id through fetchLesson's options bag
so the API can substitute universalContent for non-Claude learners.
Mirrors the existing fetchArtifact precedent in the same file.

- src/lib/api-content.ts: add optional tool? to fetchLesson options;
  emit ?tool= when present
- src/commands/get.ts: pass profile.toolId at both fetchLesson call
  sites (install flow + print/filter flow)
- tests/helpers/api-content-mock.ts: widen fetchLessonImpl signature
- tests/get-command.test.ts: add three propagation tests

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 15:10:11 +02:00
“mkczarkowski” ab9ee915ce feat(skill-directory-bundle): CLI schema types, writer, manifest (p4)
Update CLI to consume the new directory-shaped skill bundle:

- api-content.ts: SkillFile, SkillBundle, ArtifactResponse discriminated union
- tool-profile.ts: add skillDir(name) per profile
- manifest.ts: v2 schema (skills as Record<name, {files}>); v1 manifests rejected as null
- writer.ts: iterate skill.files[], chmod +x for executables, per-file diff/removal,
  empty parent-dir cleanup, assertSafeSkillFilePath path-traversal guard
- tool-switch.ts: migrate/delete walks every file under each skill directory
- commands/get.ts: per-file rendering for multi-file skills; print mode
  accommodates the new shape (Phase 5 polishes the stderr notice)

Tests cover: multi-file materialization with +x preservation, idempotent
re-apply, file-level removal within retained skills, v1 manifest rejection,
and path-traversal rejection ('../evil.sh', absolute, backslash, empty).
All 340 tests green; typecheck, lint, build, build:binary all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 09:24:14 +02:00
“mkczarkowski” a771f941fc feat: v1 canonical-string signing protocol and BUNDLE_PUBLIC_KEYSET override
Implement v1 signing verification (v1:<keyId>:<hash> canonical string) and
add loadEffectiveKeyset() with localhost-gated env var override for e2e testing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 10:53:01 +02:00
“mkczarkowski” 4d7375ab5b feat: add Ed25519 bundle signature verification for lesson responses
Implement client-side Ed25519 signature verification (Phase 5B) to ensure
lesson bundles haven't been tampered with between the API and CLI.
REQUIRE_SIGNATURES is set to true (fail-closed). The ApiResult type now
exposes responseHeaders so fetchLesson can extract X-Bundle-Signature
and X-Bundle-Key-Id headers for verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:16:01 +02:00
“mkczarkowski” 530592da67 feat: implement manifest tracking and sentinel migration for idempotent lesson application 2026-04-11 20:05:19 +02:00
“mkczarkowski” e289323d80 feat: phase 4 — get, list, doctor commands with consistent message UX
Core student commands plus shared supporting modules:

- lesson-ref parser: m<N>l<N>, module range 1..5 per 10xdevs3 shape
- api-content: typed wrappers for catalog/modules/lesson/health
- writer.ts: phase 4 planning stub; phase 5 swaps in real writes
- format.ts: shared formatReleaseAt (long-form English dates, UTC
  day-start snapping so "in N days" never drifts by one at midnight)

10x list accepts both '1' and 'm1' to match '10x get m1l1'. Drill-in
hints always include a concrete runnable example, picked from an
unlocked module when available so the suggested command works today.

10x doctor gains a hint field on every check result. Human report
uses Title-case labels (Auth/API/Config/Version/Claude); JSON keeps
stable lowercase names so machine consumers don't break.

Message style guide at the top of src/lib/output.ts codifies:
- never echo API machine codes ("module_locked", "not_found", ...)
  as human copy — build the sentence from payload fields
- error = what happened; hint = runnable '10x ...' command
- timestamps always through formatReleaseAt() on stderr; JSON
  consumers still get the raw ISO
- module hints show both accepted input forms so students discover
  the alternative

55 new tests, 121 total, all green. typecheck + oxlint clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:44:31 +02:00