sdd-cli 0.1.23 → 0.1.24

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
@@ -2,60 +2,22 @@
2
2
 
3
3
  Specification-driven delivery CLI that turns requirements into specs, architecture, tests, and traceable docs.
4
4
 
5
- ## Repository overview
6
-
7
- This repo hosts the CLI implementation, domain flows, templates, schemas, and structured documentation for the SDD workflow.
5
+ ## Repository overview
6
+
7
+ This repo hosts the CLI implementation, domain flows, templates, schemas, and structured documentation for the SDD workflow.
8
8
 
9
9
  ## Vision (think pyramids)
10
10
 
11
11
  Build the foundation once, then lift everything else. The tool provides a durable structure: requirements, architecture, technical specs, quality gates, test plans, and decision logs. AI gets "wings" by being guided, constrained, and accountable at every step.
12
12
 
13
- Mission and vision live in `docs/MISSION.md` and `docs/VISION.md`.
14
-
15
- Start with `docs/INDEX.md` for a full documentation map and `docs/STYLE.md` for formatting guidance.
16
- Contributing guidelines live in `docs/CONTRIBUTING.md`.
17
- Contributor quickstart lives in `docs/CONTRIBUTOR_QUICKSTART.md`.
18
- Issue triage taxonomy lives in `docs/ISSUE_TRIAGE_PLAYBOOK.md`.
19
- Use the PR template in `.github/PULL_REQUEST_TEMPLATE.md`.
20
- Maintenance guidance lives in `docs/MAINTENANCE.md`.
21
- Install troubleshooting lives in `docs/TROUBLESHOOTING.md`.
22
-
23
- Deep process, commands, interactions, and diagrams live in:
24
- - `docs/PROCESS.md`
25
- - `docs/COMMANDS.md`
26
- - `docs/INTERACTIONS.md`
27
- - `docs/DIAGRAMS.md`
28
- - `docs/ARCHITECTURE.md`
29
- - `docs/SDD_CHECKLIST.md`
30
- - `docs/GLOSSARY.md`
31
- - `docs/VALIDATION_CHECKLIST.md`
32
- - `docs/FLOW_TEMPLATE_MAP.md`
33
- - `docs/GATE_PROMPT_MATRIX.md`
34
- - `docs/TEMPLATE_LINT_RULES.md`
35
- - `docs/FLOW_GATE_MAP.md`
36
- - `docs/FLOW_COMPLIANCE_CHECKLIST.md`
37
- - `docs/RELEASE_READINESS_CHECKLIST.md`
38
- - `docs/AUTOMATION_OUTLINE.md`
39
- - `docs/GATE_SCHEMA_MAP.md`
40
- - `docs/GATE_TEMPLATE_MAP.md`
41
- - `docs/KNOWLEDGE_MODE_CHECKLIST.md`
42
- - `docs/DOMAIN_COMPLETENESS_CHECKLIST.md`
43
- - `docs/IMPLEMENTATION_PLAN.md`
44
- - `docs/CLEAN_ARCHITECTURE_CHECKLIST.md`
45
- - `docs/REQUIREMENTS_ALIGNMENT.md`
46
- - `docs/GITFLOW.md`
47
- - `docs/RELEASE_PROCESS.md`
48
-
49
- Reports live in:
50
- - `docs/reports/E2E_REPORT.md`
51
- - `docs/reports/FLOW_COVERAGE.md`
52
- - `docs/reports/GATE_COVERAGE_REPORT.md`
53
- - `docs/reports/GATE_TEMPLATE_COVERAGE_REPORT.md`
54
- - `docs/reports/PACK_COVERAGE_REPORT.md`
55
- - `docs/reports/PROMPT_AUDIT_REPORT.md`
56
- - `docs/reports/PROMPT_COVERAGE_REPORT.md`
57
- - `docs/reports/QUALITY_SCORE_RUBRIC.md`
58
- - `docs/reports/SPEC_COMPLETENESS_REPORT.md`
13
+ Documentation entry points:
14
+ - `docs/INDEX.md` (full docs map)
15
+ - `docs/COMMANDS.md` (CLI command reference)
16
+ - `docs/INTERACTIONS.md` (orchestration model and provider contract)
17
+ - `docs/ERROR_CODES.md` (machine-readable remediation map)
18
+ - `docs/TROUBLESHOOTING.md` (install/runtime issues)
19
+ - `docs/RELEASE_PROCESS.md` (versioning and publish flow)
20
+ - `docs/CHANGELOG.md` and `docs/releases/` (release history)
59
21
 
60
22
  Examples and templates:
61
23
  - `examples/transcripts/`
