@dezkareid/osddt 1.0.0 → 1.1.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/README.md CHANGED
@@ -5,13 +5,13 @@ Other spec driven development tool but for monorepo
5
5
 
6
6
  | Command | Description |
7
7
  | ------------------------------ | ------------------------------------------------------------- |
8
- | `osddt setup` | Generate agent command files for Claude and Gemini |
9
- | `osddt meta-info` | Output current branch and date as JSON |
10
- | `osddt done <feature-name>` | Move `working-on/<feature>` to `done/<feature>` |
8
+ | `@dezkareid/osddt setup` | Generate agent command files for Claude and Gemini |
9
+ | `@dezkareid/osddt meta-info` | Output current branch and date as JSON |
10
+ | `@dezkareid/osddt done <feature-name>` | Move `working-on/<feature>` to `done/<feature>` |
11
11
 
12
12
  ## Command Templates
13
13
 
14
- Run `osddt setup` once to generate the agent command files.
14
+ Run `npx @dezkareid/osddt setup` once to generate the agent command files.
15
15
 
16
16
  `osddt.research` and `osddt.start` are **peer entry points** — use whichever fits your situation. Both lead to `osddt.spec`. Use `osddt.continue` to resume an in-progress feature from a new session.
17
17
 
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { Command } from 'commander';
3
3
  import path from 'path';
4
4
  import fs from 'fs-extra';
5
5
  import select from '@inquirer/select';
6
+ import checkbox from '@inquirer/checkbox';
6
7
  import { execSync } from 'child_process';
7
8
 
8
9
  const REPO_PREAMBLE = `## Context
@@ -10,7 +11,7 @@ const REPO_PREAMBLE = `## Context
10
11
  Before proceeding, run the following command and parse the JSON output to get the current branch and date:
11
12
 
