65 Commits

Author SHA1 Message Date
github-actions[bot] 9b06113d9a chore(release): v1.3.2 v1.3.2 2026-05-16 14:09:47 +00:00
psmyrdek 4eb70c514c fix(list): hide lesson details for locked modules
The CLI was rendering real lesson titles and "TBD" summaries from
unreleased modules. Now renderModuleDetail returns lessons: [] in JSON
mode and a single "available after unlock" line in human mode when a
module is locked, regardless of what the API returns.

This is a client-side mask; the API still emits the data on the wire.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 16:08:54 +02:00
psmyrdek 95a8d4ec5e test(e2e): stop logging third-party recipients in resend poller
The first-poll diagnostic dumped the 5 most recent emails from the
shared Resend account, including their `to` field, leaking unrelated
customer addresses into CI logs. Replace with a counts-only summary
and drop the recipient from the timeout error message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:56:54 +02:00
psmyrdek 43710470c9 test(e2e): align list/get fixtures with prework-enabled catalog
list now returns module 0 (prework) first, and the shared test account
is only enrolled in module 0 — switch the get fixtures from m1l1 to
m0l1 and update the list assertion to expect module 0 at index 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:32:13 +02:00
github-actions[bot] 52b0c52ea9 chore(release): v1.3.1 v1.3.1 2026-05-16 13:23:50 +00:00
psmyrdek 8c90cac07f fix(api-client): render API errors with friendly messages
The API ships {error: "<code>"} envelopes (e.g. "course_not_found"); we
were displaying that raw, or worse, "[object Object]" when callers tried
to print the payload. Map the 16 known codes (catalogued from the
delivery API routes) to human strings, prefer the optional `message`
field on auth routes, and fall back to a mentor-facing message for
unknown codes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:23:11 +02:00
github-actions[bot] 8ac793812c chore(release): v1.3.0 v1.3.0 2026-05-16 08:38:02 +00:00
psmyrdek f8859d1e28 feat(lesson-ref): allow module 0 for prework
Drop MIN_MODULE from 1 to 0 so parseLessonRef and parseModuleRef accept
m0/m0l1 (the 10xdevs3 prework module). Lesson numbers remain positive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 10:37:21 +02:00
“mkczarkowski” f663dc25c0 fix(ci): include version and github-release in Slack failure check
The notify-slack job checked only check, e2e, and publish-npm but
missed version and github-release from its needs list. A failure in
either would show a green notification and skip #alerting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-12 15:25:43 +02:00
“mkczarkowski” 54d7e6228d feat(ci): add debugging links to #alerting notifications
Adds context row with quick links: commit diff, full logs, npm package.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 19:22:20 +02:00
“mkczarkowski” b2d78557de style(ci): redesign Slack notifications with emojis and block formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 19:06:02 +02:00
“mkczarkowski” 3d00d01fce feat(ci): split Slack to #observability + #alerting channels
- notify-slack: success → #observability, failure → both channels

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 18:50:26 +02:00
“mkczarkowski” 819248c081 feat(ci): add Slack notifications for pipeline results
- notify-slack job posts pipeline summary to #ci-deploys on master push
- Shows: tests, e2e, version, npm publish, GitHub release status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 18:34:23 +02:00
“mkczarkowski” b26c75350d ci: trigger e2e after API rate-limit bypass deploy 2026-05-10 16:24:08 +02:00
“mkczarkowski” 56560edbdc fix(e2e): gracefully skip tests on auth rate-limit instead of failing
When the backend rate-limits magic-link requests (e.g. from CI re-runs),
tests now skip with a clear message rather than hard-failing the entire
suite. AuthRateLimitedError is caught in beforeAll and sets authSkipped
flag that each test checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 16:01:26 +02:00
“mkczarkowski” c34e5f7020 fix(e2e): avoid rate-limit by reusing shared auth singleton
auth-flow.test.ts now uses ensureSharedAuth() (single login per run)
and verifies the resulting auth.json, rather than triggering a
duplicate login that gets rate-limited by the backend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:55:37 +02:00
“mkczarkowski” 11bbfc6517 fix(e2e): include stdout in earlyExit error for JSON mode diagnostics
In --json mode the error envelope goes to stdout, not stderr. The
earlyExit handler now reports both streams so CI failures show the
actual API error message.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:53:00 +02:00
“mkczarkowski” 261d084165 fix(smoke): skip npm pack test on Windows — hangs on CI runners
npm pack --dry-run --json consistently exceeds 30s on windows-latest
runners. Since package contents are platform-independent, this test
only needs to run on Ubuntu (check job).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:50:03 +02:00
“mkczarkowski” 8a48fc7e70 fix(smoke): increase npm pack timeout for Windows CI runners
npm pack --dry-run --json takes >15s on windows-latest runners.
Bump timeout from 15s to 30s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:43:14 +02:00
“mkczarkowski” e77b26ca8d fix(smoke): Windows CI — cross-platform tmp path and relaxed startup budget
- auto-version.mjs: use os.tmpdir() instead of hardcoded /tmp/ for
  release-notes.md (Windows has no /tmp)
