@blkc-code/cli 0.1.1 → 0.1.3
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/bin/blkc.js +24 -0
- package/dist/cli.js +24 -0
- package/dist/commands/block.d.ts +12 -1
- package/dist/commands/block.d.ts.map +1 -0
- package/dist/commands/block.js +180 -268
- package/dist/commands/block.js.map +1 -1
- package/dist/commands/circuit.d.ts +12 -1
- package/dist/commands/circuit.d.ts.map +1 -0
- package/dist/commands/circuit.js +146 -152
- package/dist/commands/circuit.js.map +1 -1
- package/dist/commands/deploy.d.ts +14 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +332 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/kit.d.ts +12 -1
- package/dist/commands/kit.d.ts.map +1 -0
- package/dist/commands/kit.js +137 -160
- package/dist/commands/kit.js.map +1 -1
- package/dist/commands/logbook.d.ts +12 -1
- package/dist/commands/logbook.d.ts.map +1 -0
- package/dist/commands/logbook.js +150 -136
- package/dist/commands/logbook.js.map +1 -1
- package/dist/index.d.ts +19 -2
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -34
- package/dist/index.js.map +1 -1
- package/package.json +59 -33
- package/src/__tests__/smoke.test.ts +8 -0
- package/src/commands/block.ts +219 -0
- package/src/commands/circuit.ts +182 -0
- package/src/commands/deploy.ts +373 -0
- package/src/commands/kit.ts +173 -0
- package/src/commands/logbook.ts +194 -0
- package/src/index.ts +70 -0
- package/LICENSE +0 -201
- package/NOTICE +0 -5
- package/README.md +0 -13
- package/dist/utils/filesystem.d.ts +0 -5
- package/dist/utils/filesystem.js +0 -21
- package/dist/utils/filesystem.js.map +0 -1
- package/dist/utils/github.d.ts +0 -23
- package/dist/utils/github.js +0 -66
- package/dist/utils/github.js.map +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BLKC CLI - Block Commands
|
|
3
|
+
*
|
|
4
|
+
* Commands for working with BLKC Blocks.
|
|
5
|
+
*
|
|
6
|
+
* @package @blkc-code/cli
|
|
7
|
+
* @license Apache-2.0
|
|
8
|
+
* @author Black Code Enterprises LLC
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Command } from "commander";
|
|
12
|
+
import chalk from "chalk";
|
|
13
|
+
import ora from "ora";
|
|
14
|
+
import { readFile } from "node:fs/promises";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { BlockSchema } from "@blkc-code/core";
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Command: block validate
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
function setupValidateCommand(program: Command): void {
|
|
23
|
+
program
|
|
24
|
+
.command("validate <manifest-path>")
|
|
25
|
+
.description("Validate a Block manifest")
|
|
26
|
+
.action(async (manifestPath: string) => {
|
|
27
|
+
const spinner = ora("Validating Block manifest...").start();
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
31
|
+
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
32
|
+
const manifest = JSON.parse(content);
|
|
33
|
+
|
|
34
|
+
const result = BlockSchema.safeParse(manifest);
|
|
35
|
+
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
spinner.fail("Validation failed");
|
|
38
|
+
console.error(chalk.red("\nValidation errors:"));
|
|
39
|
+
for (const issue of result.error.issues) {
|
|
40
|
+
console.error(` - ${chalk.red(issue.path.join("."))}: ${issue.message}`);
|
|
41
|
+
}
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
spinner.succeed("Block manifest is valid");
|
|
46
|
+
const block = result.data;
|
|
47
|
+
console.log(chalk.gray(`\nBlock ID: ${block.id}`));
|
|
48
|
+
console.log(chalk.gray(`Name: ${block.name}`));
|
|
49
|
+
console.log(chalk.gray(`Kind: ${block.kind}`));
|
|
50
|
+
console.log(chalk.gray(`Version: ${block.version}`));
|
|
51
|
+
} catch (error) {
|
|
52
|
+
spinner.fail(`Failed to validate: ${error}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Command: block test
|
|
60
|
+
// ============================================================================
|
|
61
|
+
|
|
62
|
+
function setupTestCommand(program: Command): void {
|
|
63
|
+
program
|
|
64
|
+
.command("test <manifest-path>")
|
|
65
|
+
.description("Test a Block")
|
|
66
|
+
.action(async (manifestPath: string) => {
|
|
67
|
+
const spinner = ora("Testing Block...").start();
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
71
|
+
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
72
|
+
const manifest = JSON.parse(content);
|
|
73
|
+
|
|
74
|
+
// Validate first
|
|
75
|
+
const result = BlockSchema.safeParse(manifest);
|
|
76
|
+
if (!result.success) {
|
|
77
|
+
spinner.fail("Validation failed");
|
|
78
|
+
console.error(chalk.red("Validation errors:"));
|
|
79
|
+
for (const issue of result.error.issues) {
|
|
80
|
+
console.error(` - ${chalk.red(issue.path.join("."))}: ${issue.message}`);
|
|
81
|
+
}
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const block = result.data;
|
|
86
|
+
|
|
87
|
+
// Test based on kind
|
|
88
|
+
if (block.kind === "ui") {
|
|
89
|
+
// Test UI Block
|
|
90
|
+
spinner.succeed("UI Block test passed");
|
|
91
|
+
console.log(chalk.gray(`\nBlock: ${block.id}`));
|
|
92
|
+
console.log(chalk.gray(`Has ${block.controls.length} controls`));
|
|
93
|
+
console.log(chalk.gray(`Has ${Object.keys(block.renderers).length} renderers`));
|
|
94
|
+
} else {
|
|
95
|
+
// Test Capability Block
|
|
96
|
+
spinner.succeed("Capability Block test passed");
|
|
97
|
+
console.log(chalk.gray(`\nBlock: ${block.id}`));
|
|
98
|
+
console.log(chalk.gray(`Runtime: ${block.runtime}`));
|
|
99
|
+
console.log(chalk.gray(`Entry: ${block.entryPoint}`));
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
spinner.fail(`Failed to test: ${error}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Command: block list
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
function setupListCommand(program: Command): void {
|
|
113
|
+
program
|
|
114
|
+
.command("list")
|
|
115
|
+
.description("List all Blocks in a directory")
|
|
116
|
+
.option("--dir <dir>", "Directory to search", ".")
|
|
117
|
+
.action(async () => {
|
|
118
|
+
const spinner = ora("Searching for Blocks...").start();
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
// In a real implementation, we would walk the directory tree
|
|
122
|
+
// and find all manifest.json files
|
|
123
|
+
// For now, simulate with a delay
|
|
124
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
125
|
+
|
|
126
|
+
spinner.succeed("Found Blocks");
|
|
127
|
+
console.log(chalk.gray("\nNo Blocks found in current implementation."));
|
|
128
|
+
console.log(chalk.gray("Use 'blkc block validate <path>' to validate a specific Block."));
|
|
129
|
+
} catch (error) {
|
|
130
|
+
spinner.fail(`Failed to list Blocks: ${error}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ============================================================================
|
|
137
|
+
// Command: block info
|
|
138
|
+
// ============================================================================
|
|
139
|
+
|
|
140
|
+
function setupInfoCommand(program: Command): void {
|
|
141
|
+
program
|
|
142
|
+
.command("info <manifest-path>")
|
|
143
|
+
.description("Show detailed information about a Block")
|
|
144
|
+
.action(async (manifestPath: string) => {
|
|
145
|
+
const spinner = ora("Loading Block info...").start();
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
149
|
+
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
150
|
+
const manifest = JSON.parse(content);
|
|
151
|
+
|
|
152
|
+
const result = BlockSchema.safeParse(manifest);
|
|
153
|
+
if (!result.success) {
|
|
154
|
+
spinner.fail("Invalid Block manifest");
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const block = result.data;
|
|
159
|
+
spinner.succeed(`Block: ${block.id}`);
|
|
160
|
+
|
|
161
|
+
console.log(chalk.bold("\nBlock Information"));
|
|
162
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
163
|
+
console.log(chalk.gray(`ID: ${block.id}`));
|
|
164
|
+
console.log(chalk.gray(`Name: ${block.name}`));
|
|
165
|
+
console.log(chalk.gray(`Summary: ${block.summary}`));
|
|
166
|
+
console.log(chalk.gray(`Kind: ${block.kind}`));
|
|
167
|
+
console.log(chalk.gray(`Version: ${block.version}`));
|
|
168
|
+
console.log(chalk.gray(`License: ${block.license}`));
|
|
169
|
+
console.log(chalk.gray(`Visibility: ${block.visibility}`));
|
|
170
|
+
|
|
171
|
+
if (block.tags.length > 0) {
|
|
172
|
+
console.log(chalk.gray(`Tags: ${block.tags.join(", ")}`));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (block.kind === "ui") {
|
|
176
|
+
console.log(chalk.bold("\nUI Block Details"));
|
|
177
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
178
|
+
console.log(chalk.gray(`Category: ${block.category || "none"}`));
|
|
179
|
+
console.log(chalk.gray(`Controls: ${block.controls.length}`));
|
|
180
|
+
console.log(chalk.gray(`Renderers: ${Object.keys(block.renderers).join(", ")}`));
|
|
181
|
+
console.log(chalk.gray(`Props: ${Object.keys(block.props.properties || {}).length}`));
|
|
182
|
+
} else {
|
|
183
|
+
console.log(chalk.bold("\nCapability Block Details"));
|
|
184
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
185
|
+
console.log(chalk.gray(`Runtime: ${block.runtime}`));
|
|
186
|
+
console.log(chalk.gray(`Entry: ${block.entryPoint}`));
|
|
187
|
+
console.log(chalk.gray(`Size: ${block.sizeMB || "unknown"} MB`));
|
|
188
|
+
console.log(chalk.gray(`Inputs: ${block.inputs.length > 0 ? block.inputs.join(", ") : "none"}`));
|
|
189
|
+
console.log(chalk.gray(`Outputs: ${block.outputs.length > 0 ? block.outputs.join(", ") : "none"}`));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (block.repository) {
|
|
193
|
+
console.log(chalk.bold("\nRepository"));
|
|
194
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
195
|
+
console.log(chalk.gray(block.repository));
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
spinner.fail(`Failed to show info: ${error}`);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ============================================================================
|
|
205
|
+
// Register Commands
|
|
206
|
+
// ============================================================================
|
|
207
|
+
|
|
208
|
+
/** Register all block commands with the program */
|
|
209
|
+
export function registerBlockCommands(program: Command): void {
|
|
210
|
+
const blockProgram = program
|
|
211
|
+
.command("block")
|
|
212
|
+
.description("Block commands")
|
|
213
|
+
.alias("b");
|
|
214
|
+
|
|
215
|
+
setupValidateCommand(blockProgram);
|
|
216
|
+
setupTestCommand(blockProgram);
|
|
217
|
+
setupListCommand(blockProgram);
|
|
218
|
+
setupInfoCommand(blockProgram);
|
|
219
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BLKC CLI - Circuit Commands
|
|
3
|
+
*
|
|
4
|
+
* Commands for working with BLKC Circuits.
|
|
5
|
+
*
|
|
6
|
+
* @package @blkc-code/cli
|
|
7
|
+
* @license Apache-2.0
|
|
8
|
+
* @author Black Code Enterprises LLC
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Command } from "commander";
|
|
12
|
+
import chalk from "chalk";
|
|
13
|
+
import ora from "ora";
|
|
14
|
+
import { readFile } from "node:fs/promises";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { CircuitSchema } from "@blkc-code/core";
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Command: circuit validate
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
function setupValidateCommand(program: Command): void {
|
|
23
|
+
program
|
|
24
|
+
.command("validate <manifest-path>")
|
|
25
|
+
.description("Validate a Circuit manifest")
|
|
26
|
+
.action(async (manifestPath: string) => {
|
|
27
|
+
const spinner = ora("Validating Circuit manifest...").start();
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
31
|
+
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
32
|
+
const manifest = JSON.parse(content);
|
|
33
|
+
|
|
34
|
+
const result = CircuitSchema.safeParse(manifest);
|
|
35
|
+
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
spinner.fail("Validation failed");
|
|
38
|
+
console.error(chalk.red("\nValidation errors:"));
|
|
39
|
+
for (const issue of result.error.issues) {
|
|
40
|
+
console.error(` - ${chalk.red(issue.path.join("."))}: ${issue.message}`);
|
|
41
|
+
}
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
spinner.succeed("Circuit manifest is valid");
|
|
46
|
+
const circuit = result.data;
|
|
47
|
+
console.log(chalk.gray(`\nCircuit ID: ${circuit.id}`));
|
|
48
|
+
console.log(chalk.gray(`Name: ${circuit.name}`));
|
|
49
|
+
console.log(chalk.gray(`Kits: ${circuit.kits.length}`));
|
|
50
|
+
console.log(chalk.gray(`Boards: ${circuit.boards.length}`));
|
|
51
|
+
console.log(chalk.gray(`Capabilities: ${circuit.capabilities.length}`));
|
|
52
|
+
} catch (error) {
|
|
53
|
+
spinner.fail(`Failed to validate: ${error}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Command: circuit info
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
function setupInfoCommand(program: Command): void {
|
|
64
|
+
program
|
|
65
|
+
.command("info <manifest-path>")
|
|
66
|
+
.description("Show detailed information about a Circuit")
|
|
67
|
+
.action(async (manifestPath: string) => {
|
|
68
|
+
const spinner = ora("Loading Circuit info...").start();
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
72
|
+
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
73
|
+
const manifest = JSON.parse(content);
|
|
74
|
+
|
|
75
|
+
const result = CircuitSchema.safeParse(manifest);
|
|
76
|
+
if (!result.success) {
|
|
77
|
+
spinner.fail("Invalid Circuit manifest");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const circuit = result.data;
|
|
82
|
+
spinner.succeed(`Circuit: ${circuit.id}`);
|
|
83
|
+
|
|
84
|
+
console.log(chalk.bold("\nCircuit Information"));
|
|
85
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
86
|
+
console.log(chalk.gray(`ID: ${circuit.id}`));
|
|
87
|
+
console.log(chalk.gray(`Name: ${circuit.name}`));
|
|
88
|
+
console.log(chalk.gray(`Summary: ${circuit.summary}`));
|
|
89
|
+
console.log(chalk.gray(`Version: ${circuit.version}`));
|
|
90
|
+
console.log(chalk.gray(`Status: ${circuit.status}`));
|
|
91
|
+
console.log(chalk.gray(`License: ${circuit.license}`));
|
|
92
|
+
|
|
93
|
+
if (circuit.verticals.length > 0) {
|
|
94
|
+
console.log(chalk.gray(`Verticals: ${circuit.verticals.join(", ")}`));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (circuit.tags.length > 0) {
|
|
98
|
+
console.log(chalk.gray(`Tags: ${circuit.tags.join(", ")}`));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (circuit.kits.length > 0) {
|
|
102
|
+
console.log(chalk.bold("\nKits"));
|
|
103
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
104
|
+
for (const kitRef of circuit.kits) {
|
|
105
|
+
console.log(chalk.gray(` - ${kitRef.kitId}@${kitRef.version}`));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (circuit.boards.length > 0) {
|
|
110
|
+
console.log(chalk.bold("\nBoards"));
|
|
111
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
112
|
+
for (const board of circuit.boards) {
|
|
113
|
+
console.log(chalk.gray(` - ${board.id}: ${board.name}`));
|
|
114
|
+
console.log(chalk.gray(` Columns: ${board.columns.map((c: { id: string; name: string }) => c.name).join(", ")}`));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (circuit.capabilities.length > 0) {
|
|
119
|
+
console.log(chalk.bold("\nCapabilities"));
|
|
120
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
121
|
+
for (const capRef of circuit.capabilities) {
|
|
122
|
+
console.log(chalk.gray(` - ${capRef.blockId}@${capRef.version}`));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (circuit.repository) {
|
|
127
|
+
console.log(chalk.bold("\nRepository"));
|
|
128
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
129
|
+
console.log(chalk.gray(circuit.repository));
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
spinner.fail(`Failed to show info: ${error}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Command: circuit publish
|
|
140
|
+
// ============================================================================
|
|
141
|
+
|
|
142
|
+
function setupPublishCommand(program: Command): void {
|
|
143
|
+
program
|
|
144
|
+
.command("publish")
|
|
145
|
+
.description("Publish a Circuit to registry (simulated)")
|
|
146
|
+
.option("--dry-run", "Simulate publish without actually publishing")
|
|
147
|
+
.action(async (options) => {
|
|
148
|
+
const { dryRun } = options;
|
|
149
|
+
const spinner = ora(dryRun ? "Simulating publish..." : "Publishing Circuit...").start();
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
// Simulate publish
|
|
153
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
154
|
+
|
|
155
|
+
if (dryRun) {
|
|
156
|
+
spinner.succeed("Dry run: Circuit would be published");
|
|
157
|
+
} else {
|
|
158
|
+
spinner.succeed("Circuit published successfully");
|
|
159
|
+
console.log(chalk.gray("\nNote: Actual publishing requires registry authentication."));
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
spinner.fail(`Failed to publish: ${error}`);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// Register Commands
|
|
170
|
+
// ============================================================================
|
|
171
|
+
|
|
172
|
+
/** Register all circuit commands with the program */
|
|
173
|
+
export function registerCircuitCommands(program: Command): void {
|
|
174
|
+
const circuitProgram = program
|
|
175
|
+
.command("circuit")
|
|
176
|
+
.description("Circuit commands")
|
|
177
|
+
.alias("c");
|
|
178
|
+
|
|
179
|
+
setupValidateCommand(circuitProgram);
|
|
180
|
+
setupInfoCommand(circuitProgram);
|
|
181
|
+
setupPublishCommand(circuitProgram);
|
|
182
|
+
}
|