12
13
  \`\`\`
13
- npx osddt meta-info
14
+ npx @dezkareid/osddt meta-info
14
15
  \`\`\`
15
16
 
16
17
  ## Repository Configuration
@@ -321,7 +322,7 @@ Once all tasks are checked off, run the following command to mark the feature as
321
322
  2. Run the following command to move the feature folder from \`working-on\` to \`done\`:
322
323
 
323
324
  \`\`\`
324
- npx osddt done ${args}
325
+ npx @dezkareid/osddt done ${args}
325
326
  \`\`\`
326
327
 
327
328
  The command will automatically prefix the destination folder name with today's date in \`YYYY-MM-DD\` format.
@@ -385,6 +386,29 @@ async function askRepoType() {
385
386
  ],
386
387
  });
387
388
  }
389
+ async function askAgents() {
390
+ return checkbox({
391
+ message: 'Which AI assistant tools do you want to set up?',
392
+ choices: [
393
+ {
394
+ name: 'Claude Code',
395
+ value: 'claude',
396
+ checked: true,
397
+ },
398
+ {
399
+ name: 'Gemini CLI',
400
+ value: 'gemini',
401
+ checked: true,
402
+ },
403
+ ],
404
+ validate(choices) {
405
+ if (choices.length === 0) {
406
+ return 'You must select at least one agent.';
407
+ }
408
+ return true;
409
+ },
410
+ });
411
+ }
388
412
 
389
413
  async function writeCommandFile(file) {
390
414
  await fs.ensureDir(path.dirname(file.filePath));
@@ -397,18 +421,26 @@ async function writeConfig(cwd, config) {
397
421
  console.log(`\nSaved config: ${configPath}`);
398
422
  }
399
423
  async function runSetup(cwd) {
424
+ const agents = await askAgents();
425
+ console.log('');
400
426
  const repoType = await askRepoType();
401
427
  console.log('');
402
428
  console.log('Setting up OSDDT command files...\n');
403
- const claudeFiles = getClaudeTemplates(cwd);
404
- const geminiFiles = getGeminiTemplates(cwd);
405
- console.log('Claude Code commands (.claude/commands/):');
406
- for (const file of claudeFiles) {
407
- await writeCommandFile(file);
429
+ if (agents.includes('claude')) {
430
+ const claudeFiles = getClaudeTemplates(cwd);
431
+ console.log('Claude Code commands (.claude/commands/):');
432
+ for (const file of claudeFiles) {
433
+ await writeCommandFile(file);
434
+ }
435
+ console.log('');
408
436
  }
409
- console.log('\nGemini CLI commands (.gemini/commands/):');
410
- for (const file of geminiFiles) {
411
- await writeCommandFile(file);
437
+ if (agents.includes('gemini')) {
438
+ const geminiFiles = getGeminiTemplates(cwd);
439
+ console.log('Gemini CLI commands (.gemini/commands/):');
440
+ for (const file of geminiFiles) {
441
+ await writeCommandFile(file);
442
+ }
443
+ console.log('');
412
444
  }
413
445
  await writeConfig(cwd, { repoType });
414
446
  console.log('\nSetup complete!');
@@ -1,4 +1,4 @@
1
- export declare const REPO_PREAMBLE = "## Context\n\nBefore proceeding, run the following command and parse the JSON output to get the current branch and date:\n\n```\nnpx osddt meta-info\n```\n\n## Repository Configuration\n\nBefore proceeding, read the `.osddtrc` file in the root of the repository to determine the project path.\n\n```json\n// .osddtrc example\n{ \"repoType\": \"monorepo\" | \"single\" }\n```\n\n- If `repoType` is `\"single\"`: the project path is the repository root.\n- If `repoType` is `\"monorepo\"`: ask the user which package to work on (e.g. `packages/my-package`), then use `<repo-root>/<package>` as the project path.\n\n## Working Directory\n\nAll generated files live under `<project-path>/working-on/<feature-name>/`. The `<feature-name>` is derived from the arguments provided. Create the directory if it does not exist.\n\n> All file paths in the instructions below are relative to `<project-path>/working-on/<feature-name>/`.\n\n";
1
+ export declare const REPO_PREAMBLE = "## Context\n\nBefore proceeding, run the following command and parse the JSON output to get the current branch and date:\n\n```\nnpx @dezkareid/osddt meta-info\n```\n\n## Repository Configuration\n\nBefore proceeding, read the `.osddtrc` file in the root of the repository to determine the project path.\n\n```json\n// .osddtrc example\n{ \"repoType\": \"monorepo\" | \"single\" }\n```\n\n- If `repoType` is `\"single\"`: the project path is the repository root.\n- If `repoType` is `\"monorepo\"`: ask the user which package to work on (e.g. `packages/my-package`), then use `<repo-root>/<package>` as the project path.\n\n## Working Directory\n\nAll generated files live under `<project-path>/working-on/<feature-name>/`. The `<feature-name>` is derived from the arguments provided. Create the directory if it does not exist.\n\n> All file paths in the instructions below are relative to `<project-path>/working-on/<feature-name>/`.\n\n";
2
2
  export declare const FEATURE_NAME_RULES = "### Feature Name Constraints\n\nWhen deriving a feature name from a description:\n\n- Use only lowercase letters, digits, and hyphens (`a-z`, `0-9`, `-`)\n- Replace spaces and special characters with hyphens\n- Remove consecutive hyphens (e.g. `--` \u2192 `-`)\n- Remove leading and trailing hyphens\n- **Maximum length: 30 characters** \u2014 if the derived name exceeds 30 characters, truncate at the last hyphen boundary before or at the 30th character\n- If the input is already a valid branch name (no spaces, kebab-case or slash-separated), apply the 30-character limit to the last segment only (after the last `/`)\n- Reject (and ask the user to provide a shorter name) if no valid name can be derived after truncation\n\n**Examples:**\n\n| Input | Derived feature name |\n| ----------------------------------------------------- | ---------------------------- |\n| `Add user authentication` | `add-user-authentication` |\n| `Implement real-time notifications for dashboard` | `implement-real-time` |\n| `feat/add-user-authentication` | `add-user-authentication` |\n| `feat/implement-real-time-notifications-for-dashboard` | `implement-real-time` |\n";
3
3
  export declare const WORKING_DIR_STEP = "Check whether the working directory `<project-path>/working-on/<feature-name>` already exists:\n - If it **does not exist**, create it:\n ```\n mkdir -p <project-path>/working-on/<feature-name>\n ```\n - If it **already exists**, warn the user and ask whether to:\n - **Resume** \u2014 continue into the existing folder (proceed to the next step without recreating it)\n - **Abort** \u2014 stop and do nothing";
4
4
  export type ArgPlaceholder = '$ARGUMENTS' | '{{args}}';
@@ -1,2 +1,4 @@
1
1
  export type RepoType = 'monorepo' | 'single';
2
+ export type AgentType = 'claude' | 'gemini';
2
3
  export declare function askRepoType(): Promise<RepoType>;
4
+ export declare function askAgents(): Promise<AgentType[]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dezkareid/osddt",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Package for Spec-Driven Development workflow",
5
5
  "keywords": [
6
6
  "spec-driven",
@@ -30,6 +30,7 @@
30
30
  },
31
31
  "main": "./dist/index.js",
32
32
  "dependencies": {
33
+ "@inquirer/checkbox": "5.0.7",
33
34
  "@inquirer/select": "5.0.7",
34
35
  "commander": "12.0.0",
35
36
  "fs-extra": "11.2.0",