@przeprogramowani/10x-cli 1.25.3 → 1.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -42,7 +42,7 @@ Once your release includes it, run from the intended project directory:
42
42
 
43
43
  This installs **both** `10x-cli-setup` and `10x-cli-guide`, each with its complete
44
44
  `SKILL.md` and `references/compatibility.md`, into `.github/skills/`. Use
45
- `--tool claude-code`, `cursor`, `codex`, `devin-desktop`, `gemini`, `kiro`, or `generic`
45
+ `--tool claude-code`, `cursor`, `codex`, `devin-desktop`, `factory`, `gemini`, `kiro`, or `generic`
46
46
  when that is your intended tool. The target must be explicit; installation is
47
47
  project-only. There is no `--global`, automatic agent detection, `skills`/npx
48
48
  subprocess, authentication, or network access. The helper bytes come from the
@@ -181,7 +181,7 @@ remain visible. Full lesson downloads and other commands remain available below.
181
181
 
182
182
  | Flag | Description |
183
183
  |------|-------------|
184
- | `--tool <tool>` | AI coding tool: `claude-code`, `cursor`, `copilot`, `codex`, `devin-desktop`, `gemini`, `kiro`, `generic` |
184
+ | `--tool <tool>` | AI coding tool: `claude-code`, `cursor`, `copilot`, `codex`, `devin-desktop`, `gemini`, `kiro`, `factory`, `generic` |
185
185
  | `--print` | Output artifact content to stdout instead of writing files |
186
186
  | `--type <type>` | Filter by artifact type: `skills`, `prompts`, `rules`, `configs` |
187
187
  | `--name <name>` | Filter by artifact name (requires `--type`) |
@@ -309,7 +309,7 @@ scoring live in the template and the instance.
309
309
  | Flag | Description |
310
310
  |------|-------------|
311
311
  | `--template-version <tag>` | Template tag to install (default: latest) |
312
- | `--tool <id>` | Agent tool for skill placement (`claude-code`, `cursor`, `copilot`, `codex`, `devin-desktop`, `gemini`, `kiro`, `generic`) |
312
+ | `--tool <id>` | Agent tool for skill placement (`claude-code`, `cursor`, `copilot`, `codex`, `devin-desktop`, `gemini`, `kiro`, `factory`, `generic`) |
313
313
  | `--yes` | Run non-interactively, accepting defaults |
314
314
  | `--deep` | Clone the detected base repo with full history (default: shallow, HEAD only) |
315
315
 
@@ -363,6 +363,7 @@ On first run, the CLI prompts you to choose your AI coding tool. Artifacts are w
363
363
  | Devin Desktop | `.devin/` | `AGENTS.md` |
364
364
  | Gemini CLI | `.gemini/` | `GEMINI.md` |
365
365
  | Kiro | `.kiro/` | `AGENTS.md` |
366
+ | Factory AI | `.factory/` | `AGENTS.md` |
366
367
  | Generic | `.ai/` | `AGENTS.md` |
367
368
 
368
369
  Override with `--tool <name>`. Validated writing commands save your choice in `~/.config/10x-cli/config.json`. Previews leave it unchanged.
@@ -370,6 +371,20 @@ The former `windsurf` ID remains accepted as an alias and is upgraded to
370
371
  `devin-desktop`; existing `.windsurf/` artifacts can be migrated by the normal
371
372
  tool-switch prompt.
372
373
 
374
+ Factory AI stores skills in `.factory/skills/`, prompts in
375
+ `.factory/commands/<name>.md` as custom slash commands, and config templates in
376
+ `.factory/config-templates/`. Prompt names and bytes are preserved. Config
377
+ templates are only a staging location; the CLI does not activate or merge them.
378
+ Factory requests the generic content variant from the delivery API while its
379
+ manifest records `factory`. It is auto-detected from `.factory/` (including its
380
+ manifest, `skills/`, or `commands/`); `AGENTS.md` alone does not identify
381
+ Factory.
382
+
383
+ Factory shares root `AGENTS.md` with Codex CLI, Devin Desktop, Kiro, and Generic.
384
+ The managed course-rules block can be shared only when its bytes are identical.
385
+ Factory and Generic use the same generic content, but incompatible Codex or
386
+ Devin rules stay protected even when an overwrite is requested.
387
+
373
388
  ## Development
374
389
 
