@open-agent-toolkit/cli 0.0.10 → 0.0.18

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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +12 -20
  3. package/assets/docs/{guide/getting-started.md → cli-utilities/bootstrap.md} +8 -2
  4. package/assets/docs/cli-utilities/config-and-local-state.md +84 -0
  5. package/assets/docs/{guide → cli-utilities}/configuration.md +2 -2
  6. package/assets/docs/cli-utilities/index.md +41 -0
  7. package/assets/docs/cli-utilities/overview.md +33 -0
  8. package/assets/docs/{guide → cli-utilities}/tool-packs.md +9 -3
  9. package/assets/docs/contributing/code.md +4 -2
  10. package/assets/docs/contributing/design-principles.md +3 -3
  11. package/assets/docs/contributing/documentation.md +12 -4
  12. package/assets/docs/{guide/documentation/quickstart.md → docs-tooling/add-docs-to-a-repo.md} +1 -1
  13. package/assets/docs/{guide/documentation → docs-tooling}/commands.md +8 -1
  14. package/assets/docs/docs-tooling/index.md +40 -0
  15. package/assets/docs/docs-tooling/overview.md +31 -0
  16. package/assets/docs/{guide/documentation → docs-tooling}/workflows.md +3 -3
  17. package/assets/docs/guide/concepts.md +9 -9
  18. package/assets/docs/guide/index.md +14 -11
  19. package/assets/docs/index.md +34 -18
  20. package/assets/docs/{guide/provider-sync → provider-sync}/commands.md +10 -4
  21. package/assets/docs/{guide/provider-sync → provider-sync}/config.md +1 -1
  22. package/assets/docs/provider-sync/index.md +43 -0
  23. package/assets/docs/{guide/provider-sync → provider-sync}/manifest-and-drift.md +8 -0
  24. package/assets/docs/provider-sync/overview.md +38 -0
  25. package/assets/docs/{guide/provider-sync → provider-sync}/scope-and-surface.md +3 -3
  26. package/assets/docs/quickstart.md +43 -126
  27. package/assets/docs/reference/cli-reference.md +35 -0
  28. package/assets/docs/reference/docs-index-contract.md +1 -2
  29. package/assets/docs/reference/index.md +5 -4
  30. package/assets/docs/workflows/index.md +40 -0
  31. package/assets/docs/workflows/overview.md +38 -0
  32. package/assets/docs/workflows/projects/index.md +37 -0
  33. package/assets/docs/{guide/workflow → workflows/projects}/lifecycle.md +6 -0
  34. package/assets/docs/{guide/workflow → workflows/projects}/repo-analysis.md +6 -0
  35. package/assets/docs/{guide/workflow → workflows/projects}/state-machine.md +8 -0
  36. package/assets/docs/{guide → workflows}/skills/index.md +2 -2
  37. package/assets/public-package-versions.json +4 -4
  38. package/assets/skills/oat-agent-instructions-analyze/scripts/resolve-instruction-files.sh +0 -0
  39. package/assets/skills/oat-agent-instructions-analyze/scripts/resolve-providers.sh +0 -0
  40. package/assets/skills/oat-project-complete/SKILL.md +21 -27
  41. package/assets/skills/oat-project-document/SKILL.md +2 -2
  42. package/assets/skills/oat-project-import-plan/scripts/find-recent-provider-plans.sh +0 -0
  43. package/assets/skills/oat-project-subagent-implement/scripts/dispatch.sh +0 -0
  44. package/assets/skills/oat-project-subagent-implement/scripts/reconcile.sh +0 -0
  45. package/assets/skills/oat-project-subagent-implement/scripts/review-gate.sh +0 -0
  46. package/assets/skills/oat-project-subagent-implement/tests/test-dry-run.sh +0 -0
  47. package/assets/skills/oat-project-subagent-implement/tests/test-reconcile.sh +0 -0
  48. package/assets/skills/oat-project-subagent-implement/tests/test-review-gate.sh +0 -0
  49. package/assets/skills/oat-repo-maintainability-review/scripts/resolve-analysis-output.sh +0 -0
  50. package/assets/skills/oat-review-provide/scripts/resolve-review-output.sh +0 -0
  51. package/assets/skills/oat-worktree-bootstrap-auto/scripts/bootstrap.sh +0 -0
  52. package/dist/app/create-program.js +1 -1
  53. package/dist/commands/docs/index-generate/index.d.ts +1 -0
  54. package/dist/commands/docs/index-generate/index.d.ts.map +1 -1
  55. package/dist/commands/docs/index-generate/index.js +6 -3
  56. package/dist/commands/docs/init/index.d.ts +3 -0
  57. package/dist/commands/docs/init/index.d.ts.map +1 -1
  58. package/dist/commands/docs/init/index.js +52 -3
  59. package/dist/commands/docs/init/resolve-options.d.ts +1 -1
  60. package/dist/commands/docs/init/resolve-options.d.ts.map +1 -1
  61. package/dist/commands/docs/init/resolve-options.js +1 -0
  62. package/dist/commands/docs/init/scaffold.d.ts +1 -0
  63. package/dist/commands/docs/init/scaffold.d.ts.map +1 -1
  64. package/dist/commands/docs/init/scaffold.js +26 -8
  65. package/dist/commands/internal/index.d.ts.map +1 -1
  66. package/dist/commands/internal/index.js +3 -1
  67. package/dist/commands/internal/validate-oat-skills.d.ts +2 -2
  68. package/dist/commands/internal/validate-oat-skills.d.ts.map +1 -1
  69. package/dist/commands/internal/validate-oat-skills.js +5 -4
  70. package/dist/commands/internal/validate-skill-version-bumps.d.ts +10 -0
  71. package/dist/commands/internal/validate-skill-version-bumps.d.ts.map +1 -0
  72. package/dist/commands/internal/validate-skill-version-bumps.js +74 -0
  73. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  74. package/dist/commands/project/archive/archive-utils.js +34 -2
  75. package/dist/manifest/manager.js +1 -1
  76. package/dist/validation/index.d.ts +2 -2
  77. package/dist/validation/index.d.ts.map +1 -1
  78. package/dist/validation/index.js +1 -1
  79. package/dist/validation/skills.d.ts +25 -1
  80. package/dist/validation/skills.d.ts.map +1 -1
  81. package/dist/validation/skills.js +95 -1
  82. package/package.json +17 -17
  83. package/assets/docs/guide/cli-reference.md +0 -211
  84. package/assets/docs/guide/documentation/index.md +0 -27
  85. package/assets/docs/guide/provider-sync/index.md +0 -65
  86. package/assets/docs/guide/workflow/index.md +0 -34
  87. /package/assets/docs/{guide/provider-sync → provider-sync}/providers.md +0 -0
  88. /package/assets/docs/{guide → workflows}/ideas/index.md +0 -0
  89. /package/assets/docs/{guide → workflows}/ideas/lifecycle.md +0 -0
  90. /package/assets/docs/{guide/workflow → workflows/projects}/artifacts.md +0 -0
  91. /package/assets/docs/{guide/workflow → workflows/projects}/hill-checkpoints.md +0 -0
  92. /package/assets/docs/{guide/workflow → workflows/projects}/pr-flow.md +0 -0
  93. /package/assets/docs/{guide/workflow → workflows/projects}/reviews.md +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-complete