@@ -123,15 +85,15 @@ Package name on npm is `sdd-cli` (CLI commands remain `sdd-cli` and `sdd`).
123
85
 
124
86
  Project names must use letters, numbers, spaces, `-` or `_`, and cannot include path separators.
125
87
 
126
- The `hello` command is the entry point: it connects to AI, lists active projects, and offers to create a new one or continue.
127
- Default behavior is now a guided autopilot from discovery to completion with minimal prompts.
128
- When you pass direct intent text (`sdd-cli hello "..."`), hello uses auto-guided defaults and minimizes confirmations.
129
- Use `--questions` when you want the manual question-by-question flow.
88
+ The `hello` command is the entry point: it loads workspace context, lists active projects, routes intent, and runs the guided autopilot flow.
89
+ Default behavior is now a guided autopilot from discovery to completion with minimal prompts.
90
+ When you pass direct intent text (`sdd-cli hello "..."`), hello uses auto-guided defaults and minimizes confirmations.
91
+ Use `--questions` when you want the manual question-by-question flow.
130
92
 
131
93
  ## The happy path (end-to-end flow)
132
94
 
133
- 1) **Start**
134
- `sdd-cli hello` connects to AI, shows active projects, and asks if you want to start new or continue.
95
+ 1) **Start**
96
+ `sdd-cli hello` loads workspace state, shows active projects, and asks if you want to start new or continue.
135
97
 
136
98
  2) **Autopilot Discovery**
137
99
  Creates a requirement draft in backlog with validated defaults.
@@ -145,24 +107,32 @@ Use `--questions` when you want the manual question-by-question flow.
145
107
  5) **Autopilot Verify**
146
108
  Updates/validates test-plan artifacts.
147
109
 
148
- 6) **Autopilot Finish**
149
- Finalizes requirement, writes project-level README artifacts, and moves requirement to `done`.
150
-
151
- 7) **Manual Detail (optional)**
152
- Run `sdd-cli hello --questions` when you prefer detailed prompt packs before drafting.
153
-
154
- ## Commands (proposed)
155
-
156
- ### Core
157
- - `sdd-cli hello` -- interactive session, project picker, full guided flow
158
- - `sdd-cli quickstart` -- one-command demo flow with built-in examples
110
+ 6) **Autopilot Finish**
111
+ Finalizes requirement, writes project-level README artifacts, and moves requirement to `done`.
112
+
113
+ 7) **App Lifecycle Orchestration**
114
+ Generates code scaffold in `generated-app`, runs quality checks (when scripts exist), prepares local deploy artifacts, initializes git, and attempts GitHub publish when `gh` is authenticated.
115
+
116
+ 8) **Manual Detail (optional)**
117
+ Run `sdd-cli hello --questions` when you prefer detailed prompt packs before drafting.
118
+
119
+ ## Commands (proposed)
120
+
121
+ ### Core
122
+ - `sdd-cli hello` -- interactive session, project picker, full guided flow
123
+ - `sdd-cli suite "<goal>"` -- continuous orchestration mode; asks only blocking decisions and executes full delivery end-to-end
124
+ - `sdd-cli quickstart` -- one-command demo flow with built-in examples
159
125
  - `sdd-cli init` -- create SDD workspace and config
160
126
  - `sdd-cli list` -- list flows, router flows, templates, prompt packs, and projects
161
127
  - `sdd-cli status --next` -- show current project state and exact next command
162
128
  - `sdd-cli scope list` -- list monorepo workspace scopes
163
129
  - `sdd-cli scope status <scope>` -- show status summary for one scope
164
- - `sdd-cli doctor` -- validate completeness and consistency
165
- - `sdd-cli doctor --fix` -- apply safe remediations for missing requirement ops files
130
+ - `sdd-cli doctor` -- validate completeness and consistency
131
+ - `sdd-cli doctor --fix` -- apply safe remediations for missing requirement ops files
132
+ - `sdd-cli config show` -- show active config and config file path
133
+ - `sdd-cli config init` -- create default config file
134
+ - `sdd-cli config set <key> <value>` -- update config (`workspace.default_root|ai.preferred_cli|ai.model|mode.default|git.publish_enabled`)
135
+ - include `git.publish_enabled` (`true|false`) to control GitHub publish attempts
166
136
 
167
137
  ### Router
168
138
  - `sdd-cli route` -- classify user intent and route to the right flow
@@ -211,8 +181,10 @@ Use `--questions` when you want the manual question-by-question flow.
211
181
  - `--improve` -- re-open and enhance existing docs
212
182
  - `--output <path>` -- override workspace output
213
183
  - `--scope <name>` -- isolate artifacts by monorepo scope namespace
