sdx-cli 0.2.2 → 0.3.1
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 +103 -2
- package/dist/commands/architecture/generate.js +70 -0
- package/dist/commands/architecture/validate.js +70 -0
- package/dist/commands/bootstrap/quick.js +1 -0
- package/dist/commands/docs/readme.js +62 -0
- package/dist/commands/publish/wiki.js +24 -2
- package/dist/commands/status.js +2 -1
- package/dist/lib/architecture.js +793 -0
- package/dist/lib/artifactMigration.js +2 -0
- package/dist/lib/bootstrap.js +2 -2
- package/dist/lib/mapBuilder.js +3 -1
- package/dist/lib/readme.js +1265 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
<p align="center">
|
|
20
20
|
<a href="#install-from-npm">Install from npm</a> •
|
|
21
21
|
<a href="#one-command-setup">One-Command Setup</a> •
|
|
22
|
+
<a href="#architecture-pack-org--service-deep-dives">Architecture Pack</a> •
|
|
23
|
+
<a href="#canonical-root-readme-generation">Canonical README</a> •
|
|
22
24
|
<a href="#daily-workflow">Daily Workflow</a> •
|
|
23
25
|
<a href="#for-codex-agents">For Codex Agents</a> •
|
|
24
26
|
<a href="#release-process">Release Process</a>
|
|
@@ -131,6 +133,8 @@ From your SDX workspace root:
|
|
|
131
133
|
|
|
132
134
|
./scripts/sdx contracts extract --map platform-core
|
|
133
135
|
./scripts/sdx docs generate --map platform-core
|
|
136
|
+
./scripts/sdx architecture generate --map platform-core
|
|
137
|
+
./scripts/sdx docs readme --map platform-core
|
|
134
138
|
```
|
|
135
139
|
|
|
136
140
|
For planning and rollout:
|
|
@@ -147,6 +151,96 @@ For Codex:
|
|
|
147
151
|
./scripts/sdx codex run implementation-plan --map platform-core --input ./plans/new-service.md
|
|
148
152
|
```
|
|
149
153
|
|
|
154
|
+
### Architecture Pack (Org + Service Deep Dives)
|
|
155
|
+
Generate an executive-ready architecture pack from your initialized consumer workspace:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# full pack (org-level + per-service docs/diagrams)
|
|
159
|
+
./scripts/sdx architecture generate --map platform-core
|
|
160
|
+
|
|
161
|
+
# org-level only
|
|
162
|
+
./scripts/sdx architecture generate --map platform-core --depth org
|
|
163
|
+
|
|
164
|
+
# targeted service rebuild
|
|
165
|
+
./scripts/sdx architecture generate --map platform-core --service payments-api
|
|
166
|
+
|
|
167
|
+
# explicit validation pass (override integrity + completeness checks)
|
|
168
|
+
./scripts/sdx architecture validate --map platform-core
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Override source of truth:
|
|
172
|
+
- `maps/<map-id>/architecture-overrides.json`
|
|
173
|
+
|
|
174
|
+
Use overrides to:
|
|
175
|
+
- declare hidden or external dependencies,
|
|
176
|
+
- assert missing relationships,
|
|
177
|
+
- suppress incorrect inferred edges,
|
|
178
|
+
- attach service owner/criticality/business context metadata.
|
|
179
|
+
|
|
180
|
+
### Canonical Root README Generation
|
|
181
|
+
Generate a complete root `README.md` as the canonical onboarding and architecture overview for your org workspace.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# generate/update root README.md
|
|
185
|
+
./scripts/sdx docs readme --map platform-core
|
|
186
|
+
|
|
187
|
+
# write to a different output file
|
|
188
|
+
./scripts/sdx docs readme --map platform-core --output ARCHITECTURE.md
|
|
189
|
+
|
|
190
|
+
# check mode for CI (non-zero on stale sources, missing sources, or README drift)
|
|
191
|
+
./scripts/sdx docs readme --map platform-core --check
|
|
192
|
+
|
|
193
|
+
# dry-run preview with unified diff and freshness summary
|
|
194
|
+
./scripts/sdx docs readme --map platform-core --dry-run
|
|
195
|
+
|
|
196
|
+
# selective sections
|
|
197
|
+
./scripts/sdx docs readme --map platform-core \
|
|
198
|
+
--include what_is_this_system,architecture_glance,service_catalog \
|
|
199
|
+
--exclude glossary
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Supported section IDs (baseline order):
|
|
203
|
+
- `what_is_this_system`
|
|
204
|
+
- `architecture_glance`
|
|
205
|
+
- `service_catalog`
|
|
206
|
+
- `critical_flows`
|
|
207
|
+
- `event_async_topology`
|
|
208
|
+
- `contracts_index`
|
|
209
|
+
- `repository_index`
|
|
210
|
+
- `environments_deployment`
|
|
211
|
+
- `data_stores_boundaries`
|
|
212
|
+
- `security_compliance`
|
|
213
|
+
- `local_dev_contribution`
|
|
214
|
+
- `runbooks_escalation`
|
|
215
|
+
- `adr_index`
|
|
216
|
+
- `glossary`
|
|
217
|
+
- `changelog_metadata`
|
|
218
|
+
|
|
219
|
+
README config file support (first existing file wins):
|
|
220
|
+
- `.sdx/readme.config.json`
|
|
221
|
+
- `.sdx/readme.config.yaml`
|
|
222
|
+
- `.sdx/readme.config.yml`
|
|
223
|
+
|
|
224
|
+
Config capabilities:
|
|
225
|
+
- section toggles (`sections.include`, `sections.exclude`, `sections.enabled`)
|
|
226
|
+
- repo include/exclude filters (`repos.include`, `repos.exclude`)
|
|
227
|
+
- domain grouping (`domainGroups`)
|
|
228
|
+
- owner/team overrides (`ownerTeamOverrides`)
|
|
229
|
+
- diagram behavior (`diagram.autoGenerateMissing`, `diagram.includeC4Links`)
|
|
230
|
+
- custom intro text (`customIntro`)
|
|
231
|
+
- stale threshold override in hours (`staleThresholdHours`, default `72`)
|
|
232
|
+
|
|
233
|
+
Manual content preservation:
|
|
234
|
+
- generated wrappers: `<!-- SDX:SECTION:<id>:START --> ... <!-- SDX:SECTION:<id>:END -->`
|
|
235
|
+
- preserved manual blocks: `<!-- SDX:SECTION:<id>:MANUAL:START --> ... <!-- SDX:SECTION:<id>:MANUAL:END -->`
|
|
236
|
+
|
|
237
|
+
CI automation example:
|
|
238
|
+
- copy [`docs/examples/readme-refresh.yml`](./docs/examples/readme-refresh.yml) into your consumer workspace repo under `.github/workflows/`.
|
|
239
|
+
- set repo/org variables:
|
|
240
|
+
- `SDX_ORG` (required)
|
|
241
|
+
- `SDX_MAP` (optional, defaults to `all-services` in the workflow)
|
|
242
|
+
- the workflow runs `repo sync`, `map build`, `contracts extract`, `docs generate`, and `docs readme`, then opens a PR.
|
|
243
|
+
|
|
150
244
|
## Cross-Repo Tech-Lead PRs (Spec-System Native)
|
|
151
245
|
Use this flow when SDX should create real `CC-*` contract-change PRs in downstream repos that have spec-system initialized.
|
|
152
246
|
|
|
@@ -204,11 +298,17 @@ Use this minimal runbook when an agent needs architecture context quickly:
|
|
|
204
298
|
2. `./scripts/sdx map status <map-id>`
|
|
205
299
|
3. `./scripts/sdx map build <map-id>`
|
|
206
300
|
4. `./scripts/sdx contracts extract --map <map-id>`
|
|
207
|
-
5. `./scripts/sdx
|
|
301
|
+
5. `./scripts/sdx architecture generate --map <map-id>`
|
|
302
|
+
6. `./scripts/sdx docs readme --map <map-id>`
|
|
303
|
+
7. `./scripts/sdx codex run <task-type> --map <map-id> --input <file>`
|
|
208
304
|
|
|
209
305
|
Where outputs land:
|
|
210
306
|
- `maps/<map-id>/service-map.json|md|mmd`
|
|
211
307
|
- `maps/<map-id>/contracts.json|md`
|
|
308
|
+
- `maps/<map-id>/architecture/model.json|validation.json`
|
|
309
|
+
- `maps/<map-id>/architecture-overrides.json`
|
|
310
|
+
- `docs/architecture/<map-id>/index.md`
|
|
311
|
+
- `docs/architecture/<map-id>/services/*.md`
|
|
212
312
|
- `codex/context-packs/*.json`
|
|
213
313
|
- `codex/runs/*.md|json`
|
|
214
314
|
|
|
@@ -225,8 +325,9 @@ sdx repo add
|
|
|
225
325
|
sdx map create|include|exclude|remove-override|status|build
|
|
226
326
|
sdx prompt
|
|
227
327
|
|
|
328
|
+
sdx architecture generate|validate
|
|
228
329
|
sdx contracts extract
|
|
229
|
-
sdx docs generate
|
|
330
|
+
sdx docs generate|readme
|
|
230
331
|
sdx plan review
|
|
231
332
|
sdx service propose
|
|
232
333
|
sdx handoff draft
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const architecture_1 = require("../../lib/architecture");
|
|
5
|
+
const project_1 = require("../../lib/project");
|
|
6
|
+
const workflows_1 = require("../../lib/workflows");
|
|
7
|
+
class ArchitectureGenerateCommand extends core_1.Command {
|
|
8
|
+
static description = 'Generate architecture pack artifacts and diagrams for a map';
|
|
9
|
+
static flags = {
|
|
10
|
+
map: core_1.Flags.string({ required: true, description: 'Map identifier' }),
|
|
11
|
+
depth: core_1.Flags.string({
|
|
12
|
+
required: false,
|
|
13
|
+
options: ['org', 'full'],
|
|
14
|
+
default: 'full',
|
|
15
|
+
description: 'Generation depth: org-only or full (org + per-service packs)',
|
|
16
|
+
}),
|
|
17
|
+
service: core_1.Flags.string({
|
|
18
|
+
required: false,
|
|
19
|
+
description: 'Generate only one service deep-dive (service id/repo name)',
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
const { flags } = await this.parse(ArchitectureGenerateCommand);
|
|
24
|
+
if (flags.depth === 'org' && flags.service) {
|
|
25
|
+
throw new Error('Cannot use --service with --depth org. Use --depth full for targeted service generation.');
|
|
26
|
+
}
|
|
27
|
+
const context = (0, project_1.loadProject)(process.cwd());
|
|
28
|
+
const mapArtifacts = (0, workflows_1.buildMapArtifacts)(flags.map, context.db, context.cwd);
|
|
29
|
+
const contractArtifacts = (0, workflows_1.extractContractArtifacts)(flags.map, context.db, context.cwd);
|
|
30
|
+
const docsArtifacts = (0, workflows_1.generateDocsArtifacts)(flags.map, context.db, context.cwd);
|
|
31
|
+
const result = (0, architecture_1.generateArchitecturePack)({
|
|
32
|
+
mapId: flags.map,
|
|
33
|
+
db: context.db,
|
|
34
|
+
cwd: context.cwd,
|
|
35
|
+
depth: flags.depth,
|
|
36
|
+
serviceId: flags.service,
|
|
37
|
+
});
|
|
38
|
+
(0, project_1.recordRun)(context.db, 'architecture_generate', result.validation.valid ? 'ok' : 'error', flags.map, {
|
|
39
|
+
depth: flags.depth,
|
|
40
|
+
service: flags.service,
|
|
41
|
+
generatedServices: result.generatedServices.length,
|
|
42
|
+
validation: result.validation,
|
|
43
|
+
modelPath: result.modelPath,
|
|
44
|
+
indexDocPath: result.indexDocPath,
|
|
45
|
+
baseline: {
|
|
46
|
+
mapArtifacts,
|
|
47
|
+
contractArtifacts,
|
|
48
|
+
docsArtifacts,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
context.db.close();
|
|
52
|
+
this.log(`Generated architecture pack for map '${flags.map}'.`);
|
|
53
|
+
this.log(`Model: ${result.modelPath}`);
|
|
54
|
+
this.log(`Overrides: ${result.overridesPath}`);
|
|
55
|
+
this.log(`Baseline service map: ${result.baselineArtifacts.serviceMapPath}`);
|
|
56
|
+
this.log(`Baseline contracts: ${result.baselineArtifacts.contractsPath}`);
|
|
57
|
+
this.log(`Baseline architecture doc: ${result.baselineArtifacts.architectureDocPath}`);
|
|
58
|
+
if (result.indexDocPath) {
|
|
59
|
+
this.log(`Architecture index: ${result.indexDocPath}`);
|
|
60
|
+
}
|
|
61
|
+
if (result.generatedServices.length > 0) {
|
|
62
|
+
this.log(`Service deep dives: ${result.generatedServices.length}`);
|
|
63
|
+
}
|
|
64
|
+
this.log(`Validation: ${result.validation.valid ? 'pass' : 'fail'} (errors=${result.validation.errors.length}, warnings=${result.validation.warnings.length})`);
|
|
65
|
+
if (!result.validation.valid) {
|
|
66
|
+
this.error('Architecture validation failed. Resolve override/model issues and rerun.', { exit: 1 });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.default = ArchitectureGenerateCommand;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
7
|
+
const core_1 = require("@oclif/core");
|
|
8
|
+
const architecture_1 = require("../../lib/architecture");
|
|
9
|
+
const fs_1 = require("../../lib/fs");
|
|
10
|
+
const project_1 = require("../../lib/project");
|
|
11
|
+
class ArchitectureValidateCommand extends core_1.Command {
|
|
12
|
+
static description = 'Validate architecture model completeness and override integrity for a map';
|
|
13
|
+
static flags = {
|
|
14
|
+
map: core_1.Flags.string({ required: true, description: 'Map identifier' }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { flags } = await this.parse(ArchitectureValidateCommand);
|
|
18
|
+
const context = (0, project_1.loadProject)(process.cwd());
|
|
19
|
+
const result = (0, architecture_1.validateArchitecture)({
|
|
20
|
+
mapId: flags.map,
|
|
21
|
+
db: context.db,
|
|
22
|
+
cwd: context.cwd,
|
|
23
|
+
});
|
|
24
|
+
const outDir = node_path_1.default.join(context.cwd, 'maps', flags.map, 'architecture');
|
|
25
|
+
const jsonPath = node_path_1.default.join(outDir, 'validation.json');
|
|
26
|
+
const mdPath = node_path_1.default.join(outDir, 'validation.md');
|
|
27
|
+
(0, fs_1.writeJsonFile)(jsonPath, result);
|
|
28
|
+
const lines = [
|
|
29
|
+
`# Architecture Validation: ${flags.map}`,
|
|
30
|
+
'',
|
|
31
|
+
`- Generated: ${result.generatedAt}`,
|
|
32
|
+
`- Valid: ${result.valid ? 'yes' : 'no'}`,
|
|
33
|
+
`- Errors: ${result.errors.length}`,
|
|
34
|
+
`- Warnings: ${result.warnings.length}`,
|
|
35
|
+
'',
|
|
36
|
+
];
|
|
37
|
+
if (result.errors.length > 0) {
|
|
38
|
+
lines.push('## Errors');
|
|
39
|
+
lines.push('');
|
|
40
|
+
for (const err of result.errors) {
|
|
41
|
+
lines.push(`- ${err}`);
|
|
42
|
+
}
|
|
43
|
+
lines.push('');
|
|
44
|
+
}
|
|
45
|
+
if (result.warnings.length > 0) {
|
|
46
|
+
lines.push('## Warnings');
|
|
47
|
+
lines.push('');
|
|
48
|
+
for (const warning of result.warnings) {
|
|
49
|
+
lines.push(`- ${warning}`);
|
|
50
|
+
}
|
|
51
|
+
lines.push('');
|
|
52
|
+
}
|
|
53
|
+
(0, fs_1.writeTextFile)(mdPath, `${lines.join('\n')}\n`);
|
|
54
|
+
(0, project_1.recordRun)(context.db, 'architecture_validate', result.valid ? 'ok' : 'error', flags.map, {
|
|
55
|
+
validationPath: jsonPath,
|
|
56
|
+
errorCount: result.errors.length,
|
|
57
|
+
warningCount: result.warnings.length,
|
|
58
|
+
stats: result.stats,
|
|
59
|
+
});
|
|
60
|
+
context.db.close();
|
|
61
|
+
this.log(`Validated architecture for map '${flags.map}'.`);
|
|
62
|
+
this.log(`JSON: ${jsonPath}`);
|
|
63
|
+
this.log(`Markdown: ${mdPath}`);
|
|
64
|
+
this.log(`Result: ${result.valid ? 'pass' : 'fail'}`);
|
|
65
|
+
if (!result.valid) {
|
|
66
|
+
this.error('Architecture validation failed. Resolve errors and rerun.', { exit: 1 });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.default = ArchitectureValidateCommand;
|
|
@@ -70,6 +70,7 @@ class BootstrapQuickCommand extends core_1.Command {
|
|
|
70
70
|
this.log('- ./scripts/sdx map create all-services --org <org>');
|
|
71
71
|
this.log('- ./scripts/sdx map build all-services');
|
|
72
72
|
}
|
|
73
|
+
this.log('- ./scripts/sdx architecture generate --map all-services');
|
|
73
74
|
if (result.warnings.length > 0) {
|
|
74
75
|
this.log('');
|
|
75
76
|
this.log('Warnings:');
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const readme_1 = require("../../lib/readme");
|
|
5
|
+
const project_1 = require("../../lib/project");
|
|
6
|
+
class DocsReadmeCommand extends core_1.Command {
|
|
7
|
+
static description = 'Generate or validate the canonical root README from SDX artifacts';
|
|
8
|
+
static flags = {
|
|
9
|
+
map: core_1.Flags.string({ required: true, description: 'Map identifier' }),
|
|
10
|
+
output: core_1.Flags.string({ required: false, default: 'README.md', description: 'README output path' }),
|
|
11
|
+
check: core_1.Flags.boolean({ required: false, default: false, description: 'Check mode (no writes, non-zero on stale/missing/diff)' }),
|
|
12
|
+
'dry-run': core_1.Flags.boolean({ required: false, default: false, description: 'Preview mode (no writes, print unified diff + summary)' }),
|
|
13
|
+
include: core_1.Flags.string({
|
|
14
|
+
required: false,
|
|
15
|
+
description: 'Comma-separated section IDs to include (baseline order preserved)',
|
|
16
|
+
}),
|
|
17
|
+
exclude: core_1.Flags.string({
|
|
18
|
+
required: false,
|
|
19
|
+
description: 'Comma-separated section IDs to exclude (applied after include; exclude wins)',
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
const { flags } = await this.parse(DocsReadmeCommand);
|
|
24
|
+
const context = (0, project_1.loadProject)(process.cwd());
|
|
25
|
+
const includeSections = (0, readme_1.parseReadmeSectionList)(flags.include);
|
|
26
|
+
const excludeSections = (0, readme_1.parseReadmeSectionList)(flags.exclude);
|
|
27
|
+
const result = (0, readme_1.generateReadme)({
|
|
28
|
+
mapId: flags.map,
|
|
29
|
+
db: context.db,
|
|
30
|
+
cwd: context.cwd,
|
|
31
|
+
output: flags.output,
|
|
32
|
+
includeSections,
|
|
33
|
+
excludeSections,
|
|
34
|
+
check: flags.check,
|
|
35
|
+
dryRun: flags['dry-run'],
|
|
36
|
+
});
|
|
37
|
+
const status = result.checkPassed ? 'ok' : 'error';
|
|
38
|
+
(0, project_1.recordRun)(context.db, 'docs_readme', status, flags.map, {
|
|
39
|
+
outputPath: result.outputPath,
|
|
40
|
+
sections: result.sections,
|
|
41
|
+
changed: result.changed,
|
|
42
|
+
stale: result.stale,
|
|
43
|
+
staleSources: result.staleSources.map((source) => source.label),
|
|
44
|
+
missingSources: result.missingSources.map((source) => source.label),
|
|
45
|
+
dryRun: flags['dry-run'],
|
|
46
|
+
check: flags.check,
|
|
47
|
+
});
|
|
48
|
+
context.db.close();
|
|
49
|
+
this.log(result.summary);
|
|
50
|
+
if (result.diff && result.diff.trim().length > 0) {
|
|
51
|
+
this.log('');
|
|
52
|
+
this.log(result.diff.trimEnd());
|
|
53
|
+
}
|
|
54
|
+
if (flags.check && !result.checkPassed) {
|
|
55
|
+
this.error('README check failed: stale/missing sources or content drift detected.', { exit: 1 });
|
|
56
|
+
}
|
|
57
|
+
if (!flags.check && !flags['dry-run']) {
|
|
58
|
+
this.log(`Wrote README: ${result.outputPath}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.default = DocsReadmeCommand;
|
|
@@ -8,6 +8,19 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
8
8
|
const core_1 = require("@oclif/core");
|
|
9
9
|
const fs_1 = require("../../lib/fs");
|
|
10
10
|
const project_1 = require("../../lib/project");
|
|
11
|
+
function copyRecursive(source, target) {
|
|
12
|
+
const stat = node_fs_1.default.statSync(source);
|
|
13
|
+
if (stat.isDirectory()) {
|
|
14
|
+
(0, fs_1.ensureDir)(target);
|
|
15
|
+
const entries = node_fs_1.default.readdirSync(source, { withFileTypes: true });
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
copyRecursive(node_path_1.default.join(source, entry.name), node_path_1.default.join(target, entry.name));
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const body = node_fs_1.default.readFileSync(source, 'utf8');
|
|
22
|
+
(0, fs_1.writeTextFile)(target, body);
|
|
23
|
+
}
|
|
11
24
|
class PublishWikiCommand extends core_1.Command {
|
|
12
25
|
static description = 'Export docs-first artifacts to a wiki-friendly directory';
|
|
13
26
|
static flags = {
|
|
@@ -21,6 +34,9 @@ class PublishWikiCommand extends core_1.Command {
|
|
|
21
34
|
node_path_1.default.join(context.cwd, 'maps', flags.map, 'contracts.md'),
|
|
22
35
|
node_path_1.default.join(context.cwd, 'docs', 'architecture', `${flags.map}.md`),
|
|
23
36
|
];
|
|
37
|
+
const sourceDirs = [
|
|
38
|
+
node_path_1.default.join(context.cwd, 'docs', 'architecture', flags.map),
|
|
39
|
+
];
|
|
24
40
|
const wikiDir = node_path_1.default.join(context.cwd, 'wiki-export', flags.map);
|
|
25
41
|
(0, fs_1.ensureDir)(wikiDir);
|
|
26
42
|
for (const source of sourceFiles) {
|
|
@@ -28,8 +44,14 @@ class PublishWikiCommand extends core_1.Command {
|
|
|
28
44
|
continue;
|
|
29
45
|
}
|
|
30
46
|
const target = node_path_1.default.join(wikiDir, node_path_1.default.basename(source));
|
|
31
|
-
|
|
32
|
-
|
|
47
|
+
copyRecursive(source, target);
|
|
48
|
+
}
|
|
49
|
+
for (const source of sourceDirs) {
|
|
50
|
+
if (!node_fs_1.default.existsSync(source)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const target = node_path_1.default.join(wikiDir, node_path_1.default.basename(source));
|
|
54
|
+
copyRecursive(source, target);
|
|
33
55
|
}
|
|
34
56
|
(0, project_1.recordRun)(context.db, 'publish_wiki', 'ok', flags.map, { wikiDir });
|
|
35
57
|
context.db.close();
|
package/dist/commands/status.js
CHANGED
|
@@ -29,7 +29,8 @@ class StatusCommand extends core_1.Command {
|
|
|
29
29
|
const mapDir = node_path_1.default.join(mapsDir, mapId);
|
|
30
30
|
const hasScope = (0, fs_1.fileExists)(node_path_1.default.join(mapDir, 'scope.json'));
|
|
31
31
|
const hasServiceMap = (0, fs_1.fileExists)(node_path_1.default.join(mapDir, 'service-map.json'));
|
|
32
|
-
|
|
32
|
+
const hasArchitectureModel = (0, fs_1.fileExists)(node_path_1.default.join(mapDir, 'architecture', 'model.json'));
|
|
33
|
+
this.log(`- ${mapId}: scope=${hasScope ? 'yes' : 'no'}, service-map=${hasServiceMap ? 'yes' : 'no'}, architecture=${hasArchitectureModel ? 'yes' : 'no'}`);
|
|
33
34
|
}
|
|
34
35
|
context.db.close();
|
|
35
36
|
}
|