3
- version: 1.3.3
3
+ version: 1.3.5
4
4
  description: Use when all implementation work is finished and the project is ready to close. Marks the OAT project lifecycle as complete.
5
5
  disable-model-invocation: true
6
6
  user-invocable: true
@@ -300,35 +300,30 @@ The archive-side effects in this step are CLI-owned. Follow the canonical behavi
300
300
 
301
301
  ```bash
302
302
  ARCHIVED_ROOT=".oat/projects/archived"
303
- MAIN_WORKTREE_PATH=$(git worktree list --porcelain 2>/dev/null | awk '
304
- /^worktree / { wt=$2 }
305
- /^branch refs\\/heads\\/main$/ { print wt; exit }
306
- ')
307
- MAIN_REPO_ARCHIVE=""
308
- if [[ -n "$MAIN_WORKTREE_PATH" ]]; then
309
- MAIN_REPO_ARCHIVE="${MAIN_WORKTREE_PATH}/.oat/projects/archived"
310
- fi
303
+ PRIMARY_REPO_ARCHIVE=""
311
304
  LOCAL_ARCHIVED_ROOT=".oat/projects/archived"
312
- USE_MAIN_REPO_ARCHIVE="false"
305
+ USE_PRIMARY_REPO_ARCHIVE="false"
313
306
 
314
- # Heuristic: if this checkout is a worktree and the main repo archive parent exists,
315
- # use the main repo archive as the canonical archive destination.
307
+ # Heuristic: if this checkout is a worktree and the primary repo archive parent
308
+ # exists, use that durable archive path as the canonical archive destination.
316
309
  if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
317
310
  GIT_COMMON_DIR=$(git rev-parse --git-common-dir 2>/dev/null || true)
318
311
  GIT_DIR=$(git rev-parse --git-dir 2>/dev/null || true)
319
312
  if [[ -n "$GIT_COMMON_DIR" && -n "$GIT_DIR" && "$GIT_COMMON_DIR" != "$GIT_DIR" ]]; then
320
- if [[ -d "$(dirname "$MAIN_REPO_ARCHIVE")" ]]; then
321
- USE_MAIN_REPO_ARCHIVE="true"
322
- ARCHIVED_ROOT="$MAIN_REPO_ARCHIVE"
313
+ PRIMARY_REPO_ROOT=$(cd "$(dirname "$GIT_COMMON_DIR")" && pwd)
314
+ PRIMARY_REPO_ARCHIVE="${PRIMARY_REPO_ROOT}/.oat/projects/archived"
315
+ if [[ -d "$(dirname "$PRIMARY_REPO_ARCHIVE")" ]]; then
316
+ USE_PRIMARY_REPO_ARCHIVE="true"
317
+ ARCHIVED_ROOT="$PRIMARY_REPO_ARCHIVE"
323
318
  else
324
- echo "Warning: Running in a worktree, but main repo archive path is unavailable: $MAIN_REPO_ARCHIVE"
319
+ echo "Warning: Running in a worktree, but the primary repo archive path is unavailable: $PRIMARY_REPO_ARCHIVE"
325
320
  echo "A worktree-local archive may be deleted when the worktree is removed and is not a durable archive."
326
321
  echo "Require explicit confirmation before proceeding with local-only archive."
327
322
  fi
328
323
  fi
329
324
  fi
330
325
 
331
- if [[ "$USE_MAIN_REPO_ARCHIVE" != "true" ]]; then
326
+ if [[ "$USE_PRIMARY_REPO_ARCHIVE" != "true" ]]; then
332
327
  ARCHIVED_ROOT="$LOCAL_ARCHIVED_ROOT"
333
328
  fi
334
329
 
@@ -347,17 +342,17 @@ echo "Project archived to $ARCHIVE_PATH"
347
342
  **Canonical helper behaviors (required):**
348
343
 
349
344
  - Always archive locally first. The local archive is the authoritative completion artifact even when remote sync is also configured.
350
- - If `archive.summaryExportPath` is configured and `summary.md` exists after archive, copy it to `{repoRoot}/{archive.summaryExportPath}/{PROJECT_NAME}.md`.
345
+ - If `archive.summaryExportPath` is configured and `summary.md` exists after archive, copy it to `{repoRoot}/{archive.summaryExportPath}/YYYYMMDD-{PROJECT_NAME}.md`.
351
346
  - If `archive.s3SyncOnComplete=true` and `archive.s3Uri` is configured, sync the archived project to `{archive.s3Uri}/{repo-slug}/{PROJECT_NAME}/`.
352
347
  - If AWS CLI is missing or unusable for that S3 sync, warn and continue. Completion must not fail after the local archive succeeds.
353
348
  - If `archive.s3SyncOnComplete` is false or `archive.s3Uri` is unset, skip remote sync without prompting.
354
349
 
355
350
  **Worktree durability guard (required):**
356
351
 
357
- - If running in a worktree and `MAIN_REPO_ARCHIVE` is unavailable, do not silently continue with a local-only archive.
358
- - Ask the user explicitly: "Main repo archive path is unavailable, so this archive may be lost when the worktree is deleted. Continue with local-only archive anyway?"
352
+ - If running in a worktree and the primary repo archive path is unavailable, do not silently continue with a local-only archive.
353
+ - Ask the user explicitly: "Primary repo archive path is unavailable, so this archive may be lost when the worktree is deleted. Continue with local-only archive anyway?"
359
354
  - If the user declines, skip archiving and continue the completion flow without archive.
360
- - If your repository does not use `main` as the default branch, use `git worktree list --porcelain` to identify the primary worktree path by another stable rule (for example the non-ephemeral root checkout), then append `/.oat/projects/archived`.
355
+ - Resolve the durable repo root from `git rev-parse --git-common-dir` and `git rev-parse --git-dir`, matching the CLI helper in `packages/cli/src/commands/project/archive/archive-utils.ts`. Do not rely on a `main` checkout or default-branch naming.
361
356
 
362
357
  **Git handling after archive:**
363
358
 
@@ -376,18 +371,17 @@ If running from a git worktree, the primary repo archive directory is the canoni
376
371
  Reference path:
377
372
 
378
373
  ```bash
