@przeprogramowani/10x-cli 1.25.0 → 1.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -101,10 +101,10 @@ separate project from public copies, after setup/auth:
101
101
  10x_cli() { npx --yes "@przeprogramowani/10x-cli@$CLI_VERSION" "$@"; }
102
102
  10x_cli --version
103
103
  10x_cli get --help
104
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl --dry-run
105
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl
106
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl --dry-run
107
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl
104
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl --dry-run
105
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl
106
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl --dry-run
107
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl
108
108
  ```
109
109
 
110
110
  Source membership does not prove publication. Confirm skill-filter support and direct
@@ -123,27 +123,29 @@ per-skill unregister is promised. See the compatibility reference for details.
123
123
  ## Quick Start
124
124
 
125
125
  Use an existing verified global/standalone `10x`, or the pinned `10x_cli` runner
126
- above. Retain your v3 project and use a separate v4 exercise directory. After
127
- checking skill-filter capability and content availability. Sync later refreshes
126
+ above. Retain your v3 project and use a separate v4 exercise directory. Leave
127
+ `--course` out: an unbound directory takes the highest edition your account can
128
+ reach, a bound one keeps its own, and `10x doctor` reports which edition this
129
+ project is on. After checking skill-filter capability and content availability. Sync later refreshes
128
130
  whole downloaded lessons, so inspect its preview and accept any additional
129
131
  artifacts/rules before applying; repeat a skill filter for a narrow update:
130
132
 
131
133
  ```bash
132
134
  10x_cli auth --status
133
135
  # If login is needed: 10x_cli auth (email or Circle); see auth commands below.
134
- 10x_cli list --course 10xdevs4
135
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
136
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
137
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
138
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
139
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
140
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
141
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
142
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
136
+ 10x_cli list
137
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
138
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
139
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
140
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
141
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
142
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
143
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
144
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
143
145
  # Follow the guide: read each installed SKILL.md and references, then
144
146
  # init → shape with the learner’s 10xCards inputs → PRD from approved notes.
145
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
146
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
147
+ 10x_cli sync --tool claude-code --lang pl --dry-run
148
+ 10x_cli sync --tool claude-code --lang pl
147
149
  10x_cli doctor