- binary.test.ts: raise startup budget to 150ms on Windows (CI runners
  have slower process spawn overhead)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:41:09 +02:00
“mkczarkowski” 28d66a3b31 fix(smoke): cross-platform auto-version tests — use Node.js fs APIs
Shell commands like `echo '...' > file` and `cp` don't work on Windows.
Replace with writeFileSync, appendFileSync, and copyFileSync so the
auto-version smoke tests pass on both unix and Windows CI runners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:38:10 +02:00
“mkczarkowski” 06d841f27a fix(e2e): review fixes — kill timer, fetch check, temp cleanup, earlyExit race
- cli.ts: add 60s kill timer to spawnCli, export cleanupTempDirs()
- auth-flow.test.ts: add earlyExit Promise.race + callback response check
- auth-setup.ts: check callback response status
- doctor.test.ts: use getE2EEnv().testEmail instead of hardcoded string
- all test files: add afterAll(cleanupTempDirs) hooks
- reviews/impl-review.md: save full review report

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:31:42 +02:00
“mkczarkowski” 3ce2819345 chore(e2e): close out plan (epilogue)
- plan.md: write SHA e95e9a0 to phase 5 progress rows
- change.md: status → implemented

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:18:04 +02:00
“mkczarkowski” e95e9a0c78 feat(e2e): CI workflow — e2e jobs and Windows smoke tests (p5)
- .github/workflows/ci.yml: add e2e + e2e-windows jobs with Resend secrets,
  extend check-windows with build:binary + smoke tests
