@dezkareid/osddt 1.6.0 → 1.7.0

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/AGENTS.md CHANGED
@@ -105,7 +105,8 @@ osddt/
105
105
  │ ├── commands/
106
106
  │ │ ├── setup.ts # `osddt setup` — prompts for agents & repo type (or reads --agents/--repo-type flags), writes command files and .osddtrc
107
107
  │ │ ├── meta-info.ts # `osddt meta-info` — outputs { branch, date } as JSON (consumed by generated templates)
108
- │ │ └── done.ts # `osddt done <feature>` — moves working-on/<feature> → done/YYYY-MM-DD-<feature>
108
+ │ │ ├── done.ts # `osddt done <feature>` — moves working-on/<feature> → done/YYYY-MM-DD-<feature>
109
+ │ │ └── update.ts # `osddt update` — reads .osddtrc and regenerates agent command files for detected agents
109
110
  │ ├── templates/
110
111
  │ │ ├── shared.ts # REPO_PREAMBLE, FEATURE_NAME_RULES, WORKING_DIR_STEP, and COMMAND_DEFINITIONS array
111
112
  │ │ ├── claude.ts # Formats COMMAND_DEFINITIONS as Markdown (.claude/commands/osddt.<name>.md)
@@ -117,7 +118,7 @@ osddt/
117
118
  ├── tsconfig.json # TypeScript config
118
119
  ├── vitest.config.ts # Vitest config
119
120
  ├── package.json # Package name: @dezkareid/osddt, bin: osddt → dist/index.js
120
- ├── .osddtrc # Runtime config written by setup (repoType: "single" | "monorepo")
121
+ ├── .osddtrc # Runtime config written by setup (repoType: "single" | "monorepo", agents: ["claude", "gemini"])
121
122
  ├── AGENTS.md / CLAUDE.md / GEMINI.md # Agent-specific instructions (kept in sync)
122
123
  └── README.md # Public-facing documentation
123
124
  ```
@@ -142,6 +143,8 @@ There are two contexts in which osddt commands are invoked:
142
143
 
143
144
  When `osddt setup` is run, it reads the `name` field of `package.json` in the target directory. If the name is `@dezkareid/osddt`, templates are written with `npx osddt`. Otherwise they fall back to `npx @dezkareid/osddt`. The resolution lives in `resolveNpxCommand()` in `src/commands/setup.ts`.
144
145
 
146
+ The selected agents are saved in `.osddtrc` alongside `repoType`. When `osddt update` is run, if `.osddtrc` has no `agents` key, it scans each agent's command directory for any command files to infer the active agents and writes the result back into `.osddtrc`.
147
+
145
148
  #### Available commands
146
149
 
147
150
  | Command | Context | Description |
@@ -154,6 +157,8 @@ When `osddt setup` is run, it reads the `name` field of `package.json` in the ta
154
157
  | `npx @dezkareid/osddt meta-info` | External | Output current branch and date as JSON |
155
158
  | `osddt done <feature-name> --dir <project-path>` | Local dev | Move `working-on/<feature>` to `done/<feature>` |
156
159
  | `npx @dezkareid/osddt done <feature-name> --dir <project-path>` | External | Move `working-on/<feature>` to `done/<feature>` |
160
+ | `osddt update` | Local dev | Regenerate agent command files from the existing `.osddtrc` |
161
+ | `npx @dezkareid/osddt update` | External | Regenerate agent command files from the existing `.osddtrc` |
157
162
 
158
163
  #### `osddt setup` options
159
164
 
package/README.md CHANGED
@@ -9,6 +9,7 @@ Other spec driven development tool but for monorepo
9
9
  | `@dezkareid/osddt setup --agents <list> --repo-type <type>` | Non-interactive setup (for CI/scripted environments) |
10
10
  | `@dezkareid/osddt meta-info` | Output current branch and date as JSON |
11
11
  | `@dezkareid/osddt done <feature-name> --dir <project-path>` | Move `working-on/<feature>` to `done/<feature>` |
12
+ | `@dezkareid/osddt update` | Regenerate agent command files from the existing `.osddtrc` |
12
13
 
13
14
  ### `osddt setup` options
14
15
 
@@ -20,6 +21,8 @@ Other spec driven development tool but for monorepo
20
21
 
21
22
  Both flags are optional. Providing neither runs the fully interactive mode. Providing both skips all prompts.
22
23
 
24
+ The selected agents are saved in `.osddtrc` alongside `repoType` so that `osddt update` can regenerate the correct files without prompting.
25
+
23
26
  ```bash
24
27
  # Interactive (default)
25
28
  npx @dezkareid/osddt setup
@@ -1,2 +1,3 @@
1
1
  import { Command } from 'commander';
2
+ export declare function resolveNpxCommand(cwd: string): Promise<string>;
2
3
  export declare function setupCommand(): Command;
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function updateCommand(): Command;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -526,7 +526,7 @@ function parseRepoType(raw) {
526
526
  }
527
527
  return raw;
528
528
  }