148
150
  ```
149
151
 
package/dist/index.mjs CHANGED
@@ -3183,7 +3183,7 @@ var cac = (name = "") => new CAC(name);
3183
3183
  // package.json
3184
3184
  var package_default = {
3185
3185
  name: "@przeprogramowani/10x-cli",
3186
- version: "1.25.0",
3186
+ version: "1.25.2",
3187
3187
  description: "Open-source CLI for 10xDevs course content",
3188
3188
  repository: {
3189
3189
  type: "git",
@@ -3359,6 +3359,7 @@ function updateToolConfig(patch) {
3359
3359
  import { hostname as osHostname, release as osRelease } from "node:os";
3360
3360
 
3361
3361
  // src/lib/api-client.ts
3362
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
3362
3363
  var DEFAULT_API_BASE = "https://10x-toolkit-api.przeprogramowani.workers.dev";
3363
3364
  var PROD_HOSTNAME = "10x-toolkit-api.przeprogramowani.workers.dev";
3364
3365
  var DEV_HOSTNAMES = new Set(["localhost", "127.0.0.1"]);
@@ -3401,6 +3402,7 @@ var ERROR_CODE_MESSAGES = {
3401
3402
  module_locked: "This module is not available yet.",
3402
3403
  signing_failed: "Could not sign the download URL. Try again in a moment.",
3403
3404
  invalid_json: "The server received a malformed request.",
3405
+ email_changed: "Your email changed. Run `10x auth` to sign in again.",
3404
3406
  unauthorized: "You are not signed in. Run `10x auth` first.",
3405
3407
  no_membership: "No active course membership was found for this email.",
3406
3408
  invalid_refresh_token: "Your session has expired. Run `10x auth` again.",
@@ -3423,8 +3425,9 @@ function messageForApiError(payload) {
3423
3425
  if (typeof payload.message === "string" && payload.message.length > 0) {
3424
3426
  return payload.message;
3425
3427
  }
3426
- if (typeof payload.error === "string" && payload.error.length > 0) {
3427
- return ERROR_CODE_MESSAGES[payload.error];
3428
+ const code = payload.code ?? payload.error;
3429
+ if (typeof code === "string" && code.length > 0) {
3430
+ return ERROR_CODE_MESSAGES[code];
3428
3431
  }
3429
3432
  return;
3430
3433
  }
@@ -3471,6 +3474,21 @@ async function request(method, path, body, options = {}) {
3471
3474
  }
3472
3475
  if (!response.ok) {
3473
3476
  const payload = parsed && typeof parsed === "object" ? parsed : undefined;
3477
+ if ((payload?.code ?? payload?.error) === "email_changed" && options.token && readAuth()?.access_token === options.token) {
3478
+ try {
3479
+ const release = await import_proper_lockfile.default.lock(authFilePath(), {
3480
+ realpath: false,
3481
+ stale: 1e4,
3482
+ retries: { retries: 5, factor: 2, minTimeout: 100, maxTimeout: 1000 }
3483
+ });
3484
+ try {
3485
+ if (readAuth()?.access_token === options.token)
3486
+ deleteAuth();
3487
+ } finally {
3488
+ await release();
3489
+ }
3490
+ } catch {}
3491
+ }
3474
3492
  const mapped = messageForApiError(payload);
3475
3493
  let errorMessage;
3476
3494
  if (mapped) {
@@ -3490,7 +3508,13 @@ async function request(method, path, body, options = {}) {
3490
3508
  payload
3491
3509
  };
3492
3510
  }
3493
- return { ok: true, status: response.status, data: parsed, responseHeaders: response.headers, rawBody: text };
3511
+ return {
3512
+ ok: true,
3513
+ status: response.status,
3514
+ data: parsed,
3515
+ responseHeaders: response.headers,
3516
+ rawBody: text
3517
+ };
3494
3518
  }
3495
3519
  function apiGet(path, options = {}) {
3496
3520
  return request("GET", path, undefined, options);
@@ -3652,7 +3676,7 @@ async function pollCircleLogin(deviceCode, options = {}) {
3652
3676
  }
3653
3677
 
3654
3678
  // src/lib/auth-guard.ts
3655
- var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
3679
+ var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
3656
3680
  import { mkdirSync as mkdirSync2 } from "node:fs";
3657
3681
  import { dirname } from "node:path";
3658
3682
 
@@ -3727,7 +3751,7 @@ function isNearExpiry(auth, windowMs = DEFAULT_REFRESH_WINDOW_MS, now = new Date
3727
3751
  async function acquireRefreshLock(ctx, lockTarget) {
3728
3752
  try {
3729
3753
  mkdirSync2(dirname(lockTarget), { recursive: true });
3730
- return await import_proper_lockfile.default.lock(lockTarget, {
3754
+ return await import_proper_lockfile2.default.lock(lockTarget, {
3731
3755
  realpath: false,
3732
3756
  stale: LOCK_STALE_MS,
3733
3757
  retries: {
@@ -3785,6 +3809,12 @@ async function requireAuth(ctx, options = {}) {
3785
3809
  persist(next);
3786
3810
  return next;
3787
3811
  }
3812
+ if (refreshed.code === "email_changed") {
3813
+ try {
3814
+ (options.remove ?? deleteAuth)();
3815
+ } catch {}
3816
+ outputError(ctx, "email_changed", "Your email changed. Sign in again.", ExitCodes.AUTH_REQUIRED, "Run '10x auth' to log in.");
3817
+ }
3788
3818
  if (forced) {
3789
3819
  outputError(ctx, refreshed.code, refreshed.error, refreshed.status === 403 ? ExitCodes.FORBIDDEN : refreshed.status === 401 ? ExitCodes.AUTH_REQUIRED : ExitCodes.ERROR);
3790
3820
  }
@@ -6299,11 +6329,10 @@ import {
6299
6329
  } from "node:fs";
6300
6330
  import { dirname as dirname4, join as join8 } from "node:path";
6301
6331
  var CLI_VERSION = package_default.version;
6302
- var DEFAULT_COURSE = "10xdevs3";
6303
- async function applyBundle(bundle, projectRoot, options = {}) {
6332
+ async function applyBundle(bundle, projectRoot, options) {
6304
6333
  const dryRun = options.dryRun === true;
6305
6334
  const partial = options.partial === true;
6306
- const course = options.course ?? DEFAULT_COURSE;
6335
+ const course = options.course;
6307
6336
  const profile = options.profile ?? PROFILES[DEFAULT_TOOL];
6308
6337
  const applyCourseRules = options.applyCourseRules !== false;
6309
6338
  const plan = planBundle(bundle, projectRoot, { course, profile, applyCourseRules });
@@ -6501,11 +6530,11 @@ async function applyBundle(bundle, projectRoot, options = {}) {
6501
6530
  persist();
6502
6531
  return result;
6503
6532
  }
6504
- function planBundle(bundle, projectRoot, options = {}) {
6533
+ function planBundle(bundle, projectRoot, options) {
6505
6534
  const profile = options.profile ?? PROFILES[DEFAULT_TOOL];
6506
6535
  const applyCourseRules = options.applyCourseRules !== false;
6507
6536
  validateBundlePayload(bundle);
6508
- if (options.course && bundle.course !== undefined && bundle.course !== options.course)
6537
+ if (bundle.course !== undefined && bundle.course !== options.course)
6509
6538
  throw new Error("Bundle course differs from selected project course");
6510
6539
  for (const skill of bundle.skills) {
6511
6540
  assertSafeName(skill.name, "skill");
@@ -7422,13 +7451,7 @@ function formatAction(action) {
7422
7451
  return action;
7423
7452
  }
7424
7453
  }
7425
- function renderGetResult(ctx, bundle, writeResult, dryRun, profile, langMeta = {
7426
- course: "10xdevs3",
7427
- selectionReason: "backend_recommendation",
7428
- language: "en",
7429
- languageFallback: false,
7430
- applyCourseRules: true
7431
- }) {
7454
+ function renderGetResult(ctx, bundle, writeResult, dryRun, profile, langMeta) {
7432
7455
  const applyCourseRules = langMeta.applyCourseRules;
7433
7456
  const totalRemovals = [...writeResult.removals.skills, ...writeResult.removals.prompts, ...writeResult.removals.configs].filter((entry) => entry.action === "removed").length;
7434
7457
  if (ctx.json) {
@@ -7598,10 +7621,14 @@ a magic link sent by email or a Circle message (\`--method email\` /
7598
7621
  on the user's behalf without their authorization. Never read out \`auth.json\`,
7599
7622
  tokens, magic-link URLs or email contents. Summarize only session/access state.
7600
7623
 
7601
- Then use the selected runner's \`list --course 10xdevs4\` (or the user's explicit
7602
- course). Distinguish no membership, unpublished course, locked module and network
7624
+ Then use the selected runner's bare \`list\`: with no \`--course\` the CLI takes the
7625
+ edition from the project's \`.10x-cli.json\` binding, or, in a directory that is not
7626
+ bound yet, from the live API recommendation (the highest edition the account can
7627
+ reach). Add \`--course <slug>\` only to inspect another entitled edition on purpose.
7628
+ Distinguish no membership, unpublished course, locked module and network
7603
7629
  failure. Reinstalling the CLI or selecting a different tool does not grant access.
7604
- Keep \`--course\`, \`--tool\` and \`--lang\` explicit in subsequent download/sync commands.
7630
+ Keep \`--tool\` and \`--lang\` explicit in subsequent download/sync commands and leave
7631
+ \`--course\` out, so every download stays on the project's edition.
7605
7632
 
7606
7633
  ## 4. Diagnose readiness without manufacturing a tool directory
7607
7634
 
@@ -7609,7 +7636,11 @@ Run the selected runner's \`doctor --json\`; read all of \`data.checks\` and
7609
7636
  \`data.overall\`, plus the exit status. The outer \`status: "ok"\` is an output envelope,
7610
7637
  not a promise that every check passed. Doctor uses the configured profile (or its
7611
7638
  default), so compare the reported tool with the intended one; it has no \`--tool\`
7612
- flag in the inspected baseline.
7639
+ flag in the inspected baseline. Its auth check also reports the resolved edition
7640
+ and selection reason (\`details.course\`, \`details.selectionReason\`) — use that as
7641
+ the self-check before the first download. A project is bound to one edition on its
7642
+ first write; a later edition needs a new empty directory, because writing it into a
7643
+ bound project fails with \`course_mismatch\`.
7613
7644
 
7614
7645
  In a new project before the first download, a missing \`.claude/\` (or the reported
7615
7646
  profile directory) can be expected. If that is the only failure and this is the
@@ -7723,19 +7754,27 @@ substitute its exact executable for \`10x_cli\`; no reinstall is required.
7723
7754
  10x_cli sync --help
7724
7755
  10x_cli auth --help
7725
7756
  10x_cli auth --status
7726
- 10x_cli list --course 10xdevs4
7757
+ 10x_cli list
7727
7758
  \`\`\`
7728
7759
 
7729
7760
  Run commands from the intended project root. The target guided context is
7730
- \`--course 10xdevs4 --tool claude-code --lang pl\`; preserve it in downloads,
7731
- previews, updates and recovery. \`list\` takes \`--course\`, not tool/lang flags.
7761
+ \`--tool claude-code --lang pl\` with no \`--course\`; preserve those two flags in
7762
+ downloads, previews, updates and recovery and let the edition come from the
7763
+ project. Pass \`--course <slug>\` only for a deliberate look at another entitled
7764
+ edition (\`list\`, \`get --print\`); \`list\` takes \`--course\`, not tool/lang flags.
7732
7765
  Use another context only when the user chose it. Record any language fallback
7733
7766
  reported by the CLI rather than calling English output Polish.
7734
7767
 
7735
7768
  The project edition is stored in \`.10x-cli.json\` after a validated write and shared
7736
7769
  across profiles; existing supported manifests also carry edition information.
7737
- Course selection is explicit flag → project edition → live API recommendation.
7738
- An explicit course does not authorize changing a bound project's edition. Retain
7770
+ Course selection is explicit flag → project edition → live API recommendation, so
7771
+ a bare command stays on the project's edition and a fresh directory gets the
7772
+ highest edition the account can reach. \`get\` prints the resolved pair
7773
+ (\`Course: 10xdevs4 (backend_recommendation)\`); \`doctor\`'s auth check reports the
7774
+ same one (\`details.course\` and \`details.selectionReason\` under \`--json\`). Read that
7775
+ instead of forcing a flag. An explicit course does not authorize changing a bound
7776
+ project's edition — writing another edition into a bound directory fails with
7777
+ \`course_mismatch\`, so a new edition belongs in a new empty directory. Retain
7739
7778
  the v3 project and start a separate v4 directory for this journey. Preserve unknown,
7740
7779
  corrupt or conflicting manifests; never delete a binding to force migration.
7741
7780
 
@@ -7827,10 +7866,10 @@ In a separate project from the public copies, or after the explicit takeover
7827
7866
  below, use the same verified \`10x_cli\` runner:
7828
7867
 
7829
7868
  \`\`\`bash
7830
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl --dry-run
7831
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl
7832
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl --dry-run
7833
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl
7869
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl --dry-run
7870
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl
7871
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl --dry-run
7872
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl
7834
7873
  \`\`\`
7835
7874
 
7836
7875
  Each successful filtered skill download should materialize
@@ -7867,14 +7906,14 @@ explicitly requested only a specific skill.
7867
7906
  content checks for each name, inspect each preview before its corresponding write:
7868
7907
 
7869
7908
  \`\`\`bash
7870
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
7871
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
7872
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
7873
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
7874
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
7875
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
7876
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
7877
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
7909
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
7910
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
7911
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
7912
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
7913
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
7914
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
7915
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
7916
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
7878
7917
  \`\`\`
7879
7918
 
7880
7919
  Require the complete four trees and inspect each installed entrypoint/reference.
@@ -7928,8 +7967,8 @@ when the user accepts that scope. For a narrow update, repeat the selected skill
7928
7967
  filter instead. Never use sync to silently bypass a missing lesson-rule prerequisite.
7929
7968
 
7930
7969
  \`\`\`bash
7931
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
7932
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
7970
+ 10x_cli sync --tool claude-code --lang pl --dry-run
7971
+ 10x_cli sync --tool claude-code --lang pl
7933
7972
  \`\`\`
7934
7973
 
7935
7974
  Normal sync refreshes downloaded owners, including the full lessons that own previously downloaded skills. Avoid \`--all\` for this small journey. Inspect updated,
@@ -8024,9 +8063,17 @@ verified global/standalone executable:
8024
8063
  10x_cli get --help
8025
8064
  10x_cli sync --help
8026
8065
  10x_cli auth --status
8027
- 10x_cli list --course 10xdevs4
8066
+ 10x_cli list
8028
8067
  \`\`\`
8029
8068
 
8069
+ Leave \`--course\` out of these commands: the CLI reads the edition from
8070
+ \`.10x-cli.json\` when the directory is already bound, otherwise from the live API
8071
+ recommendation (the highest edition the account can reach). \`get\` prints
8072
+ \`Course: <slug> (<reason>)\`; check it once before the first write. Use
8073
+ \`--course <slug>\` only to inspect another entitled edition on purpose — a bound
8074
+ project cannot be rewritten to a different edition (\`course_mismatch\`), so v4
8075
+ starts in a new empty directory.
8076
+
8030
8077
  Check source/release evidence for lesson reference, skill filter and lesson-scoped sync, then use the
8031
8078
  filtered preview below to check the endpoint. Do not treat a successful help exit as
8032
8079
  capability proof. Keep unsupported CLI syntax, unpublished/missing content, locked
@@ -8069,14 +8116,14 @@ narrower scope. After checking each name's capability and availability, download
8069
8116
  four separate complete selected skill trees. Inspect each dry-run before its corresponding write:
8070
8117
 
8071
8118
  \`\`\`bash
8072
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
8073
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
8074
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
8075
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
8076
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
8077
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
8078
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
8079
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
8119
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
8120
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
8121
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
8122
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
8123
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
8124
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
8125
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
8126
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
8080
8127
  \`\`\`
8081
8128
 
8082
8129
  Inspect each report and the complete supporting tree, not just SKILL.md. In the
@@ -8121,8 +8168,8 @@ missing prerequisite and obtain the supported route from the lesson/release owne
8121
8168
  before that step. Do not invent a rule command or download a full lesson to bypass
8122
8169
  it. Do not overwrite an existing project rule.
8123
8170
 
8124
- For browsing use \`10x_cli list m1 --course 10xdevs4\`. The commands above filter
8125
- one lesson by skill name; \`get 10x-init\` is not supported. \`--print\` is inspection:
8171
+ For browsing use \`10x_cli list m1\`. The commands above filter one lesson by skill
8172
+ name; \`get 10x-init\` is not supported. \`--print\` is inspection:
8126
8173
  TTY Markdown can contain only SKILL.md; non-TTY output is a JSON envelope. Never
8127
8174
  redirect print output into SKILL.md as a package installation.
8128
8175
 
@@ -8163,16 +8210,17 @@ two canonical output filenames instead of forcing an overwrite.
8163
8210
 
8164
8211
  ## Update
8165
8212
 
8166
- Use the same runner, directory, course, tool and language. Sync updates entire
8167
- downloaded lessons, including m1l1 after these filtered gets. Its preview may
8213
+ Use the same runner, directory, tool and language; the edition stays the project's
8214
+ own, so \`sync\` needs no \`--course\` either. Sync updates entire downloaded lessons,
8215
+ including m1l1 after these filtered gets. Its preview may
8168
8216
  include other skills, prompts, configs and course rules. Inspect that expanded
8169
8217
  scope and apply only when the user accepts it; to update only one skill, repeat
8170
8218
  its filtered preview/get instead. Do not use sync as a hidden rule prerequisite
8171
8219
  workaround:
8172
8220
 
8173
8221
  \`\`\`bash
8174
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
8175
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
8222
+ 10x_cli sync --tool claude-code --lang pl --dry-run
8223
+ 10x_cli sync --tool claude-code --lang pl
8176
8224
  \`\`\`
8177
8225
 
8178
8226
  Normal sync refreshes the full lessons recorded in the manifest, not just the
@@ -8183,9 +8231,9 @@ resource counts even if exit is 0: skipped conflicts alone are not process error
8183
8231
  Do not equate an unchanged remote digest with intact local files.
8184
8232
 
8185
8233
  For one conflicting skill, inspect the diff and back up local work before retrying
8186
- its filtered get in an interactive terminal with the same course/tool/lang. Preserve
8187
- the user's resolution choice. If a CLI hint omits context, restore these flags in
8188
- your proposed command. Never run automatic \`--force\`; it can overwrite local
8234
+ its filtered get in an interactive terminal, from the same directory and with the
8235
+ same tool/lang. Preserve the user's resolution choice. If a CLI hint omits context,
8236
+ restore these flags in your proposed command. Never run automatic \`--force\`; it can overwrite local
8189
8237
  skill/prompt edits and does not bypass protected rules or safe removal. Config
8190
8238
  templates remain create-only. Cleanup preserves modified/untracked files and
8191
8239
  files owned elsewhere; do not manually sweep a skill directory after sync.
@@ -8234,8 +8282,10 @@ other-agent walkthrough. Translate shell syntax to the user's actual shell.
8234
8282
 
8235
8283
  Run \`10x_cli doctor --json\` when diagnosis is useful; inspect its complete
8236
8284
  \`data.overall\` and \`data.checks\` as well as exit status. It checks the configured
8237
- profile, not a \`--tool\` or \`--course\` argument. Before first get, a missing tool
8238
- directory can be expected; explain only that failure and keep other failures
8285
+ profile, not a \`--tool\` or \`--course\` argument. Its auth check reports the resolved
8286
+ edition and selection reason (\`details.course\`, \`details.selectionReason\`) — that is
8287
+ the self-check for which edition this directory is on. Before first get, a missing
8288
+ tool directory can be expected; explain only that failure and keep other failures
8239
8289
  visible. Doctor exit 78 can coexist with outer JSON \`status: "ok"\`.
8240
8290
 
8241
8291
  | Symptom | Next step |
@@ -8329,19 +8379,27 @@ substitute its exact executable for \`10x_cli\`; no reinstall is required.
8329
8379
  10x_cli sync --help
8330
8380
  10x_cli auth --help
8331
8381
  10x_cli auth --status
8332
- 10x_cli list --course 10xdevs4
8382
+ 10x_cli list
8333
8383
  \`\`\`
8334
8384
 
8335
8385
  Run commands from the intended project root. The target guided context is
8336
- \`--course 10xdevs4 --tool claude-code --lang pl\`; preserve it in downloads,
8337
- previews, updates and recovery. \`list\` takes \`--course\`, not tool/lang flags.
8386
+ \`--tool claude-code --lang pl\` with no \`--course\`; preserve those two flags in
8387
+ downloads, previews, updates and recovery and let the edition come from the
8388
+ project. Pass \`--course <slug>\` only for a deliberate look at another entitled
8389
+ edition (\`list\`, \`get --print\`); \`list\` takes \`--course\`, not tool/lang flags.
8338
8390
  Use another context only when the user chose it. Record any language fallback
8339
8391
  reported by the CLI rather than calling English output Polish.
8340
8392
 
8341
8393
  The project edition is stored in \`.10x-cli.json\` after a validated write and shared
8342
8394
  across profiles; existing supported manifests also carry edition information.
8343
- Course selection is explicit flag → project edition → live API recommendation.
8344
- An explicit course does not authorize changing a bound project's edition. Retain
8395
+ Course selection is explicit flag → project edition → live API recommendation, so
8396
+ a bare command stays on the project's edition and a fresh directory gets the
8397
+ highest edition the account can reach. \`get\` prints the resolved pair
8398
+ (\`Course: 10xdevs4 (backend_recommendation)\`); \`doctor\`'s auth check reports the
8399
+ same one (\`details.course\` and \`details.selectionReason\` under \`--json\`). Read that
8400
+ instead of forcing a flag. An explicit course does not authorize changing a bound
8401
+ project's edition — writing another edition into a bound directory fails with
8402
+ \`course_mismatch\`, so a new edition belongs in a new empty directory. Retain
8345
8403
  the v3 project and start a separate v4 directory for this journey. Preserve unknown,
8346
8404
  corrupt or conflicting manifests; never delete a binding to force migration.
8347
8405
 
@@ -8433,10 +8491,10 @@ In a separate project from the public copies, or after the explicit takeover
8433
8491
  below, use the same verified \`10x_cli\` runner:
8434
8492
 
8435
8493
  \`\`\`bash
8436
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl --dry-run
8437
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl
8438
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl --dry-run
8439
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl
8494
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl --dry-run
8495
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl
8496
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl --dry-run
8497
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl
8440
8498
  \`\`\`
8441
8499
 
8442
8500
  Each successful filtered skill download should materialize
@@ -8473,14 +8531,14 @@ explicitly requested only a specific skill.
8473
8531
  content checks for each name, inspect each preview before its corresponding write:
8474
8532
 
8475
8533
  \`\`\`bash
8476
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
8477
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
8478
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
8479
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
8480
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
8481
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
8482
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
8483
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
8534
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
8535
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
8536
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
8537
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
8538
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
8539
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
8540
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
8541
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
8484
8542
  \`\`\`
8485
8543
 
8486
8544
  Require the complete four trees and inspect each installed entrypoint/reference.
@@ -8534,8 +8592,8 @@ when the user accepts that scope. For a narrow update, repeat the selected skill
8534
8592
  filter instead. Never use sync to silently bypass a missing lesson-rule prerequisite.
8535
8593
 
8536
8594
  \`\`\`bash
8537
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
8538
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
8595
+ 10x_cli sync --tool claude-code --lang pl --dry-run
8596
+ 10x_cli sync --tool claude-code --lang pl
8539
8597
  \`\`\`
8540
8598
 
8541
8599
  Normal sync refreshes downloaded owners, including the full lessons that own previously downloaded skills. Avoid \`--all\` for this small journey. Inspect updated,
@@ -8965,6 +9023,7 @@ async function syncLesson(ctx, lesson, opts) {
8965
9023
  const bundle = result.data;
8966
9024
  if (opts.dryRun) {
8967
9025
  const plan = planBundle(bundle, process.cwd(), {
9026
+ course: opts.course,
8968
9027
  profile: opts.profile,
8969
9028
  applyCourseRules: opts.applyCourseRules
8970
9029
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@przeprogramowani/10x-cli",
3
- "version": "1.25.0",
3
+ "version": "1.25.2",
4
4
  "description": "Open-source CLI for 10xDevs course content",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,9 +41,17 @@ verified global/standalone executable:
41
41
  10x_cli get --help
42
42
  10x_cli sync --help
43
43
  10x_cli auth --status
44
- 10x_cli list --course 10xdevs4
44
+ 10x_cli list
45
45
  ```
