@semiont/cli 0.4.1 → 0.4.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/README.md +108 -455
- package/dist/cli.mjs +1516 -551
- package/package.json +8 -10
package/dist/cli.mjs
CHANGED
|
@@ -4206,20 +4206,26 @@ var init_zod = __esm({
|
|
|
4206
4206
|
});
|
|
4207
4207
|
|
|
4208
4208
|
// src/core/base-options-schema.ts
|
|
4209
|
-
function
|
|
4209
|
+
function withOpsArgs(commandArgs = {}, commandAliases = {}, positional) {
|
|
4210
4210
|
return {
|
|
4211
|
-
args: { ...BASE_ARGS, ...commandArgs },
|
|
4212
|
-
aliases: { ...BASE_ALIASES, ...commandAliases },
|
|
4211
|
+
args: { ...BASE_ARGS, ...OPS_ARGS, ...commandArgs },
|
|
4212
|
+
aliases: { ...BASE_ALIASES, ...OPS_ALIASES, ...commandAliases },
|
|
4213
4213
|
...positional && { positional }
|
|
4214
4214
|
};
|
|
4215
4215
|
}
|
|
4216
|
-
|
|
4216
|
+
function withApiArgs(commandArgs = {}, commandAliases = {}, positional) {
|
|
4217
|
+
return {
|
|
4218
|
+
args: { ...BASE_ARGS, ...API_ARGS, ...commandArgs },
|
|
4219
|
+
aliases: { ...BASE_ALIASES, ...API_ALIASES, ...commandAliases },
|
|
4220
|
+
...positional && { positional }
|
|
4221
|
+
};
|
|
4222
|
+
}
|
|
4223
|
+
var BaseOptionsSchema, OpsOptionsSchema, ApiOptionsSchema, CommonExtensions, BASE_ARGS, OPS_ARGS, API_ARGS, BASE_ALIASES, OPS_ALIASES, API_ALIASES;
|
|
4217
4224
|
var init_base_options_schema = __esm({
|
|
4218
4225
|
"src/core/base-options-schema.ts"() {
|
|
4219
4226
|
"use strict";
|
|
4220
4227
|
init_zod();
|
|
4221
4228
|
BaseOptionsSchema = external_exports.object({
|
|
4222
|
-
environment: external_exports.string().optional(),
|
|
4223
4229
|
verbose: external_exports.boolean().optional().default(false),
|
|
4224
4230
|
dryRun: external_exports.boolean().optional().default(false),
|
|
4225
4231
|
quiet: external_exports.boolean().optional().default(false),
|
|
@@ -4227,6 +4233,12 @@ var init_base_options_schema = __esm({
|
|
|
4227
4233
|
forceDiscovery: external_exports.boolean().optional().default(false),
|
|
4228
4234
|
preflight: external_exports.boolean().optional().default(false)
|
|
4229
4235
|
});
|
|
4236
|
+
OpsOptionsSchema = BaseOptionsSchema.extend({
|
|
4237
|
+
environment: external_exports.string().optional()
|
|
4238
|
+
});
|
|
4239
|
+
ApiOptionsSchema = BaseOptionsSchema.extend({
|
|
4240
|
+
bus: external_exports.string().optional()
|
|
4241
|
+
});
|
|
4230
4242
|
CommonExtensions = {
|
|
4231
4243
|
service: external_exports.string().optional(),
|
|
4232
4244
|
all: external_exports.boolean().optional().default(false),
|
|
@@ -4236,11 +4248,6 @@ var init_base_options_schema = __esm({
|
|
|
4236
4248
|
registry: external_exports.string().optional()
|
|
4237
4249
|
};
|
|
4238
4250
|
BASE_ARGS = {
|
|
4239
|
-
"--environment": {
|
|
4240
|
-
type: "string",
|
|
4241
|
-
description: "Target environment",
|
|
4242
|
-
required: false
|
|
4243
|
-
},
|
|
4244
4251
|
"--verbose": {
|
|
4245
4252
|
type: "boolean",
|
|
4246
4253
|
description: "Verbose output",
|
|
@@ -4273,12 +4280,30 @@ var init_base_options_schema = __esm({
|
|
|
4273
4280
|
default: false
|
|
4274
4281
|
}
|
|
4275
4282
|
};
|
|
4283
|
+
OPS_ARGS = {
|
|
4284
|
+
"--environment": {
|
|
4285
|
+
type: "string",
|
|
4286
|
+
description: "Target environment",
|
|
4287
|
+
required: false
|
|
4288
|
+
}
|
|
4289
|
+
};
|
|
4290
|
+
API_ARGS = {
|
|
4291
|
+
"--bus": {
|
|
4292
|
+
type: "string",
|
|
4293
|
+
description: "Backend URL (e.g. http://localhost:4000). Fallback: $SEMIONT_BUS. Use `semiont login` to authenticate."
|
|
4294
|
+
}
|
|
4295
|
+
};
|
|
4276
4296
|
BASE_ALIASES = {
|
|
4277
|
-
"-e": "--environment",
|
|
4278
4297
|
"-v": "--verbose",
|
|
4279
4298
|
"-q": "--quiet",
|
|
4280
4299
|
"-o": "--output"
|
|
4281
4300
|
};
|
|
4301
|
+
OPS_ALIASES = {
|
|
4302
|
+
"-e": "--environment"
|
|
4303
|
+
};
|
|
4304
|
+
API_ALIASES = {
|
|
4305
|
+
"-b": "--bus"
|
|
4306
|
+
};
|
|
4282
4307
|
}
|
|
4283
4308
|
});
|
|
4284
4309
|
|
|
@@ -4410,20 +4435,20 @@ function findPortOwner(port) {
|
|
|
4410
4435
|
return null;
|
|
4411
4436
|
}
|
|
4412
4437
|
async function checkPortFree(port) {
|
|
4413
|
-
return new Promise((
|
|
4438
|
+
return new Promise((resolve10) => {
|
|
4414
4439
|
const server = net.createServer();
|
|
4415
4440
|
server.once("error", (err) => {
|
|
4416
4441
|
if (err.code === "EADDRINUSE") {
|
|
4417
4442
|
const owner = findPortOwner(port);
|
|
4418
4443
|
const hint = owner ? ` (${owner})` : "";
|
|
4419
|
-
|
|
4444
|
+
resolve10({ name: `port-${port}`, pass: false, message: `Port ${port} is in use${hint}` });
|
|
4420
4445
|
} else {
|
|
4421
|
-
|
|
4446
|
+
resolve10({ name: `port-${port}`, pass: false, message: `Cannot check port ${port}: ${err.message}` });
|
|
4422
4447
|
}
|
|
4423
4448
|
});
|
|
4424
4449
|
server.once("listening", () => {
|
|
4425
4450
|
server.close(() => {
|
|
4426
|
-
|
|
4451
|
+
resolve10({ name: `port-${port}`, pass: true, message: `Port ${port} is available` });
|
|
4427
4452
|
});
|
|
4428
4453
|
});
|
|
4429
4454
|
server.listen(port, "127.0.0.1");
|
|
@@ -6439,18 +6464,18 @@ var init_state_manager = __esm({
|
|
|
6439
6464
|
// src/core/io/network-utils.ts
|
|
6440
6465
|
import * as net2 from "net";
|
|
6441
6466
|
async function isPortInUse(port) {
|
|
6442
|
-
return new Promise((
|
|
6467
|
+
return new Promise((resolve10) => {
|
|
6443
6468
|
const server = net2.createServer();
|
|
6444
6469
|
server.once("error", (err) => {
|
|
6445
6470
|
if (err.code === "EADDRINUSE") {
|
|
6446
|
-
|
|
6471
|
+
resolve10(true);
|
|
6447
6472
|
} else {
|
|
6448
|
-
|
|
6473
|
+
resolve10(false);
|
|
6449
6474
|
}
|
|
6450
6475
|
});
|
|
6451
6476
|
server.once("listening", () => {
|
|
6452
6477
|
server.close();
|
|
6453
|
-
|
|
6478
|
+
resolve10(false);
|
|
6454
6479
|
});
|
|
6455
6480
|
server.listen(port);
|
|
6456
6481
|
});
|
|
@@ -7468,7 +7493,7 @@ var init_database_start = __esm({
|
|
|
7468
7493
|
// Use path for data directory
|
|
7469
7494
|
}
|
|
7470
7495
|
};
|
|
7471
|
-
await new Promise((
|
|
7496
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
7472
7497
|
return {
|
|
7473
7498
|
success: true,
|
|
7474
7499
|
endpoint,
|
|
@@ -7690,7 +7715,7 @@ async function startJanusGraph(context) {
|
|
|
7690
7715
|
let ready = false;
|
|
7691
7716
|
const maxAttempts = 30;
|
|
7692
7717
|
for (let i = 0; i < maxAttempts; i++) {
|
|
7693
|
-
await new Promise((
|
|
7718
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
7694
7719
|
try {
|
|
7695
7720
|
const { execFileSync: execFileSync43 } = await import("child_process");
|
|
7696
7721
|
execFileSync43(gremlinShellScript, ["-e", "g.V().count()"], {
|
|
@@ -7957,7 +7982,7 @@ var init_backend_start = __esm({
|
|
|
7957
7982
|
appLogStream.end();
|
|
7958
7983
|
errorLogStream.end();
|
|
7959
7984
|
proc.unref();
|
|
7960
|
-
await new Promise((
|
|
7985
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
7961
7986
|
try {
|
|
7962
7987
|
process.kill(proc.pid, 0);
|
|
7963
7988
|
} catch {
|
|
@@ -8193,7 +8218,7 @@ var init_frontend_start = __esm({
|
|
|
8193
8218
|
appLogStream.end();
|
|
8194
8219
|
errorLogStream.end();
|
|
8195
8220
|
proc.unref();
|
|
8196
|
-
await new Promise((
|
|
8221
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
8197
8222
|
try {
|
|
8198
8223
|
process.kill(proc.pid, 0);
|
|
8199
8224
|
} catch {
|
|
@@ -8367,7 +8392,7 @@ var init_proxy_start = __esm({
|
|
|
8367
8392
|
_ENVOY_PID: pidFile
|
|
8368
8393
|
}
|
|
8369
8394
|
});
|
|
8370
|
-
await new Promise((
|
|
8395
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
8371
8396
|
if (!fs18.existsSync(pidFile)) {
|
|
8372
8397
|
return {
|
|
8373
8398
|
success: false,
|
|
@@ -8478,7 +8503,7 @@ var init_mcp_provision = __esm({
|
|
|
8478
8503
|
if (!service.quiet) {
|
|
8479
8504
|
printInfo("\u{1F510} Setting up MCP authentication...");
|
|
8480
8505
|
}
|
|
8481
|
-
return new Promise((
|
|
8506
|
+
return new Promise((resolve10, _reject) => {
|
|
8482
8507
|
let timeoutId;
|
|
8483
8508
|
const connections = /* @__PURE__ */ new Set();
|
|
8484
8509
|
const server = http.createServer((req, res) => {
|
|
@@ -8525,7 +8550,7 @@ var init_mcp_provision = __esm({
|
|
|
8525
8550
|
}
|
|
8526
8551
|
}, null, 2));
|
|
8527
8552
|
}
|
|
8528
|
-
|
|
8553
|
+
resolve10({
|
|
8529
8554
|
success: true,
|
|
8530
8555
|
metadata: {
|
|
8531
8556
|
serviceType: "mcp",
|
|
@@ -8535,7 +8560,7 @@ var init_mcp_provision = __esm({
|
|
|
8535
8560
|
}
|
|
8536
8561
|
});
|
|
8537
8562
|
} else {
|
|
8538
|
-
|
|
8563
|
+
resolve10({
|
|
8539
8564
|
success: false,
|
|
8540
8565
|
error: "No token received from authentication",
|
|
8541
8566
|
metadata: {
|
|
@@ -8577,7 +8602,7 @@ var init_mcp_provision = __esm({
|
|
|
8577
8602
|
timeoutId = setTimeout(() => {
|
|
8578
8603
|
connections.forEach((conn) => conn.destroy());
|
|
8579
8604
|
server.close();
|
|
8580
|
-
|
|
8605
|
+
resolve10({
|
|
8581
8606
|
success: false,
|
|
8582
8607
|
error: "Authentication timeout - please try again",
|
|
8583
8608
|
metadata: {
|
|
@@ -9064,18 +9089,18 @@ import * as path20 from "path";
|
|
|
9064
9089
|
import { fileURLToPath } from "url";
|
|
9065
9090
|
function getTemplatesDir(importMetaUrl) {
|
|
9066
9091
|
const filename = fileURLToPath(importMetaUrl);
|
|
9067
|
-
const
|
|
9068
|
-
if (
|
|
9069
|
-
let dir =
|
|
9092
|
+
const dirname16 = path20.dirname(filename);
|
|
9093
|
+
if (dirname16.includes(path20.sep + "src" + path20.sep)) {
|
|
9094
|
+
let dir = dirname16;
|
|
9070
9095
|
while (dir !== path20.dirname(dir)) {
|
|
9071
9096
|
if (path20.basename(dir) === "src") {
|
|
9072
9097
|
return path20.join(path20.dirname(dir), "templates");
|
|
9073
9098
|
}
|
|
9074
9099
|
dir = path20.dirname(dir);
|
|
9075
9100
|
}
|
|
9076
|
-
throw new Error(`Cannot locate templates directory from source path: ${
|
|
9101
|
+
throw new Error(`Cannot locate templates directory from source path: ${dirname16}`);
|
|
9077
9102
|
}
|
|
9078
|
-
return path20.join(
|
|
9103
|
+
return path20.join(dirname16, "templates");
|
|
9079
9104
|
}
|
|
9080
9105
|
var init_cli_paths = __esm({
|
|
9081
9106
|
"src/core/io/cli-paths.ts"() {
|
|
@@ -9257,7 +9282,7 @@ async function stopJanusGraph(context) {
|
|
|
9257
9282
|
const startTime = Date.now();
|
|
9258
9283
|
let processRunning = true;
|
|
9259
9284
|
while (processRunning && Date.now() - startTime < timeout) {
|
|
9260
|
-
await new Promise((
|
|
9285
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
9261
9286
|
try {
|
|
9262
9287
|
process.kill(pid, 0);
|
|
9263
9288
|
} catch {
|
|
@@ -9360,14 +9385,14 @@ async function killProcessGroupAndRelated(pid, serviceType, verbose = false) {
|
|
|
9360
9385
|
}
|
|
9361
9386
|
process.kill(-pid, "SIGTERM");
|
|
9362
9387
|
killed = true;
|
|
9363
|
-
await new Promise((
|
|
9388
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
9364
9389
|
try {
|
|
9365
9390
|
process.kill(pid, 0);
|
|
9366
9391
|
if (verbose) {
|
|
9367
9392
|
printWarning(`Process group didn't terminate gracefully, force killing...`);
|
|
9368
9393
|
}
|
|
9369
9394
|
process.kill(-pid, "SIGKILL");
|
|
9370
|
-
await new Promise((
|
|
9395
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
9371
9396
|
} catch {
|
|
9372
9397
|
}
|
|
9373
9398
|
} catch (error) {
|
|
@@ -9376,7 +9401,7 @@ async function killProcessGroupAndRelated(pid, serviceType, verbose = false) {
|
|
|
9376
9401
|
}
|
|
9377
9402
|
try {
|
|
9378
9403
|
process.kill(pid, "SIGTERM");
|
|
9379
|
-
await new Promise((
|
|
9404
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
9380
9405
|
try {
|
|
9381
9406
|
process.kill(pid, 0);
|
|
9382
9407
|
process.kill(pid, "SIGKILL");
|
|
@@ -10043,7 +10068,7 @@ var init_inference_start = __esm({
|
|
|
10043
10068
|
const maxAttempts = 15;
|
|
10044
10069
|
let ready = false;
|
|
10045
10070
|
for (let i = 0; i < maxAttempts; i++) {
|
|
10046
|
-
await new Promise((
|
|
10071
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
10047
10072
|
if (await isOllamaRunning(port)) {
|
|
10048
10073
|
ready = true;
|
|
10049
10074
|
break;
|
|
@@ -10159,7 +10184,7 @@ var init_inference_stop = __esm({
|
|
|
10159
10184
|
const startTime = Date.now();
|
|
10160
10185
|
let processRunning = true;
|
|
10161
10186
|
while (processRunning && Date.now() - startTime < timeout) {
|
|
10162
|
-
await new Promise((
|
|
10187
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
10163
10188
|
try {
|
|
10164
10189
|
process.kill(pid, 0);
|
|
10165
10190
|
} catch {
|
|
@@ -11226,7 +11251,7 @@ async function waitForContainer(runtime, containerName) {
|
|
|
11226
11251
|
}
|
|
11227
11252
|
} catch {
|
|
11228
11253
|
}
|
|
11229
|
-
await new Promise((
|
|
11254
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
11230
11255
|
attempts++;
|
|
11231
11256
|
}
|
|
11232
11257
|
throw new Error(`Container ${containerName} failed to start within ${maxAttempts} seconds`);
|
|
@@ -11336,7 +11361,7 @@ import { execFileSync as execFileSync19 } from "child_process";
|
|
|
11336
11361
|
async function waitForDatabase(runtime, containerName, image, quiet, dbUser, verbose) {
|
|
11337
11362
|
const maxAttempts = 15;
|
|
11338
11363
|
let attempts = 0;
|
|
11339
|
-
await new Promise((
|
|
11364
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
11340
11365
|
const skipHealthCheck = process.env.SKIP_DB_HEALTH_CHECK === "true";
|
|
11341
11366
|
if (skipHealthCheck) {
|
|
11342
11367
|
try {
|
|
@@ -11346,7 +11371,7 @@ async function waitForDatabase(runtime, containerName, image, quiet, dbUser, ver
|
|
|
11346
11371
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
11347
11372
|
).trim();
|
|
11348
11373
|
if (status === "running") {
|
|
11349
|
-
await new Promise((
|
|
11374
|
+
await new Promise((resolve10) => setTimeout(resolve10, 3e3));
|
|
11350
11375
|
return;
|
|
11351
11376
|
}
|
|
11352
11377
|
} catch {
|
|
@@ -11379,7 +11404,7 @@ async function waitForDatabase(runtime, containerName, image, quiet, dbUser, ver
|
|
|
11379
11404
|
stdio: verbose ? "inherit" : "ignore",
|
|
11380
11405
|
timeout: 5e3
|
|
11381
11406
|
});
|
|
11382
|
-
await new Promise((
|
|
11407
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
11383
11408
|
if (verbose) {
|
|
11384
11409
|
printInfo(`PostgreSQL is ready`);
|
|
11385
11410
|
}
|
|
@@ -11408,7 +11433,7 @@ async function waitForDatabase(runtime, containerName, image, quiet, dbUser, ver
|
|
|
11408
11433
|
} catch {
|
|
11409
11434
|
}
|
|
11410
11435
|
} else {
|
|
11411
|
-
await new Promise((
|
|
11436
|
+
await new Promise((resolve10) => setTimeout(resolve10, 3e3));
|
|
11412
11437
|
return;
|
|
11413
11438
|
}
|
|
11414
11439
|
}
|
|
@@ -11417,7 +11442,7 @@ async function waitForDatabase(runtime, containerName, image, quiet, dbUser, ver
|
|
|
11417
11442
|
printInfo(`Waiting for database to be ready... (${attempts + 1}/${maxAttempts})`);
|
|
11418
11443
|
}
|
|
11419
11444
|
}
|
|
11420
|
-
await new Promise((
|
|
11445
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
11421
11446
|
attempts++;
|
|
11422
11447
|
}
|
|
11423
11448
|
printWarning(`Database container ${containerName} is taking longer than expected to start`);
|
|
@@ -11598,14 +11623,14 @@ async function startJanusGraph2(context) {
|
|
|
11598
11623
|
{ encoding: "utf-8", stdio: "pipe" }
|
|
11599
11624
|
);
|
|
11600
11625
|
if (logs.includes("Channel started") || logs.includes("Started") || i >= 5) {
|
|
11601
|
-
await new Promise((
|
|
11626
|
+
await new Promise((resolve10) => setTimeout(resolve10, 3e3));
|
|
11602
11627
|
ready = true;
|
|
11603
11628
|
break;
|
|
11604
11629
|
}
|
|
11605
11630
|
}
|
|
11606
11631
|
} catch {
|
|
11607
11632
|
}
|
|
11608
|
-
await new Promise((
|
|
11633
|
+
await new Promise((resolve10) => setTimeout(resolve10, 3e3));
|
|
11609
11634
|
if (!service.quiet && i > 0 && i % 5 === 0) {
|
|
11610
11635
|
printInfo(`Still waiting... (${i * 3}s elapsed)`);
|
|
11611
11636
|
}
|
|
@@ -11817,7 +11842,7 @@ var init_database_provision = __esm({
|
|
|
11817
11842
|
break;
|
|
11818
11843
|
}
|
|
11819
11844
|
} catch {
|
|
11820
|
-
await new Promise((
|
|
11845
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
11821
11846
|
attempts++;
|
|
11822
11847
|
}
|
|
11823
11848
|
}
|
|
@@ -14967,7 +14992,7 @@ var init_database_stop = __esm({
|
|
|
14967
14992
|
if (currentStatus === "exited" || currentStatus === "stopped") {
|
|
14968
14993
|
stopped = true;
|
|
14969
14994
|
} else {
|
|
14970
|
-
await new Promise((
|
|
14995
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
14971
14996
|
attempts++;
|
|
14972
14997
|
}
|
|
14973
14998
|
} catch {
|
|
@@ -15341,7 +15366,7 @@ var init_proxy_start2 = __esm({
|
|
|
15341
15366
|
if (!service.quiet) {
|
|
15342
15367
|
printInfo("Waiting for proxy to become healthy...");
|
|
15343
15368
|
}
|
|
15344
|
-
await new Promise((
|
|
15369
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
15345
15370
|
const isRunning = execFileSync26(runtime, ["ps", "-q", "-f", `id=${containerId}`], { encoding: "utf-8" }).trim();
|
|
15346
15371
|
if (!isRunning) {
|
|
15347
15372
|
const logs = execFileSync26(runtime, ["logs", containerId], { encoding: "utf-8" });
|
|
@@ -15942,7 +15967,7 @@ var init_inference_start2 = __esm({
|
|
|
15942
15967
|
let ready = false;
|
|
15943
15968
|
const maxAttempts = 15;
|
|
15944
15969
|
for (let i = 0; i < maxAttempts; i++) {
|
|
15945
|
-
await new Promise((
|
|
15970
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
15946
15971
|
try {
|
|
15947
15972
|
const status = execFileSync30(
|
|
15948
15973
|
runtime,
|
|
@@ -18310,7 +18335,7 @@ Waiting for ${otherActiveDeployments.length} old deployment(s) to complete drain
|
|
|
18310
18335
|
if (taskDetails.new.running > 0) {
|
|
18311
18336
|
consecutiveFailures = 0;
|
|
18312
18337
|
}
|
|
18313
|
-
await new Promise((
|
|
18338
|
+
await new Promise((resolve10) => setTimeout(resolve10, checkInterval));
|
|
18314
18339
|
} catch (error) {
|
|
18315
18340
|
if (error instanceof Error && error.message.includes("Deployment")) {
|
|
18316
18341
|
if (!verbose) {
|
|
@@ -19056,20 +19081,20 @@ var init_database_check3 = __esm({
|
|
|
19056
19081
|
const host = serviceConfig.host;
|
|
19057
19082
|
const port = serviceConfig.port;
|
|
19058
19083
|
try {
|
|
19059
|
-
const isReachable = await new Promise((
|
|
19084
|
+
const isReachable = await new Promise((resolve10) => {
|
|
19060
19085
|
const socket = new net3.Socket();
|
|
19061
19086
|
socket.setTimeout(5e3);
|
|
19062
19087
|
socket.once("connect", () => {
|
|
19063
19088
|
socket.destroy();
|
|
19064
|
-
|
|
19089
|
+
resolve10(true);
|
|
19065
19090
|
});
|
|
19066
19091
|
socket.once("error", () => {
|
|
19067
19092
|
socket.destroy();
|
|
19068
|
-
|
|
19093
|
+
resolve10(false);
|
|
19069
19094
|
});
|
|
19070
19095
|
socket.once("timeout", () => {
|
|
19071
19096
|
socket.destroy();
|
|
19072
|
-
|
|
19097
|
+
resolve10(false);
|
|
19073
19098
|
});
|
|
19074
19099
|
socket.connect(port, host);
|
|
19075
19100
|
});
|
|
@@ -19139,20 +19164,20 @@ var init_database_check3 = __esm({
|
|
|
19139
19164
|
const host = serviceConfig.host;
|
|
19140
19165
|
const port = serviceConfig.port;
|
|
19141
19166
|
try {
|
|
19142
|
-
const isReachable = await new Promise((
|
|
19167
|
+
const isReachable = await new Promise((resolve10) => {
|
|
19143
19168
|
const socket = new net3.Socket();
|
|
19144
19169
|
socket.setTimeout(5e3);
|
|
19145
19170
|
socket.once("connect", () => {
|
|
19146
19171
|
socket.destroy();
|
|
19147
|
-
|
|
19172
|
+
resolve10(true);
|
|
19148
19173
|
});
|
|
19149
19174
|
socket.once("error", () => {
|
|
19150
19175
|
socket.destroy();
|
|
19151
|
-
|
|
19176
|
+
resolve10(false);
|
|
19152
19177
|
});
|
|
19153
19178
|
socket.once("timeout", () => {
|
|
19154
19179
|
socket.destroy();
|
|
19155
|
-
|
|
19180
|
+
resolve10(false);
|
|
19156
19181
|
});
|
|
19157
19182
|
socket.connect(port, host);
|
|
19158
19183
|
});
|
|
@@ -19626,7 +19651,7 @@ var init_values = __esm({
|
|
|
19626
19651
|
var sleep;
|
|
19627
19652
|
var init_sleep = __esm({
|
|
19628
19653
|
"node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs"() {
|
|
19629
|
-
sleep = (ms) => new Promise((
|
|
19654
|
+
sleep = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
19630
19655
|
}
|
|
19631
19656
|
});
|
|
19632
19657
|
|
|
@@ -20380,8 +20405,8 @@ var init_api_promise = __esm({
|
|
|
20380
20405
|
init_parse();
|
|
20381
20406
|
APIPromise = class _APIPromise extends Promise {
|
|
20382
20407
|
constructor(client, responsePromise, parseResponse = defaultParseResponse) {
|
|
20383
|
-
super((
|
|
20384
|
-
|
|
20408
|
+
super((resolve10) => {
|
|
20409
|
+
resolve10(null);
|
|
20385
20410
|
});
|
|
20386
20411
|
this.responsePromise = responsePromise;
|
|
20387
20412
|
this.parseResponse = parseResponse;
|
|
@@ -21577,12 +21602,12 @@ var init_BetaMessageStream = __esm({
|
|
|
21577
21602
|
}
|
|
21578
21603
|
return this._emit("error", new AnthropicError(String(error)));
|
|
21579
21604
|
});
|
|
21580
|
-
__classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((
|
|
21581
|
-
__classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise,
|
|
21605
|
+
__classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve10, reject) => {
|
|
21606
|
+
__classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve10, "f");
|
|
21582
21607
|
__classPrivateFieldSet(this, _BetaMessageStream_rejectConnectedPromise, reject, "f");
|
|
21583
21608
|
}), "f");
|
|
21584
|
-
__classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((
|
|
21585
|
-
__classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise,
|
|
21609
|
+
__classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve10, reject) => {
|
|
21610
|
+
__classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve10, "f");
|
|
21586
21611
|
__classPrivateFieldSet(this, _BetaMessageStream_rejectEndPromise, reject, "f");
|
|
21587
21612
|
}), "f");
|
|
21588
21613
|
__classPrivateFieldGet(this, _BetaMessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -21748,11 +21773,11 @@ var init_BetaMessageStream = __esm({
|
|
|
21748
21773
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
21749
21774
|
*/
|
|
21750
21775
|
emitted(event) {
|
|
21751
|
-
return new Promise((
|
|
21776
|
+
return new Promise((resolve10, reject) => {
|
|
21752
21777
|
__classPrivateFieldSet(this, _BetaMessageStream_catchingPromiseCreated, true, "f");
|
|
21753
21778
|
if (event !== "error")
|
|
21754
21779
|
this.once("error", reject);
|
|
21755
|
-
this.once(event,
|
|
21780
|
+
this.once(event, resolve10);
|
|
21756
21781
|
});
|
|
21757
21782
|
}
|
|
21758
21783
|
async done() {
|
|
@@ -22075,7 +22100,7 @@ var init_BetaMessageStream = __esm({
|
|
|
22075
22100
|
if (done) {
|
|
22076
22101
|
return { value: void 0, done: true };
|
|
22077
22102
|
}
|
|
22078
|
-
return new Promise((
|
|
22103
|
+
return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
22079
22104
|
}
|
|
22080
22105
|
const chunk = pushQueue.shift();
|
|
22081
22106
|
return { value: chunk, done: false };
|
|
@@ -22113,13 +22138,13 @@ var init_constants = __esm({
|
|
|
22113
22138
|
|
|
22114
22139
|
// node_modules/@anthropic-ai/sdk/lib/tools/BetaToolRunner.mjs
|
|
22115
22140
|
function promiseWithResolvers() {
|
|
22116
|
-
let
|
|
22141
|
+
let resolve10;
|
|
22117
22142
|
let reject;
|
|
22118
22143
|
const promise = new Promise((res, rej) => {
|
|
22119
|
-
|
|
22144
|
+
resolve10 = res;
|
|
22120
22145
|
reject = rej;
|
|
22121
22146
|
});
|
|
22122
|
-
return { promise, resolve:
|
|
22147
|
+
return { promise, resolve: resolve10, reject };
|
|
22123
22148
|
}
|
|
22124
22149
|
async function generateToolResponse(params, lastMessage = params.messages.at(-1)) {
|
|
22125
22150
|
if (!lastMessage || lastMessage.role !== "assistant" || !lastMessage.content || typeof lastMessage.content === "string") {
|
|
@@ -22573,12 +22598,12 @@ var init_MessageStream = __esm({
|
|
|
22573
22598
|
}
|
|
22574
22599
|
return this._emit("error", new AnthropicError(String(error)));
|
|
22575
22600
|
});
|
|
22576
|
-
__classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((
|
|
22577
|
-
__classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise,
|
|
22601
|
+
__classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve10, reject) => {
|
|
22602
|
+
__classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve10, "f");
|
|
22578
22603
|
__classPrivateFieldSet(this, _MessageStream_rejectConnectedPromise, reject, "f");
|
|
22579
22604
|
}), "f");
|
|
22580
|
-
__classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((
|
|
22581
|
-
__classPrivateFieldSet(this, _MessageStream_resolveEndPromise,
|
|
22605
|
+
__classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve10, reject) => {
|
|
22606
|
+
__classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve10, "f");
|
|
22582
22607
|
__classPrivateFieldSet(this, _MessageStream_rejectEndPromise, reject, "f");
|
|
22583
22608
|
}), "f");
|
|
22584
22609
|
__classPrivateFieldGet(this, _MessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -22744,11 +22769,11 @@ var init_MessageStream = __esm({
|
|
|
22744
22769
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
22745
22770
|
*/
|
|
22746
22771
|
emitted(event) {
|
|
22747
|
-
return new Promise((
|
|
22772
|
+
return new Promise((resolve10, reject) => {
|
|
22748
22773
|
__classPrivateFieldSet(this, _MessageStream_catchingPromiseCreated, true, "f");
|
|
22749
22774
|
if (event !== "error")
|
|
22750
22775
|
this.once("error", reject);
|
|
22751
|
-
this.once(event,
|
|
22776
|
+
this.once(event, resolve10);
|
|
22752
22777
|
});
|
|
22753
22778
|
}
|
|
22754
22779
|
async done() {
|
|
@@ -23065,7 +23090,7 @@ var init_MessageStream = __esm({
|
|
|
23065
23090
|
if (done) {
|
|
23066
23091
|
return { value: void 0, done: true };
|
|
23067
23092
|
}
|
|
23068
|
-
return new Promise((
|
|
23093
|
+
return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
23069
23094
|
}
|
|
23070
23095
|
const chunk = pushQueue.shift();
|
|
23071
23096
|
return { value: chunk, done: false };
|
|
@@ -24272,7 +24297,7 @@ var init_default_start = __esm({
|
|
|
24272
24297
|
printInfo(`[MOCK] Starting service: ${service.name}`);
|
|
24273
24298
|
}
|
|
24274
24299
|
const startupDelay = mockData?.startupDelay || 100;
|
|
24275
|
-
await new Promise((
|
|
24300
|
+
await new Promise((resolve10) => setTimeout(resolve10, startupDelay));
|
|
24276
24301
|
if (mockData?.simulateFailure) {
|
|
24277
24302
|
return {
|
|
24278
24303
|
success: false,
|
|
@@ -25815,7 +25840,7 @@ var init_check = __esm({
|
|
|
25815
25840
|
init_multi_service_executor();
|
|
25816
25841
|
init_command_definition();
|
|
25817
25842
|
init_base_options_schema();
|
|
25818
|
-
CheckOptionsSchema =
|
|
25843
|
+
CheckOptionsSchema = OpsOptionsSchema.extend({
|
|
25819
25844
|
service: external_exports.string().optional(),
|
|
25820
25845
|
all: external_exports.boolean().default(false),
|
|
25821
25846
|
deep: external_exports.boolean().default(true),
|
|
@@ -26225,7 +26250,7 @@ var init_dashboard_data = __esm({
|
|
|
26225
26250
|
}
|
|
26226
26251
|
}
|
|
26227
26252
|
fetchBackendHealth(port) {
|
|
26228
|
-
return new Promise((
|
|
26253
|
+
return new Promise((resolve10, reject) => {
|
|
26229
26254
|
const req = http2.get(`http://localhost:${port}/api/health`, { timeout: 2e3 }, (res) => {
|
|
26230
26255
|
let body = "";
|
|
26231
26256
|
res.on("data", (chunk) => {
|
|
@@ -26233,7 +26258,7 @@ var init_dashboard_data = __esm({
|
|
|
26233
26258
|
});
|
|
26234
26259
|
res.on("end", () => {
|
|
26235
26260
|
try {
|
|
26236
|
-
|
|
26261
|
+
resolve10(JSON.parse(body));
|
|
26237
26262
|
} catch {
|
|
26238
26263
|
reject(new Error("Invalid JSON"));
|
|
26239
26264
|
}
|
|
@@ -26678,7 +26703,7 @@ var init_web_dashboard_server = __esm({
|
|
|
26678
26703
|
this.actorsInterval = null;
|
|
26679
26704
|
}
|
|
26680
26705
|
async start() {
|
|
26681
|
-
return new Promise((
|
|
26706
|
+
return new Promise((resolve10) => {
|
|
26682
26707
|
this.server.listen(this.port, () => {
|
|
26683
26708
|
console.log(`
|
|
26684
26709
|
\u{1F310} Web dashboard running at http://localhost:${this.port}`);
|
|
@@ -26687,7 +26712,7 @@ var init_web_dashboard_server = __esm({
|
|
|
26687
26712
|
console.log(`
|
|
26688
26713
|
Press Ctrl+C to stop
|
|
26689
26714
|
`);
|
|
26690
|
-
|
|
26715
|
+
resolve10();
|
|
26691
26716
|
});
|
|
26692
26717
|
});
|
|
26693
26718
|
}
|
|
@@ -27020,7 +27045,7 @@ var require_package = __commonJS({
|
|
|
27020
27045
|
"package.json"(exports, module) {
|
|
27021
27046
|
module.exports = {
|
|
27022
27047
|
name: "@semiont/cli",
|
|
27023
|
-
version: "0.4.
|
|
27048
|
+
version: "0.4.3",
|
|
27024
27049
|
description: "Semiont CLI - Unified environment management tool",
|
|
27025
27050
|
_comment: "AWS SDK dependencies (@aws-sdk/*) are only used by platforms/aws",
|
|
27026
27051
|
type: "module",
|
|
@@ -27084,13 +27109,12 @@ var require_package = __commonJS({
|
|
|
27084
27109
|
"@aws-sdk/client-secrets-manager": "^3.600.0",
|
|
27085
27110
|
"@aws-sdk/client-sts": "^3.859.0",
|
|
27086
27111
|
"@aws-sdk/client-wafv2": "^3.859.0",
|
|
27087
|
-
"@semiont/api-client": "^0.4.
|
|
27088
|
-
"@semiont/content": "^0.4.
|
|
27089
|
-
"@semiont/core": "^0.4.
|
|
27090
|
-
"@semiont/event-sourcing": "^0.4.
|
|
27091
|
-
"@semiont/graph": "^0.4.
|
|
27092
|
-
"@semiont/make-meaning": "^0.4.
|
|
27093
|
-
"@vitest/ui": "4.0.18",
|
|
27112
|
+
"@semiont/api-client": "^0.4.3",
|
|
27113
|
+
"@semiont/content": "^0.4.3",
|
|
27114
|
+
"@semiont/core": "^0.4.3",
|
|
27115
|
+
"@semiont/event-sourcing": "^0.4.3",
|
|
27116
|
+
"@semiont/graph": "^0.4.3",
|
|
27117
|
+
"@semiont/make-meaning": "^0.4.3",
|
|
27094
27118
|
arg: "^5.0.2",
|
|
27095
27119
|
argon2: "^0.44.0",
|
|
27096
27120
|
express: "^5.2.1",
|
|
@@ -27109,8 +27133,7 @@ var require_package = __commonJS({
|
|
|
27109
27133
|
"@types/react": "^19.2.14",
|
|
27110
27134
|
"@vitest/coverage-v8": "^4.1.0",
|
|
27111
27135
|
chalk: "^5.3.0",
|
|
27112
|
-
typescript: "^5.9.2"
|
|
27113
|
-
vitest: "^4.0.18"
|
|
27136
|
+
typescript: "^5.9.2"
|
|
27114
27137
|
},
|
|
27115
27138
|
overrides: {
|
|
27116
27139
|
esbuild: "0.27.2"
|
|
@@ -27144,17 +27167,15 @@ var InitOptionsSchema = BaseOptionsSchema.extend({
|
|
|
27144
27167
|
environments: external_exports.array(external_exports.string()).default(["local", "test", "staging", "production"])
|
|
27145
27168
|
}).transform((data) => ({
|
|
27146
27169
|
...data,
|
|
27147
|
-
environment: data.environment || "_init_",
|
|
27148
|
-
// Dummy value - init doesn't use environment
|
|
27149
27170
|
output: data.output === "table" ? "summary" : data.output
|
|
27150
27171
|
// Init doesn't support table output
|
|
27151
27172
|
}));
|
|
27152
27173
|
function prompt(question) {
|
|
27153
|
-
return new Promise((
|
|
27174
|
+
return new Promise((resolve10) => {
|
|
27154
27175
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
27155
27176
|
rl.question(question, (answer) => {
|
|
27156
27177
|
rl.close();
|
|
27157
|
-
|
|
27178
|
+
resolve10(answer.trim());
|
|
27158
27179
|
});
|
|
27159
27180
|
});
|
|
27160
27181
|
}
|
|
@@ -27329,7 +27350,7 @@ async function init(options) {
|
|
|
27329
27350
|
console.log(`${colors.yellow}\u2139 --no-git: git init will be skipped${colors.reset}`);
|
|
27330
27351
|
console.log(`${colors.yellow}\u2139 --no-git: git.sync will be set to false in .semiont/config${colors.reset}`);
|
|
27331
27352
|
console.log(`${colors.yellow}\u2139 --no-git: .semiont/config will NOT be staged (git add skipped)${colors.reset}`);
|
|
27332
|
-
console.log(`${colors.yellow}\u2139 --no-git: semiont yield/mv
|
|
27353
|
+
console.log(`${colors.yellow}\u2139 --no-git: semiont yield/mv will not stage files in the git index${colors.reset}`);
|
|
27333
27354
|
}
|
|
27334
27355
|
const dotSemiontConfigPath = path2.join(dotSemiontDir, "config");
|
|
27335
27356
|
if (!fs2.existsSync(dotSemiontDir) || options.force) {
|
|
@@ -27386,7 +27407,7 @@ Next steps:`);
|
|
|
27386
27407
|
results.duration = Date.now() - startTime;
|
|
27387
27408
|
return results;
|
|
27388
27409
|
}
|
|
27389
|
-
var initCommand = new CommandBuilder().name("init").description("Initialize a new Semiont project").schema(InitOptionsSchema).args(
|
|
27410
|
+
var initCommand = new CommandBuilder().name("init").description("Initialize a new Semiont project").schema(InitOptionsSchema).args(withOpsArgs({
|
|
27390
27411
|
"--name": {
|
|
27391
27412
|
type: "string",
|
|
27392
27413
|
description: "Project name"
|
|
@@ -27427,7 +27448,7 @@ init_command_descriptor();
|
|
|
27427
27448
|
init_multi_service_executor();
|
|
27428
27449
|
init_command_definition();
|
|
27429
27450
|
init_base_options_schema();
|
|
27430
|
-
var StartOptionsSchema =
|
|
27451
|
+
var StartOptionsSchema = OpsOptionsSchema.extend({
|
|
27431
27452
|
service: external_exports.string().optional()
|
|
27432
27453
|
});
|
|
27433
27454
|
var startDescriptor = createCommandDescriptor({
|
|
@@ -27498,7 +27519,7 @@ init_command_descriptor();
|
|
|
27498
27519
|
init_multi_service_executor();
|
|
27499
27520
|
init_command_definition();
|
|
27500
27521
|
init_base_options_schema();
|
|
27501
|
-
var StopOptionsSchema =
|
|
27522
|
+
var StopOptionsSchema = OpsOptionsSchema.extend({
|
|
27502
27523
|
service: external_exports.string().optional(),
|
|
27503
27524
|
force: external_exports.boolean().default(false).describe("Force stop without graceful shutdown"),
|
|
27504
27525
|
timeout: external_exports.number().default(30).describe("Timeout for graceful shutdown in seconds")
|
|
@@ -27588,7 +27609,7 @@ init_command_descriptor();
|
|
|
27588
27609
|
init_multi_service_executor();
|
|
27589
27610
|
init_command_definition();
|
|
27590
27611
|
init_base_options_schema();
|
|
27591
|
-
var ProvisionOptionsSchema =
|
|
27612
|
+
var ProvisionOptionsSchema = OpsOptionsSchema.extend({
|
|
27592
27613
|
service: external_exports.string().optional(),
|
|
27593
27614
|
all: external_exports.boolean().default(false),
|
|
27594
27615
|
stack: external_exports.enum(["data", "app", "all"]).optional(),
|
|
@@ -27722,7 +27743,7 @@ init_command_descriptor();
|
|
|
27722
27743
|
init_multi_service_executor();
|
|
27723
27744
|
init_command_definition();
|
|
27724
27745
|
init_base_options_schema();
|
|
27725
|
-
var PublishOptionsSchema =
|
|
27746
|
+
var PublishOptionsSchema = OpsOptionsSchema.extend({
|
|
27726
27747
|
service: external_exports.string().optional(),
|
|
27727
27748
|
all: external_exports.boolean().default(false),
|
|
27728
27749
|
tag: external_exports.string().optional(),
|
|
@@ -27822,7 +27843,7 @@ init_command_descriptor();
|
|
|
27822
27843
|
init_multi_service_executor();
|
|
27823
27844
|
init_command_definition();
|
|
27824
27845
|
init_base_options_schema();
|
|
27825
|
-
var UpdateOptionsSchema =
|
|
27846
|
+
var UpdateOptionsSchema = OpsOptionsSchema.extend({
|
|
27826
27847
|
service: external_exports.string().optional(),
|
|
27827
27848
|
force: external_exports.boolean().default(false),
|
|
27828
27849
|
wait: external_exports.boolean().default(false),
|
|
@@ -27948,7 +27969,7 @@ init_platform3();
|
|
|
27948
27969
|
init_platform2();
|
|
27949
27970
|
init_cli_colors();
|
|
27950
27971
|
init_dashboard_data();
|
|
27951
|
-
var WatchOptionsSchema =
|
|
27972
|
+
var WatchOptionsSchema = OpsOptionsSchema.extend({
|
|
27952
27973
|
target: external_exports.enum(["all", "logs", "metrics", "services"]).default("all"),
|
|
27953
27974
|
noFollow: external_exports.boolean().default(false),
|
|
27954
27975
|
interval: external_exports.number().int().positive().default(30),
|
|
@@ -27957,9 +27978,9 @@ var WatchOptionsSchema = BaseOptionsSchema.extend({
|
|
|
27957
27978
|
});
|
|
27958
27979
|
async function launchDashboard(environment, serviceDeployments, envConfig, interval, port) {
|
|
27959
27980
|
const startTime = Date.now();
|
|
27960
|
-
return new Promise(async (
|
|
27981
|
+
return new Promise(async (resolve10) => {
|
|
27961
27982
|
if (process.env.VITEST) {
|
|
27962
|
-
setTimeout(() =>
|
|
27983
|
+
setTimeout(() => resolve10({ duration: 100, exitReason: "user-quit" }), 100);
|
|
27963
27984
|
return;
|
|
27964
27985
|
}
|
|
27965
27986
|
try {
|
|
@@ -27977,13 +27998,13 @@ async function launchDashboard(environment, serviceDeployments, envConfig, inter
|
|
|
27977
27998
|
await server.start();
|
|
27978
27999
|
const stop2 = () => {
|
|
27979
28000
|
server.stop();
|
|
27980
|
-
|
|
28001
|
+
resolve10({ duration: Date.now() - startTime, exitReason: "user-quit" });
|
|
27981
28002
|
};
|
|
27982
28003
|
process.on("SIGINT", stop2);
|
|
27983
28004
|
process.on("SIGTERM", stop2);
|
|
27984
28005
|
} catch (error) {
|
|
27985
28006
|
console.error("Dashboard error:", error);
|
|
27986
|
-
|
|
28007
|
+
resolve10({ duration: Date.now() - startTime, exitReason: "error" });
|
|
27987
28008
|
}
|
|
27988
28009
|
});
|
|
27989
28010
|
}
|
|
@@ -28098,7 +28119,7 @@ ${colors.bright}To fix this issue:${colors.reset}`);
|
|
|
28098
28119
|
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun }
|
|
28099
28120
|
};
|
|
28100
28121
|
}
|
|
28101
|
-
var watchCommand = new CommandBuilder().name("watch").description("Monitor services using new architecture").schema(WatchOptionsSchema).requiresEnvironment(true).requiresServices(true).args(
|
|
28122
|
+
var watchCommand = new CommandBuilder().name("watch").description("Monitor services using new architecture").schema(WatchOptionsSchema).requiresEnvironment(true).requiresServices(true).args(withOpsArgs({
|
|
28102
28123
|
"--service": { type: "string", description: 'Service name or "all" for all services' },
|
|
28103
28124
|
"--target": { type: "string", description: "What to watch (all, logs, metrics, services)" },
|
|
28104
28125
|
"--no-follow": { type: "boolean", description: "Do not follow new logs" },
|
|
@@ -28146,7 +28167,7 @@ function loadPrismaClient(projectRoot) {
|
|
|
28146
28167
|
);
|
|
28147
28168
|
}
|
|
28148
28169
|
}
|
|
28149
|
-
var UseraddOptionsSchema =
|
|
28170
|
+
var UseraddOptionsSchema = OpsOptionsSchema.extend({
|
|
28150
28171
|
email: external_exports.string().email().min(1, "Email is required"),
|
|
28151
28172
|
name: external_exports.string().optional(),
|
|
28152
28173
|
password: external_exports.string().optional(),
|
|
@@ -28154,7 +28175,8 @@ var UseraddOptionsSchema = BaseOptionsSchema.extend({
|
|
|
28154
28175
|
admin: external_exports.boolean().default(false),
|
|
28155
28176
|
moderator: external_exports.boolean().default(false),
|
|
28156
28177
|
inactive: external_exports.boolean().default(false),
|
|
28157
|
-
update: external_exports.boolean().default(false)
|
|
28178
|
+
update: external_exports.boolean().default(false),
|
|
28179
|
+
upsert: external_exports.boolean().default(false)
|
|
28158
28180
|
});
|
|
28159
28181
|
function validateEmail(email) {
|
|
28160
28182
|
const emailRegex2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -28225,8 +28247,23 @@ async function useradd(options) {
|
|
|
28225
28247
|
}
|
|
28226
28248
|
let user;
|
|
28227
28249
|
if (existingUser) {
|
|
28250
|
+
if (options.upsert) {
|
|
28251
|
+
if (!options.quiet) {
|
|
28252
|
+
printSuccess(`User already exists: ${options.email}`);
|
|
28253
|
+
}
|
|
28254
|
+
await prisma.$disconnect();
|
|
28255
|
+
return {
|
|
28256
|
+
command: "useradd",
|
|
28257
|
+
environment: options.environment,
|
|
28258
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
28259
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
28260
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
28261
|
+
results: [{ entity: options.email, platform: "posix", success: true, metadata: { userId: existingUser.id, email: existingUser.email, isAdmin: existingUser.isAdmin, isModerator: existingUser.isModerator, isActive: existingUser.isActive }, duration: Date.now() - startTime }],
|
|
28262
|
+
duration: Date.now() - startTime
|
|
28263
|
+
};
|
|
28264
|
+
}
|
|
28228
28265
|
if (!options.update) {
|
|
28229
|
-
throw new Error(`User ${options.email} already exists. Use --update to modify.`);
|
|
28266
|
+
throw new Error(`User ${options.email} already exists. Use --update to modify or --upsert to skip silently.`);
|
|
28230
28267
|
}
|
|
28231
28268
|
if (!options.quiet) {
|
|
28232
28269
|
printInfo(`Updating user: ${options.email}`);
|
|
@@ -28355,6 +28392,11 @@ var useraddCommand = new CommandBuilder().name("useradd").description("Create or
|
|
|
28355
28392
|
type: "boolean",
|
|
28356
28393
|
description: "Update existing user",
|
|
28357
28394
|
default: false
|
|
28395
|
+
},
|
|
28396
|
+
"--upsert": {
|
|
28397
|
+
type: "boolean",
|
|
28398
|
+
description: "Create user if absent, skip silently if already exists",
|
|
28399
|
+
default: false
|
|
28358
28400
|
}
|
|
28359
28401
|
},
|
|
28360
28402
|
aliases: {
|
|
@@ -28386,7 +28428,7 @@ function createCliLogger(verbose) {
|
|
|
28386
28428
|
child: () => createCliLogger(verbose)
|
|
28387
28429
|
};
|
|
28388
28430
|
}
|
|
28389
|
-
var BackupOptionsSchema =
|
|
28431
|
+
var BackupOptionsSchema = OpsOptionsSchema.extend({
|
|
28390
28432
|
out: external_exports.string().min(1, "Output path is required")
|
|
28391
28433
|
});
|
|
28392
28434
|
async function runBackup(options) {
|
|
@@ -28513,7 +28555,7 @@ function createNoopGraphDatabase() {
|
|
|
28513
28555
|
clearDatabase: noop2
|
|
28514
28556
|
};
|
|
28515
28557
|
}
|
|
28516
|
-
var RestoreOptionsSchema =
|
|
28558
|
+
var RestoreOptionsSchema = OpsOptionsSchema.extend({
|
|
28517
28559
|
file: external_exports.string().min(1, "Input file path is required")
|
|
28518
28560
|
});
|
|
28519
28561
|
async function runRestore(options) {
|
|
@@ -28592,11 +28634,11 @@ import { isBackupManifest, validateManifestVersion, BACKUP_FORMAT } from "@semio
|
|
|
28592
28634
|
import { createGunzip } from "node:zlib";
|
|
28593
28635
|
var BLOCK_SIZE = 512;
|
|
28594
28636
|
async function readTarGzEntries(input) {
|
|
28595
|
-
const decompressed = await new Promise((
|
|
28637
|
+
const decompressed = await new Promise((resolve10, reject) => {
|
|
28596
28638
|
const gunzip = createGunzip();
|
|
28597
28639
|
const chunks = [];
|
|
28598
28640
|
gunzip.on("data", (chunk) => chunks.push(chunk));
|
|
28599
|
-
gunzip.on("end", () =>
|
|
28641
|
+
gunzip.on("end", () => resolve10(Buffer.concat(chunks)));
|
|
28600
28642
|
gunzip.on("error", reject);
|
|
28601
28643
|
input.on("error", reject);
|
|
28602
28644
|
input.pipe(gunzip);
|
|
@@ -28619,7 +28661,7 @@ async function readTarGzEntries(input) {
|
|
|
28619
28661
|
}
|
|
28620
28662
|
return entries;
|
|
28621
28663
|
}
|
|
28622
|
-
var VerifyOptionsSchema =
|
|
28664
|
+
var VerifyOptionsSchema = OpsOptionsSchema.extend({
|
|
28623
28665
|
file: external_exports.string().min(1, "File path is required")
|
|
28624
28666
|
});
|
|
28625
28667
|
async function runVerify(options) {
|
|
@@ -28778,7 +28820,7 @@ function createCliLogger3(verbose) {
|
|
|
28778
28820
|
child: () => createCliLogger3(verbose)
|
|
28779
28821
|
};
|
|
28780
28822
|
}
|
|
28781
|
-
var ExportOptionsSchema =
|
|
28823
|
+
var ExportOptionsSchema = OpsOptionsSchema.extend({
|
|
28782
28824
|
out: external_exports.string().min(1, "Output path is required"),
|
|
28783
28825
|
includeArchived: external_exports.boolean().optional().default(false)
|
|
28784
28826
|
});
|
|
@@ -28921,7 +28963,7 @@ function createNoopGraphDatabase2() {
|
|
|
28921
28963
|
clearDatabase: noop2
|
|
28922
28964
|
};
|
|
28923
28965
|
}
|
|
28924
|
-
var ImportOptionsSchema =
|
|
28966
|
+
var ImportOptionsSchema = OpsOptionsSchema.extend({
|
|
28925
28967
|
file: external_exports.string().min(1, "Input file path is required"),
|
|
28926
28968
|
userId: external_exports.string().optional()
|
|
28927
28969
|
});
|
|
@@ -29006,7 +29048,7 @@ import * as fs49 from "fs";
|
|
|
29006
29048
|
import * as path42 from "path";
|
|
29007
29049
|
import * as readline2 from "readline";
|
|
29008
29050
|
import { execFileSync as execFileSync41 } from "child_process";
|
|
29009
|
-
var LocalOptionsSchema =
|
|
29051
|
+
var LocalOptionsSchema = OpsOptionsSchema.extend({
|
|
29010
29052
|
directory: external_exports.string().optional(),
|
|
29011
29053
|
yes: external_exports.boolean().default(false)
|
|
29012
29054
|
}).transform((data) => ({
|
|
@@ -29014,11 +29056,11 @@ var LocalOptionsSchema = BaseOptionsSchema.extend({
|
|
|
29014
29056
|
environment: data.environment || "_local_"
|
|
29015
29057
|
}));
|
|
29016
29058
|
function prompt2(question) {
|
|
29017
|
-
return new Promise((
|
|
29059
|
+
return new Promise((resolve10) => {
|
|
29018
29060
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
29019
29061
|
rl.question(question, (answer) => {
|
|
29020
29062
|
rl.close();
|
|
29021
|
-
|
|
29063
|
+
resolve10(answer.trim());
|
|
29022
29064
|
});
|
|
29023
29065
|
});
|
|
29024
29066
|
}
|
|
@@ -29121,6 +29163,7 @@ Press Enter to create one in ${colors.bright}${defaultPath}${colors.reset}, or t
|
|
|
29121
29163
|
semiotRoot = answer || defaultPath;
|
|
29122
29164
|
fs49.mkdirSync(semiotRoot, { recursive: true });
|
|
29123
29165
|
process.env.SEMIONT_ROOT = semiotRoot;
|
|
29166
|
+
envVarsToAdvise.push(`export SEMIONT_ROOT=${semiotRoot}`);
|
|
29124
29167
|
console.log(`${colors.green}\u2713${colors.reset} Using ${semiotRoot}
|
|
29125
29168
|
`);
|
|
29126
29169
|
if (semiotRoot !== process.cwd()) {
|
|
@@ -29144,6 +29187,7 @@ Press Enter to create one in ${colors.bright}${defaultPath}${colors.reset}, or t
|
|
|
29144
29187
|
`);
|
|
29145
29188
|
}
|
|
29146
29189
|
const env = { ...process.env };
|
|
29190
|
+
await ensureGlobalConfig(false);
|
|
29147
29191
|
const isInitialized = fs49.existsSync(path42.join(semiotRoot, ".semiont"));
|
|
29148
29192
|
if (isInitialized) {
|
|
29149
29193
|
console.log(`${colors.green}\u2713${colors.reset} Project already initialized
|
|
@@ -29154,8 +29198,10 @@ Press Enter to create one in ${colors.bright}${defaultPath}${colors.reset}, or t
|
|
|
29154
29198
|
runSemiont(["init"], env);
|
|
29155
29199
|
console.log(`${colors.green}\u2713${colors.reset} Project initialized
|
|
29156
29200
|
`);
|
|
29157
|
-
} catch {
|
|
29201
|
+
} catch (err) {
|
|
29202
|
+
const initMsg = err instanceof Error ? err.message : String(err);
|
|
29158
29203
|
console.error(`${colors.red}\u2717 semiont init failed \u2014 cannot continue${colors.reset}`);
|
|
29204
|
+
console.error(` ${initMsg}`);
|
|
29159
29205
|
results.summary.failed = 1;
|
|
29160
29206
|
results.duration = Date.now() - startTime;
|
|
29161
29207
|
return results;
|
|
@@ -29227,11 +29273,11 @@ Press Enter to create one in ${colors.bright}${defaultPath}${colors.reset}, or t
|
|
|
29227
29273
|
const adminPassword = "password";
|
|
29228
29274
|
console.log(`${colors.cyan}\u25B6 Creating admin user...${colors.reset}`);
|
|
29229
29275
|
const useraddResult = runSemiontSafe(
|
|
29230
|
-
["useradd", "--email", adminEmail, "--password", adminPassword, "--admin"],
|
|
29276
|
+
["useradd", "--email", adminEmail, "--password", adminPassword, "--admin", "--upsert"],
|
|
29231
29277
|
env
|
|
29232
29278
|
);
|
|
29233
29279
|
if (useraddResult.success) {
|
|
29234
|
-
console.log(`${colors.green}\u2713${colors.reset} Admin user
|
|
29280
|
+
console.log(`${colors.green}\u2713${colors.reset} Admin user ready
|
|
29235
29281
|
`);
|
|
29236
29282
|
} else {
|
|
29237
29283
|
console.log(`${colors.yellow}\u26A0 useradd failed: ${useraddResult.error}${colors.reset}`);
|
|
@@ -29273,7 +29319,7 @@ ${colors.red}\u2717 Setup failed: ${msg}${colors.reset}`);
|
|
|
29273
29319
|
results.duration = Date.now() - startTime;
|
|
29274
29320
|
return results;
|
|
29275
29321
|
}
|
|
29276
|
-
var localCommand = new CommandBuilder().name("local").description("Set up and start Semiont locally (init + provision + start + useradd)").schema(LocalOptionsSchema).args(
|
|
29322
|
+
var localCommand = new CommandBuilder().name("local").description("Set up and start Semiont locally (init + provision + start + useradd)").schema(LocalOptionsSchema).args(withOpsArgs({
|
|
29277
29323
|
"--directory": {
|
|
29278
29324
|
type: "string",
|
|
29279
29325
|
description: "Project directory (default: cwd)"
|
|
@@ -29284,7 +29330,7 @@ var localCommand = new CommandBuilder().name("local").description("Set up and st
|
|
|
29284
29330
|
default: false
|
|
29285
29331
|
}
|
|
29286
29332
|
}, {
|
|
29287
|
-
"
|
|
29333
|
+
"-y": "--yes"
|
|
29288
29334
|
})).requiresEnvironment(false).requiresServices(false).examples(
|
|
29289
29335
|
"semiont local",
|
|
29290
29336
|
"semiont local --yes",
|
|
@@ -29300,7 +29346,7 @@ import * as fs50 from "fs";
|
|
|
29300
29346
|
import * as readline3 from "readline";
|
|
29301
29347
|
import { execFileSync as execFileSync42 } from "child_process";
|
|
29302
29348
|
import { SemiontProject as SemiontProject20 } from "@semiont/core/node";
|
|
29303
|
-
var CleanOptionsSchema =
|
|
29349
|
+
var CleanOptionsSchema = OpsOptionsSchema.extend({
|
|
29304
29350
|
force: external_exports.boolean().default(false),
|
|
29305
29351
|
logs: external_exports.boolean().default(false),
|
|
29306
29352
|
pids: external_exports.boolean().default(false),
|
|
@@ -29312,11 +29358,11 @@ var CleanOptionsSchema = BaseOptionsSchema.extend({
|
|
|
29312
29358
|
output: data.output === "table" ? "summary" : data.output
|
|
29313
29359
|
}));
|
|
29314
29360
|
function confirm(question) {
|
|
29315
|
-
return new Promise((
|
|
29361
|
+
return new Promise((resolve10) => {
|
|
29316
29362
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
29317
29363
|
rl.question(`${question} [y/N] `, (answer) => {
|
|
29318
29364
|
rl.close();
|
|
29319
|
-
|
|
29365
|
+
resolve10(answer.trim().toLowerCase() === "y");
|
|
29320
29366
|
});
|
|
29321
29367
|
});
|
|
29322
29368
|
}
|
|
@@ -29546,7 +29592,7 @@ ${colors.bright}Semiont clean \u2014 project: ${project.name}${colors.reset}
|
|
|
29546
29592
|
results.duration = Date.now() - startTime;
|
|
29547
29593
|
return results;
|
|
29548
29594
|
}
|
|
29549
|
-
var cleanCommand = new CommandBuilder().name("clean").description("Remove ephemeral files (logs, PID files, generated config, Docker volumes)").schema(CleanOptionsSchema).args(
|
|
29595
|
+
var cleanCommand = new CommandBuilder().name("clean").description("Remove ephemeral files (logs, PID files, generated config, Docker volumes)").schema(CleanOptionsSchema).args(withOpsArgs({
|
|
29550
29596
|
"--force": {
|
|
29551
29597
|
type: "boolean",
|
|
29552
29598
|
description: "Skip confirmation prompts",
|
|
@@ -29646,7 +29692,7 @@ function createNoopGraphDatabase3() {
|
|
|
29646
29692
|
clearDatabase: noop2
|
|
29647
29693
|
};
|
|
29648
29694
|
}
|
|
29649
|
-
var MvOptionsSchema =
|
|
29695
|
+
var MvOptionsSchema = OpsOptionsSchema.extend({
|
|
29650
29696
|
from: external_exports.string().min(1, "Source path is required"),
|
|
29651
29697
|
to: external_exports.string().min(1, "Destination path is required"),
|
|
29652
29698
|
noGit: external_exports.boolean().default(false)
|
|
@@ -29676,10 +29722,10 @@ async function runMv(options) {
|
|
|
29676
29722
|
const stower = new Stower3(kb, eventBus, logger.child({ component: "stower" }));
|
|
29677
29723
|
await stower.initialize();
|
|
29678
29724
|
try {
|
|
29679
|
-
const movedPromise = new Promise((
|
|
29725
|
+
const movedPromise = new Promise((resolve10, reject) => {
|
|
29680
29726
|
const sub = eventBus.get("yield:moved").subscribe(() => {
|
|
29681
29727
|
sub.unsubscribe();
|
|
29682
|
-
|
|
29728
|
+
resolve10();
|
|
29683
29729
|
});
|
|
29684
29730
|
eventBus.get("yield:move-failed").subscribe((e) => {
|
|
29685
29731
|
reject(new Error(e.error?.message ?? "Move failed"));
|
|
@@ -29739,74 +29785,83 @@ init_command_definition();
|
|
|
29739
29785
|
init_base_options_schema();
|
|
29740
29786
|
init_cli_logger();
|
|
29741
29787
|
init_config_loader();
|
|
29742
|
-
|
|
29743
|
-
import * as path43 from "path";
|
|
29788
|
+
import * as path44 from "path";
|
|
29744
29789
|
import { promises as nodeFs } from "fs";
|
|
29745
|
-
import {
|
|
29746
|
-
|
|
29747
|
-
|
|
29748
|
-
import
|
|
29749
|
-
import
|
|
29750
|
-
import
|
|
29751
|
-
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
29759
|
-
|
|
29760
|
-
|
|
29790
|
+
import { resourceId as toResourceId, annotationId as toAnnotationId, EventBus as EventBus4 } from "@semiont/core";
|
|
29791
|
+
|
|
29792
|
+
// src/core/api-client-factory.ts
|
|
29793
|
+
import * as fs51 from "fs";
|
|
29794
|
+
import * as path43 from "path";
|
|
29795
|
+
import * as os5 from "os";
|
|
29796
|
+
import { SemiontApiClient as SemiontApiClient3 } from "@semiont/api-client";
|
|
29797
|
+
import {
|
|
29798
|
+
email as toEmail,
|
|
29799
|
+
accessToken as toAccessToken,
|
|
29800
|
+
baseUrl as toBaseUrl
|
|
29801
|
+
} from "@semiont/core";
|
|
29802
|
+
var TOKEN_CACHE_TTL_MS = 864e5;
|
|
29803
|
+
function authStoreDir() {
|
|
29804
|
+
const xdgState = process.env.XDG_STATE_HOME ?? path43.join(os5.homedir(), ".local", "state");
|
|
29805
|
+
return path43.join(xdgState, "semiont", "auth");
|
|
29806
|
+
}
|
|
29807
|
+
function busSlug(rawUrl) {
|
|
29808
|
+
return rawUrl.replace(/^https?:\/\//, "").replace(/\/+$/, "").replace(/[:/]/g, "-").toLowerCase();
|
|
29809
|
+
}
|
|
29810
|
+
function tokenCachePath(rawBusUrl) {
|
|
29811
|
+
return path43.join(authStoreDir(), `${busSlug(rawBusUrl)}.json`);
|
|
29812
|
+
}
|
|
29813
|
+
function readTokenCache(cachePath) {
|
|
29814
|
+
try {
|
|
29815
|
+
const raw = fs51.readFileSync(cachePath, "utf-8");
|
|
29816
|
+
return JSON.parse(raw);
|
|
29817
|
+
} catch {
|
|
29818
|
+
return null;
|
|
29819
|
+
}
|
|
29761
29820
|
}
|
|
29762
|
-
function
|
|
29763
|
-
|
|
29764
|
-
|
|
29765
|
-
|
|
29766
|
-
|
|
29767
|
-
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
createAnnotation: noop2,
|
|
29779
|
-
getAnnotation: noop2,
|
|
29780
|
-
updateAnnotation: noop2,
|
|
29781
|
-
deleteAnnotation: noop2,
|
|
29782
|
-
listAnnotations: noop2,
|
|
29783
|
-
getHighlights: noop2,
|
|
29784
|
-
resolveReference: noop2,
|
|
29785
|
-
getReferences: noop2,
|
|
29786
|
-
getEntityReferences: noop2,
|
|
29787
|
-
getResourceAnnotations: noop2,
|
|
29788
|
-
getResourceReferencedBy: noop2,
|
|
29789
|
-
getResourceConnections: noop2,
|
|
29790
|
-
findPath: noop2,
|
|
29791
|
-
getEntityTypeStats: noop2,
|
|
29792
|
-
getStats: noop2,
|
|
29793
|
-
batchCreateResources: noop2,
|
|
29794
|
-
createAnnotations: noop2,
|
|
29795
|
-
resolveReferences: noop2,
|
|
29796
|
-
detectAnnotations: noop2,
|
|
29797
|
-
getEntityTypes: noop2,
|
|
29798
|
-
addEntityType: noop2,
|
|
29799
|
-
addEntityTypes: noop2,
|
|
29800
|
-
generateId: () => "noop",
|
|
29801
|
-
clearDatabase: noop2
|
|
29821
|
+
function writeTokenCache(cachePath, cache) {
|
|
29822
|
+
fs51.mkdirSync(path43.dirname(cachePath), { recursive: true, mode: 448 });
|
|
29823
|
+
fs51.writeFileSync(cachePath, JSON.stringify(cache, null, 2), { mode: 384 });
|
|
29824
|
+
}
|
|
29825
|
+
function isTokenValid(cache) {
|
|
29826
|
+
const cachedAt = new Date(cache.cachedAt).getTime();
|
|
29827
|
+
return Date.now() < cachedAt + TOKEN_CACHE_TTL_MS;
|
|
29828
|
+
}
|
|
29829
|
+
async function acquireToken(rawBusUrl, emailStr, passwordStr) {
|
|
29830
|
+
const client = new SemiontApiClient3({ baseUrl: toBaseUrl(rawBusUrl) });
|
|
29831
|
+
const authResult = await client.authenticatePassword(toEmail(emailStr), passwordStr);
|
|
29832
|
+
const cache = {
|
|
29833
|
+
bus: rawBusUrl,
|
|
29834
|
+
email: emailStr,
|
|
29835
|
+
token: authResult.token,
|
|
29836
|
+
cachedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
29802
29837
|
};
|
|
29838
|
+
writeTokenCache(tokenCachePath(rawBusUrl), cache);
|
|
29839
|
+
}
|
|
29840
|
+
function loadCachedClient(rawBusUrl) {
|
|
29841
|
+
const cachePath = tokenCachePath(rawBusUrl);
|
|
29842
|
+
const cached = readTokenCache(cachePath);
|
|
29843
|
+
if (!cached || !isTokenValid(cached)) {
|
|
29844
|
+
throw new Error(
|
|
29845
|
+
`Not logged in to ${rawBusUrl}.
|
|
29846
|
+
Run: semiont login --bus ${rawBusUrl}`
|
|
29847
|
+
);
|
|
29848
|
+
}
|
|
29849
|
+
const client = new SemiontApiClient3({ baseUrl: toBaseUrl(rawBusUrl) });
|
|
29850
|
+
return { client, token: toAccessToken(cached.token) };
|
|
29803
29851
|
}
|
|
29804
|
-
|
|
29805
|
-
const
|
|
29806
|
-
|
|
29852
|
+
function resolveBusUrl(busFlag) {
|
|
29853
|
+
const url = busFlag ?? process.env.SEMIONT_BUS;
|
|
29854
|
+
if (!url) {
|
|
29855
|
+
throw new Error(
|
|
29856
|
+
"Backend URL not configured. Use --bus <url> or set $SEMIONT_BUS.\nRun `semiont login --bus <url>` to authenticate."
|
|
29857
|
+
);
|
|
29858
|
+
}
|
|
29859
|
+
return url;
|
|
29807
29860
|
}
|
|
29861
|
+
|
|
29862
|
+
// src/core/commands/yield.ts
|
|
29808
29863
|
function guessFormat(filePath) {
|
|
29809
|
-
const ext =
|
|
29864
|
+
const ext = path44.extname(filePath).toLowerCase();
|
|
29810
29865
|
const map2 = {
|
|
29811
29866
|
".md": "text/markdown",
|
|
29812
29867
|
".markdown": "text/markdown",
|
|
@@ -29821,428 +29876,1332 @@ function guessFormat(filePath) {
|
|
|
29821
29876
|
};
|
|
29822
29877
|
return map2[ext] ?? "application/octet-stream";
|
|
29823
29878
|
}
|
|
29824
|
-
var YieldOptionsSchema =
|
|
29825
|
-
|
|
29879
|
+
var YieldOptionsSchema = ApiOptionsSchema.extend({
|
|
29880
|
+
// Mode flags
|
|
29881
|
+
upload: external_exports.array(external_exports.string()).default([]),
|
|
29882
|
+
delegate: external_exports.boolean().default(false),
|
|
29883
|
+
// Upload mode options
|
|
29826
29884
|
name: external_exports.string().optional(),
|
|
29827
|
-
|
|
29885
|
+
// Delegate mode required
|
|
29886
|
+
resource: external_exports.string().optional(),
|
|
29887
|
+
annotation: external_exports.string().optional(),
|
|
29888
|
+
storageUri: external_exports.string().optional(),
|
|
29889
|
+
// Delegate mode optional
|
|
29890
|
+
title: external_exports.string().optional(),
|
|
29891
|
+
prompt: external_exports.string().optional(),
|
|
29892
|
+
language: external_exports.string().optional(),
|
|
29893
|
+
temperature: external_exports.coerce.number().min(0).max(1).optional(),
|
|
29894
|
+
maxTokens: external_exports.coerce.number().int().min(100).max(4e3).optional(),
|
|
29895
|
+
contextWindow: external_exports.coerce.number().int().min(100).max(5e3).default(1e3)
|
|
29896
|
+
}).superRefine((val, ctx) => {
|
|
29897
|
+
const hasUpload = val.upload.length > 0;
|
|
29898
|
+
const hasDelegate = val.delegate;
|
|
29899
|
+
if (!hasUpload && !hasDelegate) {
|
|
29900
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "One of --upload <file> or --delegate is required" });
|
|
29901
|
+
}
|
|
29902
|
+
if (hasUpload && hasDelegate) {
|
|
29903
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--upload and --delegate are mutually exclusive" });
|
|
29904
|
+
}
|
|
29905
|
+
if (hasUpload && val.name && val.upload.length > 1) {
|
|
29906
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--name can only be used when uploading a single file" });
|
|
29907
|
+
}
|
|
29908
|
+
if (hasDelegate) {
|
|
29909
|
+
if (!val.resource) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--resource <resourceId> is required with --delegate" });
|
|
29910
|
+
if (!val.annotation) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--annotation <annotationId> is required with --delegate" });
|
|
29911
|
+
if (!val.storageUri) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--storage-uri is required with --delegate" });
|
|
29912
|
+
}
|
|
29828
29913
|
});
|
|
29914
|
+
function waitForYieldFinished(eventBus) {
|
|
29915
|
+
return new Promise((resolve10, reject) => {
|
|
29916
|
+
const doneSub = eventBus.get("yield:finished").subscribe((event) => {
|
|
29917
|
+
doneSub.unsubscribe();
|
|
29918
|
+
failSub.unsubscribe();
|
|
29919
|
+
resolve10({ resourceId: event.resourceId, resourceName: event.resourceName });
|
|
29920
|
+
});
|
|
29921
|
+
const failSub = eventBus.get("yield:failed").subscribe((event) => {
|
|
29922
|
+
doneSub.unsubscribe();
|
|
29923
|
+
failSub.unsubscribe();
|
|
29924
|
+
reject(event.error ?? new Error("Generation failed"));
|
|
29925
|
+
});
|
|
29926
|
+
});
|
|
29927
|
+
}
|
|
29928
|
+
function waitForGatherAnnotationFinished(eventBus, annotationId) {
|
|
29929
|
+
return new Promise((resolve10, reject) => {
|
|
29930
|
+
const doneSub = eventBus.get("gather:annotation-finished").subscribe((event) => {
|
|
29931
|
+
if (event.annotationId !== annotationId) return;
|
|
29932
|
+
doneSub.unsubscribe();
|
|
29933
|
+
failSub.unsubscribe();
|
|
29934
|
+
const context = event.response.context;
|
|
29935
|
+
if (!context) {
|
|
29936
|
+
reject(new Error("No context returned from gatherAnnotation \u2014 cannot generate"));
|
|
29937
|
+
} else {
|
|
29938
|
+
resolve10(context);
|
|
29939
|
+
}
|
|
29940
|
+
});
|
|
29941
|
+
const failSub = eventBus.get("gather:failed").subscribe((event) => {
|
|
29942
|
+
if (event.annotationId !== annotationId) return;
|
|
29943
|
+
doneSub.unsubscribe();
|
|
29944
|
+
failSub.unsubscribe();
|
|
29945
|
+
reject(event.error ?? new Error("Gather annotation failed"));
|
|
29946
|
+
});
|
|
29947
|
+
});
|
|
29948
|
+
}
|
|
29949
|
+
async function runDelegate(client, token, options) {
|
|
29950
|
+
const rawResourceId = options.resource;
|
|
29951
|
+
const rawAnnotationId = options.annotation;
|
|
29952
|
+
const resourceId = toResourceId(rawResourceId);
|
|
29953
|
+
const annotationId = toAnnotationId(rawAnnotationId);
|
|
29954
|
+
const gatherEventBus = new EventBus4();
|
|
29955
|
+
const gatherPromise = waitForGatherAnnotationFinished(gatherEventBus, rawAnnotationId);
|
|
29956
|
+
client.sse.gatherAnnotation(
|
|
29957
|
+
resourceId,
|
|
29958
|
+
annotationId,
|
|
29959
|
+
{ contextWindow: options.contextWindow },
|
|
29960
|
+
{ auth: token, eventBus: gatherEventBus }
|
|
29961
|
+
);
|
|
29962
|
+
const context = await gatherPromise;
|
|
29963
|
+
if (!options.quiet) process.stderr.write(`Generating from annotation ${rawAnnotationId}...
|
|
29964
|
+
`);
|
|
29965
|
+
const eventBus = new EventBus4();
|
|
29966
|
+
const donePromise = waitForYieldFinished(eventBus);
|
|
29967
|
+
client.sse.yieldResource(
|
|
29968
|
+
resourceId,
|
|
29969
|
+
annotationId,
|
|
29970
|
+
{
|
|
29971
|
+
context,
|
|
29972
|
+
storageUri: options.storageUri,
|
|
29973
|
+
...options.title && { title: options.title },
|
|
29974
|
+
...options.prompt && { prompt: options.prompt },
|
|
29975
|
+
...options.language && { language: options.language },
|
|
29976
|
+
...options.temperature !== void 0 && { temperature: options.temperature },
|
|
29977
|
+
...options.maxTokens !== void 0 && { maxTokens: options.maxTokens }
|
|
29978
|
+
},
|
|
29979
|
+
{ auth: token, eventBus }
|
|
29980
|
+
);
|
|
29981
|
+
return await donePromise;
|
|
29982
|
+
}
|
|
29829
29983
|
async function runYield(options) {
|
|
29830
29984
|
const startTime = Date.now();
|
|
29985
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
29986
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
29831
29987
|
const projectRoot = findProjectRoot();
|
|
29832
|
-
|
|
29833
|
-
|
|
29834
|
-
|
|
29835
|
-
|
|
29836
|
-
|
|
29837
|
-
|
|
29838
|
-
|
|
29839
|
-
|
|
29840
|
-
|
|
29841
|
-
|
|
29988
|
+
if (options.delegate) {
|
|
29989
|
+
const { resourceId, resourceName } = await runDelegate(client, token, options);
|
|
29990
|
+
const label = resourceName ?? resourceId ?? options.storageUri;
|
|
29991
|
+
if (!options.quiet) printSuccess(`Yielded: ${options.storageUri} \u2192 ${resourceId ?? "(pending)"}`);
|
|
29992
|
+
process.stdout.write(JSON.stringify({ resourceId, resourceName, storageUri: options.storageUri }));
|
|
29993
|
+
if (!options.quiet) process.stdout.write("\n");
|
|
29994
|
+
return {
|
|
29995
|
+
command: "yield",
|
|
29996
|
+
environment: rawBusUrl,
|
|
29997
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
29998
|
+
duration: Date.now() - startTime,
|
|
29999
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30000
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30001
|
+
results: [{ entity: label, platform: "posix", success: true, metadata: { resourceId, storageUri: options.storageUri }, duration: Date.now() - startTime }]
|
|
30002
|
+
};
|
|
29842
30003
|
}
|
|
29843
|
-
const eventBus = new EventBus4();
|
|
29844
|
-
const eventStore = createEventStore6(project, eventBus, logger);
|
|
29845
|
-
const kb = createKnowledgeBase4(eventStore, project, createNoopGraphDatabase4(), logger);
|
|
29846
|
-
const stower = new Stower4(kb, eventBus, logger.child({ component: "stower" }));
|
|
29847
|
-
await stower.initialize();
|
|
29848
30004
|
let succeeded = 0;
|
|
29849
30005
|
let failed = 0;
|
|
29850
30006
|
const results = [];
|
|
29851
|
-
|
|
29852
|
-
|
|
29853
|
-
|
|
29854
|
-
|
|
29855
|
-
|
|
29856
|
-
|
|
29857
|
-
|
|
29858
|
-
|
|
29859
|
-
|
|
29860
|
-
|
|
29861
|
-
|
|
29862
|
-
const relPath = path43.relative(projectRoot, absPath).replace(/\\/g, "/");
|
|
29863
|
-
const storageUri = `file://${relPath}`;
|
|
29864
|
-
let isTracked = false;
|
|
29865
|
-
let existingResourceId;
|
|
29866
|
-
try {
|
|
29867
|
-
existingResourceId = await resolveStorageUri(kb.projectionsDir, storageUri);
|
|
29868
|
-
isTracked = true;
|
|
29869
|
-
} catch (e) {
|
|
29870
|
-
if (!(e instanceof ResourceNotFoundError)) throw e;
|
|
29871
|
-
}
|
|
29872
|
-
const format = guessFormat(filePath);
|
|
29873
|
-
const contentChecksum = await checksumFile(absPath);
|
|
29874
|
-
const fileStart = Date.now();
|
|
29875
|
-
if (!isTracked) {
|
|
29876
|
-
const name = options.name ?? path43.basename(filePath, path43.extname(filePath));
|
|
29877
|
-
const created = await new Promise((resolve12, reject) => {
|
|
29878
|
-
const sub = eventBus.get("yield:created").subscribe((e) => {
|
|
29879
|
-
sub.unsubscribe();
|
|
29880
|
-
resolve12(e.resourceId);
|
|
29881
|
-
});
|
|
29882
|
-
eventBus.get("yield:create-failed").subscribe((e) => reject(e.error));
|
|
29883
|
-
eventBus.get("yield:create").next({ name, storageUri, contentChecksum, format, userId, noGit: options.noGit });
|
|
29884
|
-
});
|
|
29885
|
-
if (!options.quiet) printSuccess(`Yielded: ${filePath} \u2192 ${created}`);
|
|
29886
|
-
results.push({ entity: filePath, platform: "posix", success: true, metadata: { resourceId: created, storageUri }, duration: Date.now() - fileStart });
|
|
29887
|
-
succeeded++;
|
|
29888
|
-
} else {
|
|
29889
|
-
const updated = await new Promise((resolve12, reject) => {
|
|
29890
|
-
const sub = eventBus.get("yield:updated").subscribe(() => {
|
|
29891
|
-
sub.unsubscribe();
|
|
29892
|
-
resolve12();
|
|
29893
|
-
});
|
|
29894
|
-
eventBus.get("yield:update-failed").subscribe((e) => reject(e.error));
|
|
29895
|
-
eventBus.get("yield:update").next({
|
|
29896
|
-
resourceId: toResourceId(existingResourceId),
|
|
29897
|
-
storageUri,
|
|
29898
|
-
contentChecksum,
|
|
29899
|
-
userId,
|
|
29900
|
-
noGit: options.noGit
|
|
29901
|
-
});
|
|
29902
|
-
});
|
|
29903
|
-
void updated;
|
|
29904
|
-
if (!options.quiet) printSuccess(`Updated: ${filePath} (${existingResourceId})`);
|
|
29905
|
-
results.push({ entity: filePath, platform: "posix", success: true, metadata: { resourceId: existingResourceId, storageUri }, duration: Date.now() - fileStart });
|
|
29906
|
-
succeeded++;
|
|
29907
|
-
}
|
|
30007
|
+
for (const filePath of options.upload) {
|
|
30008
|
+
const absPath = path44.isAbsolute(filePath) ? filePath : path44.resolve(projectRoot, filePath);
|
|
30009
|
+
const fileStart = Date.now();
|
|
30010
|
+
let content;
|
|
30011
|
+
try {
|
|
30012
|
+
content = await nodeFs.readFile(absPath);
|
|
30013
|
+
} catch {
|
|
30014
|
+
if (!options.quiet) printWarning(`File not found: ${filePath}`);
|
|
30015
|
+
results.push({ entity: filePath, platform: "posix", success: false, metadata: { error: "File not found" }, duration: 0 });
|
|
30016
|
+
failed++;
|
|
30017
|
+
continue;
|
|
29908
30018
|
}
|
|
29909
|
-
|
|
29910
|
-
|
|
29911
|
-
|
|
30019
|
+
const relPath = path44.relative(projectRoot, absPath).replace(/\\/g, "/");
|
|
30020
|
+
const storageUri = `file://${relPath}`;
|
|
30021
|
+
const name = options.name ?? path44.basename(filePath, path44.extname(filePath));
|
|
30022
|
+
const format = guessFormat(filePath);
|
|
30023
|
+
const { resourceId } = await client.yieldResource(
|
|
30024
|
+
{ name, file: content, format, storageUri },
|
|
30025
|
+
{ auth: token }
|
|
30026
|
+
);
|
|
30027
|
+
if (!options.quiet) printSuccess(`Yielded: ${filePath} \u2192 ${resourceId}`);
|
|
30028
|
+
results.push({ entity: filePath, platform: "posix", success: true, metadata: { resourceId, storageUri }, duration: Date.now() - fileStart });
|
|
30029
|
+
succeeded++;
|
|
29912
30030
|
}
|
|
29913
|
-
const duration = Date.now() - startTime;
|
|
29914
30031
|
return {
|
|
29915
30032
|
command: "yield",
|
|
29916
|
-
environment,
|
|
30033
|
+
environment: rawBusUrl,
|
|
29917
30034
|
timestamp: /* @__PURE__ */ new Date(),
|
|
29918
|
-
duration,
|
|
29919
|
-
summary: { succeeded, failed, total: options.
|
|
30035
|
+
duration: Date.now() - startTime,
|
|
30036
|
+
summary: { succeeded, failed, total: options.upload.length, warnings: 0 },
|
|
29920
30037
|
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
29921
30038
|
results
|
|
29922
30039
|
};
|
|
29923
30040
|
}
|
|
29924
|
-
var yieldCmd = new CommandBuilder().name("yield").description(
|
|
29925
|
-
"
|
|
29926
|
-
|
|
30041
|
+
var yieldCmd = new CommandBuilder().name("yield").description(
|
|
30042
|
+
"Upload a local file as a resource (--upload), or generate a new resource from an annotation's gathered context (--delegate). Delegate mode outputs JSON { resourceId, resourceName, storageUri } to stdout."
|
|
30043
|
+
).requiresEnvironment(true).requiresServices(true).examples(
|
|
30044
|
+
"semiont yield --upload docs/overview.md",
|
|
30045
|
+
'semiont yield --upload docs/overview.md --name "Overview Document"',
|
|
30046
|
+
"semiont yield --upload docs/a.md --upload docs/b.md --upload docs/c.md",
|
|
30047
|
+
"semiont yield --delegate --resource <resourceId> --annotation <annotationId> --storage-uri file://generated/paris.md",
|
|
30048
|
+
'semiont yield --delegate --resource <resourceId> --annotation <annotationId> --storage-uri file://generated/paris.md --title "Paris" --language en',
|
|
30049
|
+
'semiont yield --delegate --resource <resourceId> --annotation <annotationId> --storage-uri file://generated/paris.md --prompt "Write a brief encyclopedia entry" --temperature 0.3',
|
|
30050
|
+
`NEW_ID=$(semiont yield --delegate --resource <resourceId> --annotation <annotationId> --storage-uri file://generated/loc.md --quiet | jq -r '.resourceId') && semiont bind <resourceId> <annotationId> "$NEW_ID"`
|
|
29927
30051
|
).args({
|
|
29928
|
-
|
|
29929
|
-
"--
|
|
29930
|
-
type: "
|
|
29931
|
-
description: "
|
|
30052
|
+
...withApiArgs({
|
|
30053
|
+
"--upload": {
|
|
30054
|
+
type: "array",
|
|
30055
|
+
description: "Upload mode: one or more local file paths to register as resources (repeatable)"
|
|
29932
30056
|
},
|
|
29933
|
-
"--
|
|
30057
|
+
"--delegate": {
|
|
29934
30058
|
type: "boolean",
|
|
29935
|
-
description: "
|
|
30059
|
+
description: "Delegate mode: generate a new resource from an annotation's gathered context",
|
|
29936
30060
|
default: false
|
|
30061
|
+
},
|
|
30062
|
+
"--name": {
|
|
30063
|
+
type: "string",
|
|
30064
|
+
description: "Upload mode: resource name (single file only)"
|
|
30065
|
+
},
|
|
30066
|
+
"--resource": {
|
|
30067
|
+
type: "string",
|
|
30068
|
+
description: "Delegate mode: source resourceId"
|
|
30069
|
+
},
|
|
30070
|
+
"--annotation": {
|
|
30071
|
+
type: "string",
|
|
30072
|
+
description: "Delegate mode: source annotationId"
|
|
30073
|
+
},
|
|
30074
|
+
"--storage-uri": {
|
|
30075
|
+
type: "string",
|
|
30076
|
+
description: "Delegate mode: file://-relative URI where the generated resource will be saved"
|
|
30077
|
+
},
|
|
30078
|
+
"--title": {
|
|
30079
|
+
type: "string",
|
|
30080
|
+
description: "Delegate mode: custom title for the generated resource"
|
|
30081
|
+
},
|
|
30082
|
+
"--prompt": {
|
|
30083
|
+
type: "string",
|
|
30084
|
+
description: "Delegate mode: custom prompt to guide content generation"
|
|
30085
|
+
},
|
|
30086
|
+
"--language": {
|
|
30087
|
+
type: "string",
|
|
30088
|
+
description: "Delegate mode: BCP 47 language tag for generated content (e.g. en, fr, ja)"
|
|
30089
|
+
},
|
|
30090
|
+
"--temperature": {
|
|
30091
|
+
type: "string",
|
|
30092
|
+
description: "Delegate mode: inference temperature 0.0\u20131.0 (0 = focused, 1 = creative)"
|
|
30093
|
+
},
|
|
30094
|
+
"--max-tokens": {
|
|
30095
|
+
type: "string",
|
|
30096
|
+
description: "Delegate mode: maximum tokens to generate (100\u20134000)"
|
|
30097
|
+
},
|
|
30098
|
+
"--context-window": {
|
|
30099
|
+
type: "string",
|
|
30100
|
+
description: "Delegate mode: characters of annotation context to gather (100\u20135000, default: 1000)"
|
|
29937
30101
|
}
|
|
29938
|
-
},
|
|
29939
|
-
aliases: {
|
|
30102
|
+
}, {
|
|
29940
30103
|
"-n": "--name"
|
|
29941
|
-
},
|
|
29942
|
-
|
|
30104
|
+
}),
|
|
30105
|
+
aliases: {}
|
|
29943
30106
|
}).schema(YieldOptionsSchema).handler(runYield).build();
|
|
29944
30107
|
|
|
29945
|
-
// src/core/commands/
|
|
30108
|
+
// src/core/commands/mark.ts
|
|
29946
30109
|
init_zod();
|
|
29947
30110
|
init_command_definition();
|
|
29948
30111
|
init_base_options_schema();
|
|
29949
30112
|
init_cli_logger();
|
|
29950
|
-
|
|
29951
|
-
|
|
29952
|
-
|
|
29953
|
-
|
|
29954
|
-
|
|
29955
|
-
|
|
29956
|
-
|
|
29957
|
-
|
|
29958
|
-
|
|
29959
|
-
|
|
29960
|
-
|
|
29961
|
-
|
|
29962
|
-
|
|
29963
|
-
|
|
29964
|
-
|
|
29965
|
-
|
|
29966
|
-
|
|
29967
|
-
|
|
30113
|
+
import { resourceId as toResourceId2, EventBus as EventBus5 } from "@semiont/core";
|
|
30114
|
+
var MOTIVATIONS = ["highlighting", "commenting", "tagging", "assessing", "linking"];
|
|
30115
|
+
var CONTEXT_WINDOW = 32;
|
|
30116
|
+
var MarkOptionsSchema = ApiOptionsSchema.extend({
|
|
30117
|
+
resourceIdArr: external_exports.array(external_exports.string()).min(1, "resourceId is required").max(1, "Only one resourceId allowed"),
|
|
30118
|
+
motivation: external_exports.enum(MOTIVATIONS),
|
|
30119
|
+
// ── Mode switch ──────────────────────────────────────────────────────
|
|
30120
|
+
delegate: external_exports.boolean().default(false),
|
|
30121
|
+
// ── Manual mode ──────────────────────────────────────────────────────
|
|
30122
|
+
// TextQuoteSelector
|
|
30123
|
+
quote: external_exports.string().optional(),
|
|
30124
|
+
prefix: external_exports.string().optional(),
|
|
30125
|
+
suffix: external_exports.string().optional(),
|
|
30126
|
+
// TextPositionSelector
|
|
30127
|
+
start: external_exports.coerce.number().int().nonnegative().optional(),
|
|
30128
|
+
end: external_exports.coerce.number().int().nonnegative().optional(),
|
|
30129
|
+
// SvgSelector
|
|
30130
|
+
svg: external_exports.string().optional(),
|
|
30131
|
+
// FragmentSelector
|
|
30132
|
+
fragment: external_exports.string().optional(),
|
|
30133
|
+
fragmentConformsTo: external_exports.string().optional(),
|
|
30134
|
+
// Content fetching
|
|
30135
|
+
fetchContent: external_exports.boolean().default(false),
|
|
30136
|
+
// Body
|
|
30137
|
+
bodyText: external_exports.string().optional(),
|
|
30138
|
+
bodyFormat: external_exports.string().optional(),
|
|
30139
|
+
bodyLanguage: external_exports.string().optional(),
|
|
30140
|
+
bodyPurpose: external_exports.string().optional(),
|
|
30141
|
+
link: external_exports.array(external_exports.string()).optional(),
|
|
30142
|
+
// ── Delegate mode: shared ──────────────────────────────────────────────
|
|
30143
|
+
instructions: external_exports.string().optional(),
|
|
30144
|
+
density: external_exports.coerce.number().int().optional(),
|
|
30145
|
+
tone: external_exports.string().optional(),
|
|
30146
|
+
// ── Delegate mode: linking ─────────────────────────────────────────────
|
|
30147
|
+
entityType: external_exports.array(external_exports.string()).default([]),
|
|
30148
|
+
includeDescriptive: external_exports.boolean().default(false),
|
|
30149
|
+
// ── Delegate mode: tagging ─────────────────────────────────────────────
|
|
30150
|
+
schemaId: external_exports.string().optional(),
|
|
30151
|
+
category: external_exports.array(external_exports.string()).default([])
|
|
30152
|
+
}).superRefine((val, ctx) => {
|
|
30153
|
+
if (val.delegate) {
|
|
30154
|
+
const manualFlags = ["quote", "start", "end", "svg", "fragment", "fetchContent", "bodyText", "link"];
|
|
30155
|
+
for (const f of manualFlags) {
|
|
30156
|
+
const v = val[f];
|
|
30157
|
+
if (v !== void 0 && v !== false && !(Array.isArray(v) && v.length === 0)) {
|
|
30158
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: `--${f.replace(/([A-Z])/g, "-$1").toLowerCase()} cannot be used with --delegate` });
|
|
30159
|
+
}
|
|
30160
|
+
}
|
|
30161
|
+
if (val.motivation === "linking" && val.entityType.length === 0) {
|
|
30162
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--entity-type is required for --delegate --motivation linking" });
|
|
30163
|
+
}
|
|
30164
|
+
if (val.motivation === "tagging") {
|
|
30165
|
+
if (!val.schemaId) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--schema-id is required for --delegate --motivation tagging" });
|
|
30166
|
+
if (val.category.length === 0) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "--category is required for --delegate --motivation tagging" });
|
|
30167
|
+
}
|
|
30168
|
+
}
|
|
30169
|
+
});
|
|
30170
|
+
async function fetchResourceText(client, resourceId, token) {
|
|
30171
|
+
const { data } = await client.getResourceRepresentation(resourceId, { accept: "text/plain", auth: token });
|
|
30172
|
+
return new TextDecoder().decode(data);
|
|
30173
|
+
}
|
|
30174
|
+
function buildTextSelector(options, content) {
|
|
30175
|
+
let exact = options.quote;
|
|
30176
|
+
let start2 = options.start;
|
|
30177
|
+
let end = options.end;
|
|
30178
|
+
if (content !== void 0) {
|
|
30179
|
+
if (exact !== void 0 && (start2 === void 0 || end === void 0)) {
|
|
30180
|
+
const idx = content.indexOf(exact);
|
|
30181
|
+
if (idx === -1) throw new Error(`--quote text not found in resource content: "${exact}"`);
|
|
30182
|
+
start2 = idx;
|
|
30183
|
+
end = idx + exact.length;
|
|
30184
|
+
} else if (start2 !== void 0 && end !== void 0 && exact === void 0) {
|
|
30185
|
+
exact = content.slice(start2, end);
|
|
30186
|
+
if (!exact) throw new Error(`--start/--end range [${start2}, ${end}) is empty or out of bounds`);
|
|
30187
|
+
}
|
|
30188
|
+
}
|
|
30189
|
+
const selectors = [];
|
|
30190
|
+
if (start2 !== void 0 && end !== void 0) {
|
|
30191
|
+
selectors.push({ type: "TextPositionSelector", start: start2, end });
|
|
30192
|
+
}
|
|
30193
|
+
if (exact !== void 0) {
|
|
30194
|
+
const q = { type: "TextQuoteSelector", exact };
|
|
30195
|
+
if (options.prefix !== void 0) {
|
|
30196
|
+
q.prefix = options.prefix;
|
|
30197
|
+
} else if (content !== void 0 && start2 !== void 0) {
|
|
30198
|
+
q.prefix = content.slice(Math.max(0, start2 - CONTEXT_WINDOW), start2);
|
|
30199
|
+
}
|
|
30200
|
+
if (options.suffix !== void 0) {
|
|
30201
|
+
q.suffix = options.suffix;
|
|
30202
|
+
} else if (content !== void 0 && end !== void 0) {
|
|
30203
|
+
q.suffix = content.slice(end, end + CONTEXT_WINDOW);
|
|
30204
|
+
}
|
|
30205
|
+
selectors.push(q);
|
|
30206
|
+
}
|
|
30207
|
+
return selectors;
|
|
30208
|
+
}
|
|
30209
|
+
async function buildSelector(options, client, resourceId, token) {
|
|
30210
|
+
const hasText = options.quote !== void 0 || options.start !== void 0 && options.end !== void 0;
|
|
30211
|
+
const hasSvg = options.svg !== void 0;
|
|
30212
|
+
const hasFragment = options.fragment !== void 0;
|
|
30213
|
+
const selectorTypes = [hasText, hasSvg, hasFragment].filter(Boolean).length;
|
|
30214
|
+
if (selectorTypes > 1) {
|
|
30215
|
+
throw new Error("Selector flags are mutually exclusive: use text (--quote/--start/--end), --svg, or --fragment, not a combination.");
|
|
30216
|
+
}
|
|
30217
|
+
if (hasSvg) {
|
|
30218
|
+
return { type: "SvgSelector", value: options.svg };
|
|
30219
|
+
}
|
|
30220
|
+
if (hasFragment) {
|
|
30221
|
+
const f = { type: "FragmentSelector", value: options.fragment };
|
|
30222
|
+
if (options.fragmentConformsTo) f.conformsTo = options.fragmentConformsTo;
|
|
30223
|
+
return f;
|
|
30224
|
+
}
|
|
30225
|
+
if (!hasText) return void 0;
|
|
30226
|
+
const content = options.fetchContent ? await fetchResourceText(client, resourceId, token) : void 0;
|
|
30227
|
+
const selectors = buildTextSelector(options, content);
|
|
30228
|
+
if (selectors.length === 0) return void 0;
|
|
30229
|
+
if (selectors.length === 1) return selectors[0];
|
|
30230
|
+
return selectors;
|
|
30231
|
+
}
|
|
30232
|
+
function buildBody(options) {
|
|
30233
|
+
const items = [];
|
|
30234
|
+
if (options.bodyText !== void 0) {
|
|
30235
|
+
const b = { type: "TextualBody", value: options.bodyText };
|
|
30236
|
+
if (options.bodyFormat) b.format = options.bodyFormat;
|
|
30237
|
+
if (options.bodyLanguage) b.language = options.bodyLanguage;
|
|
30238
|
+
b.purpose = options.bodyPurpose ?? options.motivation;
|
|
30239
|
+
items.push(b);
|
|
30240
|
+
}
|
|
30241
|
+
for (const source of options.link ?? []) {
|
|
30242
|
+
items.push({ type: "SpecificResource", source, purpose: "linking" });
|
|
30243
|
+
}
|
|
30244
|
+
if (items.length === 0) return [];
|
|
30245
|
+
if (items.length === 1) return items[0];
|
|
30246
|
+
return items;
|
|
30247
|
+
}
|
|
30248
|
+
function waitForAssistFinished(eventBus) {
|
|
30249
|
+
return new Promise((resolve10, reject) => {
|
|
30250
|
+
const doneSub = eventBus.get("mark:assist-finished").subscribe((event) => {
|
|
30251
|
+
doneSub.unsubscribe();
|
|
30252
|
+
failSub.unsubscribe();
|
|
30253
|
+
resolve10({
|
|
30254
|
+
motivation: event.motivation,
|
|
30255
|
+
resourceId: event.resourceId,
|
|
30256
|
+
createdCount: event.progress?.createdCount
|
|
30257
|
+
});
|
|
30258
|
+
});
|
|
30259
|
+
const failSub = eventBus.get("mark:assist-failed").subscribe((event) => {
|
|
30260
|
+
doneSub.unsubscribe();
|
|
30261
|
+
failSub.unsubscribe();
|
|
30262
|
+
reject(new Error(event.payload?.message ?? "Annotation failed"));
|
|
30263
|
+
});
|
|
30264
|
+
});
|
|
29968
30265
|
}
|
|
29969
|
-
function
|
|
29970
|
-
const
|
|
29971
|
-
|
|
30266
|
+
async function runDelegate2(client, token, options) {
|
|
30267
|
+
const rawResourceId = options.resourceIdArr[0];
|
|
30268
|
+
const resourceId = toResourceId2(rawResourceId);
|
|
30269
|
+
const { motivation, instructions, density, tone, entityType, includeDescriptive, schemaId, category } = options;
|
|
30270
|
+
if (!options.quiet) process.stderr.write(`Annotating ${motivation} on ${rawResourceId}...
|
|
30271
|
+
`);
|
|
30272
|
+
const eventBus = new EventBus5();
|
|
30273
|
+
const donePromise = waitForAssistFinished(eventBus);
|
|
30274
|
+
const auth = token;
|
|
30275
|
+
switch (motivation) {
|
|
30276
|
+
case "highlighting":
|
|
30277
|
+
client.sse.markHighlights(resourceId, { instructions, density }, { auth, eventBus });
|
|
30278
|
+
break;
|
|
30279
|
+
case "assessing":
|
|
30280
|
+
client.sse.markAssessments(resourceId, { instructions, tone, density }, { auth, eventBus });
|
|
30281
|
+
break;
|
|
30282
|
+
case "commenting":
|
|
30283
|
+
client.sse.markComments(resourceId, { instructions, tone, density }, { auth, eventBus });
|
|
30284
|
+
break;
|
|
30285
|
+
case "linking":
|
|
30286
|
+
client.sse.markReferences(resourceId, { entityTypes: entityType, includeDescriptiveReferences: includeDescriptive }, { auth, eventBus });
|
|
30287
|
+
break;
|
|
30288
|
+
case "tagging":
|
|
30289
|
+
client.sse.markTags(resourceId, { schemaId, categories: category }, { auth, eventBus });
|
|
30290
|
+
break;
|
|
30291
|
+
}
|
|
30292
|
+
const result = await donePromise;
|
|
30293
|
+
const createdCount = result.createdCount ?? 0;
|
|
30294
|
+
if (!options.quiet) process.stderr.write(`\u2713 ${createdCount} annotations created
|
|
30295
|
+
`);
|
|
30296
|
+
return { motivation, resourceId: rawResourceId, createdCount };
|
|
30297
|
+
}
|
|
30298
|
+
async function runMark(options) {
|
|
30299
|
+
const startTime = Date.now();
|
|
30300
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
30301
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
30302
|
+
if (options.delegate) {
|
|
30303
|
+
const result = await runDelegate2(client, token, options);
|
|
30304
|
+
process.stdout.write(JSON.stringify(result));
|
|
30305
|
+
if (!options.quiet) process.stdout.write("\n");
|
|
30306
|
+
return {
|
|
30307
|
+
command: "mark",
|
|
30308
|
+
environment: rawBusUrl,
|
|
30309
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
30310
|
+
duration: Date.now() - startTime,
|
|
30311
|
+
summary: { succeeded: result.createdCount, failed: 0, total: result.createdCount, warnings: 0 },
|
|
30312
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30313
|
+
results: [{ entity: result.resourceId, platform: "posix", success: true, metadata: { createdCount: result.createdCount, motivation: result.motivation }, duration: Date.now() - startTime }]
|
|
30314
|
+
};
|
|
30315
|
+
}
|
|
30316
|
+
const rawResourceId = options.resourceIdArr[0];
|
|
30317
|
+
const resourceId = toResourceId2(rawResourceId);
|
|
30318
|
+
const selector = await buildSelector(options, client, resourceId, token);
|
|
30319
|
+
const body = buildBody(options);
|
|
30320
|
+
const target = selector !== void 0 ? { source: rawResourceId, selector } : { source: rawResourceId, selector: void 0 };
|
|
30321
|
+
const request = {
|
|
30322
|
+
motivation: options.motivation,
|
|
30323
|
+
target,
|
|
30324
|
+
body
|
|
29972
30325
|
};
|
|
30326
|
+
const { annotationId } = await client.markAnnotation(resourceId, request, { auth: token });
|
|
30327
|
+
if (!options.quiet) printSuccess(`Marked: ${rawResourceId} \u2192 ${annotationId}`);
|
|
29973
30328
|
return {
|
|
29974
|
-
|
|
30329
|
+
command: "mark",
|
|
30330
|
+
environment: rawBusUrl,
|
|
30331
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
30332
|
+
duration: Date.now() - startTime,
|
|
30333
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30334
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30335
|
+
results: [{ entity: rawResourceId, platform: "posix", success: true, metadata: { annotationId }, duration: Date.now() - startTime }]
|
|
30336
|
+
};
|
|
30337
|
+
}
|
|
30338
|
+
var markCmd = new CommandBuilder().name("mark").description(
|
|
30339
|
+
"Create a W3C annotation on a resource. Manual mode (default): create a single explicitly-specified annotation. Delegate mode (--delegate): AI-assisted bulk annotation via SSE stream. Outputs JSON { motivation, resourceId, createdCount } in delegate mode."
|
|
30340
|
+
).requiresEnvironment(true).requiresServices(true).examples(
|
|
30341
|
+
// Manual mode
|
|
30342
|
+
'semiont mark <resourceId> --motivation highlighting --quote "some text"',
|
|
30343
|
+
'semiont mark <resourceId> --motivation highlighting --quote "some text" --fetch-content',
|
|
30344
|
+
'semiont mark <resourceId> --motivation commenting --quote "some text" --body-text "my comment"',
|
|
30345
|
+
'semiont mark <resourceId> --motivation linking --quote "some text" --link <targetResourceId>',
|
|
30346
|
+
'semiont mark <resourceId> --motivation tagging --quote "Einstein" --body-text "Person"',
|
|
30347
|
+
// Detect mode
|
|
30348
|
+
"semiont mark <resourceId> --delegate --motivation highlighting",
|
|
30349
|
+
'semiont mark <resourceId> --delegate --motivation highlighting --instructions "Focus on key claims" --density 8',
|
|
30350
|
+
"semiont mark <resourceId> --delegate --motivation assessing --tone analytical --density 4",
|
|
30351
|
+
"semiont mark <resourceId> --delegate --motivation commenting --tone scholarly",
|
|
30352
|
+
"semiont mark <resourceId> --delegate --motivation linking --entity-type Location --entity-type Person",
|
|
30353
|
+
"semiont mark <resourceId> --delegate --motivation linking --entity-type Location --include-descriptive",
|
|
30354
|
+
"semiont mark <resourceId> --delegate --motivation tagging --schema-id <schemaId> --category Biology --category Chemistry"
|
|
30355
|
+
).args({
|
|
30356
|
+
...withApiArgs({
|
|
30357
|
+
"--motivation": {
|
|
30358
|
+
type: "string",
|
|
30359
|
+
description: `Annotation motivation: ${MOTIVATIONS.join(", ")}`
|
|
29975
30360
|
},
|
|
29976
|
-
|
|
30361
|
+
// ── Mode switch ───────────────────────────────────────────────────
|
|
30362
|
+
"--delegate": {
|
|
30363
|
+
type: "boolean",
|
|
30364
|
+
description: "Delegate annotation work to AI (request mode); incompatible with manual selector flags",
|
|
30365
|
+
default: false
|
|
29977
30366
|
},
|
|
29978
|
-
|
|
29979
|
-
|
|
29980
|
-
|
|
29981
|
-
|
|
29982
|
-
|
|
29983
|
-
|
|
29984
|
-
|
|
29985
|
-
|
|
29986
|
-
|
|
29987
|
-
|
|
29988
|
-
|
|
29989
|
-
|
|
29990
|
-
|
|
29991
|
-
|
|
29992
|
-
|
|
29993
|
-
|
|
29994
|
-
|
|
29995
|
-
|
|
29996
|
-
|
|
29997
|
-
|
|
29998
|
-
|
|
29999
|
-
|
|
30000
|
-
|
|
30001
|
-
|
|
30002
|
-
|
|
30003
|
-
|
|
30004
|
-
|
|
30005
|
-
|
|
30006
|
-
|
|
30007
|
-
|
|
30008
|
-
|
|
30009
|
-
|
|
30010
|
-
|
|
30011
|
-
|
|
30012
|
-
|
|
30013
|
-
|
|
30014
|
-
|
|
30367
|
+
// ── Manual mode options ───────────────────────────────────────────
|
|
30368
|
+
"--quote": {
|
|
30369
|
+
type: "string",
|
|
30370
|
+
description: "Manual: TextQuoteSelector exact text to select"
|
|
30371
|
+
},
|
|
30372
|
+
"--prefix": {
|
|
30373
|
+
type: "string",
|
|
30374
|
+
description: "Manual: TextQuoteSelector context before the quote (auto-derived with --fetch-content)"
|
|
30375
|
+
},
|
|
30376
|
+
"--suffix": {
|
|
30377
|
+
type: "string",
|
|
30378
|
+
description: "Manual: TextQuoteSelector context after the quote (auto-derived with --fetch-content)"
|
|
30379
|
+
},
|
|
30380
|
+
"--start": {
|
|
30381
|
+
type: "string",
|
|
30382
|
+
description: "Manual: TextPositionSelector start character offset"
|
|
30383
|
+
},
|
|
30384
|
+
"--end": {
|
|
30385
|
+
type: "string",
|
|
30386
|
+
description: "Manual: TextPositionSelector end character offset"
|
|
30387
|
+
},
|
|
30388
|
+
"--fetch-content": {
|
|
30389
|
+
type: "boolean",
|
|
30390
|
+
description: "Manual: fetch resource text to auto-complete dual selector",
|
|
30391
|
+
default: false
|
|
30392
|
+
},
|
|
30393
|
+
"--svg": {
|
|
30394
|
+
type: "string",
|
|
30395
|
+
description: "Manual: SvgSelector SVG markup defining a region (for images)"
|
|
30396
|
+
},
|
|
30397
|
+
"--fragment": {
|
|
30398
|
+
type: "string",
|
|
30399
|
+
description: "Manual: FragmentSelector media fragment value"
|
|
30400
|
+
},
|
|
30401
|
+
"--fragment-conforms-to": {
|
|
30402
|
+
type: "string",
|
|
30403
|
+
description: "Manual: FragmentSelector conformance URI"
|
|
30404
|
+
},
|
|
30405
|
+
"--body-text": {
|
|
30406
|
+
type: "string",
|
|
30407
|
+
description: "Manual: TextualBody text content"
|
|
30408
|
+
},
|
|
30409
|
+
"--body-format": {
|
|
30410
|
+
type: "string",
|
|
30411
|
+
description: "Manual: TextualBody MIME type (default: text/plain)"
|
|
30412
|
+
},
|
|
30413
|
+
"--body-language": {
|
|
30414
|
+
type: "string",
|
|
30415
|
+
description: "Manual: TextualBody BCP 47 language tag"
|
|
30416
|
+
},
|
|
30417
|
+
"--body-purpose": {
|
|
30418
|
+
type: "string",
|
|
30419
|
+
description: "Manual: TextualBody purpose (defaults to motivation)"
|
|
30420
|
+
},
|
|
30421
|
+
"--link": {
|
|
30422
|
+
type: "array",
|
|
30423
|
+
description: "Manual: SpecificResource body target resourceId to link to (repeatable)"
|
|
30424
|
+
},
|
|
30425
|
+
// ── Delegate mode: shared ───────────────────────────────────────────
|
|
30426
|
+
"--instructions": {
|
|
30427
|
+
type: "string",
|
|
30428
|
+
description: "Delegate: free-text instructions for the AI (highlighting, assessing, commenting)"
|
|
30429
|
+
},
|
|
30430
|
+
"--density": {
|
|
30431
|
+
type: "string",
|
|
30432
|
+
description: "Delegate: annotations per 2000 words (highlighting: 1\u201315; assessing: 1\u201310; commenting: 2\u201312)"
|
|
30433
|
+
},
|
|
30434
|
+
"--tone": {
|
|
30435
|
+
type: "string",
|
|
30436
|
+
description: "Delegate: tone for assessing (analytical|critical|balanced|constructive) or commenting (scholarly|explanatory|conversational|technical)"
|
|
30437
|
+
},
|
|
30438
|
+
// ── Delegate mode: linking ──────────────────────────────────────────
|
|
30439
|
+
"--entity-type": {
|
|
30440
|
+
type: "array",
|
|
30441
|
+
description: "Delegate linking: entity type to detect (repeatable; at least one required)"
|
|
30442
|
+
},
|
|
30443
|
+
"--include-descriptive": {
|
|
30444
|
+
type: "boolean",
|
|
30445
|
+
description: "Delegate linking: also detect descriptive/prose references",
|
|
30446
|
+
default: false
|
|
30447
|
+
},
|
|
30448
|
+
// ── Delegate mode: tagging ──────────────────────────────────────────
|
|
30449
|
+
"--schema-id": {
|
|
30450
|
+
type: "string",
|
|
30451
|
+
description: "Delegate tagging: tag schema ID (required)"
|
|
30452
|
+
},
|
|
30453
|
+
"--category": {
|
|
30454
|
+
type: "array",
|
|
30455
|
+
description: "Delegate tagging: category within the schema (repeatable; at least one required)"
|
|
30456
|
+
}
|
|
30457
|
+
}, {
|
|
30458
|
+
"-m": "--motivation"
|
|
30459
|
+
}),
|
|
30460
|
+
restAs: "resourceIdArr",
|
|
30461
|
+
aliases: {}
|
|
30462
|
+
}).schema(MarkOptionsSchema).handler(runMark).build();
|
|
30463
|
+
|
|
30464
|
+
// src/core/commands/gather.ts
|
|
30465
|
+
init_zod();
|
|
30466
|
+
init_command_definition();
|
|
30467
|
+
init_base_options_schema();
|
|
30468
|
+
import { resourceId as toResourceId3, annotationId as toAnnotationId2, EventBus as EventBus6 } from "@semiont/core";
|
|
30469
|
+
var GatherOptionsSchema = ApiOptionsSchema.extend({
|
|
30470
|
+
args: external_exports.array(external_exports.string()).min(2, "Usage: semiont gather resource <resourceId> | gather annotation <resourceId> <annotationId>"),
|
|
30471
|
+
// resource options
|
|
30472
|
+
depth: external_exports.coerce.number().int().min(1).max(3).default(2),
|
|
30473
|
+
maxResources: external_exports.coerce.number().int().min(1).max(20).default(10),
|
|
30474
|
+
noContent: external_exports.boolean().default(false),
|
|
30475
|
+
summary: external_exports.boolean().default(false),
|
|
30476
|
+
// annotation options
|
|
30477
|
+
contextWindow: external_exports.coerce.number().int().min(100).max(5e3).default(1e3)
|
|
30015
30478
|
});
|
|
30016
|
-
|
|
30479
|
+
function waitForGatherResourceFinished(eventBus) {
|
|
30480
|
+
return new Promise((resolve10, reject) => {
|
|
30481
|
+
const doneSub = eventBus.get("gather:finished").subscribe((event) => {
|
|
30482
|
+
doneSub.unsubscribe();
|
|
30483
|
+
failSub.unsubscribe();
|
|
30484
|
+
resolve10(event.context);
|
|
30485
|
+
});
|
|
30486
|
+
const failSub = eventBus.get("gather:failed").subscribe((event) => {
|
|
30487
|
+
doneSub.unsubscribe();
|
|
30488
|
+
failSub.unsubscribe();
|
|
30489
|
+
reject(event.error ?? new Error("Gather resource failed"));
|
|
30490
|
+
});
|
|
30491
|
+
});
|
|
30492
|
+
}
|
|
30493
|
+
function waitForGatherAnnotationFinished2(eventBus) {
|
|
30494
|
+
return new Promise((resolve10, reject) => {
|
|
30495
|
+
const doneSub = eventBus.get("gather:annotation-finished").subscribe((event) => {
|
|
30496
|
+
doneSub.unsubscribe();
|
|
30497
|
+
failSub.unsubscribe();
|
|
30498
|
+
resolve10(event.response);
|
|
30499
|
+
});
|
|
30500
|
+
const failSub = eventBus.get("gather:failed").subscribe((event) => {
|
|
30501
|
+
doneSub.unsubscribe();
|
|
30502
|
+
failSub.unsubscribe();
|
|
30503
|
+
reject(event.error ?? new Error("Gather annotation failed"));
|
|
30504
|
+
});
|
|
30505
|
+
});
|
|
30506
|
+
}
|
|
30507
|
+
async function runGather(options) {
|
|
30017
30508
|
const startTime = Date.now();
|
|
30018
|
-
const
|
|
30019
|
-
const
|
|
30020
|
-
const
|
|
30021
|
-
|
|
30022
|
-
|
|
30023
|
-
|
|
30024
|
-
const
|
|
30025
|
-
|
|
30026
|
-
|
|
30027
|
-
|
|
30028
|
-
|
|
30029
|
-
|
|
30030
|
-
|
|
30031
|
-
|
|
30032
|
-
|
|
30033
|
-
|
|
30034
|
-
|
|
30035
|
-
|
|
30036
|
-
|
|
30037
|
-
|
|
30038
|
-
|
|
30039
|
-
|
|
30040
|
-
|
|
30041
|
-
|
|
30042
|
-
|
|
30043
|
-
|
|
30044
|
-
|
|
30045
|
-
|
|
30046
|
-
|
|
30047
|
-
|
|
30048
|
-
|
|
30049
|
-
|
|
30050
|
-
|
|
30051
|
-
|
|
30052
|
-
|
|
30053
|
-
|
|
30054
|
-
userId,
|
|
30055
|
-
resourceId,
|
|
30056
|
-
storageUri,
|
|
30057
|
-
keepFile: options.keepFile,
|
|
30058
|
-
noGit: options.noGit
|
|
30059
|
-
});
|
|
30060
|
-
await new Promise((resolve12) => setTimeout(resolve12, 200));
|
|
30061
|
-
if (!options.quiet) printSuccess(`Archived: ${filePath}`);
|
|
30062
|
-
results.push({ entity: filePath, platform: "posix", success: true, metadata: { resourceId, storageUri }, duration: Date.now() - fileStart });
|
|
30063
|
-
succeeded++;
|
|
30064
|
-
}
|
|
30065
|
-
} finally {
|
|
30066
|
-
await stower.stop();
|
|
30067
|
-
eventBus.destroy();
|
|
30509
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
30510
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
30511
|
+
const [subcommand, rawResourceId, rawAnnotationId] = options.args;
|
|
30512
|
+
let result;
|
|
30513
|
+
if (subcommand === "resource") {
|
|
30514
|
+
const id = toResourceId3(rawResourceId);
|
|
30515
|
+
const eventBus = new EventBus6();
|
|
30516
|
+
const donePromise = waitForGatherResourceFinished(eventBus);
|
|
30517
|
+
client.sse.gatherResource(
|
|
30518
|
+
id,
|
|
30519
|
+
{
|
|
30520
|
+
depth: options.depth,
|
|
30521
|
+
maxResources: options.maxResources,
|
|
30522
|
+
includeContent: !options.noContent,
|
|
30523
|
+
includeSummary: options.summary
|
|
30524
|
+
},
|
|
30525
|
+
{ auth: token, eventBus }
|
|
30526
|
+
);
|
|
30527
|
+
result = await donePromise;
|
|
30528
|
+
} else if (subcommand === "annotation") {
|
|
30529
|
+
if (!rawAnnotationId) {
|
|
30530
|
+
throw new Error("Usage: semiont gather annotation <resourceId> <annotationId>");
|
|
30531
|
+
}
|
|
30532
|
+
const resourceId = toResourceId3(rawResourceId);
|
|
30533
|
+
const annotationId = toAnnotationId2(rawAnnotationId);
|
|
30534
|
+
const eventBus = new EventBus6();
|
|
30535
|
+
const donePromise = waitForGatherAnnotationFinished2(eventBus);
|
|
30536
|
+
client.sse.gatherAnnotation(
|
|
30537
|
+
resourceId,
|
|
30538
|
+
annotationId,
|
|
30539
|
+
{ contextWindow: options.contextWindow },
|
|
30540
|
+
{ auth: token, eventBus }
|
|
30541
|
+
);
|
|
30542
|
+
result = await donePromise;
|
|
30543
|
+
} else {
|
|
30544
|
+
throw new Error(`Unknown subcommand: ${subcommand}. Use 'resource' or 'annotation'.`);
|
|
30068
30545
|
}
|
|
30069
|
-
|
|
30546
|
+
process.stdout.write(JSON.stringify(result, null, 2));
|
|
30547
|
+
if (!options.quiet) process.stdout.write("\n");
|
|
30070
30548
|
return {
|
|
30071
|
-
command: "
|
|
30072
|
-
environment,
|
|
30549
|
+
command: "gather",
|
|
30550
|
+
environment: rawBusUrl,
|
|
30073
30551
|
timestamp: /* @__PURE__ */ new Date(),
|
|
30074
|
-
duration,
|
|
30075
|
-
summary: { succeeded, failed, total:
|
|
30552
|
+
duration: Date.now() - startTime,
|
|
30553
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30076
30554
|
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30077
|
-
results
|
|
30555
|
+
results: [{ entity: rawResourceId, platform: "posix", success: true, duration: Date.now() - startTime }]
|
|
30078
30556
|
};
|
|
30079
30557
|
}
|
|
30080
|
-
var
|
|
30081
|
-
"semiont
|
|
30082
|
-
"semiont
|
|
30558
|
+
var gatherCmd = new CommandBuilder().name("gather").description("Fetch LLM-optimized context for a resource or annotation. Outputs JSON to stdout: ResourceLLMContextResponse (resource) or AnnotationLLMContextResponse containing GatheredContext (annotation). Schemas defined in specs/src/components/schemas/.").requiresEnvironment(true).requiresServices(true).examples(
|
|
30559
|
+
"semiont gather resource <resourceId>",
|
|
30560
|
+
"semiont gather resource <resourceId> --depth 3 --max-resources 20",
|
|
30561
|
+
"semiont gather resource <resourceId> --no-content",
|
|
30562
|
+
"semiont gather annotation <resourceId> <annotationId>",
|
|
30563
|
+
"semiont gather annotation <resourceId> <annotationId> --context-window 200",
|
|
30564
|
+
"semiont gather resource <resourceId> | jq '.mainResource.name'",
|
|
30565
|
+
"semiont gather annotation <resourceId> <annotationId> | jq '.context.sourceContext.selected'"
|
|
30083
30566
|
).args({
|
|
30084
|
-
|
|
30085
|
-
"--
|
|
30567
|
+
...withApiArgs({
|
|
30568
|
+
"--depth": {
|
|
30569
|
+
type: "string",
|
|
30570
|
+
description: "Graph traversal depth: 1\u20133 (default: 2)"
|
|
30571
|
+
},
|
|
30572
|
+
"--max-resources": {
|
|
30573
|
+
type: "string",
|
|
30574
|
+
description: "Max related resources to include: 1\u201320 (default: 10)"
|
|
30575
|
+
},
|
|
30576
|
+
"--no-content": {
|
|
30086
30577
|
type: "boolean",
|
|
30087
|
-
description: "
|
|
30578
|
+
description: "Exclude full resource content (default: content included)",
|
|
30088
30579
|
default: false
|
|
30089
30580
|
},
|
|
30090
|
-
"--
|
|
30581
|
+
"--summary": {
|
|
30091
30582
|
type: "boolean",
|
|
30092
|
-
description: "
|
|
30583
|
+
description: "Request AI-generated summary (default: false)",
|
|
30093
30584
|
default: false
|
|
30585
|
+
},
|
|
30586
|
+
"--context-window": {
|
|
30587
|
+
type: "string",
|
|
30588
|
+
description: "Characters of surrounding text context: 100\u20135000 (default: 1000)"
|
|
30094
30589
|
}
|
|
30095
|
-
},
|
|
30096
|
-
|
|
30097
|
-
|
|
30098
|
-
}).schema(
|
|
30590
|
+
}, {}),
|
|
30591
|
+
restAs: "args",
|
|
30592
|
+
aliases: {}
|
|
30593
|
+
}).schema(GatherOptionsSchema).handler(runGather).build();
|
|
30099
30594
|
|
|
30100
|
-
// src/core/commands/
|
|
30595
|
+
// src/core/commands/match.ts
|
|
30101
30596
|
init_zod();
|
|
30102
30597
|
init_command_definition();
|
|
30103
30598
|
init_base_options_schema();
|
|
30104
|
-
|
|
30105
|
-
|
|
30106
|
-
|
|
30107
|
-
|
|
30108
|
-
|
|
30109
|
-
|
|
30110
|
-
|
|
30111
|
-
|
|
30112
|
-
|
|
30113
|
-
|
|
30114
|
-
|
|
30115
|
-
|
|
30116
|
-
|
|
30599
|
+
import { resourceId as toResourceId4, annotationId as toAnnotationId3, EventBus as EventBus7 } from "@semiont/core";
|
|
30600
|
+
var MatchOptionsSchema = ApiOptionsSchema.extend({
|
|
30601
|
+
args: external_exports.array(external_exports.string()).min(2, "Usage: semiont match <resourceId> <annotationId>").max(2),
|
|
30602
|
+
contextWindow: external_exports.coerce.number().int().min(100).max(5e3).default(1e3),
|
|
30603
|
+
userHint: external_exports.string().optional(),
|
|
30604
|
+
limit: external_exports.coerce.number().int().min(1).max(20).default(10),
|
|
30605
|
+
noSemantic: external_exports.boolean().default(false)
|
|
30606
|
+
});
|
|
30607
|
+
function waitForSearchResults(eventBus, referenceId) {
|
|
30608
|
+
return new Promise((resolve10, reject) => {
|
|
30609
|
+
const resultSub = eventBus.get("bind:search-results").subscribe((event) => {
|
|
30610
|
+
if (event.referenceId === referenceId) {
|
|
30611
|
+
resultSub.unsubscribe();
|
|
30612
|
+
errorSub.unsubscribe();
|
|
30613
|
+
resolve10(event.results);
|
|
30614
|
+
}
|
|
30615
|
+
});
|
|
30616
|
+
const errorSub = eventBus.get("bind:search-failed").subscribe((event) => {
|
|
30617
|
+
if (event.referenceId === referenceId) {
|
|
30618
|
+
resultSub.unsubscribe();
|
|
30619
|
+
errorSub.unsubscribe();
|
|
30620
|
+
reject(event.error);
|
|
30621
|
+
}
|
|
30622
|
+
});
|
|
30623
|
+
});
|
|
30624
|
+
}
|
|
30625
|
+
async function gatherContext(client, resourceId, annotationId, contextWindow, token) {
|
|
30626
|
+
const eventBus = new EventBus7();
|
|
30627
|
+
const contextPromise = new Promise((resolve10, reject) => {
|
|
30628
|
+
const doneSub = eventBus.get("gather:annotation-finished").subscribe((event) => {
|
|
30629
|
+
if (event.annotationId !== annotationId) return;
|
|
30630
|
+
doneSub.unsubscribe();
|
|
30631
|
+
failSub.unsubscribe();
|
|
30632
|
+
const context = event.response.context;
|
|
30633
|
+
if (!context) {
|
|
30634
|
+
reject(new Error("No context returned from gatherAnnotation"));
|
|
30635
|
+
} else {
|
|
30636
|
+
resolve10(context);
|
|
30637
|
+
}
|
|
30638
|
+
});
|
|
30639
|
+
const failSub = eventBus.get("gather:failed").subscribe((event) => {
|
|
30640
|
+
if (event.annotationId !== annotationId) return;
|
|
30641
|
+
doneSub.unsubscribe();
|
|
30642
|
+
failSub.unsubscribe();
|
|
30643
|
+
reject(event.error ?? new Error("Gather annotation failed"));
|
|
30644
|
+
});
|
|
30645
|
+
});
|
|
30646
|
+
client.sse.gatherAnnotation(
|
|
30647
|
+
resourceId,
|
|
30648
|
+
annotationId,
|
|
30649
|
+
{ contextWindow },
|
|
30650
|
+
{ auth: token, eventBus }
|
|
30651
|
+
);
|
|
30652
|
+
return contextPromise;
|
|
30653
|
+
}
|
|
30654
|
+
async function runMatch(options) {
|
|
30655
|
+
const startTime = Date.now();
|
|
30656
|
+
const [rawResourceId, rawAnnotationId] = options.args;
|
|
30657
|
+
const resourceId = toResourceId4(rawResourceId);
|
|
30658
|
+
const annotationId = toAnnotationId3(rawAnnotationId);
|
|
30659
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
30660
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
30661
|
+
let context = await gatherContext(client, resourceId, annotationId, options.contextWindow, token);
|
|
30662
|
+
if (options.userHint) {
|
|
30663
|
+
context = { ...context, userHint: options.userHint };
|
|
30664
|
+
}
|
|
30665
|
+
const eventBus = new EventBus7();
|
|
30666
|
+
const resultsPromise = waitForSearchResults(eventBus, rawAnnotationId);
|
|
30667
|
+
client.sse.bindSearch(
|
|
30668
|
+
resourceId,
|
|
30669
|
+
{
|
|
30670
|
+
referenceId: rawAnnotationId,
|
|
30671
|
+
context,
|
|
30672
|
+
limit: options.limit,
|
|
30673
|
+
useSemanticScoring: !options.noSemantic
|
|
30117
30674
|
},
|
|
30118
|
-
|
|
30119
|
-
|
|
30120
|
-
|
|
30121
|
-
|
|
30675
|
+
{ auth: token, eventBus }
|
|
30676
|
+
);
|
|
30677
|
+
const results = await resultsPromise;
|
|
30678
|
+
process.stdout.write(JSON.stringify(results, null, 2));
|
|
30679
|
+
if (!options.quiet) process.stdout.write("\n");
|
|
30680
|
+
return {
|
|
30681
|
+
command: "match",
|
|
30682
|
+
environment: rawBusUrl,
|
|
30683
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
30684
|
+
duration: Date.now() - startTime,
|
|
30685
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30686
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30687
|
+
results: [{ entity: rawAnnotationId, platform: "posix", success: true, metadata: { resultCount: results.length }, duration: Date.now() - startTime }]
|
|
30122
30688
|
};
|
|
30123
30689
|
}
|
|
30124
|
-
|
|
30125
|
-
|
|
30126
|
-
|
|
30690
|
+
var matchCmd = new CommandBuilder().name("match").description("Search for binding candidates for an annotation. Outputs JSON array of ResourceDescriptor & { score?, matchReason? } to stdout. Uses the same flow as the Search button in the Gather Context modal.").requiresEnvironment(true).requiresServices(true).examples(
|
|
30691
|
+
"semiont match <resourceId> <annotationId>",
|
|
30692
|
+
'semiont match <resourceId> <annotationId> --user-hint "look for papers about neural scaling"',
|
|
30693
|
+
"semiont match <resourceId> <annotationId> --limit 5 --no-semantic",
|
|
30694
|
+
"semiont match <resourceId> <annotationId> | jq '.[0].name'",
|
|
30695
|
+
`semiont match <resourceId> <annotationId> | jq -r '.[0]["@id"]' | xargs -I{} semiont mark <resourceId> --motivation linking --link {}`
|
|
30696
|
+
).args({
|
|
30697
|
+
...withApiArgs({
|
|
30698
|
+
"--context-window": {
|
|
30699
|
+
type: "string",
|
|
30700
|
+
description: "Characters of context around annotation: 100\u20135000 (default: 1000)"
|
|
30701
|
+
},
|
|
30702
|
+
"--user-hint": {
|
|
30703
|
+
type: "string",
|
|
30704
|
+
description: "Override/supplement the context text used for matching"
|
|
30705
|
+
},
|
|
30706
|
+
"--limit": {
|
|
30707
|
+
type: "string",
|
|
30708
|
+
description: "Max results to return: 1\u201320 (default: 10)"
|
|
30709
|
+
},
|
|
30710
|
+
"--no-semantic": {
|
|
30711
|
+
type: "boolean",
|
|
30712
|
+
description: "Disable semantic scoring (faster, keyword-only)",
|
|
30713
|
+
default: false
|
|
30714
|
+
}
|
|
30715
|
+
}, {}),
|
|
30716
|
+
restAs: "args",
|
|
30717
|
+
aliases: {}
|
|
30718
|
+
}).schema(MatchOptionsSchema).handler(runMatch).build();
|
|
30719
|
+
|
|
30720
|
+
// src/core/commands/bind.ts
|
|
30721
|
+
init_zod();
|
|
30722
|
+
init_command_definition();
|
|
30723
|
+
init_base_options_schema();
|
|
30724
|
+
init_cli_logger();
|
|
30725
|
+
import { resourceId as toResourceId5, annotationId as toAnnotationId4, EventBus as EventBus8 } from "@semiont/core";
|
|
30726
|
+
var BindOptionsSchema = ApiOptionsSchema.extend({
|
|
30727
|
+
args: external_exports.array(external_exports.string()).min(3, "Usage: semiont bind <resourceId> <annotationId> <targetResourceId>").max(3)
|
|
30728
|
+
});
|
|
30729
|
+
function waitForBindFinished(eventBus) {
|
|
30730
|
+
return new Promise((resolve10, reject) => {
|
|
30731
|
+
const doneSub = eventBus.get("bind:finished").subscribe(() => {
|
|
30732
|
+
doneSub.unsubscribe();
|
|
30733
|
+
failSub.unsubscribe();
|
|
30734
|
+
resolve10();
|
|
30735
|
+
});
|
|
30736
|
+
const failSub = eventBus.get("bind:failed").subscribe((event) => {
|
|
30737
|
+
doneSub.unsubscribe();
|
|
30738
|
+
failSub.unsubscribe();
|
|
30739
|
+
reject(event.error ?? new Error("Bind failed"));
|
|
30740
|
+
});
|
|
30741
|
+
});
|
|
30742
|
+
}
|
|
30743
|
+
async function runBind(options) {
|
|
30744
|
+
const startTime = Date.now();
|
|
30745
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
30746
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
30747
|
+
const [rawResourceId, rawAnnotationId, targetResourceId] = options.args;
|
|
30748
|
+
const resourceId = toResourceId5(rawResourceId);
|
|
30749
|
+
const annotationId = toAnnotationId4(rawAnnotationId);
|
|
30750
|
+
const request = {
|
|
30751
|
+
resourceId: rawResourceId,
|
|
30752
|
+
operations: [{
|
|
30753
|
+
op: "add",
|
|
30754
|
+
item: {
|
|
30755
|
+
type: "SpecificResource",
|
|
30756
|
+
source: targetResourceId,
|
|
30757
|
+
purpose: "linking"
|
|
30758
|
+
}
|
|
30759
|
+
}]
|
|
30127
30760
|
};
|
|
30761
|
+
const eventBus = new EventBus8();
|
|
30762
|
+
const donePromise = waitForBindFinished(eventBus);
|
|
30763
|
+
client.sse.bindAnnotation(resourceId, annotationId, request, { auth: token, eventBus });
|
|
30764
|
+
await donePromise;
|
|
30765
|
+
if (!options.quiet) printSuccess(`Bound: ${rawAnnotationId} \u2192 ${targetResourceId}`);
|
|
30128
30766
|
return {
|
|
30129
|
-
|
|
30767
|
+
command: "bind",
|
|
30768
|
+
environment: rawBusUrl,
|
|
30769
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
30770
|
+
duration: Date.now() - startTime,
|
|
30771
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30772
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30773
|
+
results: [{ entity: rawAnnotationId, platform: "posix", success: true, metadata: { targetResourceId }, duration: Date.now() - startTime }]
|
|
30774
|
+
};
|
|
30775
|
+
}
|
|
30776
|
+
var bindCmd = new CommandBuilder().name("bind").description("Resolve a linking annotation to a target resource. Adds a SpecificResource body item (purpose: linking) via PUT /resources/{resourceId}/annotations/{annotationId}/body.").requiresEnvironment(true).requiresServices(true).examples(
|
|
30777
|
+
"semiont bind <resourceId> <annotationId> <targetResourceId>",
|
|
30778
|
+
`TARGET=$(semiont match <resourceId> <annotationId> --quiet | jq -r '.[0]["@id"]') && semiont bind <resourceId> <annotationId> "$TARGET"`
|
|
30779
|
+
).args({
|
|
30780
|
+
...withApiArgs({}, {}),
|
|
30781
|
+
restAs: "args",
|
|
30782
|
+
aliases: {}
|
|
30783
|
+
}).schema(BindOptionsSchema).handler(runBind).build();
|
|
30784
|
+
|
|
30785
|
+
// src/core/commands/beckon.ts
|
|
30786
|
+
init_zod();
|
|
30787
|
+
init_command_definition();
|
|
30788
|
+
init_base_options_schema();
|
|
30789
|
+
var BeckonOptionsSchema = ApiOptionsSchema.extend({
|
|
30790
|
+
participantArr: external_exports.array(external_exports.string()).min(1, "participantId is required").max(1, "Only one participant per beckon"),
|
|
30791
|
+
resource: external_exports.string({ required_error: "--resource <resourceId> is required" }),
|
|
30792
|
+
annotation: external_exports.string().optional(),
|
|
30793
|
+
message: external_exports.string().max(500).optional()
|
|
30794
|
+
});
|
|
30795
|
+
async function runBeckon(options) {
|
|
30796
|
+
const startTime = Date.now();
|
|
30797
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
30798
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
30799
|
+
const [participantId] = options.participantArr;
|
|
30800
|
+
const result = await client.beckonAttention(
|
|
30801
|
+
participantId,
|
|
30802
|
+
{
|
|
30803
|
+
resourceId: options.resource,
|
|
30804
|
+
...options.annotation ? { annotationId: options.annotation } : {},
|
|
30805
|
+
...options.message ? { message: options.message } : {}
|
|
30130
30806
|
},
|
|
30131
|
-
|
|
30807
|
+
{ auth: token }
|
|
30808
|
+
);
|
|
30809
|
+
if (!options.quiet) {
|
|
30810
|
+
const target = options.annotation ? `${options.resource} (${options.annotation})` : options.resource;
|
|
30811
|
+
process.stderr.write(`Beckoned ${participantId} \u2192 ${target}
|
|
30812
|
+
`);
|
|
30813
|
+
}
|
|
30814
|
+
process.stdout.write(JSON.stringify(result) + "\n");
|
|
30815
|
+
return {
|
|
30816
|
+
command: "beckon",
|
|
30817
|
+
environment: rawBusUrl,
|
|
30818
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
30819
|
+
duration: Date.now() - startTime,
|
|
30820
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30821
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30822
|
+
results: [{ entity: participantId, platform: "posix", success: true, duration: Date.now() - startTime }]
|
|
30823
|
+
};
|
|
30824
|
+
}
|
|
30825
|
+
var beckonCmd = new CommandBuilder().name("beckon").description(
|
|
30826
|
+
"Direct a participant's attention to a resource or annotation. Produces no persistent state \u2014 attention signal only. The participant may be a human username or an agent identifier."
|
|
30827
|
+
).requiresEnvironment(true).requiresServices(true).examples(
|
|
30828
|
+
"semiont beckon alice --resource <resourceId>",
|
|
30829
|
+
"semiont beckon alice --resource <resourceId> --annotation <annotationId>",
|
|
30830
|
+
'semiont beckon alice --resource <resourceId> --annotation <annotationId> --message "Needs manual review"',
|
|
30831
|
+
"semiont beckon my-review-agent --resource <resourceId> --annotation <annotationId>"
|
|
30832
|
+
).args({
|
|
30833
|
+
...withApiArgs({
|
|
30834
|
+
"--resource": {
|
|
30835
|
+
type: "string",
|
|
30836
|
+
description: "Resource to direct attention at (required)",
|
|
30837
|
+
required: true
|
|
30132
30838
|
},
|
|
30133
|
-
|
|
30134
|
-
|
|
30135
|
-
|
|
30136
|
-
|
|
30137
|
-
|
|
30138
|
-
|
|
30139
|
-
|
|
30140
|
-
|
|
30141
|
-
|
|
30142
|
-
|
|
30143
|
-
|
|
30144
|
-
|
|
30145
|
-
|
|
30146
|
-
|
|
30147
|
-
|
|
30148
|
-
|
|
30149
|
-
|
|
30150
|
-
|
|
30151
|
-
|
|
30152
|
-
|
|
30153
|
-
|
|
30154
|
-
|
|
30155
|
-
|
|
30156
|
-
|
|
30157
|
-
|
|
30158
|
-
|
|
30159
|
-
|
|
30160
|
-
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30839
|
+
"--annotation": {
|
|
30840
|
+
type: "string",
|
|
30841
|
+
description: "Specific annotation within the resource (optional)"
|
|
30842
|
+
},
|
|
30843
|
+
"--message": {
|
|
30844
|
+
type: "string",
|
|
30845
|
+
description: "Human-readable context for the participant (max 500 chars)"
|
|
30846
|
+
}
|
|
30847
|
+
}, {}),
|
|
30848
|
+
restAs: "participantArr",
|
|
30849
|
+
aliases: {}
|
|
30850
|
+
}).schema(BeckonOptionsSchema).handler(runBeckon).build();
|
|
30851
|
+
|
|
30852
|
+
// src/core/commands/browse.ts
|
|
30853
|
+
init_zod();
|
|
30854
|
+
init_command_definition();
|
|
30855
|
+
init_base_options_schema();
|
|
30856
|
+
import { resourceId as toResourceId6, annotationId as toAnnotationId5 } from "@semiont/core";
|
|
30857
|
+
var BrowseOptionsSchema = ApiOptionsSchema.extend({
|
|
30858
|
+
args: external_exports.array(external_exports.string()).min(1, "Subcommand required: resources | resource | annotation | references | events | history | entity-types"),
|
|
30859
|
+
// browse resources options
|
|
30860
|
+
search: external_exports.string().optional(),
|
|
30861
|
+
entityType: external_exports.array(external_exports.string()).default([]),
|
|
30862
|
+
limit: external_exports.coerce.number().int().min(1).max(200).default(50),
|
|
30863
|
+
// browse resource options
|
|
30864
|
+
annotations: external_exports.boolean().default(false),
|
|
30865
|
+
references: external_exports.boolean().default(false)
|
|
30866
|
+
}).superRefine((val, ctx) => {
|
|
30867
|
+
const sub = val.args[0];
|
|
30868
|
+
const valid = ["resources", "resource", "annotation", "references", "events", "history", "entity-types"];
|
|
30869
|
+
if (!valid.includes(sub)) {
|
|
30870
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: `Unknown subcommand '${sub}'. Valid: ${valid.join(", ")}` });
|
|
30871
|
+
}
|
|
30872
|
+
if (sub === "resource" && val.args.length < 2) {
|
|
30873
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Usage: semiont browse resource <resourceId>" });
|
|
30874
|
+
}
|
|
30875
|
+
if (sub === "annotation" && val.args.length < 3) {
|
|
30876
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Usage: semiont browse annotation <resourceId> <annotationId>" });
|
|
30877
|
+
}
|
|
30878
|
+
if (sub === "references" && val.args.length < 2) {
|
|
30879
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Usage: semiont browse references <resourceId>" });
|
|
30880
|
+
}
|
|
30881
|
+
if (sub === "events" && val.args.length < 2) {
|
|
30882
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Usage: semiont browse events <resourceId>" });
|
|
30883
|
+
}
|
|
30884
|
+
if (sub === "history" && val.args.length < 3) {
|
|
30885
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Usage: semiont browse history <resourceId> <annotationId>" });
|
|
30886
|
+
}
|
|
30887
|
+
});
|
|
30888
|
+
async function runBrowse(options) {
|
|
30889
|
+
const startTime = Date.now();
|
|
30890
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
30891
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
30892
|
+
const [subcommand, rawResourceId, rawAnnotationId] = options.args;
|
|
30893
|
+
let result;
|
|
30894
|
+
let label;
|
|
30895
|
+
if (subcommand === "resources") {
|
|
30896
|
+
const data = await client.browseResources(
|
|
30897
|
+
options.limit,
|
|
30898
|
+
void 0,
|
|
30899
|
+
options.search,
|
|
30900
|
+
{ auth: token }
|
|
30901
|
+
);
|
|
30902
|
+
result = data;
|
|
30903
|
+
const items = Array.isArray(data) ? data : data?.resources ?? [];
|
|
30904
|
+
label = `${items.length} resource${items.length !== 1 ? "s" : ""} found`;
|
|
30905
|
+
} else if (subcommand === "resource") {
|
|
30906
|
+
const id = toResourceId6(rawResourceId);
|
|
30907
|
+
const resourceData = await client.browseResource(id, { auth: token });
|
|
30908
|
+
if (options.annotations || options.references) {
|
|
30909
|
+
const annotationsData = await client.browseAnnotations(id, void 0, { auth: token });
|
|
30910
|
+
const annotations = annotationsData?.annotations ?? annotationsData ?? [];
|
|
30911
|
+
let referencedBy = [];
|
|
30912
|
+
if (options.references) {
|
|
30913
|
+
const refData = await client.browseReferences(id, { auth: token });
|
|
30914
|
+
referencedBy = refData.referencedBy ?? [];
|
|
30915
|
+
}
|
|
30916
|
+
result = {
|
|
30917
|
+
...resourceData,
|
|
30918
|
+
...options.annotations ? { annotations } : {},
|
|
30919
|
+
...options.references ? { referencedBy } : {}
|
|
30920
|
+
};
|
|
30921
|
+
} else {
|
|
30922
|
+
result = resourceData;
|
|
30923
|
+
}
|
|
30924
|
+
label = `${rawResourceId}: ${resourceData?.name ?? rawResourceId}`;
|
|
30925
|
+
} else if (subcommand === "annotation") {
|
|
30926
|
+
const resourceId = toResourceId6(rawResourceId);
|
|
30927
|
+
const annotationId = toAnnotationId5(rawAnnotationId);
|
|
30928
|
+
result = await client.browseAnnotation(resourceId, annotationId, { auth: token });
|
|
30929
|
+
label = `${rawAnnotationId}: annotation on ${rawResourceId}`;
|
|
30930
|
+
} else if (subcommand === "references") {
|
|
30931
|
+
const id = toResourceId6(rawResourceId);
|
|
30932
|
+
const data = await client.browseReferences(id, { auth: token });
|
|
30933
|
+
result = data.referencedBy ?? [];
|
|
30934
|
+
const count = Array.isArray(result) ? result.length : 0;
|
|
30935
|
+
label = `${count} resource${count !== 1 ? "s" : ""} reference ${rawResourceId}`;
|
|
30936
|
+
} else if (subcommand === "events") {
|
|
30937
|
+
const id = toResourceId6(rawResourceId);
|
|
30938
|
+
const data = await client.getResourceEvents(id, { auth: token });
|
|
30939
|
+
result = data.events ?? data;
|
|
30940
|
+
const items = Array.isArray(result) ? result : [];
|
|
30941
|
+
label = `${items.length} event${items.length !== 1 ? "s" : ""} for ${rawResourceId}`;
|
|
30942
|
+
} else if (subcommand === "history") {
|
|
30943
|
+
const resourceId = toResourceId6(rawResourceId);
|
|
30944
|
+
const annotationId = toAnnotationId5(rawAnnotationId);
|
|
30945
|
+
result = await client.getAnnotationHistory(resourceId, annotationId, { auth: token });
|
|
30946
|
+
label = `history for annotation ${rawAnnotationId} on ${rawResourceId}`;
|
|
30947
|
+
} else {
|
|
30948
|
+
result = await client.listEntityTypes({ auth: token });
|
|
30949
|
+
const items = Array.isArray(result) ? result : result?.tags ?? [];
|
|
30950
|
+
label = `${items.length} entity type${items.length !== 1 ? "s" : ""}`;
|
|
30951
|
+
}
|
|
30952
|
+
if (!options.quiet) process.stderr.write(label + "\n");
|
|
30953
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
30954
|
+
return {
|
|
30955
|
+
command: "browse",
|
|
30956
|
+
environment: rawBusUrl,
|
|
30957
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
30958
|
+
duration: Date.now() - startTime,
|
|
30959
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
30960
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
30961
|
+
results: [{ entity: rawResourceId ?? subcommand, platform: "posix", success: true, duration: Date.now() - startTime }]
|
|
30164
30962
|
};
|
|
30165
30963
|
}
|
|
30166
|
-
var
|
|
30167
|
-
|
|
30964
|
+
var browseCmd = new CommandBuilder().name("browse").description(
|
|
30965
|
+
"Human-readable traversal of the knowledge base. Subcommands: resources (list), resource <id> (inspect), annotation <resourceId> <annotationId> (inspect), references <id> (who links here), events <resourceId> (historical event log), history <resourceId> <annotationId> (annotation audit trail), entity-types (available entity type catalogue). Outputs JSON to stdout; progress label to stderr. For LLM pipeline consumption use `semiont gather` instead."
|
|
30966
|
+
).requiresEnvironment(true).requiresServices(true).examples(
|
|
30967
|
+
"semiont browse resources",
|
|
30968
|
+
'semiont browse resources --search "Paris"',
|
|
30969
|
+
"semiont browse resources --entity-type Location --limit 20",
|
|
30970
|
+
"semiont browse resource <resourceId>",
|
|
30971
|
+
"semiont browse resource <resourceId> --annotations",
|
|
30972
|
+
"semiont browse resource <resourceId> --references",
|
|
30973
|
+
"semiont browse annotation <resourceId> <annotationId>",
|
|
30974
|
+
"semiont browse references <resourceId>",
|
|
30975
|
+
"semiont browse events <resourceId>",
|
|
30976
|
+
"semiont browse history <resourceId> <annotationId>",
|
|
30977
|
+
"semiont browse entity-types",
|
|
30978
|
+
`semiont browse resources --search "Paris" | jq '.[]["@id"]'`,
|
|
30979
|
+
"semiont browse references <resourceId> | jq '.[].name'",
|
|
30980
|
+
"semiont browse entity-types | jq '.[].tag'"
|
|
30981
|
+
).args({
|
|
30982
|
+
...withApiArgs({
|
|
30983
|
+
"--search": {
|
|
30984
|
+
type: "string",
|
|
30985
|
+
description: "Filter resources by name or content (browse resources only)"
|
|
30986
|
+
},
|
|
30987
|
+
"--entity-type": {
|
|
30988
|
+
type: "array",
|
|
30989
|
+
description: "Filter resources by entity type (browse resources only; repeatable)"
|
|
30990
|
+
},
|
|
30991
|
+
"--limit": {
|
|
30992
|
+
type: "string",
|
|
30993
|
+
description: "Maximum number of results (browse resources only; default: 50)"
|
|
30994
|
+
},
|
|
30995
|
+
"--annotations": {
|
|
30996
|
+
type: "boolean",
|
|
30997
|
+
description: "Include annotation list in resource output (browse resource only)",
|
|
30998
|
+
default: false
|
|
30999
|
+
},
|
|
31000
|
+
"--references": {
|
|
31001
|
+
type: "boolean",
|
|
31002
|
+
description: "Include resolved reference targets (browse resource only)",
|
|
31003
|
+
default: false
|
|
31004
|
+
}
|
|
31005
|
+
}, {}),
|
|
31006
|
+
restAs: "args",
|
|
31007
|
+
aliases: {}
|
|
31008
|
+
}).schema(BrowseOptionsSchema).handler(runBrowse).build();
|
|
31009
|
+
|
|
31010
|
+
// src/core/commands/listen.ts
|
|
31011
|
+
init_zod();
|
|
31012
|
+
init_command_definition();
|
|
31013
|
+
init_base_options_schema();
|
|
31014
|
+
import { resourceId as toResourceId7, EventBus as EventBus9 } from "@semiont/core";
|
|
31015
|
+
var ListenOptionsSchema = ApiOptionsSchema.extend({
|
|
31016
|
+
args: external_exports.array(external_exports.string()).default([])
|
|
31017
|
+
}).superRefine((val, ctx) => {
|
|
31018
|
+
const sub = val.args[0];
|
|
31019
|
+
if (sub !== void 0 && sub !== "resource") {
|
|
31020
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: `Unknown subcommand '${sub}'. Usage: semiont listen [resource <resourceId>]` });
|
|
31021
|
+
}
|
|
31022
|
+
if (sub === "resource" && val.args.length < 2) {
|
|
31023
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Usage: semiont listen resource <resourceId>" });
|
|
31024
|
+
}
|
|
30168
31025
|
});
|
|
30169
|
-
async function
|
|
31026
|
+
async function runListen(options) {
|
|
30170
31027
|
const startTime = Date.now();
|
|
30171
|
-
const
|
|
30172
|
-
const
|
|
30173
|
-
const
|
|
30174
|
-
const
|
|
30175
|
-
const
|
|
30176
|
-
|
|
30177
|
-
|
|
30178
|
-
|
|
30179
|
-
|
|
30180
|
-
|
|
30181
|
-
|
|
30182
|
-
|
|
30183
|
-
const
|
|
31028
|
+
const rawBusUrl = resolveBusUrl(options.bus);
|
|
31029
|
+
const { client, token } = loadCachedClient(rawBusUrl);
|
|
31030
|
+
const [subcommand, rawResourceId] = options.args;
|
|
31031
|
+
const isResourceScoped = subcommand === "resource";
|
|
31032
|
+
const eventBus = new EventBus9();
|
|
31033
|
+
let eventCount = 0;
|
|
31034
|
+
eventBus.get("make-meaning:event").subscribe((event) => {
|
|
31035
|
+
eventCount++;
|
|
31036
|
+
process.stdout.write(JSON.stringify(event) + "\n");
|
|
31037
|
+
});
|
|
31038
|
+
const label = isResourceScoped ? `Listening for events on resource ${rawResourceId}` : "Listening for global events";
|
|
31039
|
+
if (!options.quiet) process.stderr.write(label + " (Ctrl-C to stop)\n");
|
|
31040
|
+
const stream = isResourceScoped ? client.sse.resourceEvents(toResourceId7(rawResourceId), { auth: token, eventBus }) : client.sse.globalEvents({ auth: token, eventBus });
|
|
31041
|
+
await new Promise((resolve10) => {
|
|
31042
|
+
const cleanup = () => {
|
|
31043
|
+
stream.close();
|
|
31044
|
+
resolve10();
|
|
31045
|
+
};
|
|
31046
|
+
process.once("SIGINT", cleanup);
|
|
31047
|
+
process.once("SIGTERM", cleanup);
|
|
31048
|
+
});
|
|
31049
|
+
return {
|
|
31050
|
+
command: "listen",
|
|
31051
|
+
environment: rawBusUrl,
|
|
31052
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
31053
|
+
duration: Date.now() - startTime,
|
|
31054
|
+
summary: { succeeded: eventCount, failed: 0, total: eventCount, warnings: 0 },
|
|
31055
|
+
executionContext: { user: process.env.USER || "unknown", workingDirectory: process.cwd(), dryRun: options.dryRun },
|
|
31056
|
+
results: [{ entity: rawResourceId ?? "global", platform: "posix", success: true, duration: Date.now() - startTime }]
|
|
31057
|
+
};
|
|
31058
|
+
}
|
|
31059
|
+
var listenCmd = new CommandBuilder().name("listen").description(
|
|
31060
|
+
"Open a persistent SSE connection and stream domain events as NDJSON to stdout. Without a subcommand, streams global system events. With `resource <resourceId>`, streams events scoped to that resource. Runs until Ctrl-C or the server closes the connection."
|
|
31061
|
+
).requiresEnvironment(true).requiresServices(true).examples(
|
|
31062
|
+
"semiont listen",
|
|
31063
|
+
"semiont listen resource <resourceId>",
|
|
31064
|
+
"semiont listen resource <resourceId> | jq .type",
|
|
31065
|
+
"semiont listen | grep entitytype"
|
|
31066
|
+
).args({
|
|
31067
|
+
...withApiArgs({}, {}),
|
|
31068
|
+
restAs: "args",
|
|
31069
|
+
aliases: {}
|
|
31070
|
+
}).schema(ListenOptionsSchema).handler(runListen).build();
|
|
31071
|
+
|
|
31072
|
+
// src/core/commands/login.ts
|
|
31073
|
+
init_zod();
|
|
31074
|
+
init_dist();
|
|
31075
|
+
init_command_definition();
|
|
31076
|
+
init_base_options_schema();
|
|
31077
|
+
import * as fs52 from "fs";
|
|
31078
|
+
import * as os6 from "os";
|
|
31079
|
+
import * as path45 from "path";
|
|
31080
|
+
import * as readline4 from "readline";
|
|
31081
|
+
var LoginOptionsSchema = BaseOptionsSchema.extend({
|
|
31082
|
+
bus: external_exports.string().optional(),
|
|
31083
|
+
user: external_exports.string().optional(),
|
|
31084
|
+
password: external_exports.string().optional(),
|
|
31085
|
+
refresh: external_exports.boolean().optional().default(false)
|
|
31086
|
+
});
|
|
31087
|
+
function readLoginConfig() {
|
|
31088
|
+
const configPath = path45.join(os6.homedir(), ".semiontconfig");
|
|
30184
31089
|
try {
|
|
30185
|
-
|
|
30186
|
-
|
|
30187
|
-
|
|
30188
|
-
|
|
30189
|
-
|
|
30190
|
-
|
|
30191
|
-
|
|
30192
|
-
|
|
30193
|
-
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
30199
|
-
|
|
30200
|
-
continue;
|
|
30201
|
-
}
|
|
30202
|
-
let resourceId;
|
|
30203
|
-
try {
|
|
30204
|
-
resourceId = await resolveStorageUri3(kb.projectionsDir, storageUri);
|
|
30205
|
-
} catch (e) {
|
|
30206
|
-
if (e instanceof ResourceNotFoundError3) {
|
|
30207
|
-
if (!options.quiet) printWarning(`Not tracked by semiont: ${filePath}`);
|
|
30208
|
-
results.push({ entity: filePath, platform: "posix", success: false, metadata: { error: "Not tracked" }, duration: 0 });
|
|
30209
|
-
failed++;
|
|
30210
|
-
continue;
|
|
30211
|
-
}
|
|
30212
|
-
throw e;
|
|
30213
|
-
}
|
|
30214
|
-
eventBus.scope(resourceId).get("mark:unarchive").next({
|
|
30215
|
-
userId,
|
|
30216
|
-
resourceId,
|
|
30217
|
-
storageUri
|
|
30218
|
-
});
|
|
30219
|
-
await new Promise((resolve12) => setTimeout(resolve12, 200));
|
|
30220
|
-
if (!options.quiet) printSuccess(`Unarchived: ${filePath}`);
|
|
30221
|
-
results.push({ entity: filePath, platform: "posix", success: true, metadata: { resourceId, storageUri }, duration: Date.now() - fileStart });
|
|
30222
|
-
succeeded++;
|
|
31090
|
+
const content = fs52.existsSync(configPath) ? fs52.readFileSync(configPath, "utf-8") : null;
|
|
31091
|
+
if (!content) return {};
|
|
31092
|
+
return parse(content);
|
|
31093
|
+
} catch {
|
|
31094
|
+
return {};
|
|
31095
|
+
}
|
|
31096
|
+
}
|
|
31097
|
+
function getDefaultEnvironment(config) {
|
|
31098
|
+
return config.defaults?.environment ?? null;
|
|
31099
|
+
}
|
|
31100
|
+
function promptPassword(prompt3) {
|
|
31101
|
+
return new Promise((resolve10, reject) => {
|
|
31102
|
+
if (!process.stdin.isTTY) {
|
|
31103
|
+
reject(new Error("No password provided and stdin is not a TTY. Use --password or $SEMIONT_PASSWORD."));
|
|
31104
|
+
return;
|
|
30223
31105
|
}
|
|
30224
|
-
|
|
30225
|
-
|
|
30226
|
-
|
|
31106
|
+
const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
|
|
31107
|
+
process.stderr.write(prompt3);
|
|
31108
|
+
if (process.stdin.setRawMode) {
|
|
31109
|
+
process.stdin.setRawMode(true);
|
|
31110
|
+
}
|
|
31111
|
+
let value = "";
|
|
31112
|
+
process.stdin.on("data", function onData(chunk) {
|
|
31113
|
+
const char = chunk.toString();
|
|
31114
|
+
if (char === "\r" || char === "\n") {
|
|
31115
|
+
process.stdin.removeListener("data", onData);
|
|
31116
|
+
if (process.stdin.setRawMode) {
|
|
31117
|
+
process.stdin.setRawMode(false);
|
|
31118
|
+
}
|
|
31119
|
+
process.stderr.write("\n");
|
|
31120
|
+
rl.close();
|
|
31121
|
+
resolve10(value);
|
|
31122
|
+
} else if (char === "") {
|
|
31123
|
+
process.stderr.write("\n");
|
|
31124
|
+
rl.close();
|
|
31125
|
+
reject(new Error("Interrupted"));
|
|
31126
|
+
} else if (char === "\x7F" || char === "\b") {
|
|
31127
|
+
value = value.slice(0, -1);
|
|
31128
|
+
} else {
|
|
31129
|
+
value += char;
|
|
31130
|
+
}
|
|
31131
|
+
});
|
|
31132
|
+
process.stdin.resume();
|
|
31133
|
+
});
|
|
31134
|
+
}
|
|
31135
|
+
async function runLogin(options) {
|
|
31136
|
+
const startTime = Date.now();
|
|
31137
|
+
const config = readLoginConfig();
|
|
31138
|
+
const defaultEnv = getDefaultEnvironment(config);
|
|
31139
|
+
const envSection = defaultEnv ? config.environments?.[defaultEnv] : void 0;
|
|
31140
|
+
const rawBusUrl = resolveBusUrl(
|
|
31141
|
+
options.bus ?? envSection?.backend?.publicURL
|
|
31142
|
+
);
|
|
31143
|
+
const emailStr = options.user ?? process.env.SEMIONT_USER ?? envSection?.auth?.email ?? null;
|
|
31144
|
+
if (!emailStr) {
|
|
31145
|
+
throw new Error(
|
|
31146
|
+
'No auth email configured. Use --user, set $SEMIONT_USER, or add:\n [environments.<env>.auth]\n email = "you@example.com"\nto ~/.semiontconfig'
|
|
31147
|
+
);
|
|
31148
|
+
}
|
|
31149
|
+
let passwordStr = options.password ?? process.env.SEMIONT_PASSWORD ?? envSection?.auth?.password ?? "";
|
|
31150
|
+
if (!passwordStr) {
|
|
31151
|
+
passwordStr = await promptPassword(`Password for ${emailStr}: `);
|
|
31152
|
+
}
|
|
31153
|
+
if (!passwordStr) {
|
|
31154
|
+
throw new Error("Password is required.");
|
|
31155
|
+
}
|
|
31156
|
+
await acquireToken(rawBusUrl, emailStr, passwordStr);
|
|
31157
|
+
const slug = busSlug(rawBusUrl);
|
|
31158
|
+
const xdgState = process.env.XDG_STATE_HOME ?? path45.join(os6.homedir(), ".local", "state");
|
|
31159
|
+
const cachePath = path45.join(xdgState, "semiont", "auth", `${slug}.json`);
|
|
31160
|
+
if (!options.quiet) {
|
|
31161
|
+
process.stderr.write(`Logged in to ${rawBusUrl} as ${emailStr}
|
|
31162
|
+
`);
|
|
31163
|
+
process.stderr.write(`Token cached at ${cachePath} (expires in 24h)
|
|
31164
|
+
`);
|
|
30227
31165
|
}
|
|
30228
|
-
const duration = Date.now() - startTime;
|
|
30229
31166
|
return {
|
|
30230
|
-
command: "
|
|
30231
|
-
environment,
|
|
31167
|
+
command: "login",
|
|
31168
|
+
environment: "n/a",
|
|
30232
31169
|
timestamp: /* @__PURE__ */ new Date(),
|
|
30233
|
-
duration,
|
|
30234
|
-
summary: { succeeded, failed, total:
|
|
30235
|
-
executionContext: { user:
|
|
30236
|
-
results
|
|
31170
|
+
duration: Date.now() - startTime,
|
|
31171
|
+
summary: { succeeded: 1, failed: 0, total: 1, warnings: 0 },
|
|
31172
|
+
executionContext: { user: emailStr, workingDirectory: process.cwd(), dryRun: false },
|
|
31173
|
+
results: [{ entity: rawBusUrl, platform: "posix", success: true, duration: Date.now() - startTime }]
|
|
30237
31174
|
};
|
|
30238
31175
|
}
|
|
30239
|
-
var
|
|
30240
|
-
"
|
|
31176
|
+
var loginCmd = new CommandBuilder().name("login").description(
|
|
31177
|
+
"Authenticate against a Semiont backend and cache the token. Run this once before using browse, gather, mark, bind, match, listen, yield, or beckon. Credentials resolved from: --bus/--user/--password flags \u2192 $SEMIONT_BUS/$SEMIONT_USER/$SEMIONT_PASSWORD \u2192 ~/.semiontconfig \u2192 interactive prompt."
|
|
31178
|
+
).requiresEnvironment(false).requiresServices(false).examples(
|
|
31179
|
+
"semiont login --bus http://localhost:4000 --user alice@example.com",
|
|
31180
|
+
"semiont login --bus https://api.acme.com",
|
|
31181
|
+
"semiont login --refresh --bus https://api.acme.com"
|
|
30241
31182
|
).args({
|
|
30242
|
-
args: {
|
|
30243
|
-
|
|
30244
|
-
|
|
30245
|
-
|
|
31183
|
+
args: {
|
|
31184
|
+
...BASE_ARGS,
|
|
31185
|
+
"--bus": {
|
|
31186
|
+
type: "string",
|
|
31187
|
+
description: "Backend URL (e.g. http://localhost:4000). Fallback: $SEMIONT_BUS \u2192 ~/.semiontconfig"
|
|
31188
|
+
},
|
|
31189
|
+
"--user": {
|
|
31190
|
+
type: "string",
|
|
31191
|
+
description: "Login email. Fallback: $SEMIONT_USER \u2192 ~/.semiontconfig [environments.<env>.auth] email"
|
|
31192
|
+
},
|
|
31193
|
+
"--password": {
|
|
31194
|
+
type: "string",
|
|
31195
|
+
description: "Login password. Fallback: $SEMIONT_PASSWORD \u2192 ~/.semiontconfig \u2192 interactive prompt"
|
|
31196
|
+
},
|
|
31197
|
+
"--refresh": {
|
|
31198
|
+
type: "boolean",
|
|
31199
|
+
description: "Re-authenticate using cached email without requiring a new password (if stored)",
|
|
31200
|
+
default: false
|
|
31201
|
+
}
|
|
31202
|
+
},
|
|
31203
|
+
aliases: { ...BASE_ALIASES, "-b": "--bus", "-u": "--user" }
|
|
31204
|
+
}).schema(LoginOptionsSchema).handler(runLogin).build();
|
|
30246
31205
|
|
|
30247
31206
|
// src/core/command-discovery.ts
|
|
30248
31207
|
var commandCache = /* @__PURE__ */ new Map();
|
|
@@ -30265,8 +31224,14 @@ var COMMANDS = {
|
|
|
30265
31224
|
"clean": cleanCommand,
|
|
30266
31225
|
"mv": mvCmd,
|
|
30267
31226
|
"yield": yieldCmd,
|
|
30268
|
-
"
|
|
30269
|
-
"
|
|
31227
|
+
"mark": markCmd,
|
|
31228
|
+
"gather": gatherCmd,
|
|
31229
|
+
"match": matchCmd,
|
|
31230
|
+
"bind": bindCmd,
|
|
31231
|
+
"beckon": beckonCmd,
|
|
31232
|
+
"browse": browseCmd,
|
|
31233
|
+
"listen": listenCmd,
|
|
31234
|
+
"login": loginCmd
|
|
30270
31235
|
};
|
|
30271
31236
|
async function loadCommand(name) {
|
|
30272
31237
|
if (commandCache.has(name)) {
|