npl-presence-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # @nextera.one/npl-cli
2
+
3
+ Command-line interface for **NPL (Network Presence Layer)** operations.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @nextera.one/npl-cli
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ### Presence Objects
14
+
15
+ ```bash
16
+ # Create a presence object
17
+ npl presence create -s "device:sensor-001" --scopes net,log --ttl 5
18
+
19
+ # Validate a presence object
20
+ npl presence validate '{"ver":1,"alg":"ed25519","pay":{...}}'
21
+ ```
22
+
23
+ ### NPL-ID
24
+
25
+ ```bash
26
+ # Generate presence and compute NPL-ID
27
+ npl id generate -s "user:alice" --scopes net,auth
28
+
29
+ # Compute NPL-ID from existing presence
30
+ npl id compute '{"ver":1,"alg":"ed25519","pay":{...}}'
31
+ ```
32
+
33
+ ### Resolution Records
34
+
35
+ ```bash
36
+ # Create a resolution record
37
+ npl rr create --npl-id <hash> --ip 192.168.1.1 --ip 10.0.0.1 --ttl 5
38
+
39
+ # Validate a resolution record
40
+ npl rr validate '{"ver":1,"typ":"NPL-RR",...}'
41
+ ```
42
+
43
+ ### Keypairs
44
+
45
+ ```bash
46
+ # Generate Ed25519 keypair
47
+ npl keypair generate
48
+
49
+ # Generate with base64 format
50
+ npl keypair generate --format base64
51
+ ```
52
+
53
+ ## License
54
+
55
+ Apache-2.0
@@ -0,0 +1,6 @@
1
+ /**
2
+ * NPL CLI - ID Command
3
+ * Compute and display NPL-IDs
4
+ */
5
+ import { Command } from 'commander';
6
+ export declare const idCommand: Command;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * NPL CLI - ID Command
3
+ * Compute and display NPL-IDs
4
+ */
5
+ import { Command } from 'commander';
6
+ import chalk from 'chalk';
7
+ import { createPresence, computeNplId } from '@nextera.one/npl-sdk';
8
+ export const idCommand = new Command('id')
9
+ .description('NPL-ID operations');
10
+ idCommand
11
+ .command('compute')
12
+ .description('Compute NPL-ID from a presence object')
13
+ .argument('<json>', 'Presence object JSON')
14
+ .action((json) => {
15
+ try {
16
+ const presence = JSON.parse(json);
17
+ const nplId = computeNplId(presence);
18
+ console.log(chalk.green('NPL-ID:'));
19
+ console.log(chalk.cyan(nplId));
20
+ console.log();
21
+ console.log(chalk.dim('Short:'), nplId.substring(0, 16) + '...');
22
+ }
23
+ catch (err) {
24
+ console.error(chalk.red('Error:'), err);
25
+ process.exit(1);
26
+ }
27
+ });
28
+ idCommand
29
+ .command('generate')
30
+ .description('Create a presence and compute its NPL-ID')
31
+ .requiredOption('-s, --subject <subject>', 'Subject identity')
32
+ .option('--scopes <scopes>', 'Comma-separated scopes', 'net')
33
+ .option('--ttl <minutes>', 'TTL in minutes', '5')
34
+ .action((options) => {
35
+ const scopes = options.scopes.split(',');
36
+ const ttl = parseInt(options.ttl, 10);
37
+ const presence = createPresence(options.subject, scopes, ttl);
38
+ const nplId = computeNplId(presence);
39
+ console.log(chalk.green('✓ NPL-ID generated'));
40
+ console.log();
41
+ console.log(chalk.dim('Subject:'), options.subject);
42
+ console.log(chalk.dim('Scopes:'), scopes.join(', '));
43
+ console.log(chalk.dim('TTL:'), `${ttl} minutes`);
44
+ console.log();
45
+ console.log(chalk.green('NPL-ID:'));
46
+ console.log(chalk.cyan(nplId));
47
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * NPL CLI - Keypair Command
3
+ * Generate and manage Ed25519 keypairs
4
+ */
5
+ import { Command } from 'commander';
6
+ export declare const keypairCommand: Command;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * NPL CLI - Keypair Command
3
+ * Generate and manage Ed25519 keypairs
4
+ */
5
+ import { Command } from 'commander';
6
+ import chalk from 'chalk';
7
+ import { generateKeypair, bytesToHex } from '@nextera.one/npl-sdk';
8
+ export const keypairCommand = new Command('keypair')
9
+ .description('Keypair operations');
10
+ keypairCommand
11
+ .command('generate')
12
+ .description('Generate a new Ed25519 keypair')
13
+ .option('--format <format>', 'Output format (hex, base64)', 'hex')
14
+ .action(async (options) => {
15
+ const keypair = await generateKeypair();
16
+ console.log(chalk.green('✓ Ed25519 keypair generated'));
17
+ console.log();
18
+ if (options.format === 'hex') {
19
+ console.log(chalk.dim('Private Key (hex):'));
20
+ console.log(chalk.yellow(bytesToHex(keypair.privateKey)));
21
+ console.log();
22
+ console.log(chalk.dim('Public Key (hex):'));
23
+ console.log(chalk.cyan(bytesToHex(keypair.publicKey)));
24
+ }
25
+ else {
26
+ console.log(chalk.dim('Private Key (base64):'));
27
+ console.log(chalk.yellow(Buffer.from(keypair.privateKey).toString('base64')));
28
+ console.log();
29
+ console.log(chalk.dim('Public Key (base64):'));
30
+ console.log(chalk.cyan(Buffer.from(keypair.publicKey).toString('base64')));
31
+ }
32
+ console.log();
33
+ console.log(chalk.red('⚠ Store the private key securely!'));
34
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * NPL CLI - Presence Command
3
+ * Create and validate presence objects
4
+ */
5
+ import { Command } from 'commander';
6
+ export declare const presenceCommand: Command;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * NPL CLI - Presence Command
3
+ * Create and validate presence objects
4
+ */
5
+ import { Command } from 'commander';
6
+ import chalk from 'chalk';
7
+ import { createPresence, validatePresence, formatPresence, isPresenceValid, getPresenceTtl, } from '@nextera.one/npl-sdk';
8
+ export const presenceCommand = new Command('presence')
9
+ .description('Presence object operations');
10
+ presenceCommand
11
+ .command('create')
12
+ .description('Create a new NPL presence object')
13
+ .requiredOption('-s, --subject <subject>', 'Subject identity')
14
+ .option('--scopes <scopes>', 'Comma-separated scopes (net,log,auth,exec)', 'net')
15
+ .option('--ttl <minutes>', 'TTL in minutes', '5')
16
+ .option('--anchor <type>', 'Trust anchor type (geo,carrier,org,dns,hardware,jur)')
17
+ .action((options) => {
18
+ const scopes = options.scopes.split(',');
19
+ const ttl = parseInt(options.ttl, 10);
20
+ const presence = createPresence(options.subject, scopes, ttl, options.anchor);
21
+ console.log(chalk.green('✓ Presence object created'));
22
+ console.log();
23
+ console.log(formatPresence(presence));
24
+ });
25
+ presenceCommand
26
+ .command('validate')
27
+ .description('Validate a presence object from JSON')
28
+ .argument('<json>', 'Presence object JSON')
29
+ .action((json) => {
30
+ try {
31
+ const presence = JSON.parse(json);
32
+ const result = validatePresence(presence);
33
+ if (result.ok) {
34
+ console.log(chalk.green('✓ Presence object is valid'));
35
+ console.log();
36
+ console.log('Status:', isPresenceValid(presence) ? chalk.green('Active') : chalk.red('Expired'));
37
+ console.log('TTL:', chalk.cyan(`${getPresenceTtl(presence)}s remaining`));
38
+ }
39
+ else {
40
+ console.log(chalk.red('✗ Presence object is invalid'));
41
+ result.errors.forEach((err) => {
42
+ console.log(chalk.red(` - ${err}`));
43
+ });
44
+ process.exit(1);
45
+ }
46
+ }
47
+ catch (err) {
48
+ console.error(chalk.red('Error parsing JSON:'), err);
49
+ process.exit(1);
50
+ }
51
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * NPL CLI - Resolution Record Command
3
+ * Create and validate resolution records
4
+ */
5
+ import { Command } from 'commander';
6
+ export declare const rrCommand: Command;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * NPL CLI - Resolution Record Command
3
+ * Create and validate resolution records
4
+ */
5
+ import { Command } from 'commander';
6
+ import chalk from 'chalk';
7
+ import { createResolutionRecord, validateResolutionRecord, isResolutionRecordValid, } from '@nextera.one/npl-sdk';
8
+ export const rrCommand = new Command('rr')
9
+ .description('Resolution record operations');
10
+ rrCommand
11
+ .command('create')
12
+ .description('Create a resolution record')
13
+ .requiredOption('--npl-id <id>', 'NPL-ID to bind')
14
+ .requiredOption('--ip <ip>', 'IP address (can be specified multiple times)', collect, [])
15
+ .option('--ttl <minutes>', 'TTL in minutes', '5')
16
+ .option('--ports <ports>', 'Comma-separated port numbers')
17
+ .option('--proto <protocols>', 'Comma-separated protocols (tcp,quic,udp)')
18
+ .action((options) => {
19
+ const ips = options.ip.map((ip) => ({
20
+ ip,
21
+ fam: ip.includes(':') ? 6 : 4,
22
+ }));
23
+ const ctx = {};
24
+ if (options.ports) {
25
+ ctx.port = options.ports.split(',').map((p) => parseInt(p, 10));
26
+ }
27
+ if (options.proto) {
28
+ ctx.proto = options.proto.split(',');
29
+ }
30
+ const rr = createResolutionRecord(options.nplId, ips, parseInt(options.ttl, 10), Object.keys(ctx).length > 0 ? ctx : undefined);
31
+ console.log(chalk.green('✓ Resolution record created'));
32
+ console.log();
33
+ console.log(JSON.stringify(rr, null, 2));
34
+ });
35
+ rrCommand
36
+ .command('validate')
37
+ .description('Validate a resolution record')
38
+ .argument('<json>', 'Resolution record JSON')
39
+ .action((json) => {
40
+ try {
41
+ const rr = JSON.parse(json);
42
+ const result = validateResolutionRecord(rr);
43
+ if (result.ok) {
44
+ console.log(chalk.green('✓ Resolution record is valid'));
45
+ console.log();
46
+ console.log('Status:', isResolutionRecordValid(rr) ? chalk.green('Active') : chalk.red('Expired'));
47
+ console.log('NPL-ID:', chalk.cyan(rr.npl_id.substring(0, 16) + '...'));
48
+ console.log('IPs:', rr.ips.map((ip) => ip.ip).join(', '));
49
+ }
50
+ else {
51
+ console.log(chalk.red('✗ Resolution record is invalid'));
52
+ result.errors.forEach((err) => {
53
+ console.log(chalk.red(` - ${err}`));
54
+ });
55
+ process.exit(1);
56
+ }
57
+ }
58
+ catch (err) {
59
+ console.error(chalk.red('Error parsing JSON:'), err);
60
+ process.exit(1);
61
+ }
62
+ });
63
+ function collect(value, previous) {
64
+ return previous.concat([value]);
65
+ }
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NPL CLI - Network Presence Layer
4
+ * Command-line interface for NPL operations
5
+ */
6
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NPL CLI - Network Presence Layer
4
+ * Command-line interface for NPL operations
5
+ */
6
+ import { Command } from 'commander';
7
+ import { presenceCommand } from './commands/presence.js';
8
+ import { idCommand } from './commands/id.js';
9
+ import { rrCommand } from './commands/rr.js';
10
+ import { keypairCommand } from './commands/keypair.js';
11
+ const program = new Command();
12
+ program
13
+ .name('npl')
14
+ .description('NPL CLI - Network Presence Layer operations')
15
+ .version('1.0.0');
16
+ program.addCommand(presenceCommand);
17
+ program.addCommand(idCommand);
18
+ program.addCommand(rrCommand);
19
+ program.addCommand(keypairCommand);
20
+ program.parse(process.argv);
21
+ if (!process.argv.slice(2).length) {
22
+ program.outputHelp();
23
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "npl-presence-cli",
3
+ "version": "1.0.0",
4
+ "description": "NPL CLI - Network Presence Layer command-line interface",
5
+ "type": "module",
6
+ "bin": {
7
+ "npl": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "test": "npm run build && node --test",
17
+ "prepare": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "npl",
21
+ "network-presence",
22
+ "cli",
23
+ "cryptographic",
24
+ "verification",
25
+ "nextera",
26
+ "presence-layer"
27
+ ],
28
+ "author": "NextEra.One",
29
+ "license": "Apache-2.0",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/nextera-one/npl"
33
+ },
34
+ "homepage": "https://npl-standard.org",
35
+ "dependencies": {
36
+ "chalk": "^5.6.2",
37
+ "commander": "^14.0.2",
38
+ "npl-presence-sdk": "^1.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^25.0.3",
42
+ "typescript": "^5.9.3"
43
+ }
44
+ }