46
46
 
47
+ Leave `--course` out of these commands: the CLI reads the edition from
48
+ `.10x-cli.json` when the directory is already bound, otherwise from the live API
49
+ recommendation (the highest edition the account can reach). `get` prints
50
+ `Course: <slug> (<reason>)`; check it once before the first write. Use
51
+ `--course <slug>` only to inspect another entitled edition on purpose — a bound
52
+ project cannot be rewritten to a different edition (`course_mismatch`), so v4
53
+ starts in a new empty directory.
54
+
47
55
  Check source/release evidence for lesson reference, skill filter and lesson-scoped sync, then use the
48
56
  filtered preview below to check the endpoint. Do not treat a successful help exit as
49
57
  capability proof. Keep unsupported CLI syntax, unpublished/missing content, locked
@@ -86,14 +94,14 @@ narrower scope. After checking each name's capability and availability, download
86
94
  four separate complete selected skill trees. Inspect each dry-run before its corresponding write:
87
95
 
88
96
  ```bash
89
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
90
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
91
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
92
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
93
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
94
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
95
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
96
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
97
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
98
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
99
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
100
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
101
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
102
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
103
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
104
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
97
105
  ```
98
106
 
99
107
  Inspect each report and the complete supporting tree, not just SKILL.md. In the
@@ -138,8 +146,8 @@ missing prerequisite and obtain the supported route from the lesson/release owne
138
146
  before that step. Do not invent a rule command or download a full lesson to bypass