214
- - `--metrics-local` -- record local opt-in telemetry snapshots in `workspace/metrics`
215
- - `--project <name>` -- set project name
184
+ - `--metrics-local` -- record local opt-in telemetry snapshots in `workspace/metrics`
185
+ - `--provider <name>` -- select AI provider (`gemini|codex|auto`), default `gemini`
186
+ - `--gemini` -- shortcut for `--provider gemini`
187
+ - `--project <name>` -- set project name
216
188
  - `--parallel` -- generate in parallel
217
189
  - `--questions` -- use manual question-driven discovery flow
218
190
  - `--non-interactive` -- run without confirmations (script/CI friendly)
@@ -259,13 +231,24 @@ For a full onboarding walkthrough, see:
259
231
  - Error codes and remediation guide: `docs/ERROR_CODES.md`
260
232
  - Integration adapters roadmap and contract: `docs/INTEGRATION_ADAPTERS.md`
261
233
 
262
- ## Where files are stored (clean repos)
263
-
264
- By default, the tool writes to a dedicated workspace, not into your repo:
265
-
266
- - Default (global workspace):
267
- - Windows: `%APPDATA%/sdd-cli/workspaces/<project>`
268
- - macOS/Linux: `~/.config/sdd-cli/workspaces/<project>`
234
+ ## Where files are stored (clean repos)
235
+
236
+ By default, the tool writes to a dedicated workspace, not into your repo:
237
+
238
+ - Default (config-driven workspace):
239
+ - Windows/macOS/Linux default: `~/Documents/sdd-tool-projects/<project>`
240
+ - Example on this machine: `C:\Users\jdsal\Documents\sdd-tool-projects\<project>`
241
+
242
+ Config file:
243
+ - Windows: `%APPDATA%/sdd-cli/config.yml`
244
+ - macOS/Linux: `~/.config/sdd-cli/config.yml`
245
+
246
+ Default config values:
247
+ - `workspace.default_root`: `{{home}}/Documents/sdd-tool-projects`
248
+ - `ai.preferred_cli`: `gemini`
249
+ - `ai.model`: `gemini-2.5-flash-lite`
250
+ - `mode.default`: `guided`
251
+ - `git.publish_enabled`: `false`
269
252
 
270
253
  Optional:
271
254
  - `--output ./docs/sdd` to keep SDD next to the repo
@@ -559,7 +542,7 @@ Implementation readiness:
559
542
  ## Interactive session (hello) design
560
543
 
561
544
  ### Steps
562
- 1) **Connect** to AI and load local workspace index.
545
+ 1) **Load** local workspace index and runtime flags.
563
546
  2) **List active projects** with status (backlog, wip, done).
564
547
  3) **Choose**: start new or continue.
565
548
  4) **Context**: ask domain and persona to load the right flow.
@@ -624,14 +607,17 @@ The tool can generate C4-style diagrams using templates:
624
607
 
625
608
  These are exported as text (Mermaid/PlantUML) to keep them versionable.
626
609
 
627
- ## Provider abstraction (AI)
628
-
629
- The CLI is provider-agnostic:
630
- - Local model
631
- - Remote model
632
- - Codex-compatible
633
-
634
- The router selects agent roles, while the provider is configurable.
610
+ ## Provider abstraction (AI)
611
+
612
+ The CLI is provider-agnostic:
613
+ - Local model
614
+ - Remote model
615
+ - Codex-compatible
616
+
617
+ The router selects agent roles, while the provider is configurable.
618
+ Current implementation status:
619
+ - `hello` remains local-first autopilot and now includes optional provider-assisted draft/code generation with fallback-safe defaults.
620
+ - Direct provider checks/execution are also available through `sdd-cli ai status` and `sdd-cli ai exec`.
635
621
 
636
622
  ## Privacy and approvals
637
623
 
package/dist/cli.js CHANGED
@@ -46,6 +46,7 @@ const route_1 = require("./commands/route");
46
46
  const doctor_1 = require("./commands/doctor");
47
47
  const quickstart_1 = require("./commands/quickstart");
48
48
  const status_1 = require("./commands/status");
49
+ const suite_1 = require("./commands/suite");
49
50
  const import_issue_1 = require("./commands/import-issue");
50
51
  const import_jira_1 = require("./commands/import-jira");
51
52
  const import_linear_1 = require("./commands/import-linear");
@@ -54,6 +55,8 @@ const paths_1 = require("./paths");
54
55
  const flags_1 = require("./context/flags");
55
56
  const prompt_1 = require("./ui/prompt");
56
57
  const local_metrics_1 = require("./telemetry/local-metrics");
