@semiont/cli 0.3.0 → 0.3.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/dist/cli.mjs +412 -70
- package/package.json +7 -7
package/dist/cli.mjs
CHANGED
|
@@ -512,8 +512,8 @@ var init_parseUtil = __esm({
|
|
|
512
512
|
init_errors();
|
|
513
513
|
init_en();
|
|
514
514
|
makeIssue = (params) => {
|
|
515
|
-
const { data, path:
|
|
516
|
-
const fullPath = [...
|
|
515
|
+
const { data, path: path46, errorMaps, issueData } = params;
|
|
516
|
+
const fullPath = [...path46, ...issueData.path || []];
|
|
517
517
|
const fullIssue = {
|
|
518
518
|
...issueData,
|
|
519
519
|
path: fullPath
|
|
@@ -821,11 +821,11 @@ var init_types = __esm({
|
|
|
821
821
|
init_parseUtil();
|
|
822
822
|
init_util();
|
|
823
823
|
ParseInputLazyPath = class {
|
|
824
|
-
constructor(parent, value,
|
|
824
|
+
constructor(parent, value, path46, key) {
|
|
825
825
|
this._cachedPath = [];
|
|
826
826
|
this.parent = parent;
|
|
827
827
|
this.data = value;
|
|
828
|
-
this._path =
|
|
828
|
+
this._path = path46;
|
|
829
829
|
this._key = key;
|
|
830
830
|
}
|
|
831
831
|
get path() {
|
|
@@ -5626,8 +5626,8 @@ var init_filesystem_service = __esm({
|
|
|
5626
5626
|
async checkHealth() {
|
|
5627
5627
|
const dataPath = this.getDataPath();
|
|
5628
5628
|
try {
|
|
5629
|
-
const
|
|
5630
|
-
await
|
|
5629
|
+
const fs54 = await import("fs");
|
|
5630
|
+
await fs54.promises.access(dataPath, fs54.constants.R_OK | fs54.constants.W_OK);
|
|
5631
5631
|
return {
|
|
5632
5632
|
healthy: true,
|
|
5633
5633
|
details: {
|
|
@@ -7157,11 +7157,11 @@ var init_backend_check = __esm({
|
|
|
7157
7157
|
let logs;
|
|
7158
7158
|
if (fs11.existsSync(appLogPath)) {
|
|
7159
7159
|
try {
|
|
7160
|
-
const { execFileSync:
|
|
7161
|
-
const recentLogs =
|
|
7160
|
+
const { execFileSync: execFileSync45 } = __require("child_process");
|
|
7161
|
+
const recentLogs = execFileSync45("tail", ["-10", appLogPath], { encoding: "utf-8" }).split("\n").filter((line) => line.trim());
|
|
7162
7162
|
let errorLogs = [];
|
|
7163
7163
|
if (fs11.existsSync(errorLogPath)) {
|
|
7164
|
-
errorLogs =
|
|
7164
|
+
errorLogs = execFileSync45("tail", ["-5", errorLogPath], { encoding: "utf-8" }).split("\n").filter((line) => line.trim());
|
|
7165
7165
|
}
|
|
7166
7166
|
logs = {
|
|
7167
7167
|
recent: recentLogs,
|
|
@@ -7377,11 +7377,11 @@ var init_frontend_check = __esm({
|
|
|
7377
7377
|
let logs;
|
|
7378
7378
|
if (fs12.existsSync(appLogPath)) {
|
|
7379
7379
|
try {
|
|
7380
|
-
const { execFileSync:
|
|
7381
|
-
const recentLogs =
|
|
7380
|
+
const { execFileSync: execFileSync45 } = __require("child_process");
|
|
7381
|
+
const recentLogs = execFileSync45("tail", ["-10", appLogPath], { encoding: "utf-8" }).split("\n").filter((line) => line.trim());
|
|
7382
7382
|
let errorLogs = [];
|
|
7383
7383
|
if (fs12.existsSync(errorLogPath)) {
|
|
7384
|
-
errorLogs =
|
|
7384
|
+
errorLogs = execFileSync45("tail", ["-5", errorLogPath], { encoding: "utf-8" }).split("\n").filter((line) => line.trim());
|
|
7385
7385
|
}
|
|
7386
7386
|
logs = {
|
|
7387
7387
|
recent: recentLogs,
|
|
@@ -8029,8 +8029,8 @@ async function startJanusGraph(context) {
|
|
|
8029
8029
|
for (let i = 0; i < maxAttempts; i++) {
|
|
8030
8030
|
await new Promise((resolve9) => setTimeout(resolve9, 2e3));
|
|
8031
8031
|
try {
|
|
8032
|
-
const { execFileSync:
|
|
8033
|
-
|
|
8032
|
+
const { execFileSync: execFileSync45 } = await import("child_process");
|
|
8033
|
+
execFileSync45(gremlinShellScript, ["-e", "g.V().count()"], {
|
|
8034
8034
|
stdio: "ignore",
|
|
8035
8035
|
timeout: 5e3
|
|
8036
8036
|
});
|
|
@@ -8081,9 +8081,9 @@ async function startJanusGraph(context) {
|
|
|
8081
8081
|
}
|
|
8082
8082
|
};
|
|
8083
8083
|
}
|
|
8084
|
-
async function fileExists(
|
|
8084
|
+
async function fileExists(path46) {
|
|
8085
8085
|
try {
|
|
8086
|
-
await fs17.access(
|
|
8086
|
+
await fs17.access(path46);
|
|
8087
8087
|
return true;
|
|
8088
8088
|
} catch {
|
|
8089
8089
|
return false;
|
|
@@ -8911,8 +8911,8 @@ var init_filesystem_provision = __esm({
|
|
|
8911
8911
|
metadata.directories.push(dirPath);
|
|
8912
8912
|
}
|
|
8913
8913
|
try {
|
|
8914
|
-
const { execFileSync:
|
|
8915
|
-
const dfOutput =
|
|
8914
|
+
const { execFileSync: execFileSync45 } = __require("child_process");
|
|
8915
|
+
const dfOutput = execFileSync45("df", ["-h", absolutePath], { encoding: "utf-8" });
|
|
8916
8916
|
const lines = dfOutput.split("\n");
|
|
8917
8917
|
if (lines.length > 1) {
|
|
8918
8918
|
const stats = lines[1].split(/\s+/);
|
|
@@ -9017,9 +9017,9 @@ Files placed here will persist across service restarts.
|
|
|
9017
9017
|
// src/platforms/posix/handlers/graph-provision.ts
|
|
9018
9018
|
import * as fs23 from "fs/promises";
|
|
9019
9019
|
import { execFileSync as execFileSync9 } from "child_process";
|
|
9020
|
-
async function fileExists2(
|
|
9020
|
+
async function fileExists2(path46) {
|
|
9021
9021
|
try {
|
|
9022
|
-
await fs23.access(
|
|
9022
|
+
await fs23.access(path46);
|
|
9023
9023
|
return true;
|
|
9024
9024
|
} catch {
|
|
9025
9025
|
return false;
|
|
@@ -10268,9 +10268,9 @@ async function stopJanusGraph(context) {
|
|
|
10268
10268
|
};
|
|
10269
10269
|
}
|
|
10270
10270
|
}
|
|
10271
|
-
async function fileExists3(
|
|
10271
|
+
async function fileExists3(path46) {
|
|
10272
10272
|
try {
|
|
10273
|
-
await fs27.access(
|
|
10273
|
+
await fs27.access(path46);
|
|
10274
10274
|
return true;
|
|
10275
10275
|
} catch {
|
|
10276
10276
|
return false;
|
|
@@ -12801,9 +12801,9 @@ async function startJanusGraph2(context) {
|
|
|
12801
12801
|
};
|
|
12802
12802
|
}
|
|
12803
12803
|
}
|
|
12804
|
-
async function fileExists4(
|
|
12804
|
+
async function fileExists4(path46) {
|
|
12805
12805
|
try {
|
|
12806
|
-
await fs36.access(
|
|
12806
|
+
await fs36.access(path46);
|
|
12807
12807
|
return true;
|
|
12808
12808
|
} catch {
|
|
12809
12809
|
return false;
|
|
@@ -15956,9 +15956,9 @@ async function stopJanusGraph2(context) {
|
|
|
15956
15956
|
};
|
|
15957
15957
|
}
|
|
15958
15958
|
}
|
|
15959
|
-
async function fileExists5(
|
|
15959
|
+
async function fileExists5(path46) {
|
|
15960
15960
|
try {
|
|
15961
|
-
await fs39.access(
|
|
15961
|
+
await fs39.access(path46);
|
|
15962
15962
|
return true;
|
|
15963
15963
|
} catch {
|
|
15964
15964
|
return false;
|
|
@@ -22006,12 +22006,12 @@ var init_path = __esm({
|
|
|
22006
22006
|
"node_modules/@anthropic-ai/sdk/internal/utils/path.mjs"() {
|
|
22007
22007
|
init_error();
|
|
22008
22008
|
EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
22009
|
-
createPathTagFunction = (pathEncoder = encodeURIPath) => function
|
|
22009
|
+
createPathTagFunction = (pathEncoder = encodeURIPath) => function path46(statics, ...params) {
|
|
22010
22010
|
if (statics.length === 1)
|
|
22011
22011
|
return statics[0];
|
|
22012
22012
|
let postPath = false;
|
|
22013
22013
|
const invalidSegments = [];
|
|
22014
|
-
const
|
|
22014
|
+
const path47 = statics.reduce((previousValue, currentValue, index) => {
|
|
22015
22015
|
if (/[?#]/.test(currentValue)) {
|
|
22016
22016
|
postPath = true;
|
|
22017
22017
|
}
|
|
@@ -22028,7 +22028,7 @@ var init_path = __esm({
|
|
|
22028
22028
|
}
|
|
22029
22029
|
return previousValue + currentValue + (index === params.length ? "" : encoded);
|
|
22030
22030
|
}, "");
|
|
22031
|
-
const pathOnly =
|
|
22031
|
+
const pathOnly = path47.split(/[?#]/, 1)[0];
|
|
22032
22032
|
const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
|
|
22033
22033
|
let match;
|
|
22034
22034
|
while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
|
|
@@ -22049,10 +22049,10 @@ var init_path = __esm({
|
|
|
22049
22049
|
}, "");
|
|
22050
22050
|
throw new AnthropicError(`Path parameters result in path with invalid segments:
|
|
22051
22051
|
${invalidSegments.map((e) => e.error).join("\n")}
|
|
22052
|
-
${
|
|
22052
|
+
${path47}
|
|
22053
22053
|
${underline}`);
|
|
22054
22054
|
}
|
|
22055
|
-
return
|
|
22055
|
+
return path47;
|
|
22056
22056
|
};
|
|
22057
22057
|
path34 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
|
|
22058
22058
|
}
|
|
@@ -24735,9 +24735,9 @@ var init_client = __esm({
|
|
|
24735
24735
|
makeStatusError(status, error, message, headers) {
|
|
24736
24736
|
return APIError.generate(status, error, message, headers);
|
|
24737
24737
|
}
|
|
24738
|
-
buildURL(
|
|
24738
|
+
buildURL(path46, query, defaultBaseURL) {
|
|
24739
24739
|
const baseURL = !__classPrivateFieldGet(this, _BaseAnthropic_instances, "m", _BaseAnthropic_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
|
|
24740
|
-
const url = isAbsoluteURL(
|
|
24740
|
+
const url = isAbsoluteURL(path46) ? new URL(path46) : new URL(baseURL + (baseURL.endsWith("/") && path46.startsWith("/") ? path46.slice(1) : path46));
|
|
24741
24741
|
const defaultQuery = this.defaultQuery();
|
|
24742
24742
|
if (!isEmptyObj(defaultQuery)) {
|
|
24743
24743
|
query = { ...defaultQuery, ...query };
|
|
@@ -24768,24 +24768,24 @@ var init_client = __esm({
|
|
|
24768
24768
|
*/
|
|
24769
24769
|
async prepareRequest(request, { url, options }) {
|
|
24770
24770
|
}
|
|
24771
|
-
get(
|
|
24772
|
-
return this.methodRequest("get",
|
|
24771
|
+
get(path46, opts) {
|
|
24772
|
+
return this.methodRequest("get", path46, opts);
|
|
24773
24773
|
}
|
|
24774
|
-
post(
|
|
24775
|
-
return this.methodRequest("post",
|
|
24774
|
+
post(path46, opts) {
|
|
24775
|
+
return this.methodRequest("post", path46, opts);
|
|
24776
24776
|
}
|
|
24777
|
-
patch(
|
|
24778
|
-
return this.methodRequest("patch",
|
|
24777
|
+
patch(path46, opts) {
|
|
24778
|
+
return this.methodRequest("patch", path46, opts);
|
|
24779
24779
|
}
|
|
24780
|
-
put(
|
|
24781
|
-
return this.methodRequest("put",
|
|
24780
|
+
put(path46, opts) {
|
|
24781
|
+
return this.methodRequest("put", path46, opts);
|
|
24782
24782
|
}
|
|
24783
|
-
delete(
|
|
24784
|
-
return this.methodRequest("delete",
|
|
24783
|
+
delete(path46, opts) {
|
|
24784
|
+
return this.methodRequest("delete", path46, opts);
|
|
24785
24785
|
}
|
|
24786
|
-
methodRequest(method,
|
|
24786
|
+
methodRequest(method, path46, opts) {
|
|
24787
24787
|
return this.request(Promise.resolve(opts).then((opts2) => {
|
|
24788
|
-
return { method, path:
|
|
24788
|
+
return { method, path: path46, ...opts2 };
|
|
24789
24789
|
}));
|
|
24790
24790
|
}
|
|
24791
24791
|
request(options, remainingRetries = null) {
|
|
@@ -24889,8 +24889,8 @@ var init_client = __esm({
|
|
|
24889
24889
|
}));
|
|
24890
24890
|
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
24891
24891
|
}
|
|
24892
|
-
getAPIList(
|
|
24893
|
-
return this.requestAPIList(Page2, { method: "get", path:
|
|
24892
|
+
getAPIList(path46, Page2, opts) {
|
|
24893
|
+
return this.requestAPIList(Page2, { method: "get", path: path46, ...opts });
|
|
24894
24894
|
}
|
|
24895
24895
|
requestAPIList(Page2, options) {
|
|
24896
24896
|
const request = this.makeRequest(options, null, void 0);
|
|
@@ -24977,8 +24977,8 @@ var init_client = __esm({
|
|
|
24977
24977
|
}
|
|
24978
24978
|
async buildRequest(inputOptions, { retryCount = 0 } = {}) {
|
|
24979
24979
|
const options = { ...inputOptions };
|
|
24980
|
-
const { method, path:
|
|
24981
|
-
const url = this.buildURL(
|
|
24980
|
+
const { method, path: path46, query, defaultBaseURL } = options;
|
|
24981
|
+
const url = this.buildURL(path46, query, defaultBaseURL);
|
|
24982
24982
|
if ("timeout" in options)
|
|
24983
24983
|
validatePositiveInteger("timeout", options.timeout);
|
|
24984
24984
|
options.timeout = options.timeout ?? this.timeout;
|
|
@@ -27405,7 +27405,7 @@ var require_package = __commonJS({
|
|
|
27405
27405
|
"package.json"(exports, module) {
|
|
27406
27406
|
module.exports = {
|
|
27407
27407
|
name: "@semiont/cli",
|
|
27408
|
-
version: "0.3.
|
|
27408
|
+
version: "0.3.1",
|
|
27409
27409
|
description: "Semiont CLI - Unified environment management tool",
|
|
27410
27410
|
_comment: "AWS SDK dependencies (@aws-sdk/*) are only used by platforms/aws",
|
|
27411
27411
|
type: "module",
|
|
@@ -27469,12 +27469,12 @@ var require_package = __commonJS({
|
|
|
27469
27469
|
"@aws-sdk/client-secrets-manager": "^3.600.0",
|
|
27470
27470
|
"@aws-sdk/client-sts": "^3.859.0",
|
|
27471
27471
|
"@aws-sdk/client-wafv2": "^3.859.0",
|
|
27472
|
-
"@semiont/api-client": "^0.3.
|
|
27473
|
-
"@semiont/content": "^0.3.
|
|
27474
|
-
"@semiont/core": "^0.3.
|
|
27475
|
-
"@semiont/event-sourcing": "^0.3.
|
|
27476
|
-
"@semiont/graph": "^0.3.
|
|
27477
|
-
"@semiont/make-meaning": "^0.3.
|
|
27472
|
+
"@semiont/api-client": "^0.3.1",
|
|
27473
|
+
"@semiont/content": "^0.3.1",
|
|
27474
|
+
"@semiont/core": "^0.3.1",
|
|
27475
|
+
"@semiont/event-sourcing": "^0.3.1",
|
|
27476
|
+
"@semiont/graph": "^0.3.1",
|
|
27477
|
+
"@semiont/make-meaning": "^0.3.1",
|
|
27478
27478
|
arg: "^5.0.2",
|
|
27479
27479
|
argon2: "^0.43.0",
|
|
27480
27480
|
express: "^4.18.2",
|
|
@@ -29433,6 +29433,347 @@ var importCmd = new CommandBuilder().name("import").description("Import resource
|
|
|
29433
29433
|
}
|
|
29434
29434
|
}).schema(ImportOptionsSchema).handler(runImport).build();
|
|
29435
29435
|
|
|
29436
|
+
// src/core/commands/local.ts
|
|
29437
|
+
init_zod();
|
|
29438
|
+
init_cli_colors();
|
|
29439
|
+
init_command_definition();
|
|
29440
|
+
init_base_options_schema();
|
|
29441
|
+
import * as fs52 from "fs";
|
|
29442
|
+
import * as path42 from "path";
|
|
29443
|
+
import * as readline from "readline";
|
|
29444
|
+
import { execFileSync as execFileSync44 } from "child_process";
|
|
29445
|
+
var LocalOptionsSchema = BaseOptionsSchema.extend({
|
|
29446
|
+
email: external_exports.string().optional(),
|
|
29447
|
+
password: external_exports.string().optional(),
|
|
29448
|
+
generatePassword: external_exports.boolean().default(true)
|
|
29449
|
+
}).transform((data) => ({
|
|
29450
|
+
...data,
|
|
29451
|
+
environment: data.environment || "_local_"
|
|
29452
|
+
}));
|
|
29453
|
+
function prompt(question) {
|
|
29454
|
+
return new Promise((resolve9) => {
|
|
29455
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
29456
|
+
rl.question(question, (answer) => {
|
|
29457
|
+
rl.close();
|
|
29458
|
+
resolve9(answer.trim());
|
|
29459
|
+
});
|
|
29460
|
+
});
|
|
29461
|
+
}
|
|
29462
|
+
function promptPassword(question) {
|
|
29463
|
+
return new Promise((resolve9) => {
|
|
29464
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
29465
|
+
process.stdout.write(question);
|
|
29466
|
+
let password = "";
|
|
29467
|
+
process.stdin.setRawMode?.(true);
|
|
29468
|
+
process.stdin.resume();
|
|
29469
|
+
process.stdin.setEncoding("utf8");
|
|
29470
|
+
const onData = (ch) => {
|
|
29471
|
+
if (ch === "\n" || ch === "\r" || ch === "") {
|
|
29472
|
+
process.stdin.setRawMode?.(false);
|
|
29473
|
+
process.stdin.pause();
|
|
29474
|
+
process.stdin.removeListener("data", onData);
|
|
29475
|
+
process.stdout.write("\n");
|
|
29476
|
+
rl.close();
|
|
29477
|
+
resolve9(password);
|
|
29478
|
+
} else if (ch === "\x7F") {
|
|
29479
|
+
password = password.slice(0, -1);
|
|
29480
|
+
} else {
|
|
29481
|
+
password += ch;
|
|
29482
|
+
process.stdout.write("*");
|
|
29483
|
+
}
|
|
29484
|
+
};
|
|
29485
|
+
process.stdin.on("data", onData);
|
|
29486
|
+
});
|
|
29487
|
+
}
|
|
29488
|
+
function runSemiont(args, env, captureOutput = false) {
|
|
29489
|
+
return execFileSync44("semiont", args, {
|
|
29490
|
+
env,
|
|
29491
|
+
stdio: captureOutput ? "pipe" : "inherit",
|
|
29492
|
+
encoding: "utf8"
|
|
29493
|
+
});
|
|
29494
|
+
}
|
|
29495
|
+
function runSemiontSafe(args, env) {
|
|
29496
|
+
try {
|
|
29497
|
+
const output = execFileSync44("semiont", args, {
|
|
29498
|
+
env,
|
|
29499
|
+
stdio: "pipe",
|
|
29500
|
+
encoding: "utf8"
|
|
29501
|
+
});
|
|
29502
|
+
return { success: true, output: output || "", error: "" };
|
|
29503
|
+
} catch (err) {
|
|
29504
|
+
return {
|
|
29505
|
+
success: false,
|
|
29506
|
+
output: err.stdout || "",
|
|
29507
|
+
error: err.stderr || err.message || ""
|
|
29508
|
+
};
|
|
29509
|
+
}
|
|
29510
|
+
}
|
|
29511
|
+
var REQUIRED_SERVICES = ["database", "filesystem", "backend", "frontend", "proxy"];
|
|
29512
|
+
var EXTERNAL_SERVICES = ["graph", "inference"];
|
|
29513
|
+
var ALL_SERVICES = [...REQUIRED_SERVICES, ...EXTERNAL_SERVICES];
|
|
29514
|
+
function parseCheckOutput(jsonOutput) {
|
|
29515
|
+
try {
|
|
29516
|
+
const parsed = JSON.parse(jsonOutput);
|
|
29517
|
+
const results = [];
|
|
29518
|
+
const items = parsed.results || [];
|
|
29519
|
+
for (const item of items) {
|
|
29520
|
+
const name = item.entity || "";
|
|
29521
|
+
const meta = item.metadata || {};
|
|
29522
|
+
const statusStr = meta.status || "unknown";
|
|
29523
|
+
const health = meta.health;
|
|
29524
|
+
const healthy = item.success && (health?.healthy ?? statusStr === "running");
|
|
29525
|
+
const status = statusStr === "running" && healthy ? "healthy" : statusStr === "running" ? "unhealthy" : statusStr === "stopped" ? "stopped" : "unknown";
|
|
29526
|
+
results.push({
|
|
29527
|
+
name,
|
|
29528
|
+
status,
|
|
29529
|
+
healthy,
|
|
29530
|
+
external: EXTERNAL_SERVICES.includes(name)
|
|
29531
|
+
});
|
|
29532
|
+
}
|
|
29533
|
+
return results;
|
|
29534
|
+
} catch {
|
|
29535
|
+
return [];
|
|
29536
|
+
}
|
|
29537
|
+
}
|
|
29538
|
+
function isProvisioned(serviceName, semiotRoot) {
|
|
29539
|
+
switch (serviceName) {
|
|
29540
|
+
case "backend":
|
|
29541
|
+
return fs52.existsSync(path42.join(semiotRoot, "backend", ".env"));
|
|
29542
|
+
case "frontend":
|
|
29543
|
+
return fs52.existsSync(path42.join(semiotRoot, "frontend", ".env"));
|
|
29544
|
+
case "filesystem":
|
|
29545
|
+
return fs52.existsSync(path42.join(semiotRoot, "data"));
|
|
29546
|
+
case "database":
|
|
29547
|
+
case "proxy":
|
|
29548
|
+
// For these, rely on check result only — we don't have a simple local sentinel
|
|
29549
|
+
default:
|
|
29550
|
+
return false;
|
|
29551
|
+
}
|
|
29552
|
+
}
|
|
29553
|
+
async function local(options) {
|
|
29554
|
+
const startTime = Date.now();
|
|
29555
|
+
const envVarsToAdvise = [];
|
|
29556
|
+
const warnings = [];
|
|
29557
|
+
const results = {
|
|
29558
|
+
command: "local",
|
|
29559
|
+
environment: "local",
|
|
29560
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
29561
|
+
duration: 0,
|
|
29562
|
+
results: [],
|
|
29563
|
+
summary: { total: 0, succeeded: 0, failed: 0, warnings: 0 },
|
|
29564
|
+
executionContext: {
|
|
29565
|
+
user: process.env.USER || "unknown",
|
|
29566
|
+
workingDirectory: process.cwd(),
|
|
29567
|
+
dryRun: false
|
|
29568
|
+
}
|
|
29569
|
+
};
|
|
29570
|
+
console.log(`
|
|
29571
|
+
${colors.bright}\u{1F310} Semiont Local Setup${colors.reset}
|
|
29572
|
+
`);
|
|
29573
|
+
try {
|
|
29574
|
+
let semiotRoot = process.env.SEMIONT_ROOT || "";
|
|
29575
|
+
if (!semiotRoot) {
|
|
29576
|
+
const defaultPath = path42.join(process.env.HOME || process.cwd(), "semiont");
|
|
29577
|
+
const answer = await prompt(
|
|
29578
|
+
`${colors.cyan}SEMIONT_ROOT is not set.${colors.reset}
|
|
29579
|
+
Press Enter to use ${colors.bright}${defaultPath}${colors.reset}, or type a path: `
|
|
29580
|
+
);
|
|
29581
|
+
semiotRoot = answer || defaultPath;
|
|
29582
|
+
fs52.mkdirSync(semiotRoot, { recursive: true });
|
|
29583
|
+
process.env.SEMIONT_ROOT = semiotRoot;
|
|
29584
|
+
envVarsToAdvise.push(`export SEMIONT_ROOT=${semiotRoot}`);
|
|
29585
|
+
console.log(`${colors.green}\u2713${colors.reset} Using ${semiotRoot}
|
|
29586
|
+
`);
|
|
29587
|
+
} else {
|
|
29588
|
+
console.log(`${colors.green}\u2713${colors.reset} SEMIONT_ROOT=${semiotRoot}
|
|
29589
|
+
`);
|
|
29590
|
+
}
|
|
29591
|
+
let semiotEnv = process.env.SEMIONT_ENV || "";
|
|
29592
|
+
if (!semiotEnv) {
|
|
29593
|
+
semiotEnv = "local";
|
|
29594
|
+
process.env.SEMIONT_ENV = semiotEnv;
|
|
29595
|
+
envVarsToAdvise.push(`export SEMIONT_ENV=local`);
|
|
29596
|
+
console.log(`${colors.dim}SEMIONT_ENV not set, using "local"${colors.reset}
|
|
29597
|
+
`);
|
|
29598
|
+
} else {
|
|
29599
|
+
console.log(`${colors.green}\u2713${colors.reset} SEMIONT_ENV=${semiotEnv}
|
|
29600
|
+
`);
|
|
29601
|
+
}
|
|
29602
|
+
const env = { ...process.env };
|
|
29603
|
+
const semiontJsonPath = path42.join(semiotRoot, "semiont.json");
|
|
29604
|
+
const envFilePath = path42.join(semiotRoot, "environments", `${semiotEnv}.json`);
|
|
29605
|
+
const isInitialized = fs52.existsSync(semiontJsonPath) && fs52.existsSync(envFilePath);
|
|
29606
|
+
if (isInitialized) {
|
|
29607
|
+
console.log(`${colors.green}\u2713${colors.reset} Project already initialized
|
|
29608
|
+
`);
|
|
29609
|
+
} else {
|
|
29610
|
+
console.log(`${colors.cyan}\u25B6 Initializing project...${colors.reset}`);
|
|
29611
|
+
try {
|
|
29612
|
+
runSemiont(["init"], env);
|
|
29613
|
+
console.log(`${colors.green}\u2713${colors.reset} Project initialized
|
|
29614
|
+
`);
|
|
29615
|
+
} catch {
|
|
29616
|
+
console.error(`${colors.red}\u2717 semiont init failed \u2014 cannot continue${colors.reset}`);
|
|
29617
|
+
results.summary.failed = 1;
|
|
29618
|
+
results.duration = Date.now() - startTime;
|
|
29619
|
+
return results;
|
|
29620
|
+
}
|
|
29621
|
+
}
|
|
29622
|
+
console.log(`${colors.cyan}\u25B6 Checking services...${colors.reset}`);
|
|
29623
|
+
const checkResult = runSemiontSafe(["check", "--all", "--output", "json"], env);
|
|
29624
|
+
const serviceStatuses = parseCheckOutput(checkResult.output);
|
|
29625
|
+
const statusByName = new Map(
|
|
29626
|
+
serviceStatuses.map((s) => [s.name, s])
|
|
29627
|
+
);
|
|
29628
|
+
for (const serviceName of ALL_SERVICES) {
|
|
29629
|
+
const info = statusByName.get(serviceName);
|
|
29630
|
+
const isExternal = EXTERNAL_SERVICES.includes(serviceName);
|
|
29631
|
+
if (!info) {
|
|
29632
|
+
if (isExternal) {
|
|
29633
|
+
warnings.push(`${serviceName}: not found in check output (external \u2014 skipping)`);
|
|
29634
|
+
console.log(` ${colors.yellow}\u26A0 ${serviceName}${colors.reset} (external): not found in check output`);
|
|
29635
|
+
continue;
|
|
29636
|
+
}
|
|
29637
|
+
console.log(` ${colors.yellow}? ${serviceName}${colors.reset}: not found \u2014 provisioning...`);
|
|
29638
|
+
} else if (info.healthy) {
|
|
29639
|
+
console.log(` ${colors.green}\u2713 ${serviceName}${colors.reset}: running`);
|
|
29640
|
+
continue;
|
|
29641
|
+
} else if (isExternal && !info.healthy) {
|
|
29642
|
+
warnings.push(`${serviceName}: unhealthy (external service \u2014 check credentials)`);
|
|
29643
|
+
console.log(` ${colors.yellow}\u26A0 ${serviceName}${colors.reset} (external): unhealthy \u2014 check your credentials`);
|
|
29644
|
+
continue;
|
|
29645
|
+
}
|
|
29646
|
+
const alreadyProvisioned = info ? info.status === "stopped" && isProvisioned(serviceName, semiotRoot) : false;
|
|
29647
|
+
if (!alreadyProvisioned) {
|
|
29648
|
+
console.log(` ${colors.cyan} provisioning ${serviceName}...${colors.reset}`);
|
|
29649
|
+
const provResult = runSemiontSafe(["provision", "--service", serviceName], env);
|
|
29650
|
+
if (!provResult.success) {
|
|
29651
|
+
const combinedOutput = provResult.error + provResult.output;
|
|
29652
|
+
if (combinedOutput.includes("does not support capability 'provision'")) {
|
|
29653
|
+
} else {
|
|
29654
|
+
const msg = `Failed to provision ${serviceName}: ${provResult.error}`;
|
|
29655
|
+
if (isExternal) {
|
|
29656
|
+
warnings.push(msg);
|
|
29657
|
+
console.log(` ${colors.yellow} \u26A0 ${msg}${colors.reset}`);
|
|
29658
|
+
continue;
|
|
29659
|
+
} else {
|
|
29660
|
+
throw new Error(msg);
|
|
29661
|
+
}
|
|
29662
|
+
}
|
|
29663
|
+
}
|
|
29664
|
+
}
|
|
29665
|
+
console.log(` ${colors.cyan} starting ${serviceName}...${colors.reset}`);
|
|
29666
|
+
const startResult = runSemiontSafe(["start", "--service", serviceName], env);
|
|
29667
|
+
if (!startResult.success) {
|
|
29668
|
+
const combinedOutput = startResult.error + startResult.output;
|
|
29669
|
+
if (combinedOutput.includes("does not support capability 'start'")) {
|
|
29670
|
+
} else {
|
|
29671
|
+
const msg = `Failed to start ${serviceName}: ${startResult.error}`;
|
|
29672
|
+
if (isExternal) {
|
|
29673
|
+
warnings.push(msg);
|
|
29674
|
+
console.log(` ${colors.yellow} \u26A0 ${msg}${colors.reset}`);
|
|
29675
|
+
} else {
|
|
29676
|
+
throw new Error(msg);
|
|
29677
|
+
}
|
|
29678
|
+
}
|
|
29679
|
+
} else {
|
|
29680
|
+
console.log(` ${colors.green} \u2713 ${serviceName} started${colors.reset}`);
|
|
29681
|
+
}
|
|
29682
|
+
}
|
|
29683
|
+
console.log("");
|
|
29684
|
+
const credentialsPath = path42.join(semiotRoot, "credentials.txt");
|
|
29685
|
+
if (fs52.existsSync(credentialsPath)) {
|
|
29686
|
+
console.log(`${colors.green}\u2713${colors.reset} Credentials file already exists at ${credentialsPath}
|
|
29687
|
+
`);
|
|
29688
|
+
} else {
|
|
29689
|
+
console.log(`${colors.cyan}\u25B6 Creating admin user...${colors.reset}`);
|
|
29690
|
+
let email = options.email;
|
|
29691
|
+
if (!email) {
|
|
29692
|
+
const answer = await prompt(` Admin email [admin@local]: `);
|
|
29693
|
+
email = answer || "admin@local";
|
|
29694
|
+
}
|
|
29695
|
+
let generatePassword2 = options.generatePassword;
|
|
29696
|
+
if (!options.password) {
|
|
29697
|
+
const answer = await prompt(` Generate password? [Y/n]: `);
|
|
29698
|
+
generatePassword2 = answer === "" || answer.toLowerCase() === "y";
|
|
29699
|
+
}
|
|
29700
|
+
const useraddArgs = ["useradd", "--email", email, "--admin"];
|
|
29701
|
+
if (generatePassword2) {
|
|
29702
|
+
useraddArgs.push("--generate-password");
|
|
29703
|
+
} else {
|
|
29704
|
+
const pw = options.password || await promptPassword(` Password: `);
|
|
29705
|
+
useraddArgs.push("--password", pw);
|
|
29706
|
+
}
|
|
29707
|
+
const useraddResult = runSemiontSafe(useraddArgs, env);
|
|
29708
|
+
if (useraddResult.success) {
|
|
29709
|
+
const output = useraddResult.output;
|
|
29710
|
+
console.log(output);
|
|
29711
|
+
fs52.writeFileSync(credentialsPath, output, { mode: 384 });
|
|
29712
|
+
console.log(`${colors.green}\u2713${colors.reset} Credentials saved to ${credentialsPath}`);
|
|
29713
|
+
console.log(`${colors.yellow} \u26A0 credentials.txt contains a plaintext password \u2014 keep it safe${colors.reset}
|
|
29714
|
+
`);
|
|
29715
|
+
} else {
|
|
29716
|
+
console.log(`${colors.yellow}\u26A0 useradd failed: ${useraddResult.error}${colors.reset}`);
|
|
29717
|
+
console.log(` Run manually: semiont useradd --email <email> --generate-password --admin
|
|
29718
|
+
`);
|
|
29719
|
+
warnings.push(`useradd failed: ${useraddResult.error}`);
|
|
29720
|
+
}
|
|
29721
|
+
}
|
|
29722
|
+
console.log(`${colors.cyan}\u25B6 Final service check...${colors.reset}
|
|
29723
|
+
`);
|
|
29724
|
+
runSemiont(["check", "--all"], env);
|
|
29725
|
+
console.log(`
|
|
29726
|
+
${colors.bright}${colors.green}\u2713 Semiont is running at http://localhost:8080${colors.reset}
|
|
29727
|
+
`);
|
|
29728
|
+
console.log(` Credentials: ${credentialsPath}`);
|
|
29729
|
+
if (warnings.length > 0) {
|
|
29730
|
+
console.log(`
|
|
29731
|
+
${colors.yellow}Warnings:${colors.reset}`);
|
|
29732
|
+
for (const w of warnings) {
|
|
29733
|
+
console.log(` ${colors.yellow}\u26A0${colors.reset} ${w}`);
|
|
29734
|
+
}
|
|
29735
|
+
}
|
|
29736
|
+
if (envVarsToAdvise.length > 0) {
|
|
29737
|
+
console.log(`
|
|
29738
|
+
To persist your environment across sessions, add to your shell profile:`);
|
|
29739
|
+
for (const line of envVarsToAdvise) {
|
|
29740
|
+
console.log(` ${colors.cyan}${line}${colors.reset}`);
|
|
29741
|
+
}
|
|
29742
|
+
}
|
|
29743
|
+
results.summary.succeeded = 1;
|
|
29744
|
+
results.metadata = { semiotRoot, semiotEnv, credentialsPath };
|
|
29745
|
+
} catch (error) {
|
|
29746
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
29747
|
+
console.error(`
|
|
29748
|
+
${colors.red}\u2717 Setup failed: ${msg}${colors.reset}`);
|
|
29749
|
+
results.summary.failed = 1;
|
|
29750
|
+
results.error = msg;
|
|
29751
|
+
}
|
|
29752
|
+
results.duration = Date.now() - startTime;
|
|
29753
|
+
return results;
|
|
29754
|
+
}
|
|
29755
|
+
var localCommand = new CommandBuilder().name("local").description("Set up and start Semiont locally (init + provision + start + useradd)").schema(LocalOptionsSchema).args(withBaseArgs({
|
|
29756
|
+
"--email": {
|
|
29757
|
+
type: "string",
|
|
29758
|
+
description: "Admin user email (default: admin@local)"
|
|
29759
|
+
},
|
|
29760
|
+
"--password": {
|
|
29761
|
+
type: "string",
|
|
29762
|
+
description: "Admin user password (default: auto-generate)"
|
|
29763
|
+
},
|
|
29764
|
+
"--generate-password": {
|
|
29765
|
+
type: "boolean",
|
|
29766
|
+
description: "Generate a random admin password",
|
|
29767
|
+
default: true
|
|
29768
|
+
}
|
|
29769
|
+
}, {
|
|
29770
|
+
"--email": "--email"
|
|
29771
|
+
})).requiresEnvironment(false).requiresServices(false).examples(
|
|
29772
|
+
"semiont local",
|
|
29773
|
+
"semiont local --email me@example.com",
|
|
29774
|
+
"semiont local --email me@example.com --generate-password"
|
|
29775
|
+
).setupHandler(local).build();
|
|
29776
|
+
|
|
29436
29777
|
// src/core/command-discovery.ts
|
|
29437
29778
|
var commandCache = /* @__PURE__ */ new Map();
|
|
29438
29779
|
var COMMANDS = {
|
|
@@ -29449,7 +29790,8 @@ var COMMANDS = {
|
|
|
29449
29790
|
"restore": restoreCmd,
|
|
29450
29791
|
"verify": verifyCmd,
|
|
29451
29792
|
"export": exportCmd,
|
|
29452
|
-
"import": importCmd
|
|
29793
|
+
"import": importCmd,
|
|
29794
|
+
"local": localCommand
|
|
29453
29795
|
};
|
|
29454
29796
|
async function loadCommand(name) {
|
|
29455
29797
|
if (commandCache.has(name)) {
|
|
@@ -29495,8 +29837,8 @@ function isCommandDefinition(obj) {
|
|
|
29495
29837
|
|
|
29496
29838
|
// src/core/service-discovery.ts
|
|
29497
29839
|
init_config_loader();
|
|
29498
|
-
import * as
|
|
29499
|
-
import * as
|
|
29840
|
+
import * as path43 from "path";
|
|
29841
|
+
import * as fs53 from "fs";
|
|
29500
29842
|
var BUILT_IN_SERVICES = ["frontend", "backend", "database", "filesystem"];
|
|
29501
29843
|
var environmentServicesCache = /* @__PURE__ */ new Map();
|
|
29502
29844
|
async function loadEnvironmentServices(environment) {
|
|
@@ -29505,11 +29847,11 @@ async function loadEnvironmentServices(environment) {
|
|
|
29505
29847
|
}
|
|
29506
29848
|
try {
|
|
29507
29849
|
const PROJECT_ROOT = findProjectRoot();
|
|
29508
|
-
const configPath =
|
|
29509
|
-
if (!
|
|
29850
|
+
const configPath = path43.join(PROJECT_ROOT, "environments", `${environment}.json`);
|
|
29851
|
+
if (!fs53.existsSync(configPath)) {
|
|
29510
29852
|
return [...BUILT_IN_SERVICES];
|
|
29511
29853
|
}
|
|
29512
|
-
const jsonContent =
|
|
29854
|
+
const jsonContent = fs53.readFileSync(configPath, "utf-8");
|
|
29513
29855
|
const config = JSON.parse(jsonContent);
|
|
29514
29856
|
const services = config.services ? Object.keys(config.services) : [];
|
|
29515
29857
|
environmentServicesCache.set(environment, services);
|
|
@@ -29540,7 +29882,7 @@ async function isValidService(service, environment) {
|
|
|
29540
29882
|
import { parseEnvironment as parseEnvironment2 } from "@semiont/core";
|
|
29541
29883
|
|
|
29542
29884
|
// src/core/service-resolver.ts
|
|
29543
|
-
import * as
|
|
29885
|
+
import * as path44 from "path";
|
|
29544
29886
|
import { ConfigurationError as ConfigurationError2 } from "@semiont/core";
|
|
29545
29887
|
function getServicePlatform(serviceName, config) {
|
|
29546
29888
|
const environment = config._metadata?.environment;
|
|
@@ -29588,7 +29930,7 @@ function resolveServiceDeployments(serviceNames, config) {
|
|
|
29588
29930
|
const serviceConfig = config.services?.[serviceName];
|
|
29589
29931
|
if (!serviceConfig) {
|
|
29590
29932
|
const availableServices = Object.keys(config.services || {});
|
|
29591
|
-
const configPath =
|
|
29933
|
+
const configPath = path44.join(projectRoot, "environments", `${environment}.json`);
|
|
29592
29934
|
console.warn(`\u274C Service '${serviceName}' not found in environment '${environment}'`);
|
|
29593
29935
|
if (availableServices.length > 0) {
|
|
29594
29936
|
console.warn(` Available services: ${availableServices.join(", ")}`);
|
|
@@ -29627,7 +29969,7 @@ function resolveServiceDeployments(serviceNames, config) {
|
|
|
29627
29969
|
// src/core/command-service-matcher.ts
|
|
29628
29970
|
init_service_factory();
|
|
29629
29971
|
init_service_command_capabilities();
|
|
29630
|
-
import * as
|
|
29972
|
+
import * as path45 from "path";
|
|
29631
29973
|
async function checkServiceSupportsCommand(serviceName, command, envConfig) {
|
|
29632
29974
|
try {
|
|
29633
29975
|
const projectRoot = envConfig._metadata?.projectRoot;
|
|
@@ -29711,7 +30053,7 @@ async function resolveServiceSelector(selector, capability, envConfig) {
|
|
|
29711
30053
|
if (!projectRoot) {
|
|
29712
30054
|
throw new Error("Project root is required in envConfig._metadata");
|
|
29713
30055
|
}
|
|
29714
|
-
const configPath =
|
|
30056
|
+
const configPath = path45.join(projectRoot, "environments", `${environment}.json`);
|
|
29715
30057
|
const errorMessage = [
|
|
29716
30058
|
`Unknown service '${selector}' in environment '${environment}'`,
|
|
29717
30059
|
`Available services: ${availableServices.join(", ")}`,
|
|
@@ -30207,14 +30549,14 @@ var OutputFormatter = class {
|
|
|
30207
30549
|
/**
|
|
30208
30550
|
* Get nested value from object using dot notation
|
|
30209
30551
|
*/
|
|
30210
|
-
static getNestedValue(obj,
|
|
30211
|
-
return
|
|
30552
|
+
static getNestedValue(obj, path46) {
|
|
30553
|
+
return path46.split(".").reduce((current, key) => current?.[key], obj);
|
|
30212
30554
|
}
|
|
30213
30555
|
/**
|
|
30214
30556
|
* Set nested value in object using dot notation
|
|
30215
30557
|
*/
|
|
30216
|
-
static setNestedValue(obj,
|
|
30217
|
-
const keys =
|
|
30558
|
+
static setNestedValue(obj, path46, value) {
|
|
30559
|
+
const keys = path46.split(".");
|
|
30218
30560
|
const lastKey = keys.pop();
|
|
30219
30561
|
const target = keys.reduce((current, key) => {
|
|
30220
30562
|
if (!(key in current)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semiont/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Semiont CLI - Unified environment management tool",
|
|
5
5
|
"_comment": "AWS SDK dependencies (@aws-sdk/*) are only used by platforms/aws",
|
|
6
6
|
"type": "module",
|
|
@@ -64,12 +64,12 @@
|
|
|
64
64
|
"@aws-sdk/client-secrets-manager": "^3.600.0",
|
|
65
65
|
"@aws-sdk/client-sts": "^3.859.0",
|
|
66
66
|
"@aws-sdk/client-wafv2": "^3.859.0",
|
|
67
|
-
"@semiont/api-client": "0.3.
|
|
68
|
-
"@semiont/content": "0.3.
|
|
69
|
-
"@semiont/core": "0.3.
|
|
70
|
-
"@semiont/event-sourcing": "0.3.
|
|
71
|
-
"@semiont/graph": "0.3.
|
|
72
|
-
"@semiont/make-meaning": "0.3.
|
|
67
|
+
"@semiont/api-client": "0.3.1",
|
|
68
|
+
"@semiont/content": "0.3.1",
|
|
69
|
+
"@semiont/core": "0.3.1",
|
|
70
|
+
"@semiont/event-sourcing": "0.3.1",
|
|
71
|
+
"@semiont/graph": "0.3.1",
|
|
72
|
+
"@semiont/make-meaning": "0.3.1",
|
|
73
73
|
"arg": "^5.0.2",
|
|
74
74
|
"argon2": "^0.43.0",
|
|
75
75
|
"express": "^4.18.2",
|