139
147
  it. Do not overwrite an existing project rule.
140
148
 
141
- For browsing use `10x_cli list m1 --course 10xdevs4`. The commands above filter
142
- one lesson by skill name; `get 10x-init` is not supported. `--print` is inspection:
149
+ For browsing use `10x_cli list m1`. The commands above filter one lesson by skill
150
+ name; `get 10x-init` is not supported. `--print` is inspection:
143
151
  TTY Markdown can contain only SKILL.md; non-TTY output is a JSON envelope. Never
144
152
  redirect print output into SKILL.md as a package installation.
145
153
 
@@ -180,16 +188,17 @@ two canonical output filenames instead of forcing an overwrite.
180
188
 
181
189
  ## Update
182
190
 
183
- Use the same runner, directory, course, tool and language. Sync updates entire
184
- downloaded lessons, including m1l1 after these filtered gets. Its preview may
191
+ Use the same runner, directory, tool and language; the edition stays the project's
192
+ own, so `sync` needs no `--course` either. Sync updates entire downloaded lessons,
193
+ including m1l1 after these filtered gets. Its preview may
185
194
  include other skills, prompts, configs and course rules. Inspect that expanded
186
195
  scope and apply only when the user accepts it; to update only one skill, repeat
187
196
  its filtered preview/get instead. Do not use sync as a hidden rule prerequisite
