sdtk-wiki-kit 0.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 +262 -0
- package/assets/atlas/build_atlas.py +1110 -0
- package/assets/atlas/doc_atlas_viewer_template.html +3796 -0
- package/assets/atlas/vendor/mermaid.min.js +2029 -0
- package/assets/keys/sdtk-entitlement-public.pem +11 -0
- package/bin/sdtk-wiki.js +14 -0
- package/package.json +45 -0
- package/src/commands/ask.js +139 -0
- package/src/commands/atlas.js +339 -0
- package/src/commands/deferred.js +14 -0
- package/src/commands/help.js +67 -0
- package/src/commands/init.js +91 -0
- package/src/commands/lint.js +48 -0
- package/src/commands/wiki.js +251 -0
- package/src/index.js +65 -0
- package/src/lib/args.js +68 -0
- package/src/lib/browser-open.js +32 -0
- package/src/lib/errors.js +29 -0
- package/src/lib/wiki-ask.js +175 -0
- package/src/lib/wiki-compile.js +287 -0
- package/src/lib/wiki-config.js +180 -0
- package/src/lib/wiki-discover.js +271 -0
- package/src/lib/wiki-flags.js +89 -0
- package/src/lib/wiki-ingest.js +198 -0
- package/src/lib/wiki-lint.js +468 -0
- package/src/lib/wiki-paths.js +169 -0
- package/src/lib/wiki-premium-loader.js +364 -0
- package/src/lib/wiki-prune.js +334 -0
- package/src/lib/wiki-query-history.js +111 -0
- package/src/lib/wiki-runner.js +373 -0
- package/src/lib/wiki-workspace.js +144 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
isWikiInitialized,
|
|
5
|
+
resolveWikiConfig,
|
|
6
|
+
writeWikiConfig,
|
|
7
|
+
} = require("../lib/wiki-config");
|
|
8
|
+
const { ensureWorkspace } = require("../lib/wiki-workspace");
|
|
9
|
+
const { runBuild } = require("../lib/wiki-runner");
|
|
10
|
+
const { INIT_FLAG_DEFS, parseWikiFlags } = require("../lib/wiki-flags");
|
|
11
|
+
|
|
12
|
+
function hasHelp(args) {
|
|
13
|
+
return args.includes("-h") || args.includes("--help");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function cmdInitHelp() {
|
|
17
|
+
console.log(`Usage:
|
|
18
|
+
sdtk-wiki init --help
|
|
19
|
+
|
|
20
|
+
Purpose:
|
|
21
|
+
Defines the SDTK-WIKI workspace contract for R1.
|
|
22
|
+
|
|
23
|
+
Workspace contract:
|
|
24
|
+
.sdtk/wiki New SDTK-WIKI workspace target.
|
|
25
|
+
.sdtk/wiki/graph New SDTK-WIKI graph output target.
|
|
26
|
+
.sdtk/atlas Legacy Atlas workspace remains readable.
|
|
27
|
+
|
|
28
|
+
BK-102 behavior:
|
|
29
|
+
Help exits 0.
|
|
30
|
+
Runtime initialization is implemented in BK-103.
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--project-path <path> Project root. Defaults to current working directory.
|
|
34
|
+
--output-dir <path> Graph output dir under .sdtk/wiki. Defaults to .sdtk/wiki/graph.
|
|
35
|
+
--scan-root <path> Repeatable markdown scan root.
|
|
36
|
+
--force Overwrite existing config.
|
|
37
|
+
--no-build Write config only.
|
|
38
|
+
--no-open Build graph but do not launch viewer.
|
|
39
|
+
--host <host> Viewer host. Defaults to 127.0.0.1.
|
|
40
|
+
--port <port> Viewer port. Defaults to 8765.
|
|
41
|
+
--verbose Print builder details.`);
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function cmdInit(args) {
|
|
46
|
+
if (hasHelp(args)) {
|
|
47
|
+
return cmdInitHelp();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const { flags } = parseWikiFlags(args, INIT_FLAG_DEFS);
|
|
51
|
+
const config = resolveWikiConfig(flags);
|
|
52
|
+
const { workspace } = ensureWorkspace(config.projectPath, config.outputDir);
|
|
53
|
+
|
|
54
|
+
if (isWikiInitialized(config.outputDir) && !flags.force) {
|
|
55
|
+
console.log(`[wiki] SDTK-WIKI already initialized at: ${config.outputDir}`);
|
|
56
|
+
console.log("[wiki] Use --force to overwrite existing config.");
|
|
57
|
+
} else {
|
|
58
|
+
writeWikiConfig(config);
|
|
59
|
+
console.log(`[wiki] Initialized SDTK-WIKI config: ${config.configPath}`);
|
|
60
|
+
console.log(`[wiki] Project root: ${config.projectPath}`);
|
|
61
|
+
console.log(`[wiki] Output dir: ${config.outputDir}`);
|
|
62
|
+
console.log(`[wiki] Legacy Atlas: ${config.legacyAtlasDir}`);
|
|
63
|
+
console.log(`[wiki] Scan roots: ${config.scanRoots.join(", ")}`);
|
|
64
|
+
}
|
|
65
|
+
console.log(`[wiki] Workspace: ${workspace.workspaceRoot}`);
|
|
66
|
+
console.log(`[wiki] Manifest: ${workspace.manifestPath}`);
|
|
67
|
+
|
|
68
|
+
if (flags["no-build"]) {
|
|
69
|
+
console.log("[wiki] --no-build specified; skipping initial build.");
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log("");
|
|
74
|
+
const buildResult = await runBuild(config);
|
|
75
|
+
console.log(`[wiki] Build complete: ${buildResult.docCount} docs, ${buildResult.nodeCount} nodes, ${buildResult.edgeCount} edges.`);
|
|
76
|
+
|
|
77
|
+
if (flags["no-open"]) {
|
|
78
|
+
console.log("[wiki] --no-open specified; skipping viewer launch.");
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { openViewer } = require("../lib/wiki-runner");
|
|
83
|
+
const { url } = await openViewer(config, false);
|
|
84
|
+
console.log(`[wiki] Viewer: ${url}`);
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
cmdInit,
|
|
90
|
+
cmdInitHelp,
|
|
91
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { LINT_FLAG_DEFS, parseWikiFlags } = require("../lib/wiki-flags");
|
|
4
|
+
const { runWikiLint } = require("../lib/wiki-lint");
|
|
5
|
+
|
|
6
|
+
function hasHelp(args) {
|
|
7
|
+
return args.includes("-h") || args.includes("--help");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function cmdLintHelp() {
|
|
11
|
+
console.log(`Usage:
|
|
12
|
+
sdtk-wiki lint --help
|
|
13
|
+
sdtk-wiki lint [--project-path <path>]
|
|
14
|
+
|
|
15
|
+
Purpose:
|
|
16
|
+
Run report-first, non-destructive lint checks over canonical .sdtk/wiki content.
|
|
17
|
+
|
|
18
|
+
Output:
|
|
19
|
+
.sdtk/wiki/reports/lint-report-YYYY-MM-DD.md
|
|
20
|
+
|
|
21
|
+
Behavior:
|
|
22
|
+
Findings are written to the report and do not auto-modify wiki or source files.
|
|
23
|
+
Completed lint runs exit 0 even when findings exist.
|
|
24
|
+
Missing workspace or fatal report-write failures exit non-zero.
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
--project-path <path> Project root. Defaults to current working directory.`);
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function cmdLint(args) {
|
|
32
|
+
if (hasHelp(args)) {
|
|
33
|
+
return cmdLintHelp();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const { flags } = parseWikiFlags(args, LINT_FLAG_DEFS);
|
|
37
|
+
const result = runWikiLint({ projectPath: flags["project-path"] });
|
|
38
|
+
|
|
39
|
+
console.log(`[wiki] Lint report: ${result.reportPath}`);
|
|
40
|
+
console.log(`[wiki] Findings: ${result.totalFindings}`);
|
|
41
|
+
console.log("[wiki] No wiki or source content was auto-modified.");
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = {
|
|
46
|
+
cmdLint,
|
|
47
|
+
cmdLintHelp,
|
|
48
|
+
};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { CliError, ValidationError } = require("../lib/errors");
|
|
6
|
+
const { runWikiCompileDryRun } = require("../lib/wiki-compile");
|
|
7
|
+
const { runWikiDiscoverPlan } = require("../lib/wiki-discover");
|
|
8
|
+
const { ingestLocalSource } = require("../lib/wiki-ingest");
|
|
9
|
+
const { runWikiPruneDryRun } = require("../lib/wiki-prune");
|
|
10
|
+
const { COMPILE_FLAG_DEFS, DISCOVER_FLAG_DEFS, PRUNE_FLAG_DEFS, parseWikiFlags } = require("../lib/wiki-flags");
|
|
11
|
+
|
|
12
|
+
function hasHelp(args) {
|
|
13
|
+
return args.includes("-h") || args.includes("--help");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function cmdWikiHelp() {
|
|
17
|
+
console.log(`Usage:
|
|
18
|
+
sdtk-wiki wiki --help
|
|
19
|
+
sdtk-wiki wiki ingest --help
|
|
20
|
+
sdtk-wiki wiki prune --help
|
|
21
|
+
sdtk-wiki wiki discover --help
|
|
22
|
+
sdtk-wiki wiki compile --help
|
|
23
|
+
|
|
24
|
+
Purpose:
|
|
25
|
+
Native SDTK-WIKI command namespace.
|
|
26
|
+
|
|
27
|
+
Deferred:
|
|
28
|
+
web discover/fetch, compile/apply, destructive cleanup/archive, and payload snapshots remain deferred.
|
|
29
|
+
Web discover/improve must not be enabled by default in R1.`);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function cmdWikiCompileHelp() {
|
|
34
|
+
console.log(`Usage:
|
|
35
|
+
sdtk-wiki wiki compile --plan <path> --project-path <path> --dry-run
|
|
36
|
+
|
|
37
|
+
Purpose:
|
|
38
|
+
Write a compile dry-run preview from a local markdown or JSON plan.
|
|
39
|
+
|
|
40
|
+
Writes:
|
|
41
|
+
.sdtk/wiki/reports/compile-dry-run-preview-YYYY-MM-DD.md
|
|
42
|
+
|
|
43
|
+
Safety:
|
|
44
|
+
Preview-only.
|
|
45
|
+
No --apply behavior is implemented in BK-126.
|
|
46
|
+
No wiki page, raw source, provenance, atlas compatibility, discover, prune, query-history, or release mutation.
|
|
47
|
+
Unknown operation types are reported as unsupported_operation and cause a non-zero exit after the report is written.`);
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function cmdWikiIngestHelp() {
|
|
52
|
+
console.log(`Usage:
|
|
53
|
+
sdtk-wiki wiki ingest --project-path <path> --source <path>
|
|
54
|
+
|
|
55
|
+
Purpose:
|
|
56
|
+
Register one local source in the metadata-only raw/source boundary.
|
|
57
|
+
|
|
58
|
+
Writes:
|
|
59
|
+
.sdtk/wiki/raw
|
|
60
|
+
.sdtk/wiki/provenance
|
|
61
|
+
|
|
62
|
+
Safety:
|
|
63
|
+
Local project files only.
|
|
64
|
+
Metadata-only registry; no source payload copy.
|
|
65
|
+
No compiled pages or graph/viewer rebuild side effects.`);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function cmdWikiPruneHelp() {
|
|
70
|
+
console.log(`Usage:
|
|
71
|
+
sdtk-wiki wiki prune --dry-run --project-path <path>
|
|
72
|
+
|
|
73
|
+
Purpose:
|
|
74
|
+
Write a report-only stale managed-page review for SDTK-WIKI.
|
|
75
|
+
|
|
76
|
+
Writes:
|
|
77
|
+
.sdtk/wiki/reports/prune-dry-run-report-YYYY-MM-DD.md
|
|
78
|
+
|
|
79
|
+
Safety:
|
|
80
|
+
Dry-run only.
|
|
81
|
+
Managed wiki pages under .sdtk/wiki/pages are scanned but not modified.
|
|
82
|
+
No delete, archive, apply, discover, compile, query-history, or Ask work.
|
|
83
|
+
Every finding keeps the never_delete_automatically safety posture.`);
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function cmdWikiDiscoverHelp() {
|
|
88
|
+
console.log(`Usage:
|
|
89
|
+
sdtk-wiki wiki discover --plan --project-path <path>
|
|
90
|
+
|
|
91
|
+
Purpose:
|
|
92
|
+
Write a local-only discovery plan from existing SDTK-WIKI gap evidence.
|
|
93
|
+
|
|
94
|
+
Writes:
|
|
95
|
+
.sdtk/wiki/reports/discover-plan-YYYY-MM-DD.md
|
|
96
|
+
|
|
97
|
+
Safety:
|
|
98
|
+
plan-only.
|
|
99
|
+
No web fetch, source ingest, compile, apply, prune, delete, archive, query-history, or Ask work.
|
|
100
|
+
No --web, --fetch, --apply, --compile, or --auto mode is enabled in BK-125.`);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function parseIngestFlags(args) {
|
|
105
|
+
const defs = {
|
|
106
|
+
"project-path": { type: "string" },
|
|
107
|
+
source: { type: "string" },
|
|
108
|
+
};
|
|
109
|
+
return parseWikiFlags(args, defs);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function parsePruneFlags(args) {
|
|
113
|
+
return parseWikiFlags(args, PRUNE_FLAG_DEFS);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function parseDiscoverFlags(args) {
|
|
117
|
+
return parseWikiFlags(args, DISCOVER_FLAG_DEFS);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function parseCompileFlags(args) {
|
|
121
|
+
return parseWikiFlags(args, COMPILE_FLAG_DEFS);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function ensureProjectPath(projectPath) {
|
|
125
|
+
const resolved = path.resolve(projectPath || process.cwd());
|
|
126
|
+
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory()) {
|
|
127
|
+
throw new ValidationError(`--project-path is not a valid directory: ${resolved}`);
|
|
128
|
+
}
|
|
129
|
+
return resolved;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function cmdWikiIngest(args) {
|
|
133
|
+
if (hasHelp(args)) return cmdWikiIngestHelp();
|
|
134
|
+
const { flags } = parseIngestFlags(args);
|
|
135
|
+
const projectPath = ensureProjectPath(flags["project-path"]);
|
|
136
|
+
const result = ingestLocalSource({
|
|
137
|
+
projectPath,
|
|
138
|
+
sourceArg: flags.source,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.log(`[wiki] Ingested local source: ${result.sourcePath}`);
|
|
142
|
+
console.log(`[wiki] Raw registry: ${result.registryPath}`);
|
|
143
|
+
console.log(`[wiki] Provenance events: ${result.eventsPath}`);
|
|
144
|
+
console.log("[wiki] No compiled pages or graph outputs were regenerated.");
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function cmdWikiPrune(args) {
|
|
149
|
+
if (hasHelp(args)) return cmdWikiPruneHelp();
|
|
150
|
+
const { flags } = parsePruneFlags(args);
|
|
151
|
+
if (!flags["dry-run"]) {
|
|
152
|
+
throw new ValidationError(
|
|
153
|
+
'sdtk-wiki wiki prune requires --dry-run. Delete/archive/apply modes are not implemented. No project files were changed.'
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
const projectPath = ensureProjectPath(flags["project-path"]);
|
|
157
|
+
const result = runWikiPruneDryRun({ projectPath });
|
|
158
|
+
|
|
159
|
+
console.log(`[wiki] Prune dry-run report: ${result.reportPath}`);
|
|
160
|
+
console.log(`[wiki] Pages scanned: ${result.pagesScanned}`);
|
|
161
|
+
console.log(`[wiki] Findings: ${result.findings.length}`);
|
|
162
|
+
console.log("[wiki] No wiki pages were deleted or archived.");
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function cmdWikiDiscover(args) {
|
|
167
|
+
if (hasHelp(args)) return cmdWikiDiscoverHelp();
|
|
168
|
+
const { flags } = parseDiscoverFlags(args);
|
|
169
|
+
if (!flags.plan) {
|
|
170
|
+
throw new ValidationError(
|
|
171
|
+
'sdtk-wiki wiki discover requires --plan. Web/fetch/apply/compile/auto modes are not implemented. No project files were changed.'
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
const projectPath = ensureProjectPath(flags["project-path"]);
|
|
175
|
+
const result = runWikiDiscoverPlan({ projectPath });
|
|
176
|
+
|
|
177
|
+
console.log(`[wiki] Discovery plan report: ${result.reportPath}`);
|
|
178
|
+
console.log(`[wiki] Pages scanned: ${result.pageCount}`);
|
|
179
|
+
console.log(`[wiki] Plan items: ${result.items.length}`);
|
|
180
|
+
console.log("[wiki] No sources were fetched, ingested, compiled, applied, pruned, deleted, archived, or persisted.");
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function cmdWikiCompile(args) {
|
|
185
|
+
if (hasHelp(args)) return cmdWikiCompileHelp();
|
|
186
|
+
const { flags } = parseCompileFlags(args);
|
|
187
|
+
if (flags.apply) {
|
|
188
|
+
throw new ValidationError("--apply is deferred to BK-127. BK-126 supports compile dry-run preview only. No project files were changed.");
|
|
189
|
+
}
|
|
190
|
+
if (!flags["dry-run"]) {
|
|
191
|
+
throw new ValidationError("sdtk-wiki wiki compile requires --dry-run in BK-126. No project files were changed.");
|
|
192
|
+
}
|
|
193
|
+
if (!flags.plan) {
|
|
194
|
+
throw new ValidationError("sdtk-wiki wiki compile requires --plan <path>. No project files were changed.");
|
|
195
|
+
}
|
|
196
|
+
const projectPath = ensureProjectPath(flags["project-path"]);
|
|
197
|
+
const result = runWikiCompileDryRun({ projectPath, planArg: flags.plan });
|
|
198
|
+
|
|
199
|
+
console.log(`[wiki] Compile dry-run preview: ${result.reportPath}`);
|
|
200
|
+
console.log(`[wiki] Operations: ${result.operations.length}`);
|
|
201
|
+
console.log(`[wiki] Unsupported operations: ${result.unsupportedCount}`);
|
|
202
|
+
console.log("[wiki] No wiki pages, raw sources, provenance, or atlas compatibility files were modified.");
|
|
203
|
+
if (result.unsupportedCount > 0) {
|
|
204
|
+
throw new CliError(
|
|
205
|
+
`unsupported_operation: ${result.unsupportedCount} operation(s) are blocked. Review the compile dry-run preview report.`,
|
|
206
|
+
1
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function cmdWiki(args) {
|
|
213
|
+
if (!args || args.length === 0) {
|
|
214
|
+
return cmdWikiHelp();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const [subcommand, ...rest] = args;
|
|
218
|
+
if (subcommand === "-h" || subcommand === "--help") {
|
|
219
|
+
return cmdWikiHelp();
|
|
220
|
+
}
|
|
221
|
+
if (subcommand === "ingest") {
|
|
222
|
+
return cmdWikiIngest(rest);
|
|
223
|
+
}
|
|
224
|
+
if (subcommand === "prune") {
|
|
225
|
+
return cmdWikiPrune(rest);
|
|
226
|
+
}
|
|
227
|
+
if (subcommand === "discover") {
|
|
228
|
+
return cmdWikiDiscover(rest);
|
|
229
|
+
}
|
|
230
|
+
if (subcommand === "compile") {
|
|
231
|
+
return cmdWikiCompile(rest);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
throw new CliError(
|
|
235
|
+
`Unknown wiki command: "${subcommand}". Run "sdtk-wiki wiki --help". No project files were changed.`,
|
|
236
|
+
1
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
module.exports = {
|
|
241
|
+
cmdWiki,
|
|
242
|
+
cmdWikiCompile,
|
|
243
|
+
cmdWikiCompileHelp,
|
|
244
|
+
cmdWikiDiscover,
|
|
245
|
+
cmdWikiDiscoverHelp,
|
|
246
|
+
cmdWikiHelp,
|
|
247
|
+
cmdWikiIngest,
|
|
248
|
+
cmdWikiIngestHelp,
|
|
249
|
+
cmdWikiPrune,
|
|
250
|
+
cmdWikiPruneHelp,
|
|
251
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { cmdAtlas } = require("./commands/atlas");
|
|
4
|
+
const { cmdAsk } = require("./commands/ask");
|
|
5
|
+
const { cmdHelp } = require("./commands/help");
|
|
6
|
+
const { cmdInit } = require("./commands/init");
|
|
7
|
+
const { cmdLint } = require("./commands/lint");
|
|
8
|
+
const { cmdWiki } = require("./commands/wiki");
|
|
9
|
+
const { ValidationError } = require("./lib/errors");
|
|
10
|
+
|
|
11
|
+
function getVersion() {
|
|
12
|
+
const pkg = require("../package.json");
|
|
13
|
+
return pkg.version;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseCommand(argv) {
|
|
17
|
+
if (!argv || argv.length === 0) {
|
|
18
|
+
return { command: "help", args: [] };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const [first, ...rest] = argv;
|
|
22
|
+
if (first === "-h" || first === "--help") {
|
|
23
|
+
return { command: "help", args: [] };
|
|
24
|
+
}
|
|
25
|
+
if (first === "-v" || first === "--version") {
|
|
26
|
+
return { command: "version", args: [] };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return { command: first, args: rest };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const COMMANDS = new Set(["help", "version", "init", "atlas", "wiki", "ask", "lint"]);
|
|
33
|
+
|
|
34
|
+
async function run(argv) {
|
|
35
|
+
const { command, args } = parseCommand(argv);
|
|
36
|
+
|
|
37
|
+
if (!COMMANDS.has(command)) {
|
|
38
|
+
throw new ValidationError(
|
|
39
|
+
`Unknown command: "${command}". Run "sdtk-wiki --help" for available commands.`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
switch (command) {
|
|
44
|
+
case "help":
|
|
45
|
+
return cmdHelp();
|
|
46
|
+
case "version":
|
|
47
|
+
console.log(`sdtk-wiki-kit ${getVersion()}`);
|
|
48
|
+
return 0;
|
|
49
|
+
case "init":
|
|
50
|
+
return cmdInit(args);
|
|
51
|
+
case "atlas":
|
|
52
|
+
return cmdAtlas(args);
|
|
53
|
+
case "wiki":
|
|
54
|
+
return cmdWiki(args);
|
|
55
|
+
case "ask":
|
|
56
|
+
return cmdAsk(args);
|
|
57
|
+
case "lint":
|
|
58
|
+
return cmdLint(args);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = {
|
|
63
|
+
parseCommand,
|
|
64
|
+
run,
|
|
65
|
+
};
|
package/src/lib/args.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { ValidationError } = require("./errors");
|
|
4
|
+
|
|
5
|
+
function parseFlags(argv, defs) {
|
|
6
|
+
const flags = {};
|
|
7
|
+
const positional = [];
|
|
8
|
+
const aliasMap = {};
|
|
9
|
+
|
|
10
|
+
for (const [name, def] of Object.entries(defs)) {
|
|
11
|
+
if (def.alias) aliasMap[def.alias] = name;
|
|
12
|
+
if (def.type === "boolean") flags[name] = false;
|
|
13
|
+
else flags[name] = undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let i = 0;
|
|
17
|
+
while (i < argv.length) {
|
|
18
|
+
const arg = argv[i];
|
|
19
|
+
|
|
20
|
+
if (!arg.startsWith("-")) {
|
|
21
|
+
positional.push(arg);
|
|
22
|
+
i++;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let key;
|
|
27
|
+
let inlineValue;
|
|
28
|
+
|
|
29
|
+
if (arg.includes("=")) {
|
|
30
|
+
const eqIdx = arg.indexOf("=");
|
|
31
|
+
key = arg.slice(0, eqIdx);
|
|
32
|
+
inlineValue = arg.slice(eqIdx + 1);
|
|
33
|
+
} else {
|
|
34
|
+
key = arg;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const stripped = key.replace(/^-{1,2}/, "");
|
|
38
|
+
const resolved = aliasMap[stripped] || stripped;
|
|
39
|
+
|
|
40
|
+
if (!(resolved in defs)) {
|
|
41
|
+
throw new ValidationError(`Unknown flag: ${key}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const def = defs[resolved];
|
|
45
|
+
if (def.type === "boolean") {
|
|
46
|
+
flags[resolved] = true;
|
|
47
|
+
i++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let value = inlineValue;
|
|
52
|
+
if (value === undefined) {
|
|
53
|
+
i++;
|
|
54
|
+
if (i >= argv.length) {
|
|
55
|
+
throw new ValidationError(`Flag ${key} requires a value.`);
|
|
56
|
+
}
|
|
57
|
+
value = argv[i];
|
|
58
|
+
}
|
|
59
|
+
flags[resolved] = value;
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { flags, positional };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
parseFlags,
|
|
68
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { execFile } = require("child_process");
|
|
4
|
+
|
|
5
|
+
function openBrowser(url) {
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
let cmd;
|
|
8
|
+
let args;
|
|
9
|
+
|
|
10
|
+
if (process.platform === "win32") {
|
|
11
|
+
cmd = "cmd";
|
|
12
|
+
args = ["/c", "start", "", url];
|
|
13
|
+
} else if (process.platform === "darwin") {
|
|
14
|
+
cmd = "open";
|
|
15
|
+
args = [url];
|
|
16
|
+
} else {
|
|
17
|
+
cmd = "xdg-open";
|
|
18
|
+
args = [url];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
execFile(cmd, args, { windowsHide: true }, (err) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
console.error(`[wiki] Warning: could not open browser: ${err.message}`);
|
|
24
|
+
}
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
openBrowser,
|
|
32
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
class CliError extends Error {
|
|
4
|
+
constructor(message, exitCode = 1) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "CliError";
|
|
7
|
+
this.exitCode = exitCode;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class ValidationError extends CliError {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message, 1);
|
|
14
|
+
this.name = "ValidationError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class DependencyError extends CliError {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message, 2);
|
|
21
|
+
this.name = "DependencyError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
CliError,
|
|
27
|
+
DependencyError,
|
|
28
|
+
ValidationError,
|
|
29
|
+
};
|