@dezkareid/osddt 1.6.0 → 1.8.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
@@ -224,6 +224,9 @@ ${getNextStepToSpec(args)}
224
224
  3. Identify the core problem being solved
225
225
  4. Define the scope, user-facing constraints, and acceptance criteria
226
226
  5. Write the specification to \`osddt.spec.md\` in the working directory
227
+ 6. After writing the spec, check whether the **Open Questions** section contains any items:
228
+ - If it does, inform the user: "I have some open questions — can we clarify these? You can answer them now, or run \`/osddt.clarify\` to go through them one by one."
229
+ - If it does not (or the section is absent), proceed to the Next Step without mentioning clarification.
227
230
 
228
231
  ## Specification Format
229
232
 
@@ -526,7 +529,7 @@ function parseRepoType(raw) {
526
529
  }
527
530
  return raw;
528
531
  }
529
- async function writeCommandFile(file) {
532
+ async function writeCommandFile$1(file) {
530
533
  await fs.ensureDir(path.dirname(file.filePath));
531
534
  await fs.writeFile(file.filePath, file.content, 'utf-8');
532
535
  console.log(` Created: ${file.filePath}`);
@@ -549,7 +552,7 @@ async function runSetup(cwd, rawAgents, rawRepoType) {
549
552
  const claudeFiles = getClaudeTemplates(cwd, npxCommand);
550
553
  console.log('Claude Code commands (.claude/commands/):');
551
554
  for (const file of claudeFiles) {
552
- await writeCommandFile(file);
555
+ await writeCommandFile$1(file);
553
556
  }
554
557
  console.log('');
555
558
  }
@@ -557,11 +560,11 @@ async function runSetup(cwd, rawAgents, rawRepoType) {
557
560
  const geminiFiles = getGeminiTemplates(cwd, npxCommand);
558
561
  console.log('Gemini CLI commands (.gemini/commands/):');
559
562
  for (const file of geminiFiles) {
560
- await writeCommandFile(file);
563
+ await writeCommandFile$1(file);
561
564
  }
562
565
  console.log('');
563
566
  }
564
- await writeConfig(cwd, { repoType });
567
+ await writeConfig(cwd, { repoType, agents });
565
568
  console.log('\nSetup complete!');
566
569
  console.log('Commands created: osddt.spec, osddt.plan, osddt.tasks, osddt.implement');
567
570
  }
@@ -636,6 +639,79 @@ function doneCommand() {
636
639
  return cmd;
637
640
  }
638
641
 
642
+ const AGENT_CONFIGS = {
643
+ claude: { dir: ['.claude', 'commands'], filePattern: /^osddt\..+\.md$/ },
644
+ gemini: { dir: ['.gemini', 'commands'], filePattern: /^osddt\..+\.toml$/ },
645
+ };
646
+ async function hasOsddtCommandFile(dir, pattern) {
647
+ if (!(await fs.pathExists(dir)))
648
+ return false;
649
+ const entries = await fs.readdir(dir);
650
+ return entries.some((f) => pattern.test(f));
651
+ }
652
+ async function inferAgents(cwd) {
653
+ const detected = [];
654
+ for (const [agent, config] of Object.entries(AGENT_CONFIGS)) {
655
+ const dir = path.join(cwd, ...config.dir);
656
+ if (await hasOsddtCommandFile(dir, config.filePattern)) {
657
+ detected.push(agent);
658
+ }
659
+ }
660
+ return detected;
661
+ }
662
+ async function writeCommandFile(file) {
663
+ await fs.writeFile(file.filePath, file.content, 'utf-8');
664
+ console.log(` Updated: ${file.filePath}`);
665
+ }
666
+ async function runUpdate(cwd) {
667
+ const configPath = path.join(cwd, '.osddtrc');
668
+ if (!(await fs.pathExists(configPath))) {
669
+ console.error('Error: .osddtrc not found. Run `osddt setup` first.');
670
+ process.exit(1);
671
+ }
672
+ const config = await fs.readJson(configPath);
673
+ const npxCommand = await resolveNpxCommand(cwd);
674
+ let agents = config.agents;
675
+ if (!agents || agents.length === 0) {
676
+ agents = await inferAgents(cwd);
677
+ if (agents.length === 0) {
678
+ console.error('Error: No agent command directories found. Run `osddt setup` first.');
679
+ process.exit(1);
680
+ }
681
+ await fs.writeJson(configPath, { ...config, agents }, { spaces: 2 });
682
+ console.log(`Inferred agents from command directories and saved to .osddtrc: ${agents.join(', ')}\n`);
683
+ }
684
+ console.log('Updating OSDDT command files...\n');
685
+ if (agents.includes('claude')) {
686
+ const claudeFiles = getClaudeTemplates(cwd, npxCommand);
687
+ console.log('Claude Code commands (.claude/commands/):');
688
+ for (const file of claudeFiles) {
689
+ await writeCommandFile(file);
690
+ }
691
+ console.log('');
692
+ }
693
+ if (agents.includes('gemini')) {
694
+ const geminiFiles = getGeminiTemplates(cwd, npxCommand);
695
+ console.log('Gemini CLI commands (.gemini/commands/):');
696
+ for (const file of geminiFiles) {
697
+ await writeCommandFile(file);
698
+ }
699
+ console.log('');
700
+ }
701
+ console.log('Update complete!');
702
+ }
703
+ function updateCommand() {
704
+ const cmd = new Command('update');
705
+ cmd
706
+ .description('Regenerate agent command files from the existing .osddtrc configuration')
707
+ .option('-d, --dir <directory>', 'target directory', process.cwd())
708
+ .action(async (options) => {
709
+ const targetDir = path.resolve(options.dir);
710
+ await runUpdate(targetDir);
711
+ });
712
+ return cmd;
713
+ }
714
+
639
715
  const program = new Command();
640
716
  program
641
717
  .name('osddt')
@@ -644,4 +720,5 @@ program
644
720
  program.addCommand(setupCommand());
645
721
  program.addCommand(metaInfoCommand());
646
722
  program.addCommand(doneCommand());
723
+ program.addCommand(updateCommand());
647
724
  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.8.0",
4
4
  "description": "Package for Spec-Driven Development workflow",
5
5
  "keywords": [
6
6
  "spec-driven",