188
197
  workaround:
189
198
 
190
199
  ```bash
191
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
192
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
200
+ 10x_cli sync --tool claude-code --lang pl --dry-run
201
+ 10x_cli sync --tool claude-code --lang pl
193
202
  ```
194
203
 
195
204
  Normal sync refreshes the full lessons recorded in the manifest, not just the
@@ -200,9 +209,9 @@ resource counts even if exit is 0: skipped conflicts alone are not process error
200
209
  Do not equate an unchanged remote digest with intact local files.
201
210
 
202
211
  For one conflicting skill, inspect the diff and back up local work before retrying
203
- its filtered get in an interactive terminal with the same course/tool/lang. Preserve
204
- the user's resolution choice. If a CLI hint omits context, restore these flags in
205
- your proposed command. Never run automatic `--force`; it can overwrite local
212
+ its filtered get in an interactive terminal, from the same directory and with the
213
+ same tool/lang. Preserve the user's resolution choice. If a CLI hint omits context,
214
+ restore these flags in your proposed command. Never run automatic `--force`; it can overwrite local
206
215
  skill/prompt edits and does not bypass protected rules or safe removal. Config
207
216
  templates remain create-only. Cleanup preserves modified/untracked files and
208
217
  files owned elsewhere; do not manually sweep a skill directory after sync.
