nodal-agents 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/cli.js +314 -99
- package/migrations/0020_agent_workspaces.sql +60 -0
- package/migrations/meta/0009_snapshot.json +4454 -4454
- package/migrations/meta/0010_snapshot.json +4460 -4460
- package/migrations/meta/_journal.json +153 -146
- package/package.json +7 -3
- package/runner.js +2998 -59214
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +4 -4
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +3 -2
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/page.js +2 -2
- package/web/.next/server/app/(dashboard)/agents/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/approvals/page.js +2 -2
- package/web/.next/server/app/(dashboard)/approvals/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/automations/page.js +2 -2
- package/web/.next/server/app/(dashboard)/automations/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/billing/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page.js +2 -2
- package/web/.next/server/app/(dashboard)/connectors/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/jobs/[id]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/jobs/page.js +2 -2
- package/web/.next/server/app/(dashboard)/jobs/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/llm-providers/page.js +2 -2
- package/web/.next/server/app/(dashboard)/llm-providers/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/logs/page.js +2 -2
- package/web/.next/server/app/(dashboard)/logs/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/memories/page.js +2 -2
- package/web/.next/server/app/(dashboard)/memories/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page.js +2 -2
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/web/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +2 -2
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/new/page.js +1299 -101
- package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/page.js +2 -2
- package/web/.next/server/app/(dashboard)/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +1 -1
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/server/app/_not-found.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/onboarding.html +1 -1
- package/web/.next/server/app/onboarding.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/_full.segment.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/_tree.segment.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
- package/web/.next/server/app-paths-manifest.json +4 -4
- package/web/.next/server/chunks/{9327.js → 2456.js} +1 -1
- package/web/.next/server/chunks/4574.js +1 -1
- package/web/.next/server/chunks/5786.js +1223 -0
- package/web/.next/server/chunks/5832.js +1 -0
- package/web/.next/server/chunks/6263.js +1 -0
- package/web/.next/server/chunks/9682.js +1 -0
- package/web/.next/server/middleware-build-manifest.js +1 -1
- package/web/.next/server/pages/404.html +1 -1
- package/web/.next/server/pages/500.html +1 -1
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/static/chunks/3141-f595f19634be6813.js +1 -0
- package/web/.next/static/chunks/{6118-c6a8b66d0a3e446c.js → 4239-99af3d7559fd9ec1.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-f6f39ebe8d6fb019.js +2 -0
- package/web/.next/static/chunks/app/(dashboard)/agents/page-d2e35b0af87cdc0b.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/connectors/page-6ccde8b8b9197d2f.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/credentials/page-679ca09e4625b70f.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/mcp/page-ad271be896b650a9.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/memories/page-0eed8d3610720c33.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/skills/page-472bb16429cd2798.js +1 -0
- package/web/.next/static/css/845089bde6c9e6fb.css +3 -0
- package/web/.next/server/chunks/5616.js +0 -25
- package/web/.next/server/chunks/6595.js +0 -1
- package/web/.next/server/chunks/9323.js +0 -1
- package/web/.next/static/chunks/3422-9078c04bb8df8ce5.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-faaf5d7084db1fbc.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/page-9f2c2130d2f4de95.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/connectors/page-cd7ee7dd1458ae47.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/credentials/page-73d252ca88f194f1.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/mcp/page-1b2bf2315b3b213e.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/memories/page-1e537215e80cb0c3.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/skills/page-a6736503d29a2f1c.js +0 -1
- package/web/.next/static/css/a161c147ca3606b3.css +0 -3
- /package/web/.next/static/{be4PVOMd_EIWn1rY3m-Q2 → RdognT8Zq7jK6wHyNY5k3}/_buildManifest.js +0 -0
- /package/web/.next/static/{be4PVOMd_EIWn1rY3m-Q2 → RdognT8Zq7jK6wHyNY5k3}/_ssgManifest.js +0 -0
package/cli.js
CHANGED
|
@@ -9,21 +9,67 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/lib/version.ts
|
|
13
|
+
var version_exports = {};
|
|
14
|
+
__export(version_exports, {
|
|
15
|
+
getInstalledVersion: () => getInstalledVersion,
|
|
16
|
+
getLatestVersion: () => getLatestVersion
|
|
17
|
+
});
|
|
18
|
+
import { createRequire } from "module";
|
|
19
|
+
import { fileURLToPath } from "url";
|
|
20
|
+
import { dirname, join } from "path";
|
|
21
|
+
import { existsSync } from "fs";
|
|
22
|
+
import { execa } from "execa";
|
|
23
|
+
function resolveCliPackageJsonPath() {
|
|
24
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
if (existsSync(join(here, "runner.js"))) {
|
|
26
|
+
return join(here, "package.json");
|
|
27
|
+
}
|
|
28
|
+
return join(here, "..", "..", "package.json");
|
|
29
|
+
}
|
|
30
|
+
function getInstalledVersion() {
|
|
31
|
+
try {
|
|
32
|
+
const pkgPath = resolveCliPackageJsonPath();
|
|
33
|
+
const _require = createRequire(import.meta.url);
|
|
34
|
+
const pkg = _require(pkgPath);
|
|
35
|
+
return typeof pkg.version === "string" && pkg.version ? pkg.version : "0.0.0";
|
|
36
|
+
} catch {
|
|
37
|
+
return "0.0.0";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function getLatestVersion() {
|
|
41
|
+
try {
|
|
42
|
+
const { stdout } = await execa("npm", ["view", "nodal-agents", "version"], {
|
|
43
|
+
timeout: 5e3,
|
|
44
|
+
reject: true
|
|
45
|
+
});
|
|
46
|
+
const trimmed = stdout.trim();
|
|
47
|
+
return trimmed || null;
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var init_version = __esm({
|
|
53
|
+
"src/lib/version.ts"() {
|
|
54
|
+
"use strict";
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
12
58
|
// src/lib/config.ts
|
|
13
59
|
import { z } from "zod";
|
|
14
60
|
import { homedir } from "os";
|
|
15
|
-
import { join } from "path";
|
|
16
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
61
|
+
import { join as join2 } from "path";
|
|
62
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync as existsSync2 } from "fs";
|
|
17
63
|
import { randomBytes } from "crypto";
|
|
18
64
|
function ensureConfigDir() {
|
|
19
65
|
for (const dir of [CONFIG_DIR, PID_DIR, LOG_DIR, PG_DATA_DIR]) {
|
|
20
|
-
if (!
|
|
66
|
+
if (!existsSync2(dir)) {
|
|
21
67
|
mkdirSync(dir, { recursive: true });
|
|
22
68
|
}
|
|
23
69
|
}
|
|
24
70
|
}
|
|
25
71
|
function readConfig(configFile = CONFIG_FILE) {
|
|
26
|
-
if (!
|
|
72
|
+
if (!existsSync2(configFile)) return null;
|
|
27
73
|
let parsed;
|
|
28
74
|
try {
|
|
29
75
|
const raw = JSON.parse(readFileSync(configFile, "utf-8"));
|
|
@@ -102,11 +148,11 @@ var init_config = __esm({
|
|
|
102
148
|
googleClientSecret: z.string().optional()
|
|
103
149
|
}).optional()
|
|
104
150
|
});
|
|
105
|
-
CONFIG_DIR =
|
|
106
|
-
CONFIG_FILE =
|
|
107
|
-
PID_DIR =
|
|
108
|
-
LOG_DIR =
|
|
109
|
-
PG_DATA_DIR =
|
|
151
|
+
CONFIG_DIR = join2(homedir(), ".nodalai");
|
|
152
|
+
CONFIG_FILE = join2(CONFIG_DIR, "config.json");
|
|
153
|
+
PID_DIR = join2(CONFIG_DIR, "pids");
|
|
154
|
+
LOG_DIR = join2(CONFIG_DIR, "logs");
|
|
155
|
+
PG_DATA_DIR = join2(CONFIG_DIR, "pg-data");
|
|
110
156
|
}
|
|
111
157
|
});
|
|
112
158
|
|
|
@@ -3392,7 +3438,7 @@ var init_subquery = __esm({
|
|
|
3392
3438
|
|
|
3393
3439
|
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@electri_96bd1661c4535b1384d37581a38c7c74/node_modules/drizzle-orm/version.js
|
|
3394
3440
|
var version;
|
|
3395
|
-
var
|
|
3441
|
+
var init_version2 = __esm({
|
|
3396
3442
|
"../../node_modules/.pnpm/drizzle-orm@0.45.2_@electri_96bd1661c4535b1384d37581a38c7c74/node_modules/drizzle-orm/version.js"() {
|
|
3397
3443
|
"use strict";
|
|
3398
3444
|
version = "0.45.2";
|
|
@@ -3405,7 +3451,7 @@ var init_tracing = __esm({
|
|
|
3405
3451
|
"../../node_modules/.pnpm/drizzle-orm@0.45.2_@electri_96bd1661c4535b1384d37581a38c7c74/node_modules/drizzle-orm/tracing.js"() {
|
|
3406
3452
|
"use strict";
|
|
3407
3453
|
init_tracing_utils();
|
|
3408
|
-
|
|
3454
|
+
init_version2();
|
|
3409
3455
|
tracer = {
|
|
3410
3456
|
startActiveSpan(name, fn) {
|
|
3411
3457
|
if (!otel) {
|
|
@@ -3840,7 +3886,7 @@ var init_sql = __esm({
|
|
|
3840
3886
|
return new SQL([new StringChunk(str)]);
|
|
3841
3887
|
}
|
|
3842
3888
|
sql2.raw = raw;
|
|
3843
|
-
function
|
|
3889
|
+
function join9(chunks, separator) {
|
|
3844
3890
|
const result = [];
|
|
3845
3891
|
for (const [i, chunk] of chunks.entries()) {
|
|
3846
3892
|
if (i > 0 && separator !== void 0) {
|
|
@@ -3850,7 +3896,7 @@ var init_sql = __esm({
|
|
|
3850
3896
|
}
|
|
3851
3897
|
return new SQL(result);
|
|
3852
3898
|
}
|
|
3853
|
-
sql2.join =
|
|
3899
|
+
sql2.join = join9;
|
|
3854
3900
|
function identifier(value) {
|
|
3855
3901
|
return new Name(value);
|
|
3856
3902
|
}
|
|
@@ -8149,7 +8195,7 @@ var init_select2 = __esm({
|
|
|
8149
8195
|
const baseTableName = this.tableName;
|
|
8150
8196
|
const tableName = getTableLikeName(table);
|
|
8151
8197
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
8152
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
8198
|
+
if (typeof tableName === "string" && this.config.joins?.some((join9) => join9.alias === tableName)) {
|
|
8153
8199
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
8154
8200
|
}
|
|
8155
8201
|
if (!this.isPartialSelect) {
|
|
@@ -9684,7 +9730,7 @@ var init_update = __esm({
|
|
|
9684
9730
|
createJoin(joinType) {
|
|
9685
9731
|
return (table, on) => {
|
|
9686
9732
|
const tableName = getTableLikeName(table);
|
|
9687
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
9733
|
+
if (typeof tableName === "string" && this.config.joins.some((join9) => join9.alias === tableName)) {
|
|
9688
9734
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
9689
9735
|
}
|
|
9690
9736
|
if (typeof on === "function") {
|
|
@@ -9780,10 +9826,10 @@ var init_update = __esm({
|
|
|
9780
9826
|
const fromFields = this.getTableLikeFields(this.config.from);
|
|
9781
9827
|
fields[tableName] = fromFields;
|
|
9782
9828
|
}
|
|
9783
|
-
for (const
|
|
9784
|
-
const tableName2 = getTableLikeName(
|
|
9785
|
-
if (typeof tableName2 === "string" && !is(
|
|
9786
|
-
const fromFields = this.getTableLikeFields(
|
|
9829
|
+
for (const join9 of this.config.joins) {
|
|
9830
|
+
const tableName2 = getTableLikeName(join9.table);
|
|
9831
|
+
if (typeof tableName2 === "string" && !is(join9.table, SQL)) {
|
|
9832
|
+
const fromFields = this.getTableLikeFields(join9.table);
|
|
9787
9833
|
fields[tableName2] = fromFields;
|
|
9788
9834
|
}
|
|
9789
9835
|
}
|
|
@@ -11025,10 +11071,10 @@ var migrate_exports = {};
|
|
|
11025
11071
|
__export(migrate_exports, {
|
|
11026
11072
|
runMigrations: () => runMigrations
|
|
11027
11073
|
});
|
|
11028
|
-
import { fileURLToPath } from "url";
|
|
11029
|
-
import { join as
|
|
11074
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11075
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
11030
11076
|
import {
|
|
11031
|
-
existsSync as
|
|
11077
|
+
existsSync as existsSync3,
|
|
11032
11078
|
mkdtempSync,
|
|
11033
11079
|
readdirSync,
|
|
11034
11080
|
readFileSync as readFileSync2,
|
|
@@ -11039,27 +11085,27 @@ import { tmpdir } from "os";
|
|
|
11039
11085
|
async function runMigrations(connectionString, opts = {}) {
|
|
11040
11086
|
const sql2 = src_default(connectionString, { max: 1 });
|
|
11041
11087
|
const db = drizzle(sql2);
|
|
11042
|
-
const here =
|
|
11043
|
-
const sibling =
|
|
11044
|
-
const sourceFolder =
|
|
11088
|
+
const here = dirname2(fileURLToPath2(import.meta.url));
|
|
11089
|
+
const sibling = join3(here, "migrations");
|
|
11090
|
+
const sourceFolder = existsSync3(sibling) ? sibling : join3(here, "../migrations");
|
|
11045
11091
|
const migrationsFolder = opts.patchVectorAsText ? patchMigrationsForNoVector(sourceFolder) : sourceFolder;
|
|
11046
11092
|
await migrate(db, { migrationsFolder });
|
|
11047
11093
|
await sql2.end();
|
|
11048
11094
|
}
|
|
11049
11095
|
function patchMigrationsForNoVector(sourceFolder) {
|
|
11050
|
-
const tmpFolder = mkdtempSync(
|
|
11051
|
-
const metaDir =
|
|
11096
|
+
const tmpFolder = mkdtempSync(join3(tmpdir(), "nodalai-migrations-"));
|
|
11097
|
+
const metaDir = join3(tmpFolder, "meta");
|
|
11052
11098
|
mkdirSync2(metaDir, { recursive: true });
|
|
11053
11099
|
for (const entry of readdirSync(sourceFolder, { withFileTypes: true })) {
|
|
11054
11100
|
if (entry.isDirectory() && entry.name === "meta") {
|
|
11055
|
-
for (const metaFile of readdirSync(
|
|
11056
|
-
const content = readFileSync2(
|
|
11057
|
-
writeFileSync2(
|
|
11101
|
+
for (const metaFile of readdirSync(join3(sourceFolder, "meta"))) {
|
|
11102
|
+
const content = readFileSync2(join3(sourceFolder, "meta", metaFile), "utf8");
|
|
11103
|
+
writeFileSync2(join3(metaDir, metaFile), content);
|
|
11058
11104
|
}
|
|
11059
11105
|
} else if (entry.isFile() && entry.name.endsWith(".sql")) {
|
|
11060
|
-
const content = readFileSync2(
|
|
11106
|
+
const content = readFileSync2(join3(sourceFolder, entry.name), "utf8");
|
|
11061
11107
|
const patched = content.replace(/\bvector\(\d+\)/g, "text");
|
|
11062
|
-
writeFileSync2(
|
|
11108
|
+
writeFileSync2(join3(tmpFolder, entry.name), patched);
|
|
11063
11109
|
}
|
|
11064
11110
|
}
|
|
11065
11111
|
return tmpFolder;
|
|
@@ -11074,11 +11120,11 @@ var init_migrate = __esm({
|
|
|
11074
11120
|
});
|
|
11075
11121
|
|
|
11076
11122
|
// src/lib/postgres.ts
|
|
11077
|
-
import { existsSync as
|
|
11078
|
-
import { join as
|
|
11123
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, unlinkSync } from "fs";
|
|
11124
|
+
import { join as join4 } from "path";
|
|
11079
11125
|
function clearStalePostmasterPid(dataDir) {
|
|
11080
|
-
const pidFile =
|
|
11081
|
-
if (!
|
|
11126
|
+
const pidFile = join4(dataDir, "postmaster.pid");
|
|
11127
|
+
if (!existsSync4(pidFile)) return;
|
|
11082
11128
|
let pid;
|
|
11083
11129
|
try {
|
|
11084
11130
|
const firstLine = readFileSync3(pidFile, "utf-8").split("\n")[0]?.trim() ?? "";
|
|
@@ -11099,8 +11145,8 @@ function clearStalePostmasterPid(dataDir) {
|
|
|
11099
11145
|
}
|
|
11100
11146
|
}
|
|
11101
11147
|
async function stopOrphanPostgres(dataDir = PG_DATA_DIR) {
|
|
11102
|
-
const pidFile =
|
|
11103
|
-
if (!
|
|
11148
|
+
const pidFile = join4(dataDir, "postmaster.pid");
|
|
11149
|
+
if (!existsSync4(pidFile)) return false;
|
|
11104
11150
|
try {
|
|
11105
11151
|
const EmbeddedPostgres = (await import("embedded-postgres")).default;
|
|
11106
11152
|
const pg = new EmbeddedPostgres({
|
|
@@ -11147,7 +11193,7 @@ async function startEmbeddedPostgres(dataDir = PG_DATA_DIR, port = 25432) {
|
|
|
11147
11193
|
if (verboseLog) process.stdout.write("[pg] " + m + "\n");
|
|
11148
11194
|
}
|
|
11149
11195
|
});
|
|
11150
|
-
const alreadyInitialised =
|
|
11196
|
+
const alreadyInitialised = existsSync4(join4(dataDir, "PG_VERSION"));
|
|
11151
11197
|
if (alreadyInitialised) clearStalePostmasterPid(dataDir);
|
|
11152
11198
|
try {
|
|
11153
11199
|
if (!alreadyInitialised) {
|
|
@@ -12327,12 +12373,6 @@ var init_agents = __esm({
|
|
|
12327
12373
|
// (Memory Sprint 2). Pure char budget — token estimation done at call site
|
|
12328
12374
|
// (length/4). 1500 chars ≈ ~375 tokens, similar to Hermes' 2200+1375 split.
|
|
12329
12375
|
memoryTokenBudget: integer("memory_token_budget").default(1500).notNull(),
|
|
12330
|
-
// Absolute filesystem path the agent's file_* tools are scoped to. NULL =
|
|
12331
|
-
// file tools fail loud (`workspace_not_configured`). Per-agent so each
|
|
12332
|
-
// agent in an entity can have its own scope (e.g. one agent on Obsidian
|
|
12333
|
-
// vault, another on a code repo). Resolution at tool-call time runs
|
|
12334
|
-
// through realpath + boundary check (see file-ops/workspace.ts).
|
|
12335
|
-
workspaceRootPath: text("workspace_root_path"),
|
|
12336
12376
|
// User-controlled order on the /agents page (Brique A, migration 0019).
|
|
12337
12377
|
// Default 0 — ties are broken by `name ASC` in the list query. Newly
|
|
12338
12378
|
// created agents land at the front of their group by default; the user
|
|
@@ -13172,6 +13212,43 @@ var init_agent_connector_assignments = __esm({
|
|
|
13172
13212
|
}
|
|
13173
13213
|
});
|
|
13174
13214
|
|
|
13215
|
+
// ../../packages/db/src/schema/agent-workspaces.ts
|
|
13216
|
+
var agentWorkspaces;
|
|
13217
|
+
var init_agent_workspaces = __esm({
|
|
13218
|
+
"../../packages/db/src/schema/agent-workspaces.ts"() {
|
|
13219
|
+
"use strict";
|
|
13220
|
+
init_pg_core();
|
|
13221
|
+
init_agents();
|
|
13222
|
+
init_entities();
|
|
13223
|
+
agentWorkspaces = pgTable(
|
|
13224
|
+
"agent_workspaces",
|
|
13225
|
+
{
|
|
13226
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
13227
|
+
agentId: uuid("agent_id").notNull().references(() => agents.id, { onDelete: "cascade" }),
|
|
13228
|
+
// entityId mirrors the agent's entity — useful for ownership checks without
|
|
13229
|
+
// a join. Set to CASCADE so deleting an entity also sweeps its workspaces.
|
|
13230
|
+
entityId: uuid("entity_id").references(() => entities.id, { onDelete: "cascade" }),
|
|
13231
|
+
// Human-readable label, also the first path segment the LLM must use when
|
|
13232
|
+
// the agent has more than one workspace (e.g. "notes/file.md").
|
|
13233
|
+
// Must be unique per agent. Max 80 chars keeps prompts readable.
|
|
13234
|
+
label: text("label").notNull(),
|
|
13235
|
+
// Absolute filesystem path — validated to be absolute at write time.
|
|
13236
|
+
path: text("path").notNull(),
|
|
13237
|
+
// UI display order; lower = appears first. Default 0.
|
|
13238
|
+
position: integer("position").default(0).notNull(),
|
|
13239
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
|
|
13240
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow()
|
|
13241
|
+
},
|
|
13242
|
+
(table) => [
|
|
13243
|
+
// Enforce label uniqueness per agent
|
|
13244
|
+
uniqueIndex("agent_workspaces_agent_label_unique").on(table.agentId, table.label),
|
|
13245
|
+
// Fast lookup of all workspaces for an agent (execute.ts, actions.ts)
|
|
13246
|
+
index("idx_agent_workspaces_agent_id").on(table.agentId)
|
|
13247
|
+
]
|
|
13248
|
+
);
|
|
13249
|
+
}
|
|
13250
|
+
});
|
|
13251
|
+
|
|
13175
13252
|
// ../../packages/db/src/schema/index.ts
|
|
13176
13253
|
var schema_exports = {};
|
|
13177
13254
|
__export(schema_exports, {
|
|
@@ -13209,6 +13286,7 @@ __export(schema_exports, {
|
|
|
13209
13286
|
agentSkillAssignments: () => agentSkillAssignments,
|
|
13210
13287
|
agentSkills: () => agentSkills,
|
|
13211
13288
|
agentTasks: () => agentTasks,
|
|
13289
|
+
agentWorkspaces: () => agentWorkspaces,
|
|
13212
13290
|
agents: () => agents,
|
|
13213
13291
|
approvalRequests: () => approvalRequests,
|
|
13214
13292
|
approvalRules: () => approvalRules,
|
|
@@ -13253,6 +13331,7 @@ var init_schema2 = __esm({
|
|
|
13253
13331
|
init_misc();
|
|
13254
13332
|
init_auth();
|
|
13255
13333
|
init_agent_connector_assignments();
|
|
13334
|
+
init_agent_workspaces();
|
|
13256
13335
|
}
|
|
13257
13336
|
});
|
|
13258
13337
|
|
|
@@ -13288,9 +13367,9 @@ var init_transaction = __esm({
|
|
|
13288
13367
|
|
|
13289
13368
|
// ../../packages/secrets/src/index.ts
|
|
13290
13369
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes3 } from "crypto";
|
|
13291
|
-
import { chmodSync, existsSync as
|
|
13370
|
+
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
13292
13371
|
import { homedir as homedir2 } from "os";
|
|
13293
|
-
import { dirname as
|
|
13372
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
13294
13373
|
var init_src3 = __esm({
|
|
13295
13374
|
"../../packages/secrets/src/index.ts"() {
|
|
13296
13375
|
"use strict";
|
|
@@ -13546,16 +13625,16 @@ var init_ports = __esm({
|
|
|
13546
13625
|
});
|
|
13547
13626
|
|
|
13548
13627
|
// src/lib/processes.ts
|
|
13549
|
-
import { execa } from "execa";
|
|
13550
|
-
import { createWriteStream, writeFileSync as writeFileSync4, readFileSync as readFileSync5, existsSync as
|
|
13551
|
-
import { join as
|
|
13552
|
-
import { fileURLToPath as
|
|
13628
|
+
import { execa as execa2 } from "execa";
|
|
13629
|
+
import { createWriteStream, writeFileSync as writeFileSync4, readFileSync as readFileSync5, existsSync as existsSync6 } from "fs";
|
|
13630
|
+
import { join as join6, dirname as dirname4, resolve } from "path";
|
|
13631
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
13553
13632
|
async function killProcessTree(child) {
|
|
13554
13633
|
const pid = child.pid;
|
|
13555
13634
|
if (!pid) return;
|
|
13556
13635
|
if (process.platform === "win32") {
|
|
13557
13636
|
try {
|
|
13558
|
-
await
|
|
13637
|
+
await execa2("taskkill", ["/T", "/F", "/PID", String(pid)], { reject: false });
|
|
13559
13638
|
} catch {
|
|
13560
13639
|
}
|
|
13561
13640
|
return;
|
|
@@ -13570,29 +13649,45 @@ async function killProcessTree(child) {
|
|
|
13570
13649
|
} catch {
|
|
13571
13650
|
}
|
|
13572
13651
|
}
|
|
13652
|
+
function isPidAlive(pid) {
|
|
13653
|
+
try {
|
|
13654
|
+
process.kill(pid, 0);
|
|
13655
|
+
return true;
|
|
13656
|
+
} catch (err) {
|
|
13657
|
+
return err.code === "EPERM";
|
|
13658
|
+
}
|
|
13659
|
+
}
|
|
13660
|
+
async function waitForPidDead(pid, timeoutMs = 5e3) {
|
|
13661
|
+
const deadline = Date.now() + timeoutMs;
|
|
13662
|
+
while (Date.now() < deadline) {
|
|
13663
|
+
if (!isPidAlive(pid)) return true;
|
|
13664
|
+
await sleep(250);
|
|
13665
|
+
}
|
|
13666
|
+
return !isPidAlive(pid);
|
|
13667
|
+
}
|
|
13573
13668
|
function resolveAppDir(appName) {
|
|
13574
|
-
const here =
|
|
13575
|
-
const fileDir =
|
|
13669
|
+
const here = fileURLToPath3(import.meta.url);
|
|
13670
|
+
const fileDir = dirname4(here);
|
|
13576
13671
|
let cursor = fileDir;
|
|
13577
13672
|
for (let i = 0; i < 8; i++) {
|
|
13578
|
-
if (
|
|
13579
|
-
return
|
|
13673
|
+
if (existsSync6(join6(cursor, "pnpm-workspace.yaml"))) {
|
|
13674
|
+
return join6(cursor, appName);
|
|
13580
13675
|
}
|
|
13581
|
-
const parent =
|
|
13676
|
+
const parent = dirname4(cursor);
|
|
13582
13677
|
if (parent === cursor) break;
|
|
13583
13678
|
cursor = parent;
|
|
13584
13679
|
}
|
|
13585
13680
|
return resolve(fileDir, "..", "..", "..", "..", appName);
|
|
13586
13681
|
}
|
|
13587
13682
|
function spawnRunner(env) {
|
|
13588
|
-
const logFile =
|
|
13683
|
+
const logFile = join6(LOG_DIR, "runner.log");
|
|
13589
13684
|
const outStream = createWriteStream(logFile, { flags: "a" });
|
|
13590
13685
|
let bin;
|
|
13591
13686
|
let args;
|
|
13592
13687
|
let cwd;
|
|
13593
13688
|
if (BUNDLED_ROOT) {
|
|
13594
13689
|
bin = process.execPath;
|
|
13595
|
-
args = [
|
|
13690
|
+
args = [join6(BUNDLED_ROOT, "runner.js")];
|
|
13596
13691
|
cwd = BUNDLED_ROOT;
|
|
13597
13692
|
} else {
|
|
13598
13693
|
const runnerDir = resolveAppDir("apps/runner");
|
|
@@ -13610,7 +13705,7 @@ env keys: ${Object.keys(env).join(",")}
|
|
|
13610
13705
|
|
|
13611
13706
|
`
|
|
13612
13707
|
);
|
|
13613
|
-
const child =
|
|
13708
|
+
const child = execa2(bin, args, {
|
|
13614
13709
|
cwd,
|
|
13615
13710
|
env: { ...process.env, ...env },
|
|
13616
13711
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -13624,7 +13719,7 @@ env keys: ${Object.keys(env).join(",")}
|
|
|
13624
13719
|
return child;
|
|
13625
13720
|
}
|
|
13626
13721
|
function spawnWeb(env, opts = {}) {
|
|
13627
|
-
const logFile =
|
|
13722
|
+
const logFile = join6(LOG_DIR, "web.log");
|
|
13628
13723
|
const outStream = createWriteStream(logFile, { flags: "a" });
|
|
13629
13724
|
let bin;
|
|
13630
13725
|
let args;
|
|
@@ -13632,8 +13727,8 @@ function spawnWeb(env, opts = {}) {
|
|
|
13632
13727
|
let modeLabel;
|
|
13633
13728
|
if (BUNDLED_ROOT) {
|
|
13634
13729
|
bin = process.execPath;
|
|
13635
|
-
args = [
|
|
13636
|
-
cwd =
|
|
13730
|
+
args = [join6(BUNDLED_ROOT, "web", "server.js")];
|
|
13731
|
+
cwd = join6(BUNDLED_ROOT, "web");
|
|
13637
13732
|
modeLabel = "bundled-standalone";
|
|
13638
13733
|
} else {
|
|
13639
13734
|
const webDir = resolveAppDir("apps/web");
|
|
@@ -13653,7 +13748,7 @@ env keys: ${Object.keys(env).join(",")}
|
|
|
13653
13748
|
|
|
13654
13749
|
`
|
|
13655
13750
|
);
|
|
13656
|
-
const child =
|
|
13751
|
+
const child = execa2(bin, args, {
|
|
13657
13752
|
cwd,
|
|
13658
13753
|
env: { ...process.env, ...env },
|
|
13659
13754
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -13666,14 +13761,14 @@ env keys: ${Object.keys(env).join(",")}
|
|
|
13666
13761
|
}
|
|
13667
13762
|
function resolveLocalBin(packageDir, binName) {
|
|
13668
13763
|
const ext = process.platform === "win32" ? ".CMD" : "";
|
|
13669
|
-
return
|
|
13764
|
+
return join6(packageDir, "node_modules", ".bin", `${binName}${ext}`);
|
|
13670
13765
|
}
|
|
13671
13766
|
function writePids(pids) {
|
|
13672
|
-
writeFileSync4(
|
|
13767
|
+
writeFileSync4(join6(PID_DIR, "processes.json"), JSON.stringify(pids, null, 2), "utf-8");
|
|
13673
13768
|
}
|
|
13674
13769
|
function readPids() {
|
|
13675
|
-
const pidFile =
|
|
13676
|
-
if (!
|
|
13770
|
+
const pidFile = join6(PID_DIR, "processes.json");
|
|
13771
|
+
if (!existsSync6(pidFile)) return null;
|
|
13677
13772
|
try {
|
|
13678
13773
|
return JSON.parse(readFileSync5(pidFile, "utf-8"));
|
|
13679
13774
|
} catch {
|
|
@@ -13681,8 +13776,8 @@ function readPids() {
|
|
|
13681
13776
|
}
|
|
13682
13777
|
}
|
|
13683
13778
|
function clearPids() {
|
|
13684
|
-
const pidFile =
|
|
13685
|
-
if (
|
|
13779
|
+
const pidFile = join6(PID_DIR, "processes.json");
|
|
13780
|
+
if (existsSync6(pidFile)) {
|
|
13686
13781
|
writeFileSync4(pidFile, JSON.stringify({}), "utf-8");
|
|
13687
13782
|
}
|
|
13688
13783
|
}
|
|
@@ -13710,8 +13805,8 @@ var init_processes = __esm({
|
|
|
13710
13805
|
"use strict";
|
|
13711
13806
|
init_config();
|
|
13712
13807
|
BUNDLED_ROOT = (() => {
|
|
13713
|
-
const here =
|
|
13714
|
-
return
|
|
13808
|
+
const here = dirname4(fileURLToPath3(import.meta.url));
|
|
13809
|
+
return existsSync6(join6(here, "runner.js")) ? here : null;
|
|
13715
13810
|
})();
|
|
13716
13811
|
}
|
|
13717
13812
|
});
|
|
@@ -13728,9 +13823,9 @@ async function killSilent(child) {
|
|
|
13728
13823
|
await killProcessTree(child);
|
|
13729
13824
|
}
|
|
13730
13825
|
async function pidListeningOnPort(port) {
|
|
13731
|
-
const { execa:
|
|
13826
|
+
const { execa: execa4 } = await import("execa");
|
|
13732
13827
|
try {
|
|
13733
|
-
const { stdout } = await
|
|
13828
|
+
const { stdout } = await execa4("netstat", ["-ano"], { reject: false });
|
|
13734
13829
|
for (const line2 of stdout.split(/\r?\n/)) {
|
|
13735
13830
|
const m = line2.match(/\s+TCP\s+\S+:(\d+)\s+\S+\s+LISTENING\s+(\d+)/);
|
|
13736
13831
|
if (m && m[1] && m[2] && Number.parseInt(m[1], 10) === port) {
|
|
@@ -13766,26 +13861,34 @@ async function runUp(opts = {}) {
|
|
|
13766
13861
|
console.log(chalk2.gray(` - ${o.name} on :${o.port} (pid ${o.pid})`));
|
|
13767
13862
|
}
|
|
13768
13863
|
console.log(chalk2.yellow("Cleaning up before starting\u2026"));
|
|
13769
|
-
const { execa:
|
|
13864
|
+
const { execa: execa4 } = await import("execa");
|
|
13770
13865
|
const pgOrphan = orphans.find((o) => o.name === "postgres");
|
|
13771
13866
|
if (pgOrphan) {
|
|
13772
|
-
|
|
13773
|
-
if (
|
|
13867
|
+
await stopOrphanPostgres();
|
|
13868
|
+
if (isPidAlive(pgOrphan.pid)) {
|
|
13774
13869
|
try {
|
|
13775
13870
|
if (process.platform === "win32") {
|
|
13776
|
-
await
|
|
13871
|
+
await execa4("taskkill", ["/T", "/F", "/PID", String(pgOrphan.pid)], { reject: false });
|
|
13777
13872
|
} else {
|
|
13778
13873
|
process.kill(pgOrphan.pid, "SIGKILL");
|
|
13779
13874
|
}
|
|
13780
13875
|
} catch {
|
|
13781
13876
|
}
|
|
13877
|
+
await waitForPidDead(pgOrphan.pid, 5e3);
|
|
13878
|
+
}
|
|
13879
|
+
if (isPidAlive(pgOrphan.pid)) {
|
|
13880
|
+
const killCmd = process.platform === "win32" ? `taskkill /T /F /PID ${pgOrphan.pid}` : `kill -9 ${pgOrphan.pid}`;
|
|
13881
|
+
throw new Error(
|
|
13882
|
+
`An orphaned Postgres (pid ${pgOrphan.pid}) is still running and holds the shared-memory block for the data dir. Rotating ports won't help \u2014 the SHM segment is keyed to the data dir, not the port.
|
|
13883
|
+
Fix: run \`nodal-agents down\`, then \`${killCmd}\`. If it persists, reboot to clear the orphan kernel object. No data is lost \u2014 pg-data is preserved.`
|
|
13884
|
+
);
|
|
13782
13885
|
}
|
|
13783
13886
|
}
|
|
13784
13887
|
for (const o of orphans) {
|
|
13785
13888
|
if (o.name === "postgres") continue;
|
|
13786
13889
|
try {
|
|
13787
13890
|
if (process.platform === "win32") {
|
|
13788
|
-
await
|
|
13891
|
+
await execa4("taskkill", ["/T", "/F", "/PID", String(o.pid)], { reject: false });
|
|
13789
13892
|
} else {
|
|
13790
13893
|
process.kill(o.pid, "SIGKILL");
|
|
13791
13894
|
}
|
|
@@ -13890,6 +13993,20 @@ async function runUp(opts = {}) {
|
|
|
13890
13993
|
clearPids();
|
|
13891
13994
|
throw err;
|
|
13892
13995
|
}
|
|
13996
|
+
void (async () => {
|
|
13997
|
+
try {
|
|
13998
|
+
const { getInstalledVersion: getInstalledVersion2, getLatestVersion: getLatestVersion2 } = await Promise.resolve().then(() => (init_version(), version_exports));
|
|
13999
|
+
const installed = getInstalledVersion2();
|
|
14000
|
+
const latest = await Promise.race([
|
|
14001
|
+
getLatestVersion2(),
|
|
14002
|
+
new Promise((resolve2) => setTimeout(() => resolve2(null), 3e3))
|
|
14003
|
+
]);
|
|
14004
|
+
if (latest !== null && latest !== installed) {
|
|
14005
|
+
console.log(chalk2.cyan(` \u2139 v${latest} available \u2014 run \`nodal-agents update\``));
|
|
14006
|
+
}
|
|
14007
|
+
} catch {
|
|
14008
|
+
}
|
|
14009
|
+
})();
|
|
13893
14010
|
if (!process.env["NODALAI_NO_BROWSER"]) {
|
|
13894
14011
|
try {
|
|
13895
14012
|
await open(webUrl);
|
|
@@ -13936,8 +14053,8 @@ __export(down_exports, {
|
|
|
13936
14053
|
runDown: () => runDown
|
|
13937
14054
|
});
|
|
13938
14055
|
import chalk3 from "chalk";
|
|
13939
|
-
import { existsSync as
|
|
13940
|
-
import { join as
|
|
14056
|
+
import { existsSync as existsSync7 } from "fs";
|
|
14057
|
+
import { join as join7 } from "path";
|
|
13941
14058
|
function killPid(pid, label) {
|
|
13942
14059
|
try {
|
|
13943
14060
|
process.kill(pid, "SIGTERM");
|
|
@@ -13954,8 +14071,8 @@ function killPid(pid, label) {
|
|
|
13954
14071
|
}
|
|
13955
14072
|
}
|
|
13956
14073
|
async function stopPostgresGracefully() {
|
|
13957
|
-
const pidFile =
|
|
13958
|
-
if (!
|
|
14074
|
+
const pidFile = join7(PG_DATA_DIR, "postmaster.pid");
|
|
14075
|
+
if (!existsSync7(pidFile)) return false;
|
|
13959
14076
|
try {
|
|
13960
14077
|
const EmbeddedPostgres = (await import("embedded-postgres")).default;
|
|
13961
14078
|
const pg = new EmbeddedPostgres({
|
|
@@ -14006,8 +14123,8 @@ __export(logs_exports, {
|
|
|
14006
14123
|
runLogs: () => runLogs
|
|
14007
14124
|
});
|
|
14008
14125
|
import chalk4 from "chalk";
|
|
14009
|
-
import { existsSync as
|
|
14010
|
-
import { join as
|
|
14126
|
+
import { existsSync as existsSync8, createReadStream, watch, statSync } from "fs";
|
|
14127
|
+
import { join as join8 } from "path";
|
|
14011
14128
|
function isServiceName(s) {
|
|
14012
14129
|
return VALID_SERVICES.includes(s);
|
|
14013
14130
|
}
|
|
@@ -14019,8 +14136,8 @@ async function runLogs(service) {
|
|
|
14019
14136
|
}
|
|
14020
14137
|
const services = target === "all" ? VALID_SERVICES : [target];
|
|
14021
14138
|
for (const svc of services) {
|
|
14022
|
-
const logFile =
|
|
14023
|
-
if (!
|
|
14139
|
+
const logFile = join8(LOG_DIR, `${svc}.log`);
|
|
14140
|
+
if (!existsSync8(logFile)) {
|
|
14024
14141
|
console.log(chalk4.gray(` [${svc}] No log file yet at ${logFile}`));
|
|
14025
14142
|
continue;
|
|
14026
14143
|
}
|
|
@@ -14034,8 +14151,8 @@ async function runLogs(service) {
|
|
|
14034
14151
|
});
|
|
14035
14152
|
}
|
|
14036
14153
|
if (target !== "all") {
|
|
14037
|
-
const logFile =
|
|
14038
|
-
if (!
|
|
14154
|
+
const logFile = join8(LOG_DIR, `${target}.log`);
|
|
14155
|
+
if (!existsSync8(logFile)) {
|
|
14039
14156
|
console.log(chalk4.yellow("Waiting for log file to be created\u2026"));
|
|
14040
14157
|
}
|
|
14041
14158
|
console.log(chalk4.gray("\nFollowing log (Ctrl+C to stop)...\n"));
|
|
@@ -14076,7 +14193,7 @@ __export(reset_exports, {
|
|
|
14076
14193
|
});
|
|
14077
14194
|
import chalk5 from "chalk";
|
|
14078
14195
|
import prompts2 from "prompts";
|
|
14079
|
-
import { rmSync, existsSync as
|
|
14196
|
+
import { rmSync, existsSync as existsSync9 } from "fs";
|
|
14080
14197
|
async function runReset(options = {}) {
|
|
14081
14198
|
if (!options.yes) {
|
|
14082
14199
|
const { confirm } = await prompts2({
|
|
@@ -14094,7 +14211,7 @@ async function runReset(options = {}) {
|
|
|
14094
14211
|
}
|
|
14095
14212
|
console.log(chalk5.yellow("Stopping any running processes\u2026"));
|
|
14096
14213
|
await runDown();
|
|
14097
|
-
if (
|
|
14214
|
+
if (existsSync9(CONFIG_DIR)) {
|
|
14098
14215
|
rmSync(CONFIG_DIR, { recursive: true, force: true });
|
|
14099
14216
|
console.log(chalk5.green(` Removed ${CONFIG_DIR}`));
|
|
14100
14217
|
} else {
|
|
@@ -14112,17 +14229,106 @@ var init_reset = __esm({
|
|
|
14112
14229
|
}
|
|
14113
14230
|
});
|
|
14114
14231
|
|
|
14232
|
+
// src/commands/update.ts
|
|
14233
|
+
var update_exports = {};
|
|
14234
|
+
__export(update_exports, {
|
|
14235
|
+
runUpdate: () => runUpdate
|
|
14236
|
+
});
|
|
14237
|
+
import chalk6 from "chalk";
|
|
14238
|
+
import { execa as execa3 } from "execa";
|
|
14239
|
+
async function runUpdate(opts = {}) {
|
|
14240
|
+
const installed = getInstalledVersion();
|
|
14241
|
+
const latest = await getLatestVersion();
|
|
14242
|
+
if (latest === null) {
|
|
14243
|
+
console.log(
|
|
14244
|
+
chalk6.yellow(
|
|
14245
|
+
"Could not reach the npm registry to check for the latest version (offline or npm not in PATH)."
|
|
14246
|
+
)
|
|
14247
|
+
);
|
|
14248
|
+
console.log(
|
|
14249
|
+
chalk6.yellow(
|
|
14250
|
+
"To update manually, run: npm install -g nodal-agents@latest && nodal-agents up"
|
|
14251
|
+
)
|
|
14252
|
+
);
|
|
14253
|
+
process.exit(1);
|
|
14254
|
+
}
|
|
14255
|
+
if (installed === latest) {
|
|
14256
|
+
console.log(chalk6.green(` \u2713 Already on the latest version (${installed})`));
|
|
14257
|
+
return;
|
|
14258
|
+
}
|
|
14259
|
+
console.log(chalk6.cyan(` \u2191 Updating ${installed} \u2192 ${latest}`));
|
|
14260
|
+
console.log(chalk6.gray(" Stopping services\u2026"));
|
|
14261
|
+
try {
|
|
14262
|
+
await runDown();
|
|
14263
|
+
} catch {
|
|
14264
|
+
}
|
|
14265
|
+
console.log(chalk6.gray(" Installing nodal-agents@latest\u2026"));
|
|
14266
|
+
try {
|
|
14267
|
+
await execa3("npm", ["install", "-g", "nodal-agents@latest"], { stdio: "inherit" });
|
|
14268
|
+
} catch (err) {
|
|
14269
|
+
const code = err.code;
|
|
14270
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
14271
|
+
if (code === "ENOENT" || message.includes("ENOENT")) {
|
|
14272
|
+
console.error(
|
|
14273
|
+
chalk6.red(
|
|
14274
|
+
"\n \u2717 npm not found in PATH.\n Make sure Node.js is installed and `npm` is on your PATH,\n then re-run `nodal-agents update`."
|
|
14275
|
+
)
|
|
14276
|
+
);
|
|
14277
|
+
process.exit(1);
|
|
14278
|
+
}
|
|
14279
|
+
if (code === "EACCES" || message.toLowerCase().includes("permission") || message.includes("EACCES")) {
|
|
14280
|
+
console.error(
|
|
14281
|
+
chalk6.red(
|
|
14282
|
+
"\n \u2717 Permission denied while installing.\n Run the command with elevated privileges:\n" + (process.platform === "win32" ? " Run your terminal as Administrator, then retry `nodal-agents update`." : " sudo nodal-agents update")
|
|
14283
|
+
)
|
|
14284
|
+
);
|
|
14285
|
+
process.exit(1);
|
|
14286
|
+
}
|
|
14287
|
+
throw err;
|
|
14288
|
+
}
|
|
14289
|
+
console.log(chalk6.green(" \u2713 nodal-agents updated."));
|
|
14290
|
+
if (opts.noRestart) {
|
|
14291
|
+
console.log(chalk6.cyan(" Run `nodal-agents up` to start the updated stack."));
|
|
14292
|
+
return;
|
|
14293
|
+
}
|
|
14294
|
+
console.log(chalk6.gray(" Starting updated services (detached)\u2026"));
|
|
14295
|
+
try {
|
|
14296
|
+
const child = execa3("nodal-agents", ["up"], {
|
|
14297
|
+
detached: true,
|
|
14298
|
+
stdio: "ignore",
|
|
14299
|
+
// Prefer the PATH-resolved global shim so the new version is loaded.
|
|
14300
|
+
shell: process.platform === "win32"
|
|
14301
|
+
});
|
|
14302
|
+
child.unref();
|
|
14303
|
+
} catch {
|
|
14304
|
+
console.log(
|
|
14305
|
+
chalk6.yellow(
|
|
14306
|
+
" Could not auto-start. Run `nodal-agents up` manually to start the updated stack."
|
|
14307
|
+
)
|
|
14308
|
+
);
|
|
14309
|
+
}
|
|
14310
|
+
console.log(chalk6.green(` \u2713 Updated to ${latest}. Services starting in background.`));
|
|
14311
|
+
}
|
|
14312
|
+
var init_update2 = __esm({
|
|
14313
|
+
"src/commands/update.ts"() {
|
|
14314
|
+
"use strict";
|
|
14315
|
+
init_version();
|
|
14316
|
+
init_down();
|
|
14317
|
+
}
|
|
14318
|
+
});
|
|
14319
|
+
|
|
14115
14320
|
// src/index.ts
|
|
14321
|
+
init_version();
|
|
14116
14322
|
import { Command } from "commander";
|
|
14117
|
-
import
|
|
14323
|
+
import chalk7 from "chalk";
|
|
14118
14324
|
var program = new Command();
|
|
14119
|
-
program.name("nodal-agents").description("Local AI agent platform \u2014 one command to start everything").version(
|
|
14325
|
+
program.name("nodal-agents").description("Local AI agent platform \u2014 one command to start everything").version(getInstalledVersion()).enablePositionalOptions();
|
|
14120
14326
|
program.option("--dev", "Run web in `next dev` mode (HMR, no prebuild required)").action(async (opts) => {
|
|
14121
14327
|
const { runUp: runUp2 } = await Promise.resolve().then(() => (init_up(), up_exports));
|
|
14122
14328
|
try {
|
|
14123
14329
|
await runUp2({ dev: opts.dev });
|
|
14124
14330
|
} catch (err) {
|
|
14125
|
-
console.error(
|
|
14331
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14126
14332
|
process.exit(1);
|
|
14127
14333
|
}
|
|
14128
14334
|
});
|
|
@@ -14134,7 +14340,7 @@ program.command("init").description("Interactive wizard \u2014 configure LLM, po
|
|
|
14134
14340
|
try {
|
|
14135
14341
|
await runInit2({ force: opts.force, nonInteractive: opts.nonInteractive });
|
|
14136
14342
|
} catch (err) {
|
|
14137
|
-
console.error(
|
|
14343
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14138
14344
|
process.exit(1);
|
|
14139
14345
|
}
|
|
14140
14346
|
});
|
|
@@ -14143,7 +14349,7 @@ program.command("up").description("Start Postgres, runner, and web \u2014 open b
|
|
|
14143
14349
|
try {
|
|
14144
14350
|
await runUp2({ dev: opts.dev });
|
|
14145
14351
|
} catch (err) {
|
|
14146
|
-
console.error(
|
|
14352
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14147
14353
|
process.exit(1);
|
|
14148
14354
|
}
|
|
14149
14355
|
});
|
|
@@ -14152,7 +14358,7 @@ program.command("down").description("Stop all running Nodal-Agents processes").a
|
|
|
14152
14358
|
try {
|
|
14153
14359
|
await runDown2();
|
|
14154
14360
|
} catch (err) {
|
|
14155
|
-
console.error(
|
|
14361
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14156
14362
|
process.exit(1);
|
|
14157
14363
|
}
|
|
14158
14364
|
});
|
|
@@ -14161,7 +14367,7 @@ program.command("logs [service]").description("Tail logs for a service (web | ru
|
|
|
14161
14367
|
try {
|
|
14162
14368
|
await runLogs2(service);
|
|
14163
14369
|
} catch (err) {
|
|
14164
|
-
console.error(
|
|
14370
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14165
14371
|
process.exit(1);
|
|
14166
14372
|
}
|
|
14167
14373
|
});
|
|
@@ -14170,7 +14376,16 @@ program.command("reset").description("Delete all Nodal-Agents data and config").
|
|
|
14170
14376
|
try {
|
|
14171
14377
|
await runReset2({ yes: opts.yes });
|
|
14172
14378
|
} catch (err) {
|
|
14173
|
-
console.error(
|
|
14379
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14380
|
+
process.exit(1);
|
|
14381
|
+
}
|
|
14382
|
+
});
|
|
14383
|
+
program.command("update").description("Update nodal-agents to the latest version and restart the stack").option("--no-restart", "Install the update but do not restart services automatically").action(async (opts) => {
|
|
14384
|
+
const { runUpdate: runUpdate2 } = await Promise.resolve().then(() => (init_update2(), update_exports));
|
|
14385
|
+
try {
|
|
14386
|
+
await runUpdate2({ noRestart: opts.restart === false });
|
|
14387
|
+
} catch (err) {
|
|
14388
|
+
console.error(chalk7.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
14174
14389
|
process.exit(1);
|
|
14175
14390
|
}
|
|
14176
14391
|
});
|