58
+ const providers_1 = require("./providers");
59
+ const config_1 = require("./config");
57
60
  const program = new commander_1.Command();
58
61
  function getVersion() {
59
62
  try {
@@ -79,22 +82,36 @@ program
79
82
  .option("--project <name>", "Select or name the project")
80
83
  .option("--output <path>", "Override workspace output root")
81
84
  .option("--scope <name>", "Target a monorepo scope namespace inside the workspace")
82
- .option("--metrics-local", "Enable local opt-in telemetry snapshots in workspace/metrics");
85
+ .option("--metrics-local", "Enable local opt-in telemetry snapshots in workspace/metrics")
86
+ .option("--provider <name>", "AI provider: gemini|codex|auto", (0, providers_1.defaultProviderPreference)())
87
+ .option("--model <name>", "AI model id (for providers that support model override)")
88
+ .option("--gemini", "Shortcut for --provider gemini");
83
89
  program.hook("preAction", (thisCommand, actionCommand) => {
90
+ const config = (0, config_1.ensureConfig)();
84
91
  const opts = typeof actionCommand.optsWithGlobals === "function" ? actionCommand.optsWithGlobals() : thisCommand.opts();
92
+ const defaultMode = config.mode.default;
93
+ const nonInteractive = Boolean(opts.nonInteractive) || defaultMode === "non-interactive";
94
+ const beginner = Boolean(opts.beginner) || defaultMode === "beginner";
85
95
  (0, flags_1.setFlags)({
86
96
  approve: Boolean(opts.approve),
87
97
  improve: Boolean(opts.improve),
88
98
  parallel: Boolean(opts.parallel),
89
- nonInteractive: Boolean(opts.nonInteractive),
99
+ nonInteractive,
90
100
  dryRun: Boolean(opts.dryRun),
91
- beginner: Boolean(opts.beginner),
101
+ beginner,
92
102
  fromStep: typeof opts.fromStep === "string" ? opts.fromStep : undefined,
93
103
  project: typeof opts.project === "string" ? opts.project : undefined,
94
104
  output: typeof opts.output === "string" ? opts.output : undefined,
95
105
  scope: typeof opts.scope === "string" ? opts.scope : undefined,
96
- metricsLocal: Boolean(opts.metricsLocal)
106
+ metricsLocal: Boolean(opts.metricsLocal),
107
+ provider: Boolean(opts.gemini)
108
+ ? "gemini"
109
+ : typeof opts.provider === "string"
110
+ ? opts.provider
111
+ : config.ai.preferred_cli,
112
+ model: typeof opts.model === "string" ? opts.model : config.ai.model
97
113
  });
114
+ process.env.SDD_GEMINI_MODEL = typeof opts.model === "string" ? opts.model : config.ai.model;
98
115
  const commandPath = typeof actionCommand.name === "function"
99
116
  ? `${thisCommand.name()} ${actionCommand.name()}`.trim()
100
117
  : thisCommand.name();
@@ -120,6 +137,11 @@ program
120
137
  .option("--example <name>", "Example prompt: saas|bugfix|api|ecommerce|mobile")
121
138
  .option("--list-examples", "List available example prompts")
122
139
  .action((options) => (0, quickstart_1.runQuickstart)(options.example, options.listExamples));
140
+ program
141
+ .command("suite")
142
+ .description("Run continuous SDD orchestration mode (asks only blocking decisions)")
143
+ .argument("[input...]", "Optional initial goal")
144
+ .action((input) => (0, suite_1.runSuite)(input.join(" ").trim()));
123
145
  program
124
146
  .command("list")
125
147
  .description("List flows, templates, and projects")
@@ -369,17 +391,48 @@ program
369
391
  .argument("[requirementId]", "Optional requirement ID to validate")
370
392
  .option("--fix", "Apply safe remediations (missing changelog/progress-log)")
371
393
  .action((project, requirementId, options) => (0, doctor_1.runDoctor)(project, requirementId, Boolean(options.fix)));
372
- const ai = program.command("ai").description("Codex provider commands");
394
+ const configCmd = program.command("config").description("Configuration commands");
395
+ configCmd
396
+ .command("show")
397
+ .description("Show effective config and config file path")
398
+ .action(() => {
399
+ const config = (0, config_1.ensureConfig)();
400
+ console.log(`Config file: ${(0, config_1.configPath)()}`);
401
+ console.log(JSON.stringify(config, null, 2));
402
+ });
403
+ configCmd
404
+ .command("init")
405
+ .description("Create config file with defaults if missing")
406
+ .action(() => {
407
+ const config = (0, config_1.ensureConfig)();
408
+ console.log(`Config ready: ${(0, config_1.configPath)()}`);
409
+ console.log(`Workspace default root: ${config.workspace.default_root}`);
410
+ });
411
+ configCmd
412
+ .command("set")
413
+ .description("Set config value by key")
414
+ .argument("<key>", "Key: workspace.default_root | ai.preferred_cli | ai.model | mode.default | git.publish_enabled")
415
+ .argument("<value>", "Value for key")
416
+ .action((key, value) => {
417
+ const updated = (0, config_1.updateConfigValue)(key, value);
418
+ if (!updated) {
419
+ console.log("[SDD-1506] Invalid config key. Use workspace.default_root, ai.preferred_cli, ai.model, mode.default, git.publish_enabled.");
420
+ return;
421
+ }
422
+ console.log(`Config updated: ${(0, config_1.configPath)()}`);
423
+ console.log(JSON.stringify(updated, null, 2));
424
+ });
425
+ const ai = program.command("ai").description("AI provider commands");
373
426
  ai
374
427
  .command("status")
375
- .description("Check Codex CLI availability")
428
+ .description("Check AI provider CLI availability")
376
429
  .action(async () => {
377
430
  const { runAiStatus } = await Promise.resolve().then(() => __importStar(require("./commands/ai-status")));
378
431
  runAiStatus();
379
432
  });
380
433
  ai
381
434
  .command("exec")
382
- .description("Run Codex non-interactively")
435
+ .description("Run configured AI provider non-interactively")
383
436
  .argument("[prompt...]", "Prompt to execute")
384
437
  .action(async (prompt) => {
385
438
  const { runAiExec } = await Promise.resolve().then(() => __importStar(require("./commands/ai-exec")));
@@ -414,4 +467,51 @@ importCmd
414
467
  .action(async (workItem) => {
415
468
  await (0, import_azure_1.runImportAzure)(workItem);
416
469
  });
417
- program.parse(process.argv);
470
+ const knownTopLevel = new Set([
471
+ "hello",
472
+ "init",
473
+ "quickstart",
474
+ "suite",
475
+ "list",
476
+ "status",
477
+ "scope",
478
+ "req",
479
+ "pr",
480
+ "test",
481
+ "gen",
482
+ "learn",
483
+ "route",
484
+ "doctor",
485
+ "config",
486
+ "ai",
487
+ "import"
488
+ ]);
489
+ function normalizeArgv(argv) {
490
+ const passthrough = argv.slice(0, 2);
491
+ const args = argv.slice(2);
492
+ if (args.length === 0) {
493
+ return argv;
494
+ }
495
+ const valueFlags = new Set(["--from-step", "--project", "--output", "--scope", "--provider", "--model"]);
496
+ let positionalIndex = -1;
497
+ for (let i = 0; i < args.length; i += 1) {
498
+ const token = args[i];
499
+ if (!token.startsWith("-")) {
500
+ positionalIndex = i;
501
+ break;
502
+ }
503
+ if (valueFlags.has(token)) {
504
+ i += 1;
505
+ }
506
+ }
507
+ if (positionalIndex < 0) {
508
+ return argv;
509
+ }
510
+ const firstPositional = args[positionalIndex];
511
+ if (knownTopLevel.has(firstPositional)) {
512
+ return argv;
513
+ }
514
+ // Supports one-command UX: sdd-tool "create a calculator"
515
+ return [...passthrough, ...args.slice(0, positionalIndex), "hello", ...args.slice(positionalIndex)];
516
+ }
517
+ program.parse(normalizeArgv(process.argv));
@@ -0,0 +1,19 @@
1
+ import { RequirementDraft } from "./req-create";
2
+ export declare function resetToFunctionalBaseline(appDir: string, projectName: string, intent: string): number;
3
+ export declare function enrichDraftWithAI(input: string, flow: string, domain: string, baseDraft: RequirementDraft, providerRequested?: string): RequirementDraft;
4
+ export type CodeBootstrapResult = {
5
+ attempted: boolean;
6
+ provider?: string;
7
+ generated: boolean;
8
+ outputDir: string;
9
+ fileCount: number;
10
+ reason?: string;
11
+ };
12
+ export type ImproveAppResult = {
13
+ attempted: boolean;
14
+ applied: boolean;
15
+ fileCount: number;
16
+ reason?: string;
17
+ };
18
+ export declare function bootstrapProjectCode(projectRoot: string, projectName: string, intent: string, providerRequested?: string): CodeBootstrapResult;
19
+ export declare function improveGeneratedApp(appDir: string, intent: string, providerRequested?: string, qualityDiagnostics?: string[]): ImproveAppResult;