375
390
  ```bash
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.3",
3186
+ version: "1.26.1",
3187
3187
  description: "Open-source CLI for 10xDevs course content",
3188
3188
  repository: {
3189
3189
  type: "git",
@@ -4725,6 +4725,19 @@ var PROFILES = {
4725
4725
  sentinelBegin: SENTINEL_BEGIN,
4726
4726
  sentinelEnd: SENTINEL_END
4727
4727
  },
4728
+ factory: {
4729
+ toolId: "factory",
4730
+ contentToolId: "generic",
4731
+ displayName: "Factory AI",
4732
+ skillPath: (n) => `.factory/skills/${n}/SKILL.md`,
4733
+ skillDir: (n) => `.factory/skills/${n}`,
4734
+ promptPath: (n) => `.factory/commands/${n}.md`,
4735
+ configPath: (n) => `.factory/config-templates/${n}`,
4736
+ rulesFile: "AGENTS.md",
4737
+ manifestDir: ".factory",
4738
+ sentinelBegin: SENTINEL_BEGIN,
4739
+ sentinelEnd: SENTINEL_END
4740
+ },
4728
4741
  gemini: {
4729
4742
  toolId: "gemini",
4730
4743
  displayName: "Gemini CLI",
@@ -5184,6 +5197,21 @@ function detectTools(projectRoot) {
5184
5197
  reason: ".windsurf/ directory (legacy)"
5185
5198
  });
5186
5199
  }
5200
+ if (hit(".factory/" + MANIFEST_FILENAME)) {
5201
+ signals.push({
5202
+ profileId: "factory",
5203
+ confidence: "strong",
5204
+ reason: ".factory/.10x-cli-manifest.json"
5205
+ });
5206
+ } else if (hit(".factory/commands")) {
5207
+ signals.push({ profileId: "factory", confidence: "strong", reason: ".factory/commands/" });
5208
+ } else if (hit(".factory/droids")) {
5209
+ signals.push({ profileId: "factory", confidence: "strong", reason: ".factory/droids/" });
5210
+ } else if (hit(".factory/skills")) {
5211
+ signals.push({ profileId: "factory", confidence: "strong", reason: ".factory/skills/" });
5212
+ } else if (hit(".factory")) {
5213
+ signals.push({ profileId: "factory", confidence: "strong", reason: ".factory/ directory" });
5214
+ }
5187
5215
  if (hit(".gemini/" + MANIFEST_FILENAME)) {
5188
5216
  signals.push({
5189
5217
  profileId: "gemini",
@@ -5236,6 +5264,7 @@ var PROFILE_ORDER = [
5236
5264
  "copilot",
5237
5265
  "codex",
5238
5266
  "devin-desktop",
5267
+ "factory",
5239
5268
  "gemini",
5240
5269
  "kiro",
5241
5270
  "generic"
@@ -7187,7 +7216,7 @@ function resolveCourseRulesFlag(argv) {
7187
7216
  return;
7188
7217
  }
7189
7218
  function registerGetCommand(cli) {
7190
- cli.command("get <ref>", "Fetch and apply a lesson pack").option("--dry-run", "Show what would be written without touching the filesystem").option("--course <course>", "Select course ID or slug (default: project edition or API recommendation)").option("--tool <tool>", "AI coding tool (claude-code, cursor, copilot, codex, devin-desktop, gemini, kiro, generic)").option("--print", "Print artifact content to stdout instead of writing to files").option("--type <type>", "Artifact type filter: skills, prompts, rules, configs").option("--name <name>", "Artifact name filter (requires --type)").option("--lang <lang>", "Content language: en (default) or pl").option("--no-course-rules", "Skip applying the course rules block to your rules file (CLAUDE.md/AGENTS.md)").action(async (ref, options) => {
7219
+ cli.command("get <ref>", "Fetch and apply a lesson pack").option("--dry-run", "Show what would be written without touching the filesystem").option("--course <course>", "Select course ID or slug (default: project edition or API recommendation)").option("--tool <tool>", "AI coding tool (claude-code, cursor, copilot, codex, devin-desktop, factory, gemini, kiro, generic)").option("--print", "Print artifact content to stdout instead of writing to files").option("--type <type>", "Artifact type filter: skills, prompts, rules, configs").option("--name <name>", "Artifact name filter (requires --type)").option("--lang <lang>", "Content language: en (default) or pl").option("--no-course-rules", "Skip applying the course rules block to your rules file (CLAUDE.md/AGENTS.md)").action(async (ref, options) => {
7191
7220
  const ctx = resolveContext(options);
7192
7221
  await runGet(ctx, ref, options);
7193
7222
  });
@@ -8857,7 +8886,7 @@ function isLessonFresh(root, manifest, id, profile, lang, courseRules) {
8857
8886
  // src/commands/sync.ts
8858
8887
  var SUPPORTED_LANGS = ["en", "pl"];
8859
8888
  function registerSyncCommand(cli) {
8860
- cli.command("sync", "Bulk-download and update lessons, reporting what changed upstream").option("--all", "Sync every unlocked lesson (default: only lessons you've already downloaded)").option("--dry-run", "Show what would change without writing").option("--force", "Ignore the cheap-skip digest and overwrite local edits with upstream").option("--module <module>", "Limit to one module (e.g. 'm2' or '2')").option("--course <course>", "Select course ID or slug (default: project edition or API recommendation)").option("--tool <tool>", "AI coding tool (claude-code, cursor, copilot, codex, devin-desktop, gemini, kiro, generic)").option("--lang <lang>", "Content language: en (default) or pl").option("--no-course-rules", "Skip applying the course rules block to your rules file (CLAUDE.md/AGENTS.md)").action(async (options) => {
8889
+ cli.command("sync", "Bulk-download and update lessons, reporting what changed upstream").option("--all", "Sync every unlocked lesson (default: only lessons you've already downloaded)").option("--dry-run", "Show what would change without writing").option("--force", "Ignore the cheap-skip digest and overwrite local edits with upstream").option("--module <module>", "Limit to one module (e.g. 'm2' or '2')").option("--course <course>", "Select course ID or slug (default: project edition or API recommendation)").option("--tool <tool>", "AI coding tool (claude-code, cursor, copilot, codex, devin-desktop, factory, gemini, kiro, generic)").option("--lang <lang>", "Content language: en (default) or pl").option("--no-course-rules", "Skip applying the course rules block to your rules file (CLAUDE.md/AGENTS.md)").action(async (options) => {
8861
8890
  const ctx = resolveContext(options);
8862
8891
  await runSync(ctx, options);
8863
8892
  });
@@ -9161,6 +9190,7 @@ function renderReport(ctx, profile, input) {
9161
9190
  const buckets = countBuckets(outcomes);
9162
9191
  const lessonsErrored = outcomes.filter((o) => o.status === "errored").length;
9163
9192
  const lessonsConflicts = outcomes.filter((o) => o.status === "conflicts").length;
9193
+ const lessonsWithConflicts = outcomes.filter((o) => o.resources.some((r2) => r2.bucket === "skipped-conflict")).length;
9164
9194
  if (ctx.json) {
9165
9195
  output(ctx, "", {
9166
9196
  course: input.course,
@@ -9177,6 +9207,7 @@ function renderReport(ctx, profile, input) {
9177
9207
  updated: outcomes.filter((o) => o.status === "updated").length,
9178
9208
  unchanged: outcomes.filter((o) => o.status === "unchanged").length,
9179
9209
  conflicts: lessonsConflicts,
9210
+ lessonsWithConflicts,
9180
9211
  errored: lessonsErrored,
9181
9212
  excluded: exclusions.length,
9182
9213
  resources: {
@@ -9227,7 +9258,7 @@ function renderReport(ctx, profile, input) {
9227
9258
  }
9228
9259
  lines.push("");
9229
9260
  lines.push(`Totals: ${buckets["upstream-updated"]} updated, ${buckets.created} new, ` + `${buckets.unchanged} unchanged, ${buckets["skipped-conflict"]} skipped (conflicts), ` + `${buckets.removed} removed, ${buckets["preserved-local"]} preserved locally.`);
9230
- if (lessonsConflicts > 0 && !input.force) {
9261
+ if (lessonsWithConflicts > 0 && !input.force) {
9231
9262
  lines.push("To replace edited skills and prompts: 10x sync --force. Resolve rule conflicts with 10x get <lesson> --type rules.");
9232
9263
  }
9233
9264
  output(ctx, lines.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@przeprogramowani/10x-cli",
3
- "version": "1.25.3",
3
+ "version": "1.26.1",
4
4
  "description": "Open-source CLI for 10xDevs course content",
5
5
  "repository": {
6
6
  "type": "git",