- docs/reference/platform-support.md: update CI testing table to match reality
- context/changes/e2e/plan.md: mark phase 5 automated steps complete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:16:12 +02:00
“mkczarkowski” b12e8ff572 feat(e2e): authenticated command tests — doctor, list, get (p4)
Files: tests/e2e/doctor.test.ts, tests/e2e/list.test.ts,
tests/e2e/get.test.ts, tests/e2e/support/auth-setup.ts,
context/changes/e2e/plan.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 15:08:27 +02:00
“mkczarkowski” d97ed75678 feat(e2e): auth flow e2e test with Resend magic-link verification (p3)
Files: tests/e2e/auth-flow.test.ts, tests/e2e/support/auth-setup.ts,
context/changes/e2e/plan.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 14:49:37 +02:00
“mkczarkowski” 9ec3798294 feat(e2e): auth-free e2e tests — global flags and unauthenticated auth (p2)
Files: tests/e2e/global-flags.test.ts, tests/e2e/auth-no-credentials.test.ts,
context/changes/e2e/plan.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 14:36:09 +02:00
“mkczarkowski” 40454c4eca feat(e2e): e2e infrastructure — spawn helper, Resend utility, env config (p1)
Files: tests/e2e/support/cli.ts, tests/e2e/support/env.ts,
tests/e2e/support/resend-magic-links.ts, tests/e2e/.env.test.example,
.gitignore, context/changes/e2e/{change,research,plan}.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 14:33:13 +02:00
“mkczarkowski” c9817b8737 fix: quote YAML frontmatter description in 10x-cli-guide
Colons in the unquoted description value broke GitHub's YAML parser.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 16:25:46 +02:00
“mkczarkowski” d5b1f3bf65 docs: update platform-support with PowerShell clipboard and CI matrix
Add PowerShell Set-Clipboard to clipboard table, expand CI testing
section with unit+e2e matrix for both Ubuntu and Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 16:20:25 +02:00
“mkczarkowski” e7b64c628b feat(windows-compatibility): PowerShell CI and platform-support docs
Switch Windows CI job to native PowerShell with Get-ChildItem for test
file enumeration (no glob expansion needed). Add platform-support
reference doc for learners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:44:46 +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” f1c5daaa79 fix(ci): use bash shell for Windows CI job
PowerShell does not expand glob patterns — use Git Bash (available on
all GitHub Actions Windows runners) so tests/*.test.ts resolves.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:14:18 +02:00
“mkczarkowski” d4b4b5ab2e fix(ci): use ./ prefix for bun test glob on Windows
PowerShell does not expand bare globs — bun test needs ./tests/*.test.ts
to resolve the path on Windows runners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:12:50 +02:00
github-actions[bot] f2a06468d6 chore(release): v1.2.0 v1.2.0 2026-05-09 13:10:52 +00:00
“mkczarkowski” 6c89834a3e feat(windows-compatibility): Windsurf profile, tool-aware doctor, CLI guide skill (p4)
Add Windsurf tool profile with detection (.windsurfrules, .windsurf/).
Make doctor check the configured tool's directory instead of hardcoded
.claude/. Add 10x-cli-guide skill for OS- and tool-aware daily usage
guidance. Add Cursor and Windsurf MCP config templates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:10:11 +02:00
“mkczarkowski” 1178bc13a8 feat(windows-compatibility): cross-platform test fixes and Windows CI (p3)
Replace macOS-specific patterns in tests (hardcoded /tmp, mktemp -d,
rm -rf, 2>/dev/null) with Node APIs (os.tmpdir, mkdtempSync, rmSync,
stdio pipes). Add platform guards for POSIX mode-bit assertions. Add
check-windows CI job. Document npx zero-install and Node 20+ requirement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:10:11 +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
github-actions[bot] 2305f64048 chore(release): v1.1.0 v1.1.0 2026-05-03 07:25:33 +00:00
“mkczarkowski” 075fd7ddef chore(skill-directory-bundle): prep CLI v1.0.0 release (p6)
Bump version 0.5.0 → 1.0.0 and add CHANGELOG entry for the directory-shaped
skill bundle. The CLI is functionally complete on master (commits 09a60c5,
afb9c48); this commit only stages the release metadata. `npm publish` is a
follow-up action — not run from this commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 09:24:56 +02:00
“mkczarkowski” 3ce857259d feat(skill-directory-bundle): CLI print-mode multi-file notice (p5)
In --print human mode, a skill's SKILL.md still goes to stdout, but every
non-SKILL.md file under the skill directory is now surfaced on stderr as a
"Note: skill X has N additional files not shown in --print: ..." line so
students don't assume the print output is the entire skill. JSON mode is
unchanged (the full files[] array is already in the response).

Touched:
- src/commands/get.ts: emitMultiFileSkillNotice() called from both single-
  artifact (--name) and multi-skill (no --name) print paths.
- tests/print-mode.test.ts: 4 new cases covering single-file no-notice,
  multi-file notice content, JSON-mode silence, and per-skill iteration
  in the no-name flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 09:24:14 +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
github-actions[bot] 65b837e3fc chore(release): v0.6.0 v0.6.0 2026-04-20 08:47:24 +00:00
“mkczarkowski” 1414b2e6c2 feat(cli): tool-switch migration flow with sentinel cleanup
Wave 2.1 PR2 closes the UX gap where students who switch tools would
silently accumulate orphan artifacts from their old profile. When
resolveToolProfile settles on a new tool and a prior tool's manifest
exists under a different manifestDir, the CLI now prompts once per
orphan: migrate (recommended), remove 10x artifacts, or keep both
(don't ask again).

- findOrphanedManifests in writer.ts returns structured OrphanInfo
  (profile, manifestPath, parsed manifest). Corrupt manifests are
  skipped so migration never moves files without a file list.
- ToolConfig gains acknowledgedOrphans: string[] with shape validation
  on read; readToolConfig drops the field when it isn't a string array.
- tool-switch.ts implements migrateArtifacts and deleteArtifacts:
    - isSafeName gate on every manifest entry (skills, prompts, configs)
      before any filesystem operation.
    - moveIfSafe refuses symlinked sources, compares existing destinations
      byte-for-byte (readFileSync + Buffer.equals) so two distinct binary
      payloads that decode to U+FFFD never collapse as equal.
    - EXDEV cross-device fallback writes to <to>.tmp then renames into
      place; post-copy rmSync failure is reported via summary.skipped
      while still counting the file as moved. Non-EXDEV rename errors
      propagate.
    - deleteArtifacts scopes removal to the 10x-written surface — a
      Copilot orphan no longer wipes .github/workflows; only manifest-
      listed files plus the now-empty skills/prompts/config-templates
      subdirs are removed. Partial-failure contract documented.
- removeRulesBlockWithMarkers in sentinel-migration.ts strips the 10x
  block from the old rules file, collapsing the splice to at most one
  blank line and handling CRLF endings. Symmetric to
  applyRulesBlockWithMarkers; apply + remove round-trips cleanly.
- tool-prompt.ts wires handleToolSwitch into resolveToolProfile for TTY
  flows; the "keep" branch spreads the existing config so unknown
  fields (future CLI versions, hand-edits) survive. The first-run
  prompt's saveToolConfig also spreads existing config.
- commands/get.ts keeps the legacy verbose orphan warning for non-TTY
  paths (CI, Docker); TTY flows get the interactive prompt instead.
- config.ts: writeJsonAtomic shared tmp+rename helper used by both
  saveAuth and saveToolConfig — saveToolConfig is now atomic too, so a
  crash mid-write can no longer corrupt acknowledgedOrphans state.
- fs-utils.ts: readFileOrNull hoisted out of tool-switch for reuse.

Plans:
- thoughts/shared/plans/2026-04-17-wave2.1-cli-polish.md (Phases 3-4)
- thoughts/shared/plans/2026-04-19-wave2.1-cli-polish-review-fixes.md
- thoughts/shared/plans/2026-04-20-wave2.1-cli-polish-review-fixes-review-fixes.md

bun test: 328 pass, 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:16:25 +02:00
“mkczarkowski” 857a825da6 feat(cli): auto-detect tool profile and add coherence invariants
Wave 2.1 PR1 lands two low-risk CLI polish items ahead of the prework
release so first-run students benefit from a smarter default and the
profile layer gains a drift-safety net.

- Auto-detection: scan the project root for tool-native markers
  (.cursor/rules, .claude/, CLAUDE.md, .github/copilot-instructions.md,
  AGENTS.md, .agents/, .ai/) and rank signals by confidence. The
  interactive first-run prompt pre-fills initialValue with the detected
  tool and prints a "Detected: <tool> (<reason>)" hint. User still
  confirms — no silent selection. Non-TTY paths are unchanged.
- Coherence invariants: SENTINEL_BEGIN/END hoisted to shared constants;
  every profile now references them. New describe block asserts 7
  invariants (paths rooted under manifestDir, safe leaf names, non-empty
  rulesFile, identical sentinels, unique manifestDir, unique toolId,
  non-empty displayName) so refactors fail fast on CI.

Plan: thoughts/shared/plans/2026-04-17-wave2.1-cli-polish.md (Phases 1-2)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:15:40 +02:00
github-actions[bot] 2047f6dad4 chore(release): v0.5.0 v0.5.0 2026-04-16 13:40:05 +00:00
Przemek Smyrdek 3bab69841f feat: add 10x-cli-setup skill for README-driven CLI configuration (#1)
* feat: add 10x-cli-setup skill for README-driven CLI configuration

Add a skill that fetches the latest README from GitHub and walks users
through installing, authenticating, and configuring 10x-cli. Include
skills/ directory in npm package files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add Agentic Installation section to README

Document how to install the 10x-cli-setup skill via skills.sh,
enabling AI agents to handle CLI setup automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 15:39:24 +02:00
github-actions[bot] 90ee5c7dae chore(release): v0.4.0 v0.4.0 2026-04-16 09:05:54 +00: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