529
- async function writeCommandFile(file) {
529
+ async function writeCommandFile$1(file) {
530
530
  await fs.ensureDir(path.dirname(file.filePath));
531
531
  await fs.writeFile(file.filePath, file.content, 'utf-8');
532
532
  console.log(` Created: ${file.filePath}`);
@@ -549,7 +549,7 @@ async function runSetup(cwd, rawAgents, rawRepoType) {
549
549
  const claudeFiles = getClaudeTemplates(cwd, npxCommand);
550
550
  console.log('Claude Code commands (.claude/commands/):');
551
551
  for (const file of claudeFiles) {
552
- await writeCommandFile(file);
552
+ await writeCommandFile$1(file);
553
553
  }
554
554
  console.log('');
555
555
  }
@@ -557,11 +557,11 @@ async function runSetup(cwd, rawAgents, rawRepoType) {
557
557
  const geminiFiles = getGeminiTemplates(cwd, npxCommand);
558
558
  console.log('Gemini CLI commands (.gemini/commands/):');
559
559
  for (const file of geminiFiles) {
560
- await writeCommandFile(file);
560
+ await writeCommandFile$1(file);
561
561
  }
562
562
  console.log('');
563
563
  }
564
- await writeConfig(cwd, { repoType });
564
+ await writeConfig(cwd, { repoType, agents });
565
565
  console.log('\nSetup complete!');
566
566
  console.log('Commands created: osddt.spec, osddt.plan, osddt.tasks, osddt.implement');
567
567
  }
@@ -636,6 +636,79 @@ function doneCommand() {
636
636
  return cmd;
637
637
  }
638
638
 
639
+ const AGENT_CONFIGS = {
640
+ claude: { dir: ['.claude', 'commands'], filePattern: /^osddt\..+\.md$/ },
641
+ gemini: { dir: ['.gemini', 'commands'], filePattern: /^osddt\..+\.toml$/ },
642
+ };
643
+ async function hasOsddtCommandFile(dir, pattern) {
644
+ if (!(await fs.pathExists(dir)))
645
+ return false;
646
+ const entries = await fs.readdir(dir);
647
+ return entries.some((f) => pattern.test(f));
648
+ }
649
+ async function inferAgents(cwd) {
650
+ const detected = [];
651
+ for (const [agent, config] of Object.entries(AGENT_CONFIGS)) {
652
+ const dir = path.join(cwd, ...config.dir);
653
+ if (await hasOsddtCommandFile(dir, config.filePattern)) {
654
+ detected.push(agent);
655
+ }
656
+ }
657
+ return detected;
658
+ }
659
+ async function writeCommandFile(file) {
660
+ await fs.writeFile(file.filePath, file.content, 'utf-8');
661
+ console.log(` Updated: ${file.filePath}`);
662
+ }
663
+ async function runUpdate(cwd) {
664
+ const configPath = path.join(cwd, '.osddtrc');
665
+ if (!(await fs.pathExists(configPath))) {
666
+ console.error('Error: .osddtrc not found. Run `osddt setup` first.');
667
+ process.exit(1);
668
+ }
669
+ const config = await fs.readJson(configPath);
670
+ const npxCommand = await resolveNpxCommand(cwd);
671
+ let agents = config.agents;
672
+ if (!agents || agents.length === 0) {
673
+ agents = await inferAgents(cwd);
674
+ if (agents.length === 0) {
675
+ console.error('Error: No agent command directories found. Run `osddt setup` first.');
676
+ process.exit(1);
677
+ }
678
+ await fs.writeJson(configPath, { ...config, agents }, { spaces: 2 });
679
+ console.log(`Inferred agents from command directories and saved to .osddtrc: ${agents.join(', ')}\n`);
680
+ }
681
+ console.log('Updating OSDDT command files...\n');
682
+ if (agents.includes('claude')) {
683
+ const claudeFiles = getClaudeTemplates(cwd, npxCommand);
684
+ console.log('Claude Code commands (.claude/commands/):');
685
+ for (const file of claudeFiles) {
686
+ await writeCommandFile(file);
687
+ }
688
+ console.log('');
689
+ }
690
+ if (agents.includes('gemini')) {
691
+ const geminiFiles = getGeminiTemplates(cwd, npxCommand);
692
+ console.log('Gemini CLI commands (.gemini/commands/):');
693
+ for (const file of geminiFiles) {
694
+ await writeCommandFile(file);
695
+ }
696
+ console.log('');
697
+ }
698
+ console.log('Update complete!');
699
+ }
700
+ function updateCommand() {
701
+ const cmd = new Command('update');
702
+ cmd
703
+ .description('Regenerate agent command files from the existing .osddtrc configuration')
704
+ .option('-d, --dir <directory>', 'target directory', process.cwd())
705
+ .action(async (options) => {
706
+ const targetDir = path.resolve(options.dir);
707
+ await runUpdate(targetDir);
708
+ });
709
+ return cmd;
710
+ }
711
+
639
712
  const program = new Command();
640
713
  program
641
714
  .name('osddt')
@@ -644,4 +717,5 @@ program
644
717
  program.addCommand(setupCommand());
645
718
  program.addCommand(metaInfoCommand());
646
719
  program.addCommand(doneCommand());
720
+ program.addCommand(updateCommand());
647
721
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dezkareid/osddt",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Package for Spec-Driven Development workflow",
5
5
  "keywords": [
6
6
  "spec-driven",