@blkc-code/cli 0.0.0-stage → 0.1.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.
@@ -0,0 +1,166 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import chalk from "chalk";
4
+ import { CircuitRegistrySchema, CircuitSchema, IdentifierSchema, nowISO, } from "@blkc-code/core";
5
+ import { ensureDirectory, exists, readJsonFile, workspacePath, writeJsonFile, } from "../utils/filesystem";
6
+ const CIRCUITS_DIR = "circuits";
7
+ const CIRCUIT_REGISTRY_PATH = "registry/circuits.json";
8
+ const MANIFEST_FILENAME = "manifest.json";
9
+ const README_FILENAME = "README.md";
10
+ const collectValues = (value, previous) => [...previous, value];
11
+ const parseKitReference = (input) => {
12
+ const [kitIdRaw, version = "0.1.0"] = input.split("@");
13
+ const kitId = IdentifierSchema.parse(kitIdRaw);
14
+ return { kitId, version };
15
+ };
16
+ const readRegistry = async () => {
17
+ try {
18
+ const registry = await readJsonFile(CIRCUIT_REGISTRY_PATH);
19
+ return CircuitRegistrySchema.parse(registry);
20
+ }
21
+ catch (error) {
22
+ console.warn(chalk.yellow("⚠ Circuit registry not found, creating a new one."));
23
+ return { updatedAt: nowISO(), circuits: [] };
24
+ }
25
+ };
26
+ const saveRegistry = async (registry) => {
27
+ await writeJsonFile(CIRCUIT_REGISTRY_PATH, {
28
+ ...registry,
29
+ updatedAt: nowISO(),
30
+ });
31
+ };
32
+ const manifestPath = (circuitId) => path.join(CIRCUITS_DIR, circuitId, MANIFEST_FILENAME);
33
+ const writeManifest = async (circuitId, manifest) => {
34
+ await writeJsonFile(manifestPath(circuitId), manifest);
35
+ };
36
+ const readManifest = async (circuitId) => {
37
+ const manifest = await readJsonFile(manifestPath(circuitId));
38
+ return CircuitSchema.parse(manifest);
39
+ };
40
+ const renderReadme = (manifest) => {
41
+ const kits = manifest.kits.map((kit) => `- ${kit.kitId}@${kit.version}`).join("\n");
42
+ return `# ${manifest.name}\n\n${manifest.description}\n\n## Kits\n\n${kits}\n\n## Verticals\n\n${manifest.verticals.join(", ") || "general"}\n`;
43
+ };
44
+ const publishCircuit = async (circuitId) => {
45
+ const manifest = await readManifest(circuitId);
46
+ const registry = await readRegistry();
47
+ const remainder = registry.circuits.filter((circuit) => circuit.id !== circuitId);
48
+ const updated = {
49
+ updatedAt: nowISO(),
50
+ circuits: [...remainder, manifest].sort((a, b) => a.id.localeCompare(b.id)),
51
+ };
52
+ await saveRegistry(updated);
53
+ console.log(chalk.green(`✔ Published circuit ${manifest.id}@${manifest.version}`));
54
+ };
55
+ export const registerCircuitCommands = (program) => {
56
+ const circuit = program
57
+ .command("circuit")
58
+ .description("Manage BLKC circuits");
59
+ circuit
60
+ .command("list")
61
+ .description("List registered circuits")
62
+ .option("--json", "Emit JSON output", false)
63
+ .action(async (options) => {
64
+ const registry = await readRegistry();
65
+ if (registry.circuits.length === 0) {
66
+ console.log(chalk.yellow("No circuits registered yet."));
67
+ return;
68
+ }
69
+ if (options.json) {
70
+ console.log(JSON.stringify(registry.circuits, null, 2));
71
+ return;
72
+ }
73
+ registry.circuits
74
+ .sort((a, b) => a.id.localeCompare(b.id))
75
+ .forEach((item) => {
76
+ console.log(chalk.cyan(`${item.id}@${item.version}`));
77
+ console.log(` name: ${item.name}`);
78
+ console.log(` summary: ${item.summary}`);
79
+ console.log(` kits: ${item.kits.map((kit) => kit.kitId).join(", ")}`);
80
+ console.log(` status: ${item.status}`);
81
+ console.log("");
82
+ });
83
+ });
84
+ circuit
85
+ .command("create")
86
+ .description("Scaffold a circuit manifest")
87
+ .argument("<circuit-id>", "Circuit identifier (lowercase slug)")
88
+ .option("--name <name>", "Display name")
89
+ .option("--summary <summary>", "Short summary")
90
+ .option("--description <description>", "Long-form description")
91
+ .option("--version <semver>", "Version", "0.1.0")
92
+ .option("--vertical <vertical>", "Target vertical", collectValues, [])
93
+ .option("--kit <kit@version>", "Reference a kit", collectValues, [])
94
+ .option("--tag <tag>", "Add a tag", collectValues, [])
95
+ .option("--status <status>", "Circuit status", "draft")
96
+ .option("--launch-date <iso>", "Planned launch date")
97
+ .option("--maintainer-name <name>", "Maintainer name")
98
+ .option("--maintainer-email <email>", "Maintainer email")
99
+ .option("--maintainer-role <role>", "Maintainer role")
100
+ .option("--publish", "Publish after creation", false)
101
+ .option("--force", "Overwrite manifest if it exists", false)
102
+ .action(async (rawId, options) => {
103
+ const circuitId = IdentifierSchema.parse(rawId);
104
+ const manifestFile = manifestPath(circuitId);
105
+ const existsAlready = await exists(manifestFile);
106
+ if (existsAlready && !options.force) {
107
+ console.error(chalk.red(`✖ Circuit ${circuitId} already exists. Use --force to overwrite.`));
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+ await ensureDirectory(path.join(CIRCUITS_DIR, circuitId));
112
+ const kits = options.kit.map(parseKitReference);
113
+ if (kits.length === 0) {
114
+ console.warn(chalk.yellow("⚠ No kits specified. Add them later before publishing."));
115
+ }
116
+ const manifestDraft = CircuitSchema.parse({
117
+ id: circuitId,
118
+ name: options.name ?? circuitId
119
+ .split("-")
120
+ .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
121
+ .join(" "),
122
+ summary: options.summary ?? `Summary for ${circuitId}.`,
123
+ description: options.description ?? `Detailed description for circuit ${circuitId}. Update before publishing.`,
124
+ version: options.version,
125
+ verticals: options.vertical ?? [],
126
+ tags: options.tag ?? [],
127
+ kits,
128
+ status: options.status,
129
+ launchDate: options.launchDate,
130
+ maintainers: options.maintainerName
131
+ ? [
132
+ {
133
+ name: options.maintainerName,
134
+ email: options.maintainerEmail,
135
+ role: options.maintainerRole,
136
+ },
137
+ ]
138
+ : [],
139
+ });
140
+ await writeManifest(circuitId, manifestDraft);
141
+ const readmePath = workspacePath(CIRCUITS_DIR, circuitId, README_FILENAME);
142
+ await writeFile(readmePath, renderReadme(manifestDraft), { encoding: "utf8" });
143
+ console.log(chalk.green(`✔ Created circuit scaffold at ${path.join(CIRCUITS_DIR, circuitId)}`));
144
+ if (options.publish) {
145
+ await publishCircuit(circuitId);
146
+ }
147
+ else {
148
+ console.log(chalk.gray(`Run 'blkc circuit publish ${circuitId}' after finalising the manifest.`));
149
+ }
150
+ });
151
+ circuit
152
+ .command("publish")
153
+ .description("Validate and add a circuit to the registry")
154
+ .argument("<circuit-id>", "Circuit identifier")
155
+ .action(async (rawId) => {
156
+ try {
157
+ const circuitId = IdentifierSchema.parse(rawId);
158
+ await publishCircuit(circuitId);
159
+ }
160
+ catch (error) {
161
+ console.error(chalk.red(`✖ Failed to publish circuit: ${error.message}`));
162
+ process.exitCode = 1;
163
+ }
164
+ });
165
+ };
166
+ //# sourceMappingURL=circuit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit.js","sourceRoot":"","sources":["../../src/commands/circuit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const registerKitCommands: (program: Command) => void;
@@ -0,0 +1,175 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import chalk from "chalk";
4
+ import { IdentifierSchema, KitRegistrySchema, KitSchema, nowISO, } from "@blkc-code/core";
5
+ import { ensureDirectory, exists, readJsonFile, workspacePath, writeJsonFile, } from "../utils/filesystem";
6
+ const KITS_DIR = "kits";
7
+ const KIT_REGISTRY_PATH = "registry/kits.json";
8
+ const MANIFEST_FILENAME = "manifest.json";
9
+ const README_FILENAME = "README.md";
10
+ const collectValues = (value, previous) => [...previous, value];
11
+ const parseBlockReference = (input) => {
12
+ const [blockIdRaw, version = "0.1.0"] = input.split("@");
13
+ const blockId = IdentifierSchema.parse(blockIdRaw);
14
+ return { blockId, version };
15
+ };
16
+ const readRegistry = async () => {
17
+ try {
18
+ const registry = await readJsonFile(KIT_REGISTRY_PATH);
19
+ return KitRegistrySchema.parse(registry);
20
+ }
21
+ catch (error) {
22
+ console.warn(chalk.yellow("⚠ Kit registry not found, creating a new one."));
23
+ return { updatedAt: nowISO(), kits: [] };
24
+ }
25
+ };
26
+ const saveRegistry = async (registry) => {
27
+ await writeJsonFile(KIT_REGISTRY_PATH, {
28
+ ...registry,
29
+ updatedAt: nowISO(),
30
+ });
31
+ };
32
+ const manifestPath = (kitId) => path.join(KITS_DIR, kitId, MANIFEST_FILENAME);
33
+ const writeManifest = async (kitId, manifest) => {
34
+ await writeJsonFile(manifestPath(kitId), manifest);
35
+ };
36
+ const readManifest = async (kitId) => {
37
+ const manifest = await readJsonFile(manifestPath(kitId));
38
+ return KitSchema.parse(manifest);
39
+ };
40
+ const renderReadme = (manifest) => {
41
+ const blockTable = manifest.blocks
42
+ .map((block) => `- ${block.blockId}@${block.version}`)
43
+ .join("\n");
44
+ return `# ${manifest.name}\n\n${manifest.description}\n\n## Blocks\n\n${blockTable}\n\n## Category\n\n- ${manifest.category}\n`;
45
+ };
46
+ const publishKit = async (kitId) => {
47
+ const manifest = await readManifest(kitId);
48
+ const registry = await readRegistry();
49
+ const remainder = registry.kits.filter((kit) => kit.id !== kitId);
50
+ const updated = {
51
+ updatedAt: nowISO(),
52
+ kits: [...remainder, manifest].sort((a, b) => a.id.localeCompare(b.id)),
53
+ };
54
+ await saveRegistry(updated);
55
+ console.log(chalk.green(`✔ Published kit ${manifest.id}@${manifest.version}`));
56
+ };
57
+ export const registerKitCommands = (program) => {
58
+ const kit = program
59
+ .command("kit")
60
+ .description("Scaffold and manage BLKC kits");
61
+ kit
62
+ .command("list")
63
+ .description("List registered kits")
64
+ .option("--json", "Emit JSON output", false)
65
+ .action(async (options) => {
66
+ const registry = await readRegistry();
67
+ if (registry.kits.length === 0) {
68
+ console.log(chalk.yellow("No kits registered yet."));
69
+ return;
70
+ }
71
+ if (options.json) {
72
+ console.log(JSON.stringify(registry.kits, null, 2));
73
+ return;
74
+ }
75
+ registry.kits
76
+ .sort((a, b) => a.id.localeCompare(b.id))
77
+ .forEach((item) => {
78
+ console.log(chalk.cyan(`${item.id}@${item.version}`));
79
+ console.log(` name: ${item.name}`);
80
+ console.log(` summary: ${item.summary}`);
81
+ console.log(` blocks: ${item.blocks.map((block) => block.blockId).join(", ")}`);
82
+ console.log("");
83
+ });
84
+ });
85
+ kit
86
+ .command("create")
87
+ .description("Scaffold a new kit manifest")
88
+ .argument("<kit-id>", "Kit identifier (lowercase slug)")
89
+ .option("--name <name>", "Display name")
90
+ .option("--summary <summary>", "Short summary")
91
+ .option("--description <description>", "Long-form description")
92
+ .option("--category <category>", "Business category", "general")
93
+ .option("--block <block@version>", "Reference a block", collectValues, [])
94
+ .option("--version <semver>", "Version", "0.1.0")
95
+ .option("--tag <tag>", "Add a tag", collectValues, [])
96
+ .option("--maintainer-name <name>", "Maintainer name")
97
+ .option("--maintainer-email <email>", "Maintainer email")
98
+ .option("--maintainer-role <role>", "Maintainer role")
99
+ .option("--documentation <url>", "Documentation URL")
100
+ .option("--pricing-model <model>", "Pricing model (free|one-time|subscription|usage)")
101
+ .option("--pricing-amount <amount>", "Pricing amount", parseFloat)
102
+ .option("--pricing-currency <currency>", "Pricing currency", "USD")
103
+ .option("--publish", "Publish after creation", false)
104
+ .option("--force", "Overwrite manifest if it exists", false)
105
+ .action(async (rawId, options) => {
106
+ const kitId = IdentifierSchema.parse(rawId);
107
+ const manifestFile = manifestPath(kitId);
108
+ const existsAlready = await exists(manifestFile);
109
+ if (existsAlready && !options.force) {
110
+ console.error(chalk.red(`✖ Kit ${kitId} already exists. Use --force to overwrite.`));
111
+ process.exitCode = 1;
112
+ return;
113
+ }
114
+ await ensureDirectory(path.join(KITS_DIR, kitId));
115
+ const blocks = options.block.map(parseBlockReference);
116
+ if (blocks.length === 0) {
117
+ console.warn(chalk.yellow("⚠ No blocks specified. Add them later before publishing."));
118
+ }
119
+ const manifestDraft = KitSchema.parse({
120
+ id: kitId,
121
+ name: options.name ?? kitId
122
+ .split("-")
123
+ .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
124
+ .join(" "),
125
+ summary: options.summary ?? `Summary for ${kitId}.`,
126
+ description: options.description ?? `Detailed description for kit ${kitId}. Update before publishing.`,
127
+ category: options.category,
128
+ version: options.version,
129
+ tags: options.tag ?? [],
130
+ blocks,
131
+ maintainers: options.maintainerName
132
+ ? [
133
+ {
134
+ name: options.maintainerName,
135
+ email: options.maintainerEmail,
136
+ role: options.maintainerRole,
137
+ },
138
+ ]
139
+ : [],
140
+ documentation: options.documentation,
141
+ pricing: options.pricingModel
142
+ ? {
143
+ model: options.pricingModel,
144
+ amount: options.pricingAmount,
145
+ currency: options.pricingCurrency,
146
+ }
147
+ : undefined,
148
+ });
149
+ await writeManifest(kitId, manifestDraft);
150
+ const readmePath = workspacePath(KITS_DIR, kitId, README_FILENAME);
151
+ await writeFile(readmePath, renderReadme(manifestDraft), { encoding: "utf8" });
152
+ console.log(chalk.green(`✔ Created kit scaffold at ${path.join(KITS_DIR, kitId)}`));
153
+ if (options.publish) {
154
+ await publishKit(kitId);
155
+ }
156
+ else {
157
+ console.log(chalk.gray(`Run 'blkc kit publish ${kitId}' after finalising the manifest.`));
158
+ }
159
+ });
160
+ kit
161
+ .command("publish")
162
+ .description("Validate and add a kit to the registry")
163
+ .argument("<kit-id>", "Kit identifier")
164
+ .action(async (rawId) => {
165
+ try {
166
+ const kitId = IdentifierSchema.parse(rawId);
167
+ await publishKit(kitId);
168
+ }
169
+ catch (error) {
170
+ console.error(chalk.red(`✖ Failed to publish kit: ${error.message}`));
171
+ process.exitCode = 1;
172
+ }
173
+ });
174
+ };
175
+ //# sourceMappingURL=kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kit.js","sourceRoot":"","sources":["../../src/commands/kit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const registerLogbookCommands: (program: Command) => void;
@@ -0,0 +1,156 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import chalk from "chalk";
5
+ import { DEFAULT_ALGORITHM } from "@blkc-code/core";
6
+ import { DEFAULT_LOGBOOK_PATH, Logbook, } from "@blkc-code/logbook";
7
+ const parseJson = (value, source) => {
8
+ try {
9
+ return JSON.parse(value);
10
+ }
11
+ catch (error) {
12
+ throw new Error(`Failed to parse JSON from ${source}: ${error.message}`);
13
+ }
14
+ };
15
+ const parseJsonFile = async (filePath) => {
16
+ const buffer = await readFile(filePath, { encoding: "utf8" });
17
+ return parseJson(buffer, filePath);
18
+ };
19
+ const mergeRecords = (records) => records.reduce((acc, record) => ({ ...acc, ...record }), {});
20
+ const cleanRecord = (record) => Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && value !== null));
21
+ const buildDataPayload = async (options) => {
22
+ const dataAggregates = [];
23
+ if (options.data && typeof options.data === "string") {
24
+ dataAggregates.push(parseJson(options.data, "--data"));
25
+ }
26
+ if (options.dataFile && typeof options.dataFile === "string") {
27
+ const resolved = path.resolve(options.dataFile);
28
+ dataAggregates.push(await parseJsonFile(resolved));
29
+ }
30
+ if (options.message && typeof options.message === "string") {
31
+ dataAggregates.push({ message: options.message });
32
+ }
33
+ if (dataAggregates.length === 0) {
34
+ return {};
35
+ }
36
+ return mergeRecords(dataAggregates);
37
+ };
38
+ const defaultActorName = () => process.env.BLKC_ACTOR_NAME ?? os.userInfo().username;
39
+ const resolveLogbook = (options) => new Logbook({
40
+ filePath: path.resolve(options.file ?? DEFAULT_LOGBOOK_PATH),
41
+ algorithm: options.algorithm ?? DEFAULT_ALGORITHM,
42
+ });
43
+ const printVerification = (result) => {
44
+ if (result.valid) {
45
+ console.log(chalk.green(`✔ Logbook verified (${result.entries.length} entries)`));
46
+ if (result.lastHash) {
47
+ console.log(chalk.dim(`Last hash: ${result.lastHash}`));
48
+ }
49
+ return;
50
+ }
51
+ console.error(chalk.red("✖ Logbook verification failed"));
52
+ result.issues.forEach((issue) => {
53
+ const context = issue.entry ? chalk.dim(` ${JSON.stringify(issue.entry)}`) : "";
54
+ console.error(chalk.red(` • [${issue.index + 1}] ${issue.message}${context}`));
55
+ });
56
+ };
57
+ export const registerLogbookCommands = (program) => {
58
+ const logbook = program
59
+ .command("logbook")
60
+ .description("Inspect and update the BLKC logbook")
61
+ .option("-f, --file <path>", "Path to logbook JSONL file", DEFAULT_LOGBOOK_PATH)
62
+ .option("-a, --algorithm <hash>", "Hash algorithm", DEFAULT_ALGORITHM);
63
+ logbook
64
+ .command("append")
65
+ .description("Append a new entry to the logbook")
66
+ .requiredOption("-e, --event <event>", "Event identifier")
67
+ .option("-m, --message <message>", "Optional message stored under data.message")
68
+ .option("-d, --data <json>", "JSON payload merged into entry data")
69
+ .option("--data-file <path>", "Path to JSON file merged into entry data")
70
+ .option("--actor-name <name>", "Actor display name")
71
+ .option("--actor-email <email>", "Actor email")
72
+ .option("--actor-role <role>", "Actor role")
73
+ .option("--timestamp <iso>", "Override timestamp (ISO-8601)")
74
+ .action(async (options, command) => {
75
+ const parentOpts = (command.parent?.opts() ?? {});
76
+ const logbookInstance = resolveLogbook(parentOpts);
77
+ const data = await buildDataPayload(options);
78
+ const actor = cleanRecord({
79
+ name: options.actorName ?? defaultActorName(),
80
+ email: options.actorEmail,
81
+ role: options.actorRole,
82
+ });
83
+ const entry = {
84
+ event: options.event,
85
+ actor: actor,
86
+ data,
87
+ timestamp: options.timestamp,
88
+ };
89
+ try {
90
+ const appended = await logbookInstance.append(entry);
91
+ console.log(chalk.green(`✔ Appended ${appended.event}`));
92
+ console.log(chalk.dim(`Hash: ${appended.hash}`));
93
+ }
94
+ catch (error) {
95
+ console.error(chalk.red(`✖ Failed to append entry: ${error.message}`));
96
+ process.exitCode = 1;
97
+ }
98
+ });
99
+ logbook
100
+ .command("verify")
101
+ .description("Verify integrity of the logbook hash chain")
102
+ .action(async (_options, command) => {
103
+ const parentOpts = (command.parent?.opts() ?? {});
104
+ const logbookInstance = resolveLogbook(parentOpts);
105
+ try {
106
+ const result = await logbookInstance.verify();
107
+ printVerification(result);
108
+ if (!result.valid) {
109
+ process.exitCode = 1;
110
+ }
111
+ }
112
+ catch (error) {
113
+ console.error(chalk.red(`✖ Verification failed: ${error.message}`));
114
+ process.exitCode = 1;
115
+ }
116
+ });
117
+ logbook
118
+ .command("show")
119
+ .description("Display logbook entries")
120
+ .option("-l, --limit <count>", "Limit number of entries returned", (value) => parseInt(value, 10))
121
+ .option("--json", "Output as JSON", false)
122
+ .action(async (options, command) => {
123
+ const parentOpts = (command.parent?.opts() ?? {});
124
+ const logbookInstance = resolveLogbook(parentOpts);
125
+ try {
126
+ const entries = await logbookInstance.entries();
127
+ const limit = typeof options.limit === "number" && !Number.isNaN(options.limit)
128
+ ? options.limit
129
+ : entries.length;
130
+ const subset = entries.slice(Math.max(0, entries.length - limit));
131
+ if (options.json) {
132
+ console.log(JSON.stringify(subset, null, 2));
133
+ return;
134
+ }
135
+ subset.forEach((entry, index) => {
136
+ const idx = entries.length - subset.length + index + 1;
137
+ console.log(chalk.cyan(`#${idx} ${entry.event}`));
138
+ console.log(` actor: ${entry.actor.name}${entry.actor.role ? ` (${entry.actor.role})` : ""}`);
139
+ console.log(` timestamp: ${entry.timestamp}`);
140
+ console.log(` hash: ${entry.hash}`);
141
+ if (entry.prevHash) {
142
+ console.log(` prevHash: ${entry.prevHash}`);
143
+ }
144
+ if (entry.data && Object.keys(entry.data).length > 0) {
145
+ console.log(` data: ${JSON.stringify(entry.data)}`);
146
+ }
147
+ console.log("");
148
+ });
149
+ }
150
+ catch (error) {
151
+ console.error(chalk.red(`✖ Failed to read logbook: ${error.message}`));
152
+ process.exitCode = 1;
153
+ }
154
+ });
155
+ };
156
+ //# sourceMappingURL=logbook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logbook.js","sourceRoot":"","sources":["../../src/commands/logbook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from "commander";
3
+ export declare const program: Command;
4
+ export declare const run: () => Promise<void>;
package/dist/index.js ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env bun
2
+ import { realpathSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { Command } from "commander";
6
+ import { registerBlockCommands } from "./commands/block";
7
+ import { registerCircuitCommands } from "./commands/circuit";
8
+ import { registerKitCommands } from "./commands/kit";
9
+ import { registerLogbookCommands } from "./commands/logbook";
10
+ export const program = new Command();
11
+ program
12
+ .name("blkc")
13
+ .description("BLKC developer CLI")
14
+ .version("0.1.0");
15
+ program.showHelpAfterError();
16
+ program.configureOutput({
17
+ outputError: (str) => {
18
+ // eslint-disable-next-line no-console
19
+ console.error(str.trim());
20
+ },
21
+ });
22
+ registerBlockCommands(program);
23
+ registerCircuitCommands(program);
24
+ registerKitCommands(program);
25
+ registerLogbookCommands(program);
26
+ const isDirectExecution = () => {
27
+ const entryPoint = process.argv[1];
28
+ if (!entryPoint) {
29
+ return false;
30
+ }
31
+ // npm/bun install the bin as a symlink, so compare real paths.
32
+ const resolve = (file) => {
33
+ try {
34
+ return realpathSync(file);
35
+ }
36
+ catch {
37
+ return path.resolve(file);
38
+ }
39
+ };
40
+ return resolve(fileURLToPath(import.meta.url)) === resolve(entryPoint);
41
+ };
42
+ export const run = async () => {
43
+ await program.parseAsync(process.argv);
44
+ };
45
+ if (isDirectExecution()) {
46
+ run().catch((error) => {
47
+ // eslint-disable-next-line no-console
48
+ console.error(error instanceof Error ? error.message : error);
49
+ process.exitCode = 1;
50
+ });
51
+ }
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAErC,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,oBAAoB,CAAC;KACjC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,kBAAkB,EAAE,CAAC;AAC7B,OAAO,CAAC,eAAe,CAAC;IACtB,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;QACnB,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;CACF,CAAC,CAAC;AAEH,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAEjC,MAAM,iBAAiB,GAAG,GAAG,EAAE;IAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+DAA+D;IAC/D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC;IACF,OAAO,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;IAC5B,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,IAAI,iBAAiB,EAAE,EAAE,CAAC;IACxB,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACpB,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const workspacePath: (...segments: string[]) => string;
2
+ export declare const ensureDirectory: (relativePath: string) => Promise<void>;
3
+ export declare const readJsonFile: <T>(relativePath: string) => Promise<T>;
4
+ export declare const writeJsonFile: (relativePath: string, payload: unknown) => Promise<void>;
5
+ export declare const exists: (relativePath: string) => Promise<boolean>;
@@ -0,0 +1,21 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { ensureDir, pathExists } from "fs-extra";
4
+ export const workspacePath = (...segments) => path.resolve(process.cwd(), ...segments);
5
+ export const ensureDirectory = async (relativePath) => {
6
+ await ensureDir(workspacePath(relativePath));
7
+ };
8
+ export const readJsonFile = async (relativePath) => {
9
+ const filePath = workspacePath(relativePath);
10
+ const contents = await readFile(filePath, { encoding: "utf8" });
11
+ // Some manifests were written by PowerShell with a UTF-8 BOM, which JSON.parse rejects.
12
+ return JSON.parse(contents.replace(/^\uFEFF/, ""));
13
+ };
14
+ export const writeJsonFile = async (relativePath, payload) => {
15
+ const filePath = workspacePath(relativePath);
16
+ await ensureDir(path.dirname(filePath));
17
+ const formatted = `${JSON.stringify(payload, null, 2)}\n`;
18
+ await writeFile(filePath, formatted, { encoding: "utf8" });
19
+ };
20
+ export const exists = async (relativePath) => pathExists(workspacePath(relativePath));
21
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/utils/filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAG,QAAkB,EAAE,EAAE,CACrD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,YAAoB,EAAE,EAAE;IAC5D,MAAM,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAK,YAAoB,EAAc,EAAE;IACxE,MAAM,QAAQ,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAChE,wFAAwF;IACxF,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAM,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,YAAoB,EAAE,OAAgB,EAAE,EAAE;IAC5E,MAAM,QAAQ,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,YAAoB,EAAE,EAAE,CACnD,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC"}