@@ -251,8 +260,10 @@ other-agent walkthrough. Translate shell syntax to the user's actual shell.
251
260
 
252
261
  Run `10x_cli doctor --json` when diagnosis is useful; inspect its complete
253
262
  `data.overall` and `data.checks` as well as exit status. It checks the configured
254
- profile, not a `--tool` or `--course` argument. Before first get, a missing tool
255
- directory can be expected; explain only that failure and keep other failures
263
+ profile, not a `--tool` or `--course` argument. Its auth check reports the resolved
264
+ edition and selection reason (`details.course`, `details.selectionReason`) — that is
265
+ the self-check for which edition this directory is on. Before first get, a missing
266
+ tool directory can be expected; explain only that failure and keep other failures
256
267
  visible. Doctor exit 78 can coexist with outer JSON `status: "ok"`.
257
268
 
258
269
  | Symptom | Next step |
@@ -66,19 +66,27 @@ substitute its exact executable for `10x_cli`; no reinstall is required.
66
66
  10x_cli sync --help
67
67
  10x_cli auth --help
68
68
  10x_cli auth --status
69
- 10x_cli list --course 10xdevs4
69
+ 10x_cli list
70
70
  ```
71
71
 
72
72
  Run commands from the intended project root. The target guided context is
73
- `--course 10xdevs4 --tool claude-code --lang pl`; preserve it in downloads,
74
- previews, updates and recovery. `list` takes `--course`, not tool/lang flags.
73
+ `--tool claude-code --lang pl` with no `--course`; preserve those two flags in
74
+ downloads, previews, updates and recovery and let the edition come from the
75
+ project. Pass `--course <slug>` only for a deliberate look at another entitled
76
+ edition (`list`, `get --print`); `list` takes `--course`, not tool/lang flags.
75
77
  Use another context only when the user chose it. Record any language fallback
76
78
  reported by the CLI rather than calling English output Polish.
77
79
 
78
80
  The project edition is stored in `.10x-cli.json` after a validated write and shared
79
81
  across profiles; existing supported manifests also carry edition information.
80
- Course selection is explicit flag → project edition → live API recommendation.
81
- An explicit course does not authorize changing a bound project's edition. Retain
82
+ Course selection is explicit flag → project edition → live API recommendation, so
83
+ a bare command stays on the project's edition and a fresh directory gets the
84
+ highest edition the account can reach. `get` prints the resolved pair
85
+ (`Course: 10xdevs4 (backend_recommendation)`); `doctor`'s auth check reports the
86
+ same one (`details.course` and `details.selectionReason` under `--json`). Read that
87
+ instead of forcing a flag. An explicit course does not authorize changing a bound
88
+ project's edition — writing another edition into a bound directory fails with
89
+ `course_mismatch`, so a new edition belongs in a new empty directory. Retain
82
90
  the v3 project and start a separate v4 directory for this journey. Preserve unknown,
83
91
  corrupt or conflicting manifests; never delete a binding to force migration.
84
92
 
@@ -170,10 +178,10 @@ In a separate project from the public copies, or after the explicit takeover
170
178
  below, use the same verified `10x_cli` runner:
171
179
 
172
180
  ```bash
