@contextecf/guardian-cli 0.1.0 → 0.1.2
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.
|
@@ -15172,8 +15172,7 @@ import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:
|
|
|
15172
15172
|
import { readFileSync } from "node:fs";
|
|
15173
15173
|
import { copyFile, mkdir, readFile, stat } from "node:fs/promises";
|
|
15174
15174
|
import path from "node:path";
|
|
15175
|
-
import
|
|
15176
|
-
import PageEncryptedDatabase from "better-sqlite3-multiple-ciphers";
|
|
15175
|
+
import SQLiteDatabase from "better-sqlite3-multiple-ciphers";
|
|
15177
15176
|
var HashSchema2 = external_exports.string().regex(/^(sha256:)?[a-f0-9]{64}$/);
|
|
15178
15177
|
var NonEmptyStringSchema2 = external_exports.string().trim().min(1);
|
|
15179
15178
|
var DateTimeStringSchema2 = external_exports.string().datetime({ offset: true });
|
|
@@ -15966,12 +15965,12 @@ function buildSQLitePersonalFabricStorePageEncryption(options) {
|
|
|
15966
15965
|
}
|
|
15967
15966
|
function openSQLitePersonalFabricDatabase(databasePath, pageEncryption) {
|
|
15968
15967
|
if (!pageEncryption) {
|
|
15969
|
-
return new
|
|
15968
|
+
return new SQLiteDatabase(databasePath ?? ":memory:");
|
|
15970
15969
|
}
|
|
15971
15970
|
if (!databasePath) {
|
|
15972
15971
|
throw new Error("Guardian SQLite page encryption requires a filesystem database path.");
|
|
15973
15972
|
}
|
|
15974
|
-
const db = new
|
|
15973
|
+
const db = new SQLiteDatabase(databasePath);
|
|
15975
15974
|
if (pageEncryption.cipher === "sqlcipher") {
|
|
15976
15975
|
db.pragma(`cipher=${sqliteStringLiteral("sqlcipher")}`);
|
|
15977
15976
|
db.pragma(`legacy=${pageEncryption.legacy ?? 4}`);
|
|
@@ -16276,7 +16275,7 @@ function cloneList(values) {
|
|
|
16276
16275
|
}
|
|
16277
16276
|
|
|
16278
16277
|
// packages/guardian-cli/src/runtime.ts
|
|
16279
|
-
var GUARDIAN_CLI_VERSION = "0.1.
|
|
16278
|
+
var GUARDIAN_CLI_VERSION = "0.1.2";
|
|
16280
16279
|
var GUARDIAN_PROFILE_SCHEMA_VERSION = "contextecf/project-guardian-profile/v1";
|
|
16281
16280
|
var GUARDIAN_NPM_PACKAGE_NAME = "@contextecf/guardian-cli";
|
|
16282
16281
|
var GUARDIAN_GLOBAL_INSTALL_COMMAND = `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}`;
|
|
@@ -17437,7 +17436,7 @@ async function runStartCommand(flags, options) {
|
|
|
17437
17436
|
const home = resolveGuardianHome(options.env, options.platform);
|
|
17438
17437
|
const profile = await readProfile(home);
|
|
17439
17438
|
if (!profile) {
|
|
17440
|
-
write(stderr, "Guardian is not installed. Run guardian
|
|
17439
|
+
write(stderr, "Guardian is not installed. Run guardian setup first.\n");
|
|
17441
17440
|
return 1;
|
|
17442
17441
|
}
|
|
17443
17442
|
const host = stringFlag(flags, "host") ?? "127.0.0.1";
|
|
@@ -17445,10 +17444,8 @@ async function runStartCommand(flags, options) {
|
|
|
17445
17444
|
write(stderr, "Guardian start only accepts loopback hosts: 127.0.0.1, localhost, or ::1.\n");
|
|
17446
17445
|
return 1;
|
|
17447
17446
|
}
|
|
17448
|
-
const
|
|
17449
|
-
const
|
|
17450
|
-
const requestedControlTowerUrl = `${requestedDaemonUrl}/control-tower`;
|
|
17451
|
-
const controlTowerSource = host === "127.0.0.1" && port === 4317 ? "default_loopback" : "env_or_flag";
|
|
17447
|
+
const explicitPort = numberFlag(flags, "port");
|
|
17448
|
+
const port = explicitPort ?? 4317;
|
|
17452
17449
|
let token;
|
|
17453
17450
|
try {
|
|
17454
17451
|
token = await readRuntimeToken(home);
|
|
@@ -17460,14 +17457,66 @@ async function runStartCommand(flags, options) {
|
|
|
17460
17457
|
);
|
|
17461
17458
|
return 1;
|
|
17462
17459
|
}
|
|
17463
|
-
const
|
|
17464
|
-
|
|
17465
|
-
|
|
17460
|
+
const healthChecker = options.healthDaemon ?? requestGuardianDaemonHealth;
|
|
17461
|
+
const candidates = explicitPort ? [explicitPort] : Array.from({ length: 8 }, (_, index) => port + index);
|
|
17462
|
+
let selected;
|
|
17463
|
+
let firstTokenMismatch;
|
|
17464
|
+
for (const candidatePort of candidates) {
|
|
17465
|
+
const requestedDaemonUrl2 = formatDaemonBaseUrl(host, candidatePort);
|
|
17466
|
+
const requestedControlTowerUrl2 = `${requestedDaemonUrl2}/control-tower`;
|
|
17467
|
+
const controlTowerSource2 = host === "127.0.0.1" && candidatePort === 4317 ? "default_loopback" : "env_or_flag";
|
|
17468
|
+
const healthUrl2 = resolveDaemonHealthUrl(requestedControlTowerUrl2);
|
|
17469
|
+
if (!healthUrl2.ok) {
|
|
17470
|
+
write(stderr, `${healthUrl2.error}
|
|
17466
17471
|
`);
|
|
17472
|
+
return 1;
|
|
17473
|
+
}
|
|
17474
|
+
const existing2 = await healthChecker({ url: healthUrl2.url, token });
|
|
17475
|
+
if (existing2.ok && existing2.reachable) {
|
|
17476
|
+
selected = {
|
|
17477
|
+
port: candidatePort,
|
|
17478
|
+
requestedDaemonUrl: requestedDaemonUrl2,
|
|
17479
|
+
requestedControlTowerUrl: requestedControlTowerUrl2,
|
|
17480
|
+
healthUrl: healthUrl2.url,
|
|
17481
|
+
controlTowerSource: controlTowerSource2,
|
|
17482
|
+
existing: existing2
|
|
17483
|
+
};
|
|
17484
|
+
break;
|
|
17485
|
+
}
|
|
17486
|
+
if (existing2.statusCode === 401) {
|
|
17487
|
+
firstTokenMismatch ??= {
|
|
17488
|
+
requestedDaemonUrl: requestedDaemonUrl2,
|
|
17489
|
+
port: candidatePort,
|
|
17490
|
+
healthUrl: healthUrl2.url,
|
|
17491
|
+
existing: existing2
|
|
17492
|
+
};
|
|
17493
|
+
if (explicitPort) {
|
|
17494
|
+
write(stderr, renderDaemonTokenMismatchMessage(requestedDaemonUrl2, candidatePort));
|
|
17495
|
+
return 1;
|
|
17496
|
+
}
|
|
17497
|
+
continue;
|
|
17498
|
+
}
|
|
17499
|
+
selected = {
|
|
17500
|
+
port: candidatePort,
|
|
17501
|
+
requestedDaemonUrl: requestedDaemonUrl2,
|
|
17502
|
+
requestedControlTowerUrl: requestedControlTowerUrl2,
|
|
17503
|
+
healthUrl: healthUrl2.url,
|
|
17504
|
+
controlTowerSource: controlTowerSource2,
|
|
17505
|
+
existing: existing2
|
|
17506
|
+
};
|
|
17507
|
+
break;
|
|
17508
|
+
}
|
|
17509
|
+
if (!selected) {
|
|
17510
|
+
const mismatch = firstTokenMismatch ?? {
|
|
17511
|
+
requestedDaemonUrl: formatDaemonBaseUrl(host, port),
|
|
17512
|
+
port,
|
|
17513
|
+
healthUrl: `${formatDaemonBaseUrl(host, port)}/v1/guardian/admin/health`,
|
|
17514
|
+
existing: { ok: false, reachable: false, statusCode: 401, error: "unauthorized" }
|
|
17515
|
+
};
|
|
17516
|
+
write(stderr, renderDaemonTokenMismatchMessage(mismatch.requestedDaemonUrl, mismatch.port));
|
|
17467
17517
|
return 1;
|
|
17468
17518
|
}
|
|
17469
|
-
const
|
|
17470
|
-
const existing = await healthChecker({ url: healthUrl.url, token });
|
|
17519
|
+
const { requestedDaemonUrl, requestedControlTowerUrl, healthUrl, controlTowerSource, existing } = selected;
|
|
17471
17520
|
if (existing.ok && existing.reachable) {
|
|
17472
17521
|
profile.runtime.daemon_status = "start_requested";
|
|
17473
17522
|
profile.control_tower = {
|
|
@@ -17481,7 +17530,7 @@ async function runStartCommand(flags, options) {
|
|
|
17481
17530
|
daemonStatus: profile.runtime.daemon_status,
|
|
17482
17531
|
daemonUrl: requestedDaemonUrl,
|
|
17483
17532
|
controlTowerUrl: requestedControlTowerUrl,
|
|
17484
|
-
healthUrl
|
|
17533
|
+
healthUrl,
|
|
17485
17534
|
healthStatus: "reachable",
|
|
17486
17535
|
nextCommands: ["guardian open", "guardian status", "guardian daemon pair --json"]
|
|
17487
17536
|
};
|
|
@@ -17498,20 +17547,12 @@ async function runStartCommand(flags, options) {
|
|
|
17498
17547
|
);
|
|
17499
17548
|
return 0;
|
|
17500
17549
|
}
|
|
17501
|
-
if (existing.statusCode === 401) {
|
|
17502
|
-
write(
|
|
17503
|
-
stderr,
|
|
17504
|
-
`Guardian daemon at ${requestedDaemonUrl} rejected the local runtime token. Run guardian status or guardian stop before starting another daemon.
|
|
17505
|
-
`
|
|
17506
|
-
);
|
|
17507
|
-
return 1;
|
|
17508
|
-
}
|
|
17509
17550
|
if (!options.startDetachedDaemon) {
|
|
17510
17551
|
write(stderr, "Guardian detached daemon launcher is unavailable in this runtime.\n");
|
|
17511
17552
|
return 1;
|
|
17512
17553
|
}
|
|
17513
|
-
const started = await options.startDetachedDaemon({ home, host, port });
|
|
17514
|
-
const daemonUrl = normalizeDaemonBaseUrl(started.url, host, port);
|
|
17554
|
+
const started = await options.startDetachedDaemon({ home, host, port: selected.port });
|
|
17555
|
+
const daemonUrl = normalizeDaemonBaseUrl(started.url, host, selected.port);
|
|
17515
17556
|
const controlTowerUrl = `${daemonUrl}/control-tower`;
|
|
17516
17557
|
profile.runtime.daemon_status = "start_requested";
|
|
17517
17558
|
profile.control_tower = {
|
|
@@ -17526,7 +17567,7 @@ async function runStartCommand(flags, options) {
|
|
|
17526
17567
|
daemonUrl,
|
|
17527
17568
|
controlTowerUrl,
|
|
17528
17569
|
pid: started.pid,
|
|
17529
|
-
healthUrl
|
|
17570
|
+
healthUrl,
|
|
17530
17571
|
healthStatus: existing.error ? "unreachable" : "not_reachable",
|
|
17531
17572
|
nextCommands: ["guardian open", "guardian status", "guardian daemon pair --json"]
|
|
17532
17573
|
};
|
|
@@ -17544,6 +17585,15 @@ async function runStartCommand(flags, options) {
|
|
|
17544
17585
|
);
|
|
17545
17586
|
return 0;
|
|
17546
17587
|
}
|
|
17588
|
+
function renderDaemonTokenMismatchMessage(requestedDaemonUrl, port) {
|
|
17589
|
+
return [
|
|
17590
|
+
`Guardian found another daemon or container at ${requestedDaemonUrl}, but it rejected this profile's local runtime token.`,
|
|
17591
|
+
"This usually means an older Guardian daemon or Docker demo is still using the port.",
|
|
17592
|
+
`Recovery: stop the other process/container, or run Guardian on a different port with guardian launch --port=${port + 1}.`,
|
|
17593
|
+
`Diagnostics: guardian status; docker ps --filter publish=${port}`,
|
|
17594
|
+
""
|
|
17595
|
+
].join("\n");
|
|
17596
|
+
}
|
|
17547
17597
|
async function runStopCommand(flags, options) {
|
|
17548
17598
|
const stdout = options.stdout ?? process.stdout;
|
|
17549
17599
|
const stderr = options.stderr ?? process.stderr;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Writable } from 'node:stream';
|
|
2
2
|
import { type PolicyPackMarketplaceManifest } from '@contextecf/personal-fabric-contracts';
|
|
3
3
|
import { SQLitePersonalFabricStore, type PersonalFabricDataImportResult, type PersonalFabricMutableDataDeleteResult, type SQLitePersonalFabricBackupResult } from '@contextecf/personal-fabric-store';
|
|
4
|
-
export declare const GUARDIAN_CLI_VERSION = "0.1.
|
|
4
|
+
export declare const GUARDIAN_CLI_VERSION = "0.1.2";
|
|
5
5
|
export declare const GUARDIAN_PROFILE_SCHEMA_VERSION = "contextecf/project-guardian-profile/v1";
|
|
6
6
|
export declare const GUARDIAN_NPM_PACKAGE_NAME = "@contextecf/guardian-cli";
|
|
7
7
|
export declare const GUARDIAN_GLOBAL_INSTALL_COMMAND = "npm install -g @contextecf/guardian-cli";
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contextecf/guardian-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Project Guardian local-first Personal Context Fabric CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"main": "dist/packages/guardian-cli/src/index.js",
|
|
8
8
|
"types": "dist/packages/guardian-cli/src/index.d.ts",
|
|
9
9
|
"engines": {
|
|
10
|
-
"node": ">=
|
|
10
|
+
"node": ">=20.20.0"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/packages/guardian-cli/src/bin.d.ts",
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
"mcp"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"better-sqlite3": "^13.0.1",
|
|
50
49
|
"better-sqlite3-multiple-ciphers": "^12.11.1"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|