@tekyzinc/gsd-t 2.50.12 → 2.53.10
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/CHANGELOG.md +24 -0
- package/README.md +379 -372
- package/bin/component-registry.js +250 -0
- package/bin/graph-cgc.js +510 -510
- package/bin/graph-indexer.js +147 -147
- package/bin/graph-overlay.js +195 -195
- package/bin/graph-parsers.js +327 -327
- package/bin/graph-query.js +453 -452
- package/bin/graph-store.js +154 -154
- package/bin/qa-calibrator.js +194 -0
- package/bin/scan-data-collector.js +153 -153
- package/bin/scan-diagrams-generators.js +187 -187
- package/bin/scan-diagrams.js +79 -79
- package/bin/scan-renderer.js +92 -92
- package/bin/scan-report-sections.js +121 -121
- package/bin/scan-report.js +184 -184
- package/bin/scan-schema-parsers.js +199 -199
- package/bin/scan-schema.js +103 -103
- package/bin/token-budget.js +246 -0
- package/commands/Claude-md.md +10 -10
- package/commands/branch.md +15 -15
- package/commands/checkin.md +45 -45
- package/commands/global-change.md +209 -209
- package/commands/gsd-t-audit.md +199 -0
- package/commands/gsd-t-backlog-add.md +94 -94
- package/commands/gsd-t-backlog-edit.md +111 -111
- package/commands/gsd-t-backlog-list.md +63 -63
- package/commands/gsd-t-backlog-move.md +94 -94
- package/commands/gsd-t-backlog-promote.md +123 -123
- package/commands/gsd-t-backlog-remove.md +86 -86
- package/commands/gsd-t-backlog-settings.md +158 -158
- package/commands/gsd-t-complete-milestone.md +528 -515
- package/commands/gsd-t-debug.md +506 -399
- package/commands/gsd-t-discuss.md +174 -174
- package/commands/gsd-t-execute.md +758 -634
- package/commands/gsd-t-feature.md +276 -276
- package/commands/gsd-t-health.md +142 -142
- package/commands/gsd-t-help.md +465 -457
- package/commands/gsd-t-impact.md +302 -302
- package/commands/gsd-t-init.md +320 -280
- package/commands/gsd-t-integrate.md +365 -249
- package/commands/gsd-t-milestone.md +87 -87
- package/commands/gsd-t-partition.md +442 -361
- package/commands/gsd-t-pause.md +82 -82
- package/commands/gsd-t-plan.md +345 -344
- package/commands/gsd-t-populate.md +111 -111
- package/commands/gsd-t-prd.md +326 -326
- package/commands/gsd-t-project.md +211 -211
- package/commands/gsd-t-promote-debt.md +123 -123
- package/commands/gsd-t-prompt.md +137 -137
- package/commands/gsd-t-qa.md +266 -266
- package/commands/gsd-t-quick.md +357 -234
- package/commands/gsd-t-reflect.md +134 -134
- package/commands/gsd-t-resume.md +72 -72
- package/commands/gsd-t-scan.md +615 -615
- package/commands/gsd-t-setup.md +76 -0
- package/commands/gsd-t-status.md +192 -166
- package/commands/gsd-t-test-sync.md +381 -381
- package/commands/gsd-t-triage-and-merge.md +171 -171
- package/commands/gsd-t-verify.md +382 -382
- package/commands/gsd-t-visualize.md +118 -118
- package/commands/gsd-t-wave.md +401 -378
- package/docs/GSD-T-README.md +425 -422
- package/docs/architecture.md +385 -369
- package/docs/harness-design-analysis.md +371 -0
- package/docs/infrastructure.md +205 -205
- package/docs/prd-graph-engine.md +398 -398
- package/docs/prd-gsd2-hybrid.md +559 -559
- package/docs/prd-harness-evolution.md +583 -0
- package/docs/requirements.md +14 -0
- package/docs/workflows.md +226 -226
- package/examples/.gsd-t/domains/example-domain/scope.md +13 -13
- package/package.json +40 -40
- package/scripts/gsd-t-auto-route.js +39 -39
- package/scripts/gsd-t-dashboard-mockup.html +1143 -1143
- package/scripts/gsd-t-dashboard-server.js +171 -171
- package/scripts/gsd-t-dashboard.html +262 -262
- package/scripts/gsd-t-event-writer.js +128 -128
- package/scripts/gsd-t-statusline.js +94 -94
- package/scripts/gsd-t-tools.js +175 -175
- package/templates/CLAUDE-global.md +639 -614
- package/templates/CLAUDE-project.md +24 -0
- package/templates/backlog-settings.md +18 -18
- package/templates/backlog.md +1 -1
- package/templates/progress.md +40 -40
- package/templates/shared-services-contract.md +60 -60
- package/templates/stacks/desktop.ini +2 -2
- package/bin/desktop.ini +0 -2
- package/commands/desktop.ini +0 -2
- package/docs/ci-examples/desktop.ini +0 -2
- package/docs/desktop.ini +0 -2
- package/examples/.gsd-t/contracts/desktop.ini +0 -2
- package/examples/.gsd-t/desktop.ini +0 -2
- package/examples/.gsd-t/domains/desktop.ini +0 -2
- package/examples/.gsd-t/domains/example-domain/desktop.ini +0 -2
- package/examples/desktop.ini +0 -2
- package/examples/rules/desktop.ini +0 -2
- package/scripts/desktop.ini +0 -2
- package/templates/desktop.ini +0 -2
package/scripts/gsd-t-tools.js
CHANGED
|
@@ -1,175 +1,175 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
// gsd-t-tools.js — GSD-T state utility CLI. Zero external dependencies.
|
|
4
|
-
// Returns compact JSON. Subcommands: state, validate, parse, list, git, template
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const { execFileSync } = require('child_process');
|
|
8
|
-
|
|
9
|
-
// Find nearest .gsd-t/ directory walking up from cwd
|
|
10
|
-
function findProjectRoot() {
|
|
11
|
-
let dir = process.cwd();
|
|
12
|
-
while (dir !== path.dirname(dir)) {
|
|
13
|
-
if (fs.existsSync(path.join(dir, '.gsd-t'))) return dir;
|
|
14
|
-
dir = path.dirname(dir);
|
|
15
|
-
}
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const root = findProjectRoot() || process.cwd();
|
|
20
|
-
const gsdDir = path.join(root, '.gsd-t');
|
|
21
|
-
|
|
22
|
-
function readProgress() {
|
|
23
|
-
const p = path.join(gsdDir, 'progress.md');
|
|
24
|
-
if (!fs.existsSync(p)) return null;
|
|
25
|
-
return fs.readFileSync(p, 'utf8');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function stateGet(key) {
|
|
29
|
-
const content = readProgress();
|
|
30
|
-
if (!content) return { error: 'progress.md not found' };
|
|
31
|
-
const re = new RegExp(`^## ${escapeRe(key)}:\\s*(.+)`, 'm');
|
|
32
|
-
const m = content.match(re);
|
|
33
|
-
if (!m) return { error: `key not found: ${key}` };
|
|
34
|
-
return { key, value: m[1].trim() };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function stateSet(key, value) {
|
|
38
|
-
const p = path.join(gsdDir, 'progress.md');
|
|
39
|
-
if (!fs.existsSync(p)) return { error: 'progress.md not found' };
|
|
40
|
-
const content = fs.readFileSync(p, 'utf8');
|
|
41
|
-
const re = new RegExp(`(^## ${escapeRe(key)}:\\s*)(.+)`, 'm');
|
|
42
|
-
if (!re.test(content)) return { error: `key not found: ${key}` };
|
|
43
|
-
const safeValue = String(value).replace(/[\r\n]/g, ' ');
|
|
44
|
-
fs.writeFileSync(p, content.replace(re, `$1${safeValue}`));
|
|
45
|
-
return { ok: true, key, value };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function validate() {
|
|
49
|
-
const required = [
|
|
50
|
-
'.gsd-t/progress.md',
|
|
51
|
-
'.gsd-t/contracts',
|
|
52
|
-
'.gsd-t/domains',
|
|
53
|
-
'CLAUDE.md',
|
|
54
|
-
];
|
|
55
|
-
const results = {};
|
|
56
|
-
const missing = [];
|
|
57
|
-
for (const f of required) {
|
|
58
|
-
const exists = fs.existsSync(path.join(root, f));
|
|
59
|
-
results[f] = exists ? 'ok' : 'missing';
|
|
60
|
-
if (!exists) missing.push(f);
|
|
61
|
-
}
|
|
62
|
-
return { valid: missing.length === 0, results, missing };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function parseSection(sectionName) {
|
|
66
|
-
const content = readProgress();
|
|
67
|
-
if (!content) return { error: 'progress.md not found' };
|
|
68
|
-
const re = new RegExp(`## ${escapeRe(sectionName)}\\n([\\s\\S]*?)(?=\\n## |$)`);
|
|
69
|
-
const m = content.match(re);
|
|
70
|
-
if (!m) return { error: `section not found: ${sectionName}` };
|
|
71
|
-
return { section: sectionName, content: m[1].trim() };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function listDomains() {
|
|
75
|
-
const dir = path.join(gsdDir, 'domains');
|
|
76
|
-
if (!fs.existsSync(dir)) return { domains: [] };
|
|
77
|
-
const domains = fs.readdirSync(dir).filter(f => {
|
|
78
|
-
try { return fs.statSync(path.join(dir, f)).isDirectory(); } catch { return false; }
|
|
79
|
-
});
|
|
80
|
-
return { domains };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function listContracts() {
|
|
84
|
-
const dir = path.join(gsdDir, 'contracts');
|
|
85
|
-
if (!fs.existsSync(dir)) return { contracts: [] };
|
|
86
|
-
const contracts = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
|
|
87
|
-
return { contracts };
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function preCommitCheck() {
|
|
91
|
-
const result = {};
|
|
92
|
-
try {
|
|
93
|
-
result.branch = execFileSync('git', ['branch', '--show-current'], { cwd: root, encoding: 'utf8' }).trim();
|
|
94
|
-
} catch {
|
|
95
|
-
result.branch = 'error';
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
const status = execFileSync('git', ['status', '--porcelain'], { cwd: root, encoding: 'utf8' }).trim();
|
|
99
|
-
result.clean = status.length === 0;
|
|
100
|
-
result.changes = status ? status.split('\n').filter(Boolean) : [];
|
|
101
|
-
} catch {
|
|
102
|
-
result.clean = 'error';
|
|
103
|
-
}
|
|
104
|
-
try {
|
|
105
|
-
result.lastCommit = execFileSync('git', ['log', '-1', '--format=%h %s'], { cwd: root, encoding: 'utf8' }).trim();
|
|
106
|
-
} catch {
|
|
107
|
-
result.lastCommit = 'error';
|
|
108
|
-
}
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function validateDomainPath(domain) {
|
|
113
|
-
const domainsDir = path.join(gsdDir, 'domains');
|
|
114
|
-
const resolved = path.resolve(domainsDir, domain);
|
|
115
|
-
if (!resolved.startsWith(domainsDir + path.sep)) return null;
|
|
116
|
-
return resolved;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function templateScope(domain) {
|
|
120
|
-
const domainDir = validateDomainPath(domain);
|
|
121
|
-
if (!domainDir) return { error: `Invalid domain name: ${domain}` };
|
|
122
|
-
const p = path.join(domainDir, 'scope.md');
|
|
123
|
-
if (!fs.existsSync(p)) return { error: `scope.md not found for domain: ${domain}` };
|
|
124
|
-
return { domain, scope: fs.readFileSync(p, 'utf8') };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function templateTasks(domain) {
|
|
128
|
-
const domainDir = validateDomainPath(domain);
|
|
129
|
-
if (!domainDir) return { error: `Invalid domain name: ${domain}` };
|
|
130
|
-
const p = path.join(domainDir, 'tasks.md');
|
|
131
|
-
if (!fs.existsSync(p)) return { error: `tasks.md not found for domain: ${domain}` };
|
|
132
|
-
return { domain, tasks: fs.readFileSync(p, 'utf8') };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function escapeRe(s) {
|
|
136
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Parse args
|
|
140
|
-
const args = process.argv.slice(2);
|
|
141
|
-
const [cmd, subcmd, ...rest] = args;
|
|
142
|
-
|
|
143
|
-
let result;
|
|
144
|
-
if (cmd === 'state') {
|
|
145
|
-
if (subcmd === 'get' && rest[0]) {
|
|
146
|
-
result = stateGet(rest[0]);
|
|
147
|
-
} else if (subcmd === 'set' && rest[0] && rest[1]) {
|
|
148
|
-
result = stateSet(rest[0], rest[1]);
|
|
149
|
-
} else {
|
|
150
|
-
result = { error: 'Usage: state get <key> | state set <key> <value>' };
|
|
151
|
-
}
|
|
152
|
-
} else if (cmd === 'validate') {
|
|
153
|
-
result = validate();
|
|
154
|
-
} else if (cmd === 'parse' && subcmd === 'progress') {
|
|
155
|
-
const si = args.indexOf('--section');
|
|
156
|
-
const section = si !== -1 ? args[si + 1] : null;
|
|
157
|
-
result = section ? parseSection(section) : { error: 'Usage: parse progress --section <name>' };
|
|
158
|
-
} else if (cmd === 'list') {
|
|
159
|
-
if (subcmd === 'domains') result = listDomains();
|
|
160
|
-
else if (subcmd === 'contracts') result = listContracts();
|
|
161
|
-
else result = { error: 'Usage: list domains | list contracts' };
|
|
162
|
-
} else if (cmd === 'git' && subcmd === 'pre-commit-check') {
|
|
163
|
-
result = preCommitCheck();
|
|
164
|
-
} else if (cmd === 'template') {
|
|
165
|
-
if (subcmd === 'scope' && rest[0]) result = templateScope(rest[0]);
|
|
166
|
-
else if (subcmd === 'tasks' && rest[0]) result = templateTasks(rest[0]);
|
|
167
|
-
else result = { error: 'Usage: template scope <domain> | template tasks <domain>' };
|
|
168
|
-
} else {
|
|
169
|
-
result = {
|
|
170
|
-
error: cmd ? `Unknown command: ${cmd}` : 'No command specified',
|
|
171
|
-
usage: 'state get|set validate parse progress --section <name> list domains|contracts git pre-commit-check template scope|tasks <domain>',
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
// gsd-t-tools.js — GSD-T state utility CLI. Zero external dependencies.
|
|
4
|
+
// Returns compact JSON. Subcommands: state, validate, parse, list, git, template
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { execFileSync } = require('child_process');
|
|
8
|
+
|
|
9
|
+
// Find nearest .gsd-t/ directory walking up from cwd
|
|
10
|
+
function findProjectRoot() {
|
|
11
|
+
let dir = process.cwd();
|
|
12
|
+
while (dir !== path.dirname(dir)) {
|
|
13
|
+
if (fs.existsSync(path.join(dir, '.gsd-t'))) return dir;
|
|
14
|
+
dir = path.dirname(dir);
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const root = findProjectRoot() || process.cwd();
|
|
20
|
+
const gsdDir = path.join(root, '.gsd-t');
|
|
21
|
+
|
|
22
|
+
function readProgress() {
|
|
23
|
+
const p = path.join(gsdDir, 'progress.md');
|
|
24
|
+
if (!fs.existsSync(p)) return null;
|
|
25
|
+
return fs.readFileSync(p, 'utf8');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function stateGet(key) {
|
|
29
|
+
const content = readProgress();
|
|
30
|
+
if (!content) return { error: 'progress.md not found' };
|
|
31
|
+
const re = new RegExp(`^## ${escapeRe(key)}:\\s*(.+)`, 'm');
|
|
32
|
+
const m = content.match(re);
|
|
33
|
+
if (!m) return { error: `key not found: ${key}` };
|
|
34
|
+
return { key, value: m[1].trim() };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function stateSet(key, value) {
|
|
38
|
+
const p = path.join(gsdDir, 'progress.md');
|
|
39
|
+
if (!fs.existsSync(p)) return { error: 'progress.md not found' };
|
|
40
|
+
const content = fs.readFileSync(p, 'utf8');
|
|
41
|
+
const re = new RegExp(`(^## ${escapeRe(key)}:\\s*)(.+)`, 'm');
|
|
42
|
+
if (!re.test(content)) return { error: `key not found: ${key}` };
|
|
43
|
+
const safeValue = String(value).replace(/[\r\n]/g, ' ');
|
|
44
|
+
fs.writeFileSync(p, content.replace(re, `$1${safeValue}`));
|
|
45
|
+
return { ok: true, key, value };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function validate() {
|
|
49
|
+
const required = [
|
|
50
|
+
'.gsd-t/progress.md',
|
|
51
|
+
'.gsd-t/contracts',
|
|
52
|
+
'.gsd-t/domains',
|
|
53
|
+
'CLAUDE.md',
|
|
54
|
+
];
|
|
55
|
+
const results = {};
|
|
56
|
+
const missing = [];
|
|
57
|
+
for (const f of required) {
|
|
58
|
+
const exists = fs.existsSync(path.join(root, f));
|
|
59
|
+
results[f] = exists ? 'ok' : 'missing';
|
|
60
|
+
if (!exists) missing.push(f);
|
|
61
|
+
}
|
|
62
|
+
return { valid: missing.length === 0, results, missing };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function parseSection(sectionName) {
|
|
66
|
+
const content = readProgress();
|
|
67
|
+
if (!content) return { error: 'progress.md not found' };
|
|
68
|
+
const re = new RegExp(`## ${escapeRe(sectionName)}\\n([\\s\\S]*?)(?=\\n## |$)`);
|
|
69
|
+
const m = content.match(re);
|
|
70
|
+
if (!m) return { error: `section not found: ${sectionName}` };
|
|
71
|
+
return { section: sectionName, content: m[1].trim() };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function listDomains() {
|
|
75
|
+
const dir = path.join(gsdDir, 'domains');
|
|
76
|
+
if (!fs.existsSync(dir)) return { domains: [] };
|
|
77
|
+
const domains = fs.readdirSync(dir).filter(f => {
|
|
78
|
+
try { return fs.statSync(path.join(dir, f)).isDirectory(); } catch { return false; }
|
|
79
|
+
});
|
|
80
|
+
return { domains };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function listContracts() {
|
|
84
|
+
const dir = path.join(gsdDir, 'contracts');
|
|
85
|
+
if (!fs.existsSync(dir)) return { contracts: [] };
|
|
86
|
+
const contracts = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
|
|
87
|
+
return { contracts };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function preCommitCheck() {
|
|
91
|
+
const result = {};
|
|
92
|
+
try {
|
|
93
|
+
result.branch = execFileSync('git', ['branch', '--show-current'], { cwd: root, encoding: 'utf8' }).trim();
|
|
94
|
+
} catch {
|
|
95
|
+
result.branch = 'error';
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const status = execFileSync('git', ['status', '--porcelain'], { cwd: root, encoding: 'utf8' }).trim();
|
|
99
|
+
result.clean = status.length === 0;
|
|
100
|
+
result.changes = status ? status.split('\n').filter(Boolean) : [];
|
|
101
|
+
} catch {
|
|
102
|
+
result.clean = 'error';
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
result.lastCommit = execFileSync('git', ['log', '-1', '--format=%h %s'], { cwd: root, encoding: 'utf8' }).trim();
|
|
106
|
+
} catch {
|
|
107
|
+
result.lastCommit = 'error';
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function validateDomainPath(domain) {
|
|
113
|
+
const domainsDir = path.join(gsdDir, 'domains');
|
|
114
|
+
const resolved = path.resolve(domainsDir, domain);
|
|
115
|
+
if (!resolved.startsWith(domainsDir + path.sep)) return null;
|
|
116
|
+
return resolved;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function templateScope(domain) {
|
|
120
|
+
const domainDir = validateDomainPath(domain);
|
|
121
|
+
if (!domainDir) return { error: `Invalid domain name: ${domain}` };
|
|
122
|
+
const p = path.join(domainDir, 'scope.md');
|
|
123
|
+
if (!fs.existsSync(p)) return { error: `scope.md not found for domain: ${domain}` };
|
|
124
|
+
return { domain, scope: fs.readFileSync(p, 'utf8') };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function templateTasks(domain) {
|
|
128
|
+
const domainDir = validateDomainPath(domain);
|
|
129
|
+
if (!domainDir) return { error: `Invalid domain name: ${domain}` };
|
|
130
|
+
const p = path.join(domainDir, 'tasks.md');
|
|
131
|
+
if (!fs.existsSync(p)) return { error: `tasks.md not found for domain: ${domain}` };
|
|
132
|
+
return { domain, tasks: fs.readFileSync(p, 'utf8') };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function escapeRe(s) {
|
|
136
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Parse args
|
|
140
|
+
const args = process.argv.slice(2);
|
|
141
|
+
const [cmd, subcmd, ...rest] = args;
|
|
142
|
+
|
|
143
|
+
let result;
|
|
144
|
+
if (cmd === 'state') {
|
|
145
|
+
if (subcmd === 'get' && rest[0]) {
|
|
146
|
+
result = stateGet(rest[0]);
|
|
147
|
+
} else if (subcmd === 'set' && rest[0] && rest[1]) {
|
|
148
|
+
result = stateSet(rest[0], rest[1]);
|
|
149
|
+
} else {
|
|
150
|
+
result = { error: 'Usage: state get <key> | state set <key> <value>' };
|
|
151
|
+
}
|
|
152
|
+
} else if (cmd === 'validate') {
|
|
153
|
+
result = validate();
|
|
154
|
+
} else if (cmd === 'parse' && subcmd === 'progress') {
|
|
155
|
+
const si = args.indexOf('--section');
|
|
156
|
+
const section = si !== -1 ? args[si + 1] : null;
|
|
157
|
+
result = section ? parseSection(section) : { error: 'Usage: parse progress --section <name>' };
|
|
158
|
+
} else if (cmd === 'list') {
|
|
159
|
+
if (subcmd === 'domains') result = listDomains();
|
|
160
|
+
else if (subcmd === 'contracts') result = listContracts();
|
|
161
|
+
else result = { error: 'Usage: list domains | list contracts' };
|
|
162
|
+
} else if (cmd === 'git' && subcmd === 'pre-commit-check') {
|
|
163
|
+
result = preCommitCheck();
|
|
164
|
+
} else if (cmd === 'template') {
|
|
165
|
+
if (subcmd === 'scope' && rest[0]) result = templateScope(rest[0]);
|
|
166
|
+
else if (subcmd === 'tasks' && rest[0]) result = templateTasks(rest[0]);
|
|
167
|
+
else result = { error: 'Usage: template scope <domain> | template tasks <domain>' };
|
|
168
|
+
} else {
|
|
169
|
+
result = {
|
|
170
|
+
error: cmd ? `Unknown command: ${cmd}` : 'No command specified',
|
|
171
|
+
usage: 'state get|set validate parse progress --section <name> list domains|contracts git pre-commit-check template scope|tasks <domain>',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|