@tmddev/tmd 0.1.0 → 0.2.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
@@ -9,7 +9,9 @@
9
9
  <p align="center">
10
10
  <a href="https://tmdd.dev"><img alt="Website" src="https://img.shields.io/badge/Website-tmdd.dev-blue?style=flat-square" /></a>
11
11
  <a href="https://github.com/sdd330/tmd/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/sdd330/tmd/actions/workflows/ci.yml/badge.svg" /></a>
12
- <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
12
+ <a href="https://www.npmjs.com/package/@tmddev/tmd"><img alt="npm version" src="https://img.shields.io/npm/v/@tmddev/tmd?style=flat-square" /></a>
13
+ <a href="https://nodejs.org/"><img alt="node version" src="https://img.shields.io/node/v/@tmddev/tmd?style=flat-square" /></a>
14
+ <a href="./LICENSE"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat-square" /></a>
13
15
  <a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square" /></a>
14
16
  </p>
15
17
 
@@ -34,9 +36,11 @@ At the core of TMD is the principle that tasks should be **pee-break (10 seconds
34
36
  ## Features
35
37
 
36
38
  - **PDCA Cycle Management**: Four-phase commands for Plan, Do, Check, and Act
39
+ - **Pipe Execution**: Automated PDCA cycles without human input for CI/CD and AI agent workflows
37
40
  - **Ten sec to Ten min Task!**: Tasks are designed to be pee-break (10 seconds to 10 minutes) sized for quick completion
38
41
  - **OpenSpec Integration**: Automatic creation and linking of OpenSpec change proposals
39
42
  - **Skills System**: Reusable capabilities for AI agents with cross-agent invocation support
43
+ - **Step Executors**: Built-in executors for bash commands, file operations, and API calls
40
44
  - **English Language Standard**: All documents and specifications use English
41
45
  - **Markdown-Based**: All documentation stored in Markdown format
42
46
  - **CLI Interface**: Simple command-line interface with aliases
@@ -44,7 +48,7 @@ At the core of TMD is the principle that tasks should be **pee-break (10 seconds
44
48
  ## Installation
45
49
 
46
50
  ### Prerequisites
47
- - **Node.js >= 20.19.0** - Check your version with `node --version`
51
+ - **Node.js >= 20.19.0** or **Bun >= 1.0** — Check with `node --version` or `bun --version`
48
52
 
49
53
  ### Install the CLI globally
50
54
 
@@ -72,6 +76,38 @@ pnpm run build
72
76
  pnpm link --global # Optional: link for local development
73
77
  ```
74
78
 
79
+ **Option D: Using Bun**
80
+ ```bash
81
+ bun install -g @tmddev/tmd@latest
82
+ # or run without global install:
83
+ bun x @tmddev/tmd --version
84
+ bun run tmd --help # when in a project with @tmddev/tmd as a dependency
85
+ ```
86
+ In the TMD repo: `bun install`, `bun run build`, `bun run test`, and `bun ./bin/tmd.js --version` are all supported.
87
+
88
+ ### Install from source
89
+
90
+ **Prerequisites:** Node.js >=20.19.0 or Bun >=1.0, pnpm, [Rust](https://rustup.rs/) (for the `tmd-skills` binary), git.
91
+
92
+ ```bash
93
+ git clone https://github.com/sdd330/tmd.git
94
+ cd tmd
95
+ pnpm install
96
+ pnpm build # includes the tmd-skills native binary
97
+ pnpm link --global # optional: use `tmd` from this build
98
+ ```
99
+
100
+ Optional:
101
+
102
+ - **`pnpm build:native`** — Rebuild only the `tmd-skills` Rust binary (faster when only Rust code changed).
103
+ - **`./bin/agent-browser install`** — When using the agent-browser skill, install the agent-browser CLI if this script is provided (e.g. by the agent-browser project; skip if not present).
104
+
105
+ Example: add the `pdf` skill from [anthropics/skills](https://github.com/anthropics/skills) and symlink to all detected agents:
106
+
107
+ ```bash
108
+ tmd skills add anthropics/skills --github --skill pdf --all
109
+ ```
110
+
75
111
  ## Quick Start
76
112
 
77
113
  ### 1. Create a Plan
@@ -162,6 +198,18 @@ This principle ensures tasks are:
162
198
 
163
199
  ## Commands
164
200
 
201
+ ### Setup and Dashboard
202
+
203
+ - `tmd init [path]` - Initialize TMD in your project (creates `tmd/` and `schemas/pdca/` when missing; default path `.`)
204
+ - `tmd view` - Display a dashboard of tasks by phase and status
205
+ - `tmd validate [task-id]` - Validate task documents or PDCA schemas
206
+ - `--schemas [name]` - Validate schemas only (name optional)
207
+ - `--all` - Validate all tasks and schemas
208
+ - `--strict` - Stricter checks (e.g. task size)
209
+ - `--json` - Output as JSON
210
+ - `tmd schemas` - List available workflow schemas
211
+ - `--json` - Output as JSON
212
+
165
213
  ### PDCA Commands
166
214
 
167
215
  - `tmd plan <description>` / `tmdp` - Create a new plan
@@ -190,12 +238,28 @@ This principle ensures tasks are:
190
238
 
191
239
  - `tmd show <task-id>` - Show task details
192
240
 
241
+ ### Pipe (Automated PDCA)
242
+
243
+ - `tmd pipe init <task-id>` - Initialize pipe configuration
244
+ - `--force` - Overwrite existing configuration
245
+
246
+ - `tmd pipe run <task-id>` - Run full PDCA cycle automatically
247
+ - `--from <phase>` - Start from specific phase (do, check, act)
248
+ - `--dry-run` - Preview execution without making changes
249
+
250
+ - `tmd pipe status <task-id>` - Show pipe execution state
251
+ - `--json` - Output in JSON format
252
+
193
253
  ### Skills Management
194
254
 
195
255
  - `tmd skills list` - List all available skills
256
+ - `--tag <tag>` - Filter by tag (repeatable, OR semantics)
196
257
  - `tmd skills search <query>` - Search skills
197
258
  - `tmd skills show <skill-name>` - Show skill details
198
259
  - `tmd skills invoke <skill-name> --input <params>` - Invoke a skill
260
+ - `tmd skills create <name>` - Create a skill (optionally `--description <desc>`, `--tags <t1,t2>`)
261
+ - `tmd skills update <name>` - Update metadata (`--description <desc>`, `--tags <t1,t2>`; at least one required)
262
+ - `tmd skills remove <name>` - Remove a skill (`--force` to skip confirmation)
199
263
 
200
264
  ## Skills System
201
265
 
@@ -244,6 +308,94 @@ Skills can be invoked by any AI agent:
244
308
  tmd skill invoke generate-readme-multilang --input "template_path=README.md target_languages=[zh,es,fr]"
245
309
  ```
246
310
 
311
+ ## Pipe Execution
312
+
313
+ Pipe execution enables fully automated PDCA cycles without human intervention - ideal for CI/CD integration and AI agent workflows.
314
+
315
+ ### Initialize Pipe
316
+
317
+ ```bash
318
+ tmd pipe init <task-id>
319
+ ```
320
+
321
+ This creates a `pipeline.yaml` configuration file in the task's plan directory with customizable settings for each phase.
322
+
323
+ ### Run Full Pipe
324
+
325
+ ```bash
326
+ tmd pipe run <task-id>
327
+ ```
328
+
329
+ This automatically executes:
330
+ 1. **Do phase**: Executes all tasks, runs skill steps, captures output
331
+ 2. **Check phase**: Compares results against goals, analyzes deviations
332
+ 3. **Act phase**: Processes results, generates improvements, marks task complete
333
+
334
+ ### Pipeline Configuration
335
+
336
+ ```yaml
337
+ # pipeline.yaml
338
+ version: "1.0"
339
+ phases:
340
+ do:
341
+ auto: true
342
+ parallel: false
343
+ maxConcurrency: 4
344
+ successCriteria:
345
+ minTasksCompleted: "100%"
346
+ check:
347
+ auto: true
348
+ analyze: true
349
+ recommend: true
350
+ act:
351
+ auto: true
352
+ standardize: true
353
+ carryForward: true
354
+ completeOnSuccess: true
355
+ ```
356
+
357
+ ### Step Executors
358
+
359
+ Pipeline supports three step types for automated task execution:
360
+
361
+ - **bash**: Execute shell commands
362
+ ```yaml
363
+ - type: bash
364
+ command: "npm run build"
365
+ ```
366
+
367
+ - **file**: File operations (read, write, copy, delete)
368
+ ```yaml
369
+ - type: file
370
+ operation: write
371
+ path: output.txt
372
+ content: "Hello World"
373
+ ```
374
+
375
+ - **api**: HTTP requests
376
+ ```yaml
377
+ - type: api
378
+ url: "https://api.example.com/data"
379
+ method: POST
380
+ body: { "key": "value" }
381
+ ```
382
+
383
+ ### Dry Run Mode
384
+
385
+ Preview pipe execution without making changes:
386
+
387
+ ```bash
388
+ tmd pipe run <task-id> --dry-run
389
+ ```
390
+
391
+ ### Resume from Phase
392
+
393
+ Start from a specific phase (useful for recovering from failures):
394
+
395
+ ```bash
396
+ tmd pipe run <task-id> --from check
397
+ ```
398
+
247
399
  ## OpenSpec Integration
248
400
 
249
401
  TMD automatically integrates with OpenSpec projects:
@@ -328,6 +480,46 @@ tmd plan "Generate README for new project" --use-skill generate-readme-multilang
328
480
  tmd do <task-id> --skill generate-readme-multilang
329
481
  ```
330
482
 
483
+ ### Example 3: Automated Pipe
484
+
485
+ ```bash
486
+ # Create a plan with tasks
487
+ tmd plan "Build and deploy application"
488
+
489
+ # Initialize pipe configuration
490
+ tmd pipe init 20260123-build-and-deploy-application
491
+
492
+ # Preview what will happen (dry run)
493
+ tmd pipe run 20260123-build-and-deploy-application --dry-run
494
+
495
+ # Run the full automated PDCA cycle
496
+ tmd pipe run 20260123-build-and-deploy-application
497
+
498
+ # Check pipe status
499
+ tmd pipe status 20260123-build-and-deploy-application
500
+ ```
501
+
502
+ Output:
503
+ ```
504
+ Pipe: 20260123-build-and-deploy-application
505
+ ──────────────────────────────────────────────────
506
+
507
+ Phase: DO
508
+ Tasks to execute: 5/5
509
+ Phase do completed
510
+
511
+ Phase: CHECK
512
+ Goals met: 3/3
513
+ Phase check completed
514
+
515
+ Phase: ACT
516
+ Task marked as completed
517
+ Phase act completed
518
+ ──────────────────────────────────────────────────
519
+
520
+ Pipe completed successfully
521
+ ```
522
+
331
523
  ## Language Standard
332
524
 
333
525
  All documents and specifications use English. The system:
@@ -421,4 +613,4 @@ See [MAINTAINERS.md](MAINTAINERS.md) for maintainer information.
421
613
 
422
614
  ## License
423
615
 
424
- MIT
616
+ Apache-2.0
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { createRequire } from 'module';
3
+ import { readFileSync } from 'fs';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { dirname, join } from 'path';
6
6
  import { planCommand } from './commands/plan.js';
@@ -10,20 +10,46 @@ import { actCommand } from './commands/act.js';
10
10
  import { listCommand } from './commands/list.js';
11
11
  import { showCommand } from './commands/show.js';
12
12
  import { skillsCommand } from './commands/skills.js';
13
+ import { pipelineInitCommand, pipelineRunCommand, pipelineStatusCommand } from './commands/pipeline.js';
14
+ import { initCommand } from './commands/init.js';
15
+ import { viewCommand } from './commands/view.js';
16
+ import { validateCommand } from './commands/validate.js';
17
+ import { schemasCommand } from './commands/schemas.js';
13
18
  const program = new Command();
14
- // Use fileURLToPath to resolve package.json relative to project root
15
- // When running from bin/tmd.js -> dist/cli.js, we need to go up from dist/ to project root
16
- const require = createRequire(import.meta.url);
19
+ // Resolve project root: bin/tmd.js -> dist/cli.js -> dist/ -> project root
17
20
  const __filename = fileURLToPath(import.meta.url);
18
- // dist/cli.js -> dist/ -> project root
19
21
  const projectRoot = dirname(dirname(__filename));
20
22
  const packageJsonPath = join(projectRoot, 'package.json');
21
- const pkg = require(packageJsonPath);
23
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
22
24
  const { version } = pkg;
23
25
  program
24
26
  .name('tmd')
25
27
  .description('Task Markdown Driven - PDCA cycle management framework')
26
28
  .version(version);
29
+ // Init
30
+ program
31
+ .command('init')
32
+ .description('Initialize TMD in your project')
33
+ .argument('[path]', 'Target path', '.')
34
+ .action((pathArg) => { initCommand(pathArg); });
35
+ program
36
+ .command('view')
37
+ .description('Display a dashboard of tasks by phase and status')
38
+ .action(viewCommand);
39
+ program
40
+ .command('validate')
41
+ .description('Validate task documents or PDCA schemas')
42
+ .argument('[task-id]', 'Task ID to validate')
43
+ .option('--schemas [name]', 'Validate schemas only (name optional)')
44
+ .option('--all', 'Validate all tasks and schemas')
45
+ .option('--strict', 'Stricter checks (e.g. task size)')
46
+ .option('--json', 'Output as JSON')
47
+ .action((taskId, opts) => { validateCommand(taskId, opts); });
48
+ program
49
+ .command('schemas')
50
+ .description('List available workflow schemas')
51
+ .option('--json', 'Output as JSON')
52
+ .action((opts) => { schemasCommand(opts); });
27
53
  // PDCA commands
28
54
  program
29
55
  .command('plan')
@@ -83,10 +109,44 @@ program
83
109
  // Skills commands
84
110
  program
85
111
  .command('skills')
86
- .description('Manage skills')
87
- .argument('[action]', 'Action: list, search, show, invoke')
88
- .argument('[name]', 'Skill name or search query')
112
+ .description('Manage skills (list, search, show, invoke, add, create, update, remove)')
113
+ .argument('[action]', 'Action: list, search, show, invoke, add, create, update, remove')
114
+ .argument('[name]', 'Skill name, search query, or repository (owner/repo)')
89
115
  .option('--input <params>', 'Input parameters for invoke')
90
- .action(skillsCommand);
116
+ .option('--skill <skill-name>', 'Skill name when adding from repository')
117
+ .option('--description <desc>', 'Description for create/update')
118
+ .option('--tags <t1,t2>', 'Comma-separated tags for create/update')
119
+ .option('--tag <tag>', 'Filter list by tag (repeatable)', (v, prev) => (prev ?? []).concat([v]))
120
+ .option('--force', 'Remove without confirmation, or overwrite existing skill on add')
121
+ .option('--all', 'With remove: also delete agent/IDE links. With create/add/update: also create symlinks under .cursor, .agents, .codex, .opencode, etc. so the skill is available to those IDEs')
122
+ .option('--github', 'Import skill from GitHub repository (not skills.sh)')
123
+ .option('--branch <branch>', 'GitHub branch to fetch from (default: main/master)')
124
+ .option('--path <path>', 'Custom path to skill file in repository')
125
+ .action(function (action, name) {
126
+ void skillsCommand(action, name, this.opts());
127
+ });
128
+ // Pipeline commands
129
+ const pipe = program
130
+ .command('pipe')
131
+ .description('Automated PDCA pipeline execution');
132
+ pipe
133
+ .command('init')
134
+ .description('Initialize pipe configuration for a task')
135
+ .argument('<task-id>', 'Task ID')
136
+ .option('--force', 'Overwrite existing configuration')
137
+ .action(pipelineInitCommand);
138
+ pipe
139
+ .command('run')
140
+ .description('Run the PDCA pipe for a task')
141
+ .argument('<task-id>', 'Task ID')
142
+ .option('--from <phase>', 'Start from specific phase (do, check, act)')
143
+ .option('--dry-run', 'Preview execution without making changes')
144
+ .action(pipelineRunCommand);
145
+ pipe
146
+ .command('status')
147
+ .description('Show pipe status for a task')
148
+ .argument('<task-id>', 'Task ID')
149
+ .option('--json', 'Output in JSON format')
150
+ .action(pipelineStatusCommand);
91
151
  program.parse();
92
152
  //# sourceMappingURL=cli.js.map
@@ -0,0 +1,2 @@
1
+ export declare function initCommand(pathArg?: string): void;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1,60 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { dirname, join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import chalk from 'chalk';
5
+ import { ensureDir, getSchemasDir, getTmdDir } from '../utils/paths.js';
6
+ const MINIMAL_PDCA_SCHEMA = `name: pdca
7
+ version: 1
8
+ description: PDCA (Plan-Do-Check-Act) cycle workflow for task management
9
+ artifacts:
10
+ - id: plan
11
+ generates: plan.md
12
+ description: Planning document
13
+ template: plan.md
14
+ requires: []
15
+ - id: do
16
+ generates: execution.md
17
+ description: Execution log
18
+ template: execution.md
19
+ requires: [plan]
20
+ - id: check
21
+ generates: evaluation.md
22
+ description: Evaluation and deviation analysis
23
+ template: evaluation.md
24
+ requires: [do]
25
+ - id: act
26
+ generates: improvement.md
27
+ description: Improvement and standardization
28
+ template: improvement.md
29
+ requires: [check]
30
+ apply:
31
+ requires: [plan]
32
+ tracks: plan.md
33
+ `;
34
+ export function initCommand(pathArg) {
35
+ const targetPath = join(process.cwd(), pathArg ?? '.');
36
+ if (!existsSync(targetPath)) {
37
+ mkdirSync(targetPath, { recursive: true });
38
+ }
39
+ const tmdDir = join(targetPath, getTmdDir());
40
+ const schemasPdcaDir = join(targetPath, getSchemasDir(), 'pdca');
41
+ const schemaPath = join(schemasPdcaDir, 'schema.yaml');
42
+ ensureDir(tmdDir);
43
+ ensureDir(schemasPdcaDir);
44
+ if (!existsSync(schemaPath)) {
45
+ // Bun: import.meta.dirname; Node: derive from import.meta.url
46
+ const __dirname = typeof import.meta.dirname === 'string'
47
+ ? import.meta.dirname
48
+ : dirname(fileURLToPath(import.meta.url));
49
+ const packageRoot = join(__dirname, '..', '..');
50
+ const builtin = join(packageRoot, 'schemas', 'pdca', 'schema.yaml');
51
+ if (existsSync(builtin)) {
52
+ writeFileSync(schemaPath, readFileSync(builtin, 'utf-8'));
53
+ }
54
+ else {
55
+ writeFileSync(schemaPath, MINIMAL_PDCA_SCHEMA);
56
+ }
57
+ }
58
+ console.log(chalk.green('TMD initialized'));
59
+ }
60
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Pipeline command handlers for automated PDCA execution
3
+ */
4
+ export interface PipelineInitOptions {
5
+ force?: boolean;
6
+ }
7
+ export interface PipelineRunOptions {
8
+ from?: string;
9
+ dryRun?: boolean;
10
+ }
11
+ export interface PipelineStatusOptions {
12
+ json?: boolean;
13
+ }
14
+ /**
15
+ * Initialize pipeline configuration for a task
16
+ */
17
+ export declare function pipelineInitCommand(taskId: string, options: PipelineInitOptions): void;
18
+ /**
19
+ * Run the pipeline for a task
20
+ */
21
+ export declare function pipelineRunCommand(taskId: string, options: PipelineRunOptions): Promise<void>;
22
+ /**
23
+ * Show pipeline status for a task
24
+ */
25
+ export declare function pipelineStatusCommand(taskId: string, options: PipelineStatusOptions): void;
26
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Pipeline command handlers for automated PDCA execution
3
+ */
4
+ import { existsSync } from 'fs';
5
+ import { join } from 'path';
6
+ import chalk from 'chalk';
7
+ import { getPlanDir, ensureDir } from '../utils/paths.js';
8
+ import { loadPipelineConfig, generatePipelineConfigTemplate, getPipelineConfigPath, DEFAULT_PIPELINE_CONFIG } from '../utils/pipeline-config.js';
9
+ import { PipelineRunner, getPipelineState } from '../utils/pipeline.js';
10
+ import { writeFileSync } from 'fs';
11
+ /**
12
+ * Initialize pipeline configuration for a task
13
+ */
14
+ export function pipelineInitCommand(taskId, options) {
15
+ const planPath = join(getPlanDir(taskId), 'plan.md');
16
+ if (!existsSync(planPath)) {
17
+ console.error(chalk.red(`Error: Plan not found for task: ${taskId}`));
18
+ process.exit(1);
19
+ }
20
+ const configPath = getPipelineConfigPath(taskId);
21
+ if (existsSync(configPath) && !options.force) {
22
+ console.log(chalk.yellow(`Pipe config already exists: ${configPath}`));
23
+ console.log(chalk.gray('Use --force to overwrite'));
24
+ return;
25
+ }
26
+ const configContent = generatePipelineConfigTemplate();
27
+ ensureDir(getPlanDir(taskId));
28
+ writeFileSync(configPath, configContent);
29
+ console.log(chalk.green(`Created pipeline configuration: ${configPath}`));
30
+ console.log(chalk.gray('\nDefault settings:'));
31
+ console.log(chalk.gray(' - Do phase: auto execution enabled'));
32
+ console.log(chalk.gray(' - Check phase: auto comparison with analysis'));
33
+ console.log(chalk.gray(' - Act phase: auto processing with standardization'));
34
+ console.log(chalk.gray('\nEdit pipeline.yaml to customize behavior.'));
35
+ }
36
+ /**
37
+ * Run the pipeline for a task
38
+ */
39
+ export async function pipelineRunCommand(taskId, options) {
40
+ const planPath = join(getPlanDir(taskId), 'plan.md');
41
+ if (!existsSync(planPath)) {
42
+ console.error(chalk.red(`Error: Plan not found for task: ${taskId}`));
43
+ process.exit(1);
44
+ }
45
+ // Load config or use defaults
46
+ let config = loadPipelineConfig(taskId);
47
+ if (!config) {
48
+ console.log(chalk.yellow('No pipeline.yaml found, using default configuration'));
49
+ config = DEFAULT_PIPELINE_CONFIG;
50
+ }
51
+ // Validate --from option
52
+ const validPhases = ['do', 'check', 'act'];
53
+ let fromPhase;
54
+ if (options.from) {
55
+ if (!validPhases.includes(options.from)) {
56
+ console.error(chalk.red(`Error: Invalid phase: ${options.from}`));
57
+ console.error(chalk.gray(`Valid phases: ${validPhases.join(', ')}`));
58
+ process.exit(1);
59
+ }
60
+ fromPhase = options.from;
61
+ }
62
+ // Create and run pipeline
63
+ const runner = new PipelineRunner(taskId, config, options.dryRun);
64
+ console.log(chalk.blue(`\nPipe: ${taskId}`));
65
+ if (options.dryRun) {
66
+ console.log(chalk.yellow('Mode: DRY RUN (no changes will be made)'));
67
+ }
68
+ if (fromPhase) {
69
+ console.log(chalk.gray(`Starting from: ${fromPhase}`));
70
+ }
71
+ console.log(chalk.gray('─'.repeat(50)));
72
+ const result = await runner.run(fromPhase);
73
+ console.log(chalk.gray('─'.repeat(50)));
74
+ if (result.success) {
75
+ console.log(chalk.green('\nPipe completed successfully'));
76
+ displayPipelineSummary(result);
77
+ }
78
+ else {
79
+ console.log(chalk.red(`\nPipe failed: ${result.error ?? ''}`));
80
+ displayPipelineSummary(result);
81
+ process.exit(1);
82
+ }
83
+ }
84
+ /**
85
+ * Show pipeline status for a task
86
+ */
87
+ export function pipelineStatusCommand(taskId, options) {
88
+ const planPath = join(getPlanDir(taskId), 'plan.md');
89
+ if (!existsSync(planPath)) {
90
+ console.error(chalk.red(`Error: Plan not found for task: ${taskId}`));
91
+ process.exit(1);
92
+ }
93
+ const state = getPipelineState(taskId);
94
+ const config = loadPipelineConfig(taskId);
95
+ if (options.json) {
96
+ console.log(JSON.stringify({
97
+ taskId,
98
+ state,
99
+ hasConfig: !!config
100
+ }, null, 2));
101
+ return;
102
+ }
103
+ console.log(chalk.blue(`\nPipe Status: ${taskId}`));
104
+ console.log(chalk.gray('─'.repeat(50)));
105
+ // Config status
106
+ console.log(chalk.gray('\nConfiguration:'));
107
+ if (config) {
108
+ console.log(chalk.green(' pipeline.yaml: found'));
109
+ }
110
+ else {
111
+ console.log(chalk.yellow(' pipeline.yaml: not found (will use defaults)'));
112
+ }
113
+ // Phase status
114
+ console.log(chalk.gray('\nPhases:'));
115
+ const phases = ['do', 'check', 'act'];
116
+ for (const phase of phases) {
117
+ const completed = state.completedPhases.includes(phase);
118
+ const current = state.currentPhase === phase;
119
+ let status;
120
+ let color;
121
+ if (completed) {
122
+ status = 'completed';
123
+ color = chalk.green;
124
+ }
125
+ else if (current) {
126
+ status = 'in progress';
127
+ color = chalk.yellow;
128
+ }
129
+ else {
130
+ status = 'pending';
131
+ color = chalk.gray;
132
+ }
133
+ const indicator = completed ? '✓' : current ? '→' : '○';
134
+ console.log(color(` ${indicator} ${phase.toUpperCase()}: ${status}`));
135
+ }
136
+ // Last run info
137
+ if (state.lastRun) {
138
+ console.log(chalk.gray(`\nLast run: ${state.lastRun.toISOString()}`));
139
+ }
140
+ if (state.lastError) {
141
+ console.log(chalk.red(`\nLast error: ${state.lastError}`));
142
+ }
143
+ console.log('');
144
+ }
145
+ /**
146
+ * Display pipeline execution summary
147
+ */
148
+ function displayPipelineSummary(result) {
149
+ if (result.phases.length === 0) {
150
+ return;
151
+ }
152
+ console.log(chalk.gray('\nPhase Summary:'));
153
+ for (const phase of result.phases) {
154
+ const duration = phase.endTime.getTime() - phase.startTime.getTime();
155
+ const status = phase.success ? chalk.green('✓') : chalk.red('✗');
156
+ const durationStr = duration < 1000 ? `${String(duration)}ms` : `${(duration / 1000).toFixed(1)}s`;
157
+ console.log(` ${status} ${phase.phase.toUpperCase()} (${durationStr})`);
158
+ if (phase.details) {
159
+ for (const [key, value] of Object.entries(phase.details)) {
160
+ console.log(chalk.gray(` ${key}: ${String(value)}`));
161
+ }
162
+ }
163
+ if (phase.error) {
164
+ console.log(chalk.red(` Error: ${phase.error}`));
165
+ }
166
+ }
167
+ }
168
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1,4 @@
1
+ export declare function schemasCommand(opts?: {
2
+ json?: boolean;
3
+ }): void;
4
+ //# sourceMappingURL=schemas.d.ts.map