@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.
- package/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.md +12 -2
- package/dist/commands/block.d.ts +2 -0
- package/dist/commands/block.js +284 -0
- package/dist/commands/block.js.map +1 -0
- package/dist/commands/circuit.d.ts +2 -0
- package/dist/commands/circuit.js +166 -0
- package/dist/commands/circuit.js.map +1 -0
- package/dist/commands/kit.d.ts +2 -0
- package/dist/commands/kit.js +175 -0
- package/dist/commands/kit.js.map +1 -0
- package/dist/commands/logbook.d.ts +2 -0
- package/dist/commands/logbook.js +156 -0
- package/dist/commands/logbook.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/filesystem.d.ts +5 -0
- package/dist/utils/filesystem.js +21 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/github.d.ts +23 -0
- package/dist/utils/github.js +66 -0
- package/dist/utils/github.js.map +1 -0
- package/package.json +47 -4
|
@@ -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,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,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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"}
|
package/dist/index.d.ts
ADDED
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"}
|