379
- MAIN_WORKTREE_PATH=$(git worktree list --porcelain | awk '
380
- /^worktree / { wt=$2 }
381
- /^branch refs\\/heads\\/main$/ { print wt; exit }
382
- ')
383
- MAIN_REPO_ARCHIVE="${MAIN_WORKTREE_PATH}/.oat/projects/archived"
374
+ GIT_COMMON_DIR=$(git rev-parse --git-common-dir)
375
+ PRIMARY_REPO_ROOT=$(cd "$(dirname "$GIT_COMMON_DIR")" && pwd)
376
+ PRIMARY_REPO_ARCHIVE="${PRIMARY_REPO_ROOT}/.oat/projects/archived"
384
377
  ```
385
378
 
386
379
  Guidance:
387
380
 
388
- - In a worktree, prefer moving directly to `MAIN_REPO_ARCHIVE` instead of archiving locally and copying later.
381
+ - In a worktree, only prefer `PRIMARY_REPO_ARCHIVE` when the archive destination is local-only/gitignored in the current checkout. If `.oat/projects/archived/` is version controlled on the current branch, archive in the current checkout instead.
389
382
  - Do not treat the worktree-local archive as durable.
390
383
  - If forced to use a local-only archive, warn and require explicit user confirmation.
384
+ - Always write the dated `archive.summaryExportPath` copy into the current checkout (`repoRoot`), even when the project archive itself is written to the primary checkout.
391
385
  - Do not hardcode user-specific absolute paths.
392
386
 
393
387
  ### Step 9: Regenerate Dashboard
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-document
3
- version: 1.0.0
3
+ version: 1.0.1
4
4
  description: Run when implementation is complete and documentation needs updating. Analyzes project artifacts to produce documentation update recommendations, then applies approved changes before project completion.
5
5
  argument-hint: '[project-path] [--auto]'
6
6
  disable-model-invocation: true
@@ -222,7 +222,7 @@ Scan the repository for all documentation and instruction surfaces.
222
222
 
223
223
  4. **Reference files:**
224
224
  - Check `.oat/repo/reference/` directory
225
- - Read: `current-state.md`, `backlog.md`, `roadmap.md`, `decision-record.md` (whichever exist)
225
+ - Read: `current-state.md`, `backlog/index.md`, `backlog/completed.md`, `roadmap.md`, `decision-record.md`, and relevant `backlog/items/*.md` files as needed (whichever exist)
226
226
 
227
227
  **3b. Instruction surfaces (secondary — strong signals only):**
228
228
 
@@ -1,7 +1,7 @@
1
1
  import { Command, Option } from 'commander';
2
2
  const PROGRAM_NAME = 'oat';
3
3
  const PROGRAM_DESCRIPTION = 'Open Agent Toolkit CLI for provider interoperability';
4
- const PROGRAM_VERSION = '0.0.7';
4
+ const PROGRAM_VERSION = '0.0.18';
5
5
  const SCOPE_CHOICES = ['project', 'user', 'all'];
6
6
  export function createProgram() {
7
7
  return new Command()
@@ -6,6 +6,7 @@ interface IndexGenerateFileDependencies {
6
6
  writeFile: (path: string, content: string, encoding: BufferEncoding) => Promise<void>;
7
7
  readOatConfig: (repoRoot: string) => Promise<import('../../../config/oat-config.js').OatConfig>;
8
8
  writeOatConfig: (repoRoot: string, config: import('../../../config/oat-config.js').OatConfig) => Promise<void>;
9
+ resolveRepoRoot: (cwd: string) => Promise<string>;
9
10
  }
10
11
  interface IndexGenerateDependencies {
11
12
  buildCommandContext: (options: GlobalOptions) => CommandContext;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/index-generate/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAS5C,UAAU,6BAA6B;IACrC,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,OAAO,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,aAAa,EAAE,UAAU,EAAE,KAAK,MAAM,CAAC;IACrE,SAAS,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,OAAO,oBAAoB,EAAE,SAAS,CAAC,CAAC;IACrD,cAAc,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,oBAAoB,EAAE,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,QAAQ,EAAE,6BAA6B,CAAC;CACzC;AAsED,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CAsBT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/index-generate/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAS5C,UAAU,6BAA6B;IACrC,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,OAAO,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,aAAa,EAAE,UAAU,EAAE,KAAK,MAAM,CAAC;IACrE,SAAS,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,OAAO,oBAAoB,EAAE,SAAS,CAAC,CAAC;IACrD,cAAc,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,oBAAoB,EAAE,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,QAAQ,EAAE,6BAA6B,CAAC;CACzC;AAwED,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CAsBT"}
@@ -3,6 +3,7 @@ import { join, relative } from 'node:path';
3
3
  import { buildCommandContext, } from '../../../app/command-context.js';
4
4
  import { readGlobalOptions } from '../../shared/shared.utils.js';
5
5
  import { readOatConfig, writeOatConfig } from '../../../config/oat-config.js';
6
+ import { resolveProjectRoot } from '../../../fs/paths.js';
6
7
  import { Command, Option } from 'commander';
7
8
  import { generateIndex, renderIndex } from './generator.js';
8
9
  const DEFAULT_FILE_DEPS = {
@@ -11,6 +12,7 @@ const DEFAULT_FILE_DEPS = {
11
12
  writeFile,
12
13
  readOatConfig,
13
14
  writeOatConfig,
15
+ resolveRepoRoot: resolveProjectRoot,
14
16
  };
15
17
  const DEFAULT_DEPENDENCIES = {
16
18
  buildCommandContext,
@@ -24,12 +26,13 @@ async function runIndexGenerate(context, options, deps) {
24
26
  const entries = await deps.generateIndex(docsDir);
25
27
  const content = deps.renderIndex(entries);
26
28
  await deps.writeFile(outputPath, content, 'utf8');
27
- const config = await deps.readOatConfig(context.cwd);
29
+ const repoRoot = await deps.resolveRepoRoot(context.cwd);
30
+ const config = await deps.readOatConfig(repoRoot);
28
31
  config.documentation = {
29
32
  ...config.documentation,
30
- index: relative(context.cwd, outputPath) || 'index.md',
33
+ index: relative(repoRoot, outputPath) || 'index.md',
31
34
  };
32
- await deps.writeOatConfig(context.cwd, config);
35
+ await deps.writeOatConfig(repoRoot, config);
33
36
  if (context.json) {
34
37
  context.logger.json({
35
38
  status: 'ok',
@@ -1,6 +1,7 @@
1
1
  import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
2
2
  import { type UpsertSectionResult } from '../../shared/agents-md.js';
3
3
  import { type PromptContext, type SelectChoice } from '../../shared/shared.prompts.js';
4
+ import { type OatConfig } from '../../../config/oat-config.js';
4
5
  import { Command } from 'commander';
5
6
  import { type DocsInitResolvedOptions } from './resolve-options.js';
6
7
  interface DocsInitDependencies {
@@ -11,6 +12,8 @@ interface DocsInitDependencies {
11
12
  selectWithAbort: <T extends string>(message: string, choices: SelectChoice<T>[], ctx: PromptContext) => Promise<T | null>;
12
13
  runDocsInit: (context: CommandContext, options: DocsInitResolvedOptions, assetsRoot: string) => Promise<void>;
13
14
  upsertAgentsMdSection: (repoRoot: string, key: string, body: string) => Promise<UpsertSectionResult>;
15
+ readOatConfig: (repoRoot: string) => Promise<OatConfig>;
16
+ confirmAction: (message: string, ctx: PromptContext) => Promise<boolean>;
14
17
  }
15
18
  export declare function buildDocsSectionBody(options: DocsInitResolvedOptions): string;
16
19
  export declare function createDocsInitCommand(overrides?: Partial<DocsInitDependencies>): Command;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAE5C,OAAO,EAIL,KAAK,uBAAuB,EAI7B,MAAM,mBAAmB,CAAC;AAa3B,UAAU,oBAAoB;IAC5B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAAC;IAC9E,gBAAgB,EAAE,CAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAC1B,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACvB,WAAW,EAAE,CACX,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,uBAAuB,EAChC,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,qBAAqB,EAAE,CACrB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACnC;AA+CD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAc7E;AAyDD,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,OAAO,CAgCT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAE5C,OAAO,EAIL,KAAK,uBAAuB,EAK7B,MAAM,mBAAmB,CAAC;AAa3B,UAAU,oBAAoB;IAC5B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAAC;IAC9E,gBAAgB,EAAE,CAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAC1B,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACvB,WAAW,EAAE,CACX,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,uBAAuB,EAChC,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,qBAAqB,EAAE,CACrB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAClC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1E;AAiDD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAc7E;AA8GD,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,OAAO,CAsCT"}
@@ -1,11 +1,11 @@
1
1
  import { buildCommandContext, } from '../../../app/command-context.js';
2
2
  import { upsertAgentsMdSection, } from '../../shared/agents-md.js';
3
- import { inputWithDefault, selectWithAbort, } from '../../shared/shared.prompts.js';
3
+ import { confirmAction, inputWithDefault, selectWithAbort, } from '../../shared/shared.prompts.js';
4
4
  import { readGlobalOptions } from '../../shared/shared.utils.js';
5
- import { readOatConfig, writeOatConfig } from '../../../config/oat-config.js';
5
+ import { readOatConfig, writeOatConfig, } from '../../../config/oat-config.js';
6
6
  import { resolveAssetsRoot } from '../../../fs/assets.js';
7
7
  import { Command, Option } from 'commander';
8
- import { DEFAULT_DOCS_REPO_SHAPE_DEPENDENCIES, detectDocsRepoShape, resolveDocsInitOptions, } from './resolve-options.js';
8
+ import { DEFAULT_DOCS_REPO_SHAPE_DEPENDENCIES, detectDocsRepoShape, getDefaultDocsAppName, resolveDocsInitOptions, } from './resolve-options.js';
9
9
  import { scaffoldDocsApp } from './scaffold.js';
10
10
  const DEFAULT_DEPENDENCIES = {
11
11
  buildCommandContext,
@@ -41,6 +41,8 @@ const DEFAULT_DEPENDENCIES = {
41
41
  context.logger.info(` Format: ${options.format}`);
42
42
  },
43
43
  upsertAgentsMdSection,
44
+ readOatConfig,
45
+ confirmAction,
44
46
  };
45
47
  const FRAMEWORK_LABELS = {
46
48
  fumadocs: 'Fumadocs (Next.js + MDX)',
@@ -83,6 +85,32 @@ async function runDocsInitCommand(context, options, dependencies) {
83
85
  process.exitCode = 0;
84
86
  return;
85
87
  }
88
+ const existingConfig = await dependencies.readOatConfig(context.cwd);
89
+ if (existingConfig.documentation?.root) {
90
+ const configDesc = `root: ${existingConfig.documentation.root}, tooling: ${existingConfig.documentation.tooling ?? 'unknown'}`;
91
+ if (context.json) {
92
+ // JSON mode: include warning in output, proceed only with --yes
93
+ if (!options.yes) {
94
+ context.logger.json({
95
+ status: 'error',
96
+ message: `Existing docs config found (${configDesc}). Use --yes to replace.`,
97
+ });
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ }
102
+ else {
103
+ context.logger.warn(`Existing docs config detected (${configDesc}). This will replace the current setup.`);
104
+ if (!options.yes) {
105
+ const proceed = await dependencies.confirmAction('Replace existing docs setup?', { interactive: context.interactive });
106
+ if (!proceed) {
107
+ context.logger.info('Docs init cancelled.');
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+ }
112
+ }
113
+ }
86
114
  const assetsRoot = await dependencies.resolveAssetsRoot();
87
115
  await dependencies.runDocsInit(context, resolved, assetsRoot);
88
116
  const sectionBody = buildDocsSectionBody(resolved);
@@ -90,6 +118,23 @@ async function runDocsInitCommand(context, options, dependencies) {
90
118
  if (!context.json && sectionResult.action !== 'no-change') {
91
119
  context.logger.info(`AGENTS.md docs section ${sectionResult.action}.`);
92
120
  }
121
+ if (!context.json) {
122
+ context.logger.info('');
123
+ context.logger.info('Next steps:');
124
+ if (resolved.repoShape === 'single-package') {
125
+ context.logger.info(` cd ${resolved.targetDir} && pnpm install`);
126
+ context.logger.info(' pnpm build');
127
+ }
128
+ else {
129
+ context.logger.info(' pnpm install');
130
+ context.logger.info(` pnpm --filter ${resolved.appName} build`);
131
+ const defaultName = getDefaultDocsAppName(context.cwd, resolved.repoShape);
132
+ if (resolved.appName !== defaultName) {
133
+ context.logger.info('');
134
+ context.logger.info(`Note: Your docs app is named "${resolved.appName}" — if you have root scripts or CI filters referencing "${defaultName}", update them to match.`);
135
+ }
136
+ }
137
+ }
93
138
  process.exitCode = 0;
94
139
  }
95
140
  catch (error) {
@@ -117,6 +162,10 @@ export function createDocsInitCommand(overrides = {}) {
117
162
  .addOption(new Option('--app-name <name>', 'Docs app name'))
118
163
  .addOption(new Option('--target-dir <path>', 'Target directory for the docs app'))
119
164
  .addOption(new Option('--description <text>', 'Site description'))
165
+ .addOption(new Option('--lint <mode>', 'Markdown lint mode').choices([
166
+ 'none',
167
+ 'markdownlint-cli2',
168
+ ]))
120
169
  .addOption(new Option('--format <mode>', 'Markdown format mode').choices([
121
170
  'oxfmt',
122
171
  'none',
@@ -1,7 +1,7 @@
1
1
  import type { PromptContext, SelectChoice } from '../../shared/shared.prompts.js';
2
2
  export type DocsRepoShape = 'monorepo' | 'single-package';
3
3
  export type DocsFramework = 'fumadocs' | 'mkdocs';
4
- export type DocsLintMode = 'none';
4
+ export type DocsLintMode = 'none' | 'markdownlint-cli2';
5
5
  export type DocsFormatMode = 'oxfmt' | 'none';
6
6
  export interface DocsInitResolvedOptions {
7
7
  repoRoot: string;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-options.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/resolve-options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACb,MAAM,iCAAiC,CAAC;AAGzC,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAC1D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,QAAQ,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAClC,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,aAAa,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gBAAgB,EAAE,CAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAC1B,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvE;AAgBD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,aAAa,GACvB,MAAM,CAMR;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAoBD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,yBAAyB,GACtC,OAAO,CAAC,aAAa,CAAC,CAqBxB;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAE/D;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CA+EzC;AAED,eAAO,MAAM,oCAAoC,EAAE,yBAOlD,CAAC"}
1
+ {"version":3,"file":"resolve-options.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/resolve-options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACb,MAAM,iCAAiC,CAAC;AAGzC,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAC1D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,QAAQ,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,mBAAmB,CAAC;AACxD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,aAAa,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gBAAgB,EAAE,CAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAC1B,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvE;AAiBD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,aAAa,GACvB,MAAM,CAMR;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAoBD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,yBAAyB,GACtC,OAAO,CAAC,aAAa,CAAC,CAqBxB;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAE/D;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CA+EzC;AAED,eAAO,MAAM,oCAAoC,EAAE,yBAOlD,CAAC"}
@@ -6,6 +6,7 @@ const FRAMEWORK_CHOICES = [
6
6
  ];
7
7
  const LINT_CHOICES = [
8
8
  { label: 'none', value: 'none' },
9
+ { label: 'markdownlint-cli2', value: 'markdownlint-cli2' },
9
10
  ];
10
11
  const FORMAT_CHOICES = [
11
12
  { label: 'oxfmt', value: 'oxfmt' },
@@ -10,6 +10,7 @@ export interface ScaffoldDocsAppResult {
10
10
  }
11
11
  export interface OatDepContext {
12
12
  isOatRepo: boolean;
13
+ localPackages: Set<string>;
13
14
  oatPackageVersions: Record<string, string>;
14
15
  }
15
16
  export declare function detectIsOatRepo(repoRoot: string): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/scaffold.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,KAAK,EAGV,uBAAuB,EAExB,MAAM,mBAAmB,CAAC;AA+E3B,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,sBAAsB,CAAC;CAC7C;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAWD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;AAsCD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAYxB;AAiID,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAoChC"}
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/scaffold.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,KAAK,EAGV,uBAAuB,EAExB,MAAM,mBAAmB,CAAC;AA+E3B,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,sBAAsB,CAAC;CAC7C;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAWD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;AAgDD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAaxB;AA4ID,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAoChC"}
@@ -71,7 +71,7 @@ const OAT_DEP_PACKAGES = [
71
71
  'docs-theme',
72
72
  'docs-transforms',
73
73
  ];
74
- const DEFAULT_OAT_PUBLISHED_VERSION = '0.0.8';
74
+ const DEFAULT_OAT_PUBLISHED_VERSION = '0.0.18';
75
75
  const PUBLIC_PACKAGE_VERSIONS_FILE = 'public-package-versions.json';
76
76
  export async function detectIsOatRepo(repoRoot) {
77
77
  for (const pkg of OAT_DEP_PACKAGES) {
@@ -105,17 +105,27 @@ async function readBundledOatPackageVersions(assetsRoot) {
105
105
  function buildFallbackOatPackageVersions(version) {
106
106
  return Object.fromEntries(OAT_DEP_PACKAGES.map((name) => [name, version]));
107
107
  }
108
+ async function detectLocalOatPackages(repoRoot) {
109
+ const found = new Set();
110
+ for (const pkg of OAT_DEP_PACKAGES) {
111
+ if (await fileExists(join(repoRoot, 'packages', pkg, 'package.json'))) {
112
+ found.add(pkg);
113
+ }
114
+ }
115
+ return found;
116
+ }
108
117
  export async function resolveOatDepContext(repoRoot, assetsRoot) {
109
- const isOatRepo = await detectIsOatRepo(repoRoot);
118
+ const localPackages = await detectLocalOatPackages(repoRoot);
119
+ const isOatRepo = localPackages.size === OAT_DEP_PACKAGES.length;
110
120
  if (isOatRepo) {
111
- return { isOatRepo, oatPackageVersions: {} };
121
+ return { isOatRepo, localPackages, oatPackageVersions: {} };
112
122
  }
113
123
  const cliVersion = await readCliVersion(assetsRoot);
114
124
  const oatPackageVersions = {
115
125
  ...buildFallbackOatPackageVersions(cliVersion),
116
126
  ...(await readBundledOatPackageVersions(assetsRoot)),
117
127
  };
118
- return { isOatRepo, oatPackageVersions };
128
+ return { isOatRepo, localPackages, oatPackageVersions };
119
129
  }
120
130
  function humanizeAppName(appName) {
121
131
  return appName
@@ -126,6 +136,9 @@ function humanizeAppName(appName) {
126
136
  }
127
137
  function buildDevDependencies(lint, format) {
128
138
  const entries = [];
139
+ if (lint === 'markdownlint-cli2') {
140
+ entries.push(' "markdownlint-cli2": "^0.13.0"');
141
+ }
129
142
  if (format === 'oxfmt') {
130
143
  entries.push(' "oxfmt": "^0.36.0"');
131
144
  }
@@ -133,6 +146,9 @@ function buildDevDependencies(lint, format) {
133
146
  }
134
147
  function buildFumaDevDependencies(lint, format) {
135
148
  const entries = [];
149
+ if (lint === 'markdownlint-cli2') {
150
+ entries.push(' "markdownlint-cli2": "^0.13.0"');
151
+ }
136
152
  if (format === 'oxfmt') {
137
153
  entries.push(' "oxfmt": "^0.36.0"');
138
154
  }
@@ -145,10 +161,10 @@ function buildGenerateIndexCmd(isOatRepo, targetDir) {
145
161
  if (isOatRepo) {
146
162
  return `pnpm -w run cli -- docs generate-index --docs-dir ${targetDir}/docs --output ${targetDir}/index.md`;
147
163
  }
148
- return '(oat docs generate-index --docs-dir docs --output index.md || true)';
164
+ return 'oat docs generate-index --docs-dir docs --output index.md';
149
165
  }
150
166
  function oatDepVersion(depContext, packageName) {
151
- if (depContext.isOatRepo) {
167
+ if (depContext.localPackages.has(packageName)) {
152
168
  return 'workspace:*';
153
169
  }
154
170
  return `^${depContext.oatPackageVersions[packageName] ?? DEFAULT_OAT_PUBLISHED_VERSION}`;
@@ -161,7 +177,9 @@ function renderTemplate(template, options, depContext) {
161
177
  '{{PACKAGE_NAME}}': options.appName,
162
178
  '{{SITE_NAME}}': siteName,
163
179
  '{{SITE_DESCRIPTION}}': options.siteDescription,
164
- '{{DOCS_LINT_SCRIPT}}': "echo 'docs lint disabled'",
180
+ '{{DOCS_LINT_SCRIPT}}': options.lint === 'markdownlint-cli2'
181
+ ? "markdownlint-cli2 'docs/**/*.md'"
182
+ : "echo 'docs lint disabled'",
165
183
  '{{DOCS_FORMAT_SCRIPT}}': options.format === 'oxfmt'
166
184
  ? "oxfmt 'docs/**/*.md'"
167
185
  : "echo 'docs formatting disabled'",
@@ -185,7 +203,7 @@ function buildDocumentationConfig(framework, targetDir) {
185
203
  return {
186
204
  root: targetDir,
187
205
  tooling: 'fumadocs',
188
- index: join(targetDir, 'index.md'),
206
+ index: join(targetDir, 'docs', 'index.md'),
189
207
  };
190
208
  }
191
209
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/internal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,qBAAqB,IAAI,OAAO,CAI/C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/internal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,IAAI,OAAO,CAK/C"}
@@ -1,7 +1,9 @@
1
1
  import { Command } from 'commander';
2
2
  import { createValidateOatSkillsCommand } from './validate-oat-skills.js';
3
+ import { createValidateSkillVersionBumpsCommand } from './validate-skill-version-bumps.js';
3
4
  export function createInternalCommand() {
4
5
  return new Command('internal')
5
6
  .description('Internal OAT maintenance commands')
6
- .addCommand(createValidateOatSkillsCommand());
7
+ .addCommand(createValidateOatSkillsCommand())
8
+ .addCommand(createValidateSkillVersionBumpsCommand());
7
9
  }
@@ -1,9 +1,9 @@
1
1
  import { type CommandContext, type GlobalOptions } from '../../app/command-context.js';
2
- import { type ValidateOatSkillsResult } from '../../validation/index.js';
2
+ import { type ValidateOatSkillsOptions, type ValidateOatSkillsResult } from '../../validation/index.js';
3
3
  import { Command } from 'commander';
4
4
  interface ValidateOatSkillsDependencies {
5
5
  buildCommandContext: (options: GlobalOptions) => CommandContext;
6
- validateOatSkills: (repoRoot: string) => Promise<ValidateOatSkillsResult>;
6
+ validateOatSkills: (repoRoot: string, options?: ValidateOatSkillsOptions) => Promise<ValidateOatSkillsResult>;
7
7
  }
8
8
  export declare function createValidateOatSkillsCommand(overrides?: Partial<ValidateOatSkillsDependencies>): Command;
9
9
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"validate-oat-skills.d.ts","sourceRoot":"","sources":["../../../src/commands/internal/validate-oat-skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,UAAU,6BAA6B;IACrC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC3E;AAiED,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,6BAA6B,CAAM,GACrD,OAAO,CAcT"}
1
+ {"version":3,"file":"validate-oat-skills.d.ts","sourceRoot":"","sources":["../../../src/commands/internal/validate-oat-skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,UAAU,6BAA6B;IACrC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,iBAAiB,EAAE,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,wBAAwB,KAC/B,OAAO,CAAC,uBAAuB,CAAC,CAAC;CACvC;AAkED,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,6BAA6B,CAAM,GACrD,OAAO,CAkBT"}
@@ -21,9 +21,9 @@ function reportFindings(context, result) {
21
21
  }
22
22
  context.logger.error('\nFix the issues above, then re-run: pnpm oat:validate-skills');
23
23
  }
24
- async function runValidateOatSkills(context, dependencies) {
24
+ async function runValidateOatSkills(context, options, dependencies) {
25
25
  try {
26
- const result = await dependencies.validateOatSkills(context.cwd);
26
+ const result = await dependencies.validateOatSkills(context.cwd, options);
27
27
  if (result.findings.length > 0) {
28
28
  reportFindings(context, result);
29
29
  process.exitCode = 1;
@@ -59,8 +59,9 @@ export function createValidateOatSkillsCommand(overrides = {}) {
59
59
  };
60
60
  return new Command('validate-oat-skills')
61
61
  .description('Validate required structure of oat-* workflow skills')
62
- .action(async (_options, command) => {
62
+ .option('--base-ref <ref>', 'Also require changed canonical skills to bump version relative to this git ref')
63
+ .action(async (options, command) => {
63
64
  const context = dependencies.buildCommandContext(readGlobalOptions(command));
64
- await runValidateOatSkills(context, dependencies);
65
+ await runValidateOatSkills(context, options, dependencies);
65
66
  });
66
67
  }
@@ -0,0 +1,10 @@
1
+ import { type CommandContext, type GlobalOptions } from '../../app/command-context.js';
2
+ import { type ValidateChangedSkillVersionBumpsOptions, type ValidateChangedSkillVersionBumpsResult } from '../../validation/index.js';
3
+ import { Command } from 'commander';
4
+ interface ValidateSkillVersionBumpsDependencies {
5
+ buildCommandContext: (options: GlobalOptions) => CommandContext;
6
+ validateChangedSkillVersionBumps: (repoRoot: string, options: ValidateChangedSkillVersionBumpsOptions) => Promise<ValidateChangedSkillVersionBumpsResult>;
7
+ }
8
+ export declare function createValidateSkillVersionBumpsCommand(overrides?: Partial<ValidateSkillVersionBumpsDependencies>): Command;
9
+ export {};
10
+ //# sourceMappingURL=validate-skill-version-bumps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-skill-version-bumps.d.ts","sourceRoot":"","sources":["../../../src/commands/internal/validate-skill-version-bumps.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,uCAAuC,EAC5C,KAAK,sCAAsC,EAC5C,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,UAAU,qCAAqC;IAC7C,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,gCAAgC,EAAE,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,uCAAuC,KAC7C,OAAO,CAAC,sCAAsC,CAAC,CAAC;CACtD;AA8ED,wBAAgB,sCAAsC,CACpD,SAAS,GAAE,OAAO,CAAC,qCAAqC,CAAM,GAC7D,OAAO,CAyBT"}
@@ -0,0 +1,74 @@
1
+ import { buildCommandContext, } from '../../app/command-context.js';
2
+ import { readGlobalOptions } from '../shared/shared.utils.js';
3
+ import { validateChangedSkillVersionBumps as defaultValidateChangedSkillVersionBumps, } from '../../validation/index.js';
4
+ import { Command } from 'commander';
5
+ const DEFAULT_DEPENDENCIES = {
6
+ buildCommandContext,
7
+ validateChangedSkillVersionBumps: defaultValidateChangedSkillVersionBumps,
8
+ };
9
+ function reportFindings(context, baseRef, result) {
10
+ if (context.json) {
11
+ context.logger.json({
12
+ status: 'failed',
13
+ baseRef,
14
+ validatedSkillCount: result.validatedSkillCount,
15
+ findings: result.findings,
16
+ });
17
+ return;
18
+ }
19
+ context.logger.error('Canonical skill version validation failed:\n');
20
+ for (const finding of result.findings) {
21
+ context.logger.error(`- ${finding.file}: ${finding.message}`);
22
+ }
23
+ context.logger.error(`\nFix the issues above, then re-run: oat internal validate-skill-version-bumps --base-ref ${baseRef}`);
24
+ }
25
+ async function runValidateSkillVersionBumps(context, options, dependencies) {
26
+ try {
27
+ const result = await dependencies.validateChangedSkillVersionBumps(context.cwd, options);
28
+ if (result.findings.length > 0) {
29
+ reportFindings(context, options.baseRef, result);
30
+ process.exitCode = 1;
31
+ return;
32
+ }
33
+ if (context.json) {
34
+ context.logger.json({
35
+ status: 'ok',
36
+ baseRef: options.baseRef,
37
+ validatedSkillCount: result.validatedSkillCount,
38
+ findings: result.findings,
39
+ });
40
+ }
41
+ else {
42
+ if (result.validatedSkillCount === 0) {
43
+ context.logger.info(`OK: 0 canonical skills changed relative to ${options.baseRef} - nothing to validate`);
44
+ }
45
+ else {
46
+ context.logger.info(`OK: validated ${result.validatedSkillCount} changed canonical skill version bump checks against ${options.baseRef}`);
47
+ }
48
+ }
49
+ process.exitCode = 0;
50
+ }
51
+ catch (error) {
52
+ const message = error instanceof Error ? error.message : String(error);
53
+ if (context.json) {
54
+ context.logger.json({ status: 'error', message });
55
+ }
56
+ else {
57
+ context.logger.error(message);
58
+ }
59
+ process.exitCode = 2;
60
+ }
61
+ }
62
+ export function createValidateSkillVersionBumpsCommand(overrides = {}) {
63
+ const dependencies = {
64
+ ...DEFAULT_DEPENDENCIES,
65
+ ...overrides,
66
+ };
67
+ return new Command('validate-skill-version-bumps')
68
+ .description('Validate that changed canonical skills bump version relative to a git base ref')
69
+ .requiredOption('--base-ref <ref>', 'Git ref used as the comparison base for changed canonical skills')
70
+ .action(async (options, command) => {
71
+ const context = dependencies.buildCommandContext(readGlobalOptions(command));
72
+ await runValidateSkillVersionBumps(context, options, dependencies);
73
+ });
74
+ }