@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 +7 -2
- package/README.md +3 -0
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.spec.d.ts +1 -0
- package/dist/index.js +81 -4
- package/package.json +1 -1
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
|
-
│ │
|
|
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
|
package/dist/commands/setup.d.ts
CHANGED
|
@@ -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);
|