173
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl --dry-run
174
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl
175
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl --dry-run
176
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl
181
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl --dry-run
182
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl
183
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl --dry-run
184
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl
177
185
  ```
178
186
 
179
187
  Each successful filtered skill download should materialize
@@ -210,14 +218,14 @@ explicitly requested only a specific skill.
210
218
  content checks for each name, inspect each preview before its corresponding write:
211
219
 
212
220
  ```bash
213
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
214
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
215
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
216
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
217
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
218
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
219
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
220
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
221
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
222
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
223
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
224
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
225
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
226
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
227
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
228
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
221
229
  ```
222
230
 
223
231
  Require the complete four trees and inspect each installed entrypoint/reference.
@@ -271,8 +279,8 @@ when the user accepts that scope. For a narrow update, repeat the selected skill
271
279
  filter instead. Never use sync to silently bypass a missing lesson-rule prerequisite.
272
280
 
273
281
  ```bash
274
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
275
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
282
+ 10x_cli sync --tool claude-code --lang pl --dry-run
283
+ 10x_cli sync --tool claude-code --lang pl
276
284
  ```
277
285
 
278
286
  Normal sync refreshes downloaded owners, including the full lessons that own previously downloaded skills. Avoid `--all` for this small journey. Inspect updated,
@@ -83,10 +83,14 @@ a magic link sent by email or a Circle message (`--method email` /
83
83
  on the user's behalf without their authorization. Never read out `auth.json`,
84
84
  tokens, magic-link URLs or email contents. Summarize only session/access state.
85
85
 
86
- Then use the selected runner's `list --course 10xdevs4` (or the user's explicit
87
- course). Distinguish no membership, unpublished course, locked module and network
86
+ Then use the selected runner's bare `list`: with no `--course` the CLI takes the
87
+ edition from the project's `.10x-cli.json` binding, or, in a directory that is not
88
+ bound yet, from the live API recommendation (the highest edition the account can
89
+ reach). Add `--course <slug>` only to inspect another entitled edition on purpose.
90
+ Distinguish no membership, unpublished course, locked module and network
88
91
  failure. Reinstalling the CLI or selecting a different tool does not grant access.
89
- Keep `--course`, `--tool` and `--lang` explicit in subsequent download/sync commands.
92
+ Keep `--tool` and `--lang` explicit in subsequent download/sync commands and leave
93
+ `--course` out, so every download stays on the project's edition.
90
94
 
91
95
  ## 4. Diagnose readiness without manufacturing a tool directory
92
96
 
@@ -94,7 +98,11 @@ Run the selected runner's `doctor --json`; read all of `data.checks` and
94
98
  `data.overall`, plus the exit status. The outer `status: "ok"` is an output envelope,
95
99
  not a promise that every check passed. Doctor uses the configured profile (or its
96
100
  default), so compare the reported tool with the intended one; it has no `--tool`
97
- flag in the inspected baseline.
101
+ flag in the inspected baseline. Its auth check also reports the resolved edition
102
+ and selection reason (`details.course`, `details.selectionReason`) — use that as
103
+ the self-check before the first download. A project is bound to one edition on its
104
+ first write; a later edition needs a new empty directory, because writing it into a
105
+ bound project fails with `course_mismatch`.
98
106
 
99
107
  In a new project before the first download, a missing `.claude/` (or the reported
100
108
  profile directory) can be expected. If that is the only failure and this is the
@@ -66,19 +66,27 @@ substitute its exact executable for `10x_cli`; no reinstall is required.
66
66
  10x_cli sync --help
67
67
  10x_cli auth --help
68
68
  10x_cli auth --status
69
- 10x_cli list --course 10xdevs4
69
+ 10x_cli list
70
70
  ```
71
71
 
72
72
  Run commands from the intended project root. The target guided context is
73
- `--course 10xdevs4 --tool claude-code --lang pl`; preserve it in downloads,
74
- previews, updates and recovery. `list` takes `--course`, not tool/lang flags.
73
+ `--tool claude-code --lang pl` with no `--course`; preserve those two flags in
74
+ downloads, previews, updates and recovery and let the edition come from the
75
+ project. Pass `--course <slug>` only for a deliberate look at another entitled
76
+ edition (`list`, `get --print`); `list` takes `--course`, not tool/lang flags.
75
77
  Use another context only when the user chose it. Record any language fallback
76
78
  reported by the CLI rather than calling English output Polish.
77
79
 
78
80
  The project edition is stored in `.10x-cli.json` after a validated write and shared
79
81
  across profiles; existing supported manifests also carry edition information.
80
- Course selection is explicit flag → project edition → live API recommendation.
81
- An explicit course does not authorize changing a bound project's edition. Retain
82
+ Course selection is explicit flag → project edition → live API recommendation, so
83
+ a bare command stays on the project's edition and a fresh directory gets the
84
+ highest edition the account can reach. `get` prints the resolved pair
85
+ (`Course: 10xdevs4 (backend_recommendation)`); `doctor`'s auth check reports the
86
+ same one (`details.course` and `details.selectionReason` under `--json`). Read that
87
+ instead of forcing a flag. An explicit course does not authorize changing a bound
88
+ project's edition — writing another edition into a bound directory fails with
89
+ `course_mismatch`, so a new edition belongs in a new empty directory. Retain
82
90
  the v3 project and start a separate v4 directory for this journey. Preserve unknown,
83
91
  corrupt or conflicting manifests; never delete a binding to force migration.
84
92
 
@@ -170,10 +178,10 @@ In a separate project from the public copies, or after the explicit takeover
170
178
  below, use the same verified `10x_cli` runner:
171
179
 
172
180
  ```bash
173
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl --dry-run
174
- 10x_cli get m1l1 --type skills --name 10x-cli-setup --course 10xdevs4 --tool claude-code --lang pl
175
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl --dry-run
176
- 10x_cli get m1l1 --type skills --name 10x-cli-guide --course 10xdevs4 --tool claude-code --lang pl
181
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl --dry-run
182
+ 10x_cli get m1l1 --type skills --name 10x-cli-setup --tool claude-code --lang pl
183
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl --dry-run
184
+ 10x_cli get m1l1 --type skills --name 10x-cli-guide --tool claude-code --lang pl
177
185
  ```
178
186
 
179
187
  Each successful filtered skill download should materialize
@@ -210,14 +218,14 @@ explicitly requested only a specific skill.
210
218
  content checks for each name, inspect each preview before its corresponding write:
211
219
 
212
220
  ```bash
213
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl --dry-run
214
- 10x_cli get m1l1 --type skills --name 10x-idea-check --course 10xdevs4 --tool claude-code --lang pl
215
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl --dry-run
216
- 10x_cli get m1l1 --type skills --name 10x-init --course 10xdevs4 --tool claude-code --lang pl
217
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl --dry-run
218
- 10x_cli get m1l1 --type skills --name 10x-shape --course 10xdevs4 --tool claude-code --lang pl
219
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl --dry-run
220
- 10x_cli get m1l1 --type skills --name 10x-prd --course 10xdevs4 --tool claude-code --lang pl
221
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl --dry-run
222
+ 10x_cli get m1l1 --type skills --name 10x-idea-check --tool claude-code --lang pl
223
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl --dry-run
224
+ 10x_cli get m1l1 --type skills --name 10x-init --tool claude-code --lang pl
225
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl --dry-run
226
+ 10x_cli get m1l1 --type skills --name 10x-shape --tool claude-code --lang pl
227
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl --dry-run
228
+ 10x_cli get m1l1 --type skills --name 10x-prd --tool claude-code --lang pl
221
229
  ```
222
230
 
223
231
  Require the complete four trees and inspect each installed entrypoint/reference.
@@ -271,8 +279,8 @@ when the user accepts that scope. For a narrow update, repeat the selected skill
271
279
  filter instead. Never use sync to silently bypass a missing lesson-rule prerequisite.
272
280
 
273
281
  ```bash
274
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl --dry-run
275
- 10x_cli sync --course 10xdevs4 --tool claude-code --lang pl
282
+ 10x_cli sync --tool claude-code --lang pl --dry-run
283
+ 10x_cli sync --tool claude-code --lang pl
276
284
  ```
277
285
 
278
286
  Normal sync refreshes downloaded owners, including the full lessons that own previously downloaded skills. Avoid `--all` for this small journey. Inspect updated,