@onesi/genesis-cli 0.1.13 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -2
- package/dist/beacons.js +68 -0
- package/dist/dials.js +7 -4
- package/dist/fleets.js +30 -0
- package/dist/flocks.d.ts +7 -1
- package/dist/flocks.js +281 -4
- package/dist/henry.d.ts +5 -1
- package/dist/henry.js +60 -1
- package/dist/hives-coverage.d.ts +12 -0
- package/dist/hives-coverage.js +133 -0
- package/dist/hives-node-transport.js +4 -1
- package/dist/hives-operations.d.ts +1 -0
- package/dist/hives-operations.js +2 -0
- package/dist/hives-platform.d.ts +13 -0
- package/dist/hives-platform.js +133 -0
- package/dist/hives-resources.d.ts +1 -0
- package/dist/hives-resources.js +5 -3
- package/dist/iam-directory.d.ts +15 -0
- package/dist/iam-directory.js +71 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +273 -30
- package/dist/minds.d.ts +1 -1
- package/dist/minds.js +37 -2
- package/dist/onboard/art.d.ts +50 -0
- package/dist/onboard/art.js +139 -0
- package/dist/onboard/brand.d.ts +56 -0
- package/dist/onboard/brand.js +134 -0
- package/dist/onboard/caps.d.ts +90 -0
- package/dist/onboard/caps.js +232 -0
- package/dist/onboard/encode.d.ts +23 -0
- package/dist/onboard/encode.js +235 -0
- package/dist/onboard/eye.d.ts +103 -0
- package/dist/onboard/eye.js +147 -0
- package/dist/onboard/index.d.ts +61 -0
- package/dist/onboard/index.js +562 -0
- package/dist/onboard/mcp.d.ts +35 -0
- package/dist/onboard/mcp.js +118 -0
- package/dist/onboard/raster.d.ts +43 -0
- package/dist/onboard/raster.js +253 -0
- package/dist/onboard/sound.d.ts +2 -0
- package/dist/onboard/sound.js +54 -0
- package/dist/onboard/state.d.ts +24 -0
- package/dist/onboard/state.js +48 -0
- package/dist/onboard/term.d.ts +69 -0
- package/dist/onboard/term.js +292 -0
- package/dist/onboard/ui.d.ts +97 -0
- package/dist/onboard/ui.js +615 -0
- package/dist/orgs.d.ts +16 -0
- package/dist/orgs.js +89 -0
- package/dist/output.d.ts +13 -1
- package/dist/output.js +21 -2
- package/dist/products.d.ts +6 -2
- package/dist/products.js +474 -13
- package/dist/relays-commands/certificates.d.ts +3 -0
- package/dist/relays-commands/certificates.js +20 -0
- package/dist/relays-commands/domains.d.ts +3 -0
- package/dist/relays-commands/domains.js +23 -0
- package/dist/relays-commands/index.d.ts +4 -0
- package/dist/relays-commands/index.js +10 -0
- package/dist/relays-commands/monitoring.d.ts +3 -0
- package/dist/relays-commands/monitoring.js +41 -0
- package/dist/relays-commands/telemetry.d.ts +3 -0
- package/dist/relays-commands/telemetry.js +28 -0
- package/dist/relays-commands/zones.d.ts +7 -0
- package/dist/relays-commands/zones.js +16 -0
- package/dist/runner.js +2 -0
- package/package.json +2 -2
package/dist/orgs.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { basename, extname } from 'node:path';
|
|
3
|
+
import { readFunctionFile, readFunctionJson, writeFunctionOutput } from './function-input.js';
|
|
4
|
+
/** Orgs accepts documents of 1 byte to 5 MiB (sent as base64 in JSON). */
|
|
5
|
+
export const ORGS_MAX_DOCUMENT_BYTES = 5 * 1024 * 1024;
|
|
6
|
+
const MEDIA_TYPES = {
|
|
7
|
+
'.pdf': 'application/pdf', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
|
|
8
|
+
'.txt': 'text/plain', '.md': 'text/markdown', '.markdown': 'text/markdown', '.json': 'application/json',
|
|
9
|
+
};
|
|
10
|
+
const DOCUMENT_KINDS = ['articles', 'certificate', 'operating_agreement', 'bylaws', 'resolution', 'filing_receipt', 'tax_letter', 'other'];
|
|
11
|
+
const group = (parent, name) => parent.commands.find(c => c.name() === name) ?? parent.command(name);
|
|
12
|
+
/**
|
|
13
|
+
* The Orgs commands that are more than one JSON request: uploading a document from a file, downloading
|
|
14
|
+
* a document's bytes to a path (checked against its sha256), and requesting formation with --dry-run.
|
|
15
|
+
* Every other Orgs operation is a generic command under `genesis orgs` (products.ts).
|
|
16
|
+
*/
|
|
17
|
+
export function registerOrgs(program, deps) {
|
|
18
|
+
const orgs = group(program, 'orgs');
|
|
19
|
+
const documents = group(orgs, 'documents');
|
|
20
|
+
documents.command('add <entity>')
|
|
21
|
+
.description('Add a document from a file (up to 5 MiB) or a Boxes file (POST /v1/orgs/entities/{entity}/documents)')
|
|
22
|
+
.requiredOption('--kind <kind>', DOCUMENT_KINDS.join(' | '))
|
|
23
|
+
.option('--file <path>', 'document file; sent as base64')
|
|
24
|
+
.option('--boxes-file-id <id>', 'a Boxes file instead of --file')
|
|
25
|
+
.option('--title <title>', 'defaults to the file name')
|
|
26
|
+
.option('--media-type <type>', 'application/pdf | image/png | image/jpeg | text/plain | text/markdown | application/json (default: from the file extension)')
|
|
27
|
+
.action(async (entity, o) => {
|
|
28
|
+
if (!DOCUMENT_KINDS.includes(o.kind))
|
|
29
|
+
throw new Error(`--kind must be one of ${DOCUMENT_KINDS.join(', ')}`);
|
|
30
|
+
if (!o.file === !o.boxesFileId)
|
|
31
|
+
throw new Error('Pass exactly one of --file or --boxes-file-id.');
|
|
32
|
+
const mediaType = o.mediaType ?? (o.file ? MEDIA_TYPES[extname(o.file).toLowerCase()] : undefined);
|
|
33
|
+
if (!mediaType)
|
|
34
|
+
throw new Error('Pass --media-type (the file extension does not name a supported type).');
|
|
35
|
+
const title = o.title ?? (o.file ? basename(o.file) : undefined);
|
|
36
|
+
if (!title)
|
|
37
|
+
throw new Error('Pass --title.');
|
|
38
|
+
let content;
|
|
39
|
+
if (o.file) {
|
|
40
|
+
const bytes = await readFunctionFile(o.file, ORGS_MAX_DOCUMENT_BYTES);
|
|
41
|
+
if (!bytes.length)
|
|
42
|
+
throw new Error('The document file is empty.');
|
|
43
|
+
content = { content_base64: Buffer.from(bytes).toString('base64') };
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
content = { boxes_file_id: o.boxesFileId };
|
|
47
|
+
const body = { kind: o.kind, title, media_type: mediaType, ...content };
|
|
48
|
+
const result = await (await deps.client()).request('orgs_add_document', { entity, body }, { signal: deps.signal });
|
|
49
|
+
deps.emit(result, () => JSON.stringify(result, null, 2));
|
|
50
|
+
});
|
|
51
|
+
documents.command('content <document>')
|
|
52
|
+
.description("Download a document's bytes to a new file and check its sha256 (GET /v1/orgs/documents/{document}/content)")
|
|
53
|
+
.requiredOption('--out <path>', 'new file to write (an existing file is never overwritten)')
|
|
54
|
+
.action(async (document, o) => {
|
|
55
|
+
const genesis = await deps.client();
|
|
56
|
+
const { bytes, contentType, sha256 } = await genesis.orgs.documents.content(document, { signal: deps.signal });
|
|
57
|
+
const actual = createHash('sha256').update(bytes).digest('hex');
|
|
58
|
+
if (sha256 && sha256 !== actual)
|
|
59
|
+
throw new Error('The downloaded bytes do not match the document sha256. Nothing was written.');
|
|
60
|
+
await writeFunctionOutput(o.out, bytes);
|
|
61
|
+
const result = { document, path: o.out, bytes: bytes.byteLength, content_type: contentType, sha256: actual, verified: sha256 === actual };
|
|
62
|
+
deps.emit(result, () => JSON.stringify(result, null, 2));
|
|
63
|
+
});
|
|
64
|
+
group(orgs, 'formation').command('request <entity>')
|
|
65
|
+
.description('Prepare the formation packet and start a rehearsal run that stops at the state submit/payment page; --dry-run returns only the packet (POST /v1/orgs/entities/{entity}/formation)')
|
|
66
|
+
.option('--contact-email <email>', 'contact email for the filing (required unless in --body-file)')
|
|
67
|
+
.option('--runtime <runtime>', 'panes (default) | rigs | shells')
|
|
68
|
+
.option('--instance-id <id>', 'an existing browser instance to drive')
|
|
69
|
+
.option('--effective-date <date>', 'YYYY-MM-DD')
|
|
70
|
+
.option('--dry-run', 'build and return the packet only; start nothing')
|
|
71
|
+
.option('--body-file <path>', 'JSON request body (e.g. organizers), up to 1 MiB; flags override its fields')
|
|
72
|
+
.action(async (entity, o) => {
|
|
73
|
+
const body = o.bodyFile ? await readFunctionJson(o.bodyFile, 1024 * 1024) : {};
|
|
74
|
+
if (o.contactEmail !== undefined)
|
|
75
|
+
body.contact_email = o.contactEmail;
|
|
76
|
+
if (o.runtime !== undefined)
|
|
77
|
+
body.runtime = o.runtime;
|
|
78
|
+
if (o.instanceId !== undefined)
|
|
79
|
+
body.instance_id = o.instanceId;
|
|
80
|
+
if (o.effectiveDate !== undefined)
|
|
81
|
+
body.effective_date = o.effectiveDate;
|
|
82
|
+
if (o.dryRun)
|
|
83
|
+
body.dry_run = true;
|
|
84
|
+
if (typeof body.contact_email !== 'string')
|
|
85
|
+
throw new Error('Pass --contact-email (or contact_email in --body-file).');
|
|
86
|
+
const result = await (await deps.client()).request('orgs_request_formation', { entity, body }, { signal: deps.signal });
|
|
87
|
+
deps.emit(result, () => JSON.stringify(result, null, 2));
|
|
88
|
+
});
|
|
89
|
+
}
|
package/dist/output.d.ts
CHANGED
|
@@ -21,7 +21,19 @@ export declare const c: {
|
|
|
21
21
|
* operators (U+2060-2064), Mongolian vowel separator (U+180E), soft hyphen
|
|
22
22
|
* (U+00AD) and tag characters (U+E0000-E007F).
|
|
23
23
|
*/
|
|
24
|
-
export declare function safe(v: unknown): string;
|
|
24
|
+
export declare function safe(v: unknown, keepLines?: boolean): string;
|
|
25
|
+
/**
|
|
26
|
+
* A message cleaned for redaction: terminal controls and invisible characters are stripped first (line breaks
|
|
27
|
+
* kept, so header lines still match), so none can split a secret and hide it from the patterns.
|
|
28
|
+
*/
|
|
29
|
+
export declare function redactMessage(message: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* A message as the terminal prints it: redacted, made safe, then redacted again, because `safe` drops the tabs and
|
|
32
|
+
* line breaks redaction kept, which could join the pieces of a split secret back together.
|
|
33
|
+
*/
|
|
34
|
+
export declare function printable(message: string): string;
|
|
35
|
+
/** The message of a caught error, redacted (tokens, card numbers, emails...) and safe to print. */
|
|
36
|
+
export declare function errorText(e: unknown): string;
|
|
25
37
|
/** Render rows as an aligned table; every cell is passed through safe(). */
|
|
26
38
|
export declare function table(rows: Record<string, unknown>[], cols: string[]): string;
|
|
27
39
|
/** Pull the array out of the various list envelopes ({data}, {zones}, {records}, bare array). */
|
package/dist/output.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { redactErrorText } from '@onesi/genesis';
|
|
1
2
|
export const stdio = { log: (s) => process.stdout.write(s + '\n'), err: (s) => process.stderr.write(s + '\n') };
|
|
2
3
|
const tty = () => !!process.stdout.isTTY && !process.env.NO_COLOR;
|
|
3
4
|
export const c = {
|
|
@@ -18,14 +19,32 @@ export const c = {
|
|
|
18
19
|
* operators (U+2060-2064), Mongolian vowel separator (U+180E), soft hyphen
|
|
19
20
|
* (U+00AD) and tag characters (U+E0000-E007F).
|
|
20
21
|
*/
|
|
21
|
-
export function safe(v) {
|
|
22
|
+
export function safe(v, keepLines = false) {
|
|
22
23
|
return String(v)
|
|
23
24
|
.replace(/(?:\x1b\]|\x9d)[^\x07\x1b\x9c]*(?:\x07|\x1b\\|\x9c)?/g, '')
|
|
24
25
|
.replace(/(?:\x1b\[|\x9b)[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]?/g, '')
|
|
25
26
|
.replace(/\x1b[\x20-\x2f]*[\x30-\x7e]?/g, '')
|
|
26
|
-
.replace(/[\x00-\x1f\x7f-\x9f]/g, '')
|
|
27
|
+
.replace(keepLines ? /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g : /[\x00-\x1f\x7f-\x9f]/g, '')
|
|
27
28
|
.replace(/[\u202a-\u202e\u2066-\u2069\u200b-\u200f\u061c\ufeff\u2028\u2029\u2060-\u2064\u180e\u00ad\u{e0000}-\u{e007f}]/gu, '');
|
|
28
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* A message cleaned for redaction: terminal controls and invisible characters are stripped first (line breaks
|
|
32
|
+
* kept, so header lines still match), so none can split a secret and hide it from the patterns.
|
|
33
|
+
*/
|
|
34
|
+
export function redactMessage(message) {
|
|
35
|
+
return redactErrorText(safe(message, true));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A message as the terminal prints it: redacted, made safe, then redacted again, because `safe` drops the tabs and
|
|
39
|
+
* line breaks redaction kept, which could join the pieces of a split secret back together.
|
|
40
|
+
*/
|
|
41
|
+
export function printable(message) {
|
|
42
|
+
return redactErrorText(safe(redactMessage(message)));
|
|
43
|
+
}
|
|
44
|
+
/** The message of a caught error, redacted (tokens, card numbers, emails...) and safe to print. */
|
|
45
|
+
export function errorText(e) {
|
|
46
|
+
return printable(e instanceof Error ? e.message : String(e));
|
|
47
|
+
}
|
|
29
48
|
/** Render rows as an aligned table; every cell is passed through safe(). */
|
|
30
49
|
export function table(rows, cols) {
|
|
31
50
|
if (!rows.length)
|
package/dist/products.d.ts
CHANGED
|
@@ -7,8 +7,12 @@ export declare const PRODUCT_COMMANDS: Record<string, {
|
|
|
7
7
|
description: string;
|
|
8
8
|
commands: Record<string, OperationId>;
|
|
9
9
|
}>;
|
|
10
|
-
|
|
10
|
+
type ProductDependencies = {
|
|
11
11
|
client: () => Promise<Genesis>;
|
|
12
12
|
emit: (data: unknown, pretty: () => string) => void;
|
|
13
13
|
signal?: AbortSignal;
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
|
+
export declare function registerProducts(program: Command, dependencies: ProductDependencies): void;
|
|
16
|
+
export declare function printableMediaType(contentType: string | null | undefined): boolean;
|
|
17
|
+
export declare function registerOperationCommands(root: Command, commands: Readonly<Record<string, OperationId>>, dependencies: ProductDependencies): void;
|
|
18
|
+
export {};
|