agent-remnote 1.0.0 → 1.1.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/CHANGELOG.md +6 -0
- package/dist/main.js +1783 -908
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -74062,6 +74062,7 @@ function resolveStaleMs(explicit) {
|
|
|
74062
74062
|
// src/lib/remnote.ts
|
|
74063
74063
|
import fs2 from "node:fs";
|
|
74064
74064
|
import path5 from "node:path";
|
|
74065
|
+
var SECONDARY_WORKSPACE_DIRS = new Set(["browser", "remnote-browser", "lnotes"]);
|
|
74065
74066
|
function tryParseRemnoteLink(input) {
|
|
74066
74067
|
const raw4 = input.trim();
|
|
74067
74068
|
let u;
|
|
@@ -74107,6 +74108,47 @@ function tryParseRemnoteLinkFromRef(input) {
|
|
|
74107
74108
|
function remnoteDbPathForWorkspaceId(workspaceId) {
|
|
74108
74109
|
return path5.join(homeDir(), "remnote", `remnote-${workspaceId}`, "remnote.db");
|
|
74109
74110
|
}
|
|
74111
|
+
function discoverWorkspaceCandidatesSync(baseDir = path5.join(homeDir(), "remnote")) {
|
|
74112
|
+
let entries2;
|
|
74113
|
+
try {
|
|
74114
|
+
entries2 = fs2.readdirSync(baseDir, { withFileTypes: true });
|
|
74115
|
+
} catch {
|
|
74116
|
+
return [];
|
|
74117
|
+
}
|
|
74118
|
+
const out = [];
|
|
74119
|
+
for (const entry of entries2) {
|
|
74120
|
+
if (!entry.isDirectory() || entry.name === "backups")
|
|
74121
|
+
continue;
|
|
74122
|
+
const isPrimary = entry.name.startsWith("remnote-");
|
|
74123
|
+
const isSecondary = SECONDARY_WORKSPACE_DIRS.has(entry.name);
|
|
74124
|
+
if (!isPrimary && !isSecondary)
|
|
74125
|
+
continue;
|
|
74126
|
+
const workspaceId = isPrimary ? entry.name.slice("remnote-".length).trim() : entry.name.trim();
|
|
74127
|
+
if (!workspaceId)
|
|
74128
|
+
continue;
|
|
74129
|
+
const dbPath = path5.join(baseDir, entry.name, "remnote.db");
|
|
74130
|
+
try {
|
|
74131
|
+
const stat3 = fs2.statSync(dbPath);
|
|
74132
|
+
if (!stat3.isFile())
|
|
74133
|
+
continue;
|
|
74134
|
+
out.push({
|
|
74135
|
+
workspaceId,
|
|
74136
|
+
dbPath,
|
|
74137
|
+
kind: isPrimary ? "primary" : "secondary",
|
|
74138
|
+
dirName: entry.name,
|
|
74139
|
+
mtimeMs: Number(stat3.mtimeMs ?? 0)
|
|
74140
|
+
});
|
|
74141
|
+
} catch {
|
|
74142
|
+
continue;
|
|
74143
|
+
}
|
|
74144
|
+
}
|
|
74145
|
+
out.sort((a, b) => {
|
|
74146
|
+
if (a.kind !== b.kind)
|
|
74147
|
+
return a.kind === "primary" ? -1 : 1;
|
|
74148
|
+
return b.mtimeMs - a.mtimeMs;
|
|
74149
|
+
});
|
|
74150
|
+
return out;
|
|
74151
|
+
}
|
|
74110
74152
|
function tryResolveRemnoteDbPathForWorkspaceIdSync(workspaceId) {
|
|
74111
74153
|
const p3 = remnoteDbPathForWorkspaceId(workspaceId);
|
|
74112
74154
|
try {
|
|
@@ -75915,8 +75957,38 @@ var migration5 = {
|
|
|
75915
75957
|
}
|
|
75916
75958
|
};
|
|
75917
75959
|
|
|
75960
|
+
// src/internal/store/migrations/0006-add-workspace-bindings.ts
|
|
75961
|
+
var WORKSPACE_BINDINGS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS workspace_bindings (
|
|
75962
|
+
workspace_id TEXT PRIMARY KEY,
|
|
75963
|
+
kb_name TEXT,
|
|
75964
|
+
db_path TEXT NOT NULL,
|
|
75965
|
+
source TEXT NOT NULL CHECK (source IN ('explicit','live_ui_context','single_candidate_auto','deep_link')),
|
|
75966
|
+
is_current INTEGER NOT NULL DEFAULT 0 CHECK (is_current IN (0, 1)),
|
|
75967
|
+
first_seen_at INTEGER NOT NULL,
|
|
75968
|
+
last_verified_at INTEGER NOT NULL,
|
|
75969
|
+
last_ui_context_at INTEGER,
|
|
75970
|
+
updated_at INTEGER NOT NULL
|
|
75971
|
+
);`;
|
|
75972
|
+
var WORKSPACE_BINDINGS_CURRENT_INDEX_SQL = `CREATE UNIQUE INDEX IF NOT EXISTS uq_workspace_bindings_current ON workspace_bindings(is_current) WHERE is_current = 1;`;
|
|
75973
|
+
var WORKSPACE_BINDINGS_UPDATED_AT_INDEX_SQL = `CREATE INDEX IF NOT EXISTS idx_workspace_bindings_updated_at ON workspace_bindings(updated_at DESC);`;
|
|
75974
|
+
var WORKSPACE_BINDINGS_MIGRATION_SQL = [
|
|
75975
|
+
WORKSPACE_BINDINGS_TABLE_SQL,
|
|
75976
|
+
WORKSPACE_BINDINGS_CURRENT_INDEX_SQL,
|
|
75977
|
+
WORKSPACE_BINDINGS_UPDATED_AT_INDEX_SQL
|
|
75978
|
+
];
|
|
75979
|
+
var migration6 = {
|
|
75980
|
+
version: 6,
|
|
75981
|
+
name: "add_workspace_bindings",
|
|
75982
|
+
checksumInput: WORKSPACE_BINDINGS_MIGRATION_SQL.join(`
|
|
75983
|
+
`),
|
|
75984
|
+
apply: (db) => {
|
|
75985
|
+
db.exec(WORKSPACE_BINDINGS_MIGRATION_SQL.join(`
|
|
75986
|
+
`));
|
|
75987
|
+
}
|
|
75988
|
+
};
|
|
75989
|
+
|
|
75918
75990
|
// src/internal/store/migrations/index.ts
|
|
75919
|
-
var migrationSpecs = [migration, migration2, migration3, migration4, migration5];
|
|
75991
|
+
var migrationSpecs = [migration, migration2, migration3, migration4, migration5, migration6];
|
|
75920
75992
|
|
|
75921
75993
|
// src/internal/store/db.ts
|
|
75922
75994
|
class StoreSchemaError extends Error {
|
|
@@ -76037,6 +76109,25 @@ CREATE TABLE IF NOT EXISTS queue_consumers (
|
|
|
76037
76109
|
last_seen_at INTEGER NOT NULL,
|
|
76038
76110
|
meta_json TEXT NOT NULL DEFAULT '{}'
|
|
76039
76111
|
);
|
|
76112
|
+
|
|
76113
|
+
CREATE TABLE IF NOT EXISTS workspace_bindings (
|
|
76114
|
+
workspace_id TEXT PRIMARY KEY,
|
|
76115
|
+
kb_name TEXT,
|
|
76116
|
+
db_path TEXT NOT NULL,
|
|
76117
|
+
source TEXT NOT NULL CHECK (source IN ('explicit','live_ui_context','single_candidate_auto','deep_link')),
|
|
76118
|
+
is_current INTEGER NOT NULL DEFAULT 0 CHECK (is_current IN (0, 1)),
|
|
76119
|
+
first_seen_at INTEGER NOT NULL,
|
|
76120
|
+
last_verified_at INTEGER NOT NULL,
|
|
76121
|
+
last_ui_context_at INTEGER,
|
|
76122
|
+
updated_at INTEGER NOT NULL
|
|
76123
|
+
);
|
|
76124
|
+
|
|
76125
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uq_workspace_bindings_current
|
|
76126
|
+
ON workspace_bindings(is_current)
|
|
76127
|
+
WHERE is_current = 1;
|
|
76128
|
+
|
|
76129
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_bindings_updated_at
|
|
76130
|
+
ON workspace_bindings(updated_at DESC);
|
|
76040
76131
|
`;
|
|
76041
76132
|
function absoluteDefaultStorePath() {
|
|
76042
76133
|
return path12.join(homeDir(), ".agent-remnote", "store.sqlite");
|
|
@@ -76233,17 +76324,17 @@ function readAppliedMigrations(db) {
|
|
|
76233
76324
|
return new Map;
|
|
76234
76325
|
}
|
|
76235
76326
|
}
|
|
76236
|
-
function ensureMigrationRecorded(db,
|
|
76237
|
-
const existing = db.prepare(`SELECT name, checksum FROM store_migrations WHERE version=?`).get(
|
|
76327
|
+
function ensureMigrationRecorded(db, migration7, appliedAt, appVersion) {
|
|
76328
|
+
const existing = db.prepare(`SELECT name, checksum FROM store_migrations WHERE version=?`).get(migration7.version);
|
|
76238
76329
|
if (existing) {
|
|
76239
76330
|
const actualChecksum = typeof existing?.checksum === "string" ? existing.checksum : String(existing?.checksum ?? "");
|
|
76240
|
-
if (actualChecksum !==
|
|
76331
|
+
if (actualChecksum !== migration7.checksum) {
|
|
76241
76332
|
throw new StoreSchemaError({
|
|
76242
76333
|
code: "STORE_SCHEMA_INVALID",
|
|
76243
76334
|
message: "Store database migration drift detected",
|
|
76244
76335
|
details: {
|
|
76245
|
-
version:
|
|
76246
|
-
expected: { name:
|
|
76336
|
+
version: migration7.version,
|
|
76337
|
+
expected: { name: migration7.name, checksum: migration7.checksum },
|
|
76247
76338
|
actual: { name: String(existing?.name ?? ""), checksum: actualChecksum }
|
|
76248
76339
|
},
|
|
76249
76340
|
nextActions: ["Upgrade `agent-remnote` to a newer version", "agent-remnote doctor"]
|
|
@@ -76254,9 +76345,9 @@ function ensureMigrationRecorded(db, migration6, appliedAt, appVersion) {
|
|
|
76254
76345
|
try {
|
|
76255
76346
|
db.prepare(`INSERT INTO store_migrations(version, name, checksum, applied_at, app_version)
|
|
76256
76347
|
VALUES(@version, @name, @checksum, @applied_at, @app_version)`).run({
|
|
76257
|
-
version:
|
|
76258
|
-
name:
|
|
76259
|
-
checksum:
|
|
76348
|
+
version: migration7.version,
|
|
76349
|
+
name: migration7.name,
|
|
76350
|
+
checksum: migration7.checksum,
|
|
76260
76351
|
applied_at: appliedAt,
|
|
76261
76352
|
app_version: appVersion
|
|
76262
76353
|
});
|
|
@@ -76264,15 +76355,15 @@ function ensureMigrationRecorded(db, migration6, appliedAt, appVersion) {
|
|
|
76264
76355
|
const code2 = String(e?.code || "");
|
|
76265
76356
|
if (code2 !== "SQLITE_CONSTRAINT" && code2 !== "SQLITE_CONSTRAINT_PRIMARYKEY" && code2 !== "SQLITE_CONSTRAINT_UNIQUE")
|
|
76266
76357
|
throw e;
|
|
76267
|
-
const again = db.prepare(`SELECT name, checksum FROM store_migrations WHERE version=?`).get(
|
|
76358
|
+
const again = db.prepare(`SELECT name, checksum FROM store_migrations WHERE version=?`).get(migration7.version);
|
|
76268
76359
|
const actualChecksum = typeof again?.checksum === "string" ? again.checksum : String(again?.checksum ?? "");
|
|
76269
|
-
if (actualChecksum !==
|
|
76360
|
+
if (actualChecksum !== migration7.checksum) {
|
|
76270
76361
|
throw new StoreSchemaError({
|
|
76271
76362
|
code: "STORE_SCHEMA_INVALID",
|
|
76272
76363
|
message: "Store database migration drift detected",
|
|
76273
76364
|
details: {
|
|
76274
|
-
version:
|
|
76275
|
-
expected: { name:
|
|
76365
|
+
version: migration7.version,
|
|
76366
|
+
expected: { name: migration7.name, checksum: migration7.checksum },
|
|
76276
76367
|
actual: { name: String(again?.name ?? ""), checksum: actualChecksum }
|
|
76277
76368
|
},
|
|
76278
76369
|
nextActions: ["Upgrade `agent-remnote` to a newer version", "agent-remnote doctor"]
|
|
@@ -76307,8 +76398,8 @@ function ensureAuditUpTo(db, version) {
|
|
|
76307
76398
|
}
|
|
76308
76399
|
}
|
|
76309
76400
|
function applyMigration(db, targetVersion) {
|
|
76310
|
-
const
|
|
76311
|
-
if (!
|
|
76401
|
+
const migration7 = MIGRATION_PLAN.migrations[targetVersion - 1];
|
|
76402
|
+
if (!migration7 || migration7.version !== targetVersion) {
|
|
76312
76403
|
throw new StoreSchemaError({
|
|
76313
76404
|
code: "STORE_SCHEMA_UNKNOWN",
|
|
76314
76405
|
message: `Unknown store migration target: ${targetVersion}`,
|
|
@@ -76316,8 +76407,8 @@ function applyMigration(db, targetVersion) {
|
|
|
76316
76407
|
nextActions: ["Report this as a bug"]
|
|
76317
76408
|
});
|
|
76318
76409
|
}
|
|
76319
|
-
|
|
76320
|
-
ensureMigrationRecorded(db,
|
|
76410
|
+
migration7.apply(db);
|
|
76411
|
+
ensureMigrationRecorded(db, migration7, Date.now(), appVersionForAudit());
|
|
76321
76412
|
}
|
|
76322
76413
|
function migrate(db, resolvedPath) {
|
|
76323
76414
|
const initial = readUserVersion(db);
|
|
@@ -87251,7 +87342,7 @@ function loadCellsForRows(db, rowIds, ctx) {
|
|
|
87251
87342
|
json_extract(doc, '$.parent') AS parentId
|
|
87252
87343
|
FROM quanta
|
|
87253
87344
|
WHERE json_extract(doc, '$.parent') IN (${placeholders})
|
|
87254
|
-
|
|
87345
|
+
`).all(...rowIds);
|
|
87255
87346
|
for (const row of rows) {
|
|
87256
87347
|
const doc = safeJsonParse(row.doc) ?? {};
|
|
87257
87348
|
const parentId = typeof row.parentId === "string" ? row.parentId : "";
|
|
@@ -87263,6 +87354,8 @@ function loadCellsForRows(db, rowIds, ctx) {
|
|
|
87263
87354
|
if (!propertyId)
|
|
87264
87355
|
continue;
|
|
87265
87356
|
const prop = ctx.propertiesById.get(propertyId);
|
|
87357
|
+
if (!prop)
|
|
87358
|
+
continue;
|
|
87266
87359
|
const kind = String(prop?.kind ?? "unknown");
|
|
87267
87360
|
const propertyName = String(prop?.name ?? propertyId);
|
|
87268
87361
|
const valueTokens = doc.value;
|
|
@@ -87314,33 +87407,38 @@ function loadCellsForRows(db, rowIds, ctx) {
|
|
|
87314
87407
|
return { cellsByRowId, dailyInfoById };
|
|
87315
87408
|
}
|
|
87316
87409
|
function loadProperties(db, tagId) {
|
|
87410
|
+
const propertyMarkerIds = loadPropertyMarkerIds(db);
|
|
87317
87411
|
const stmt = db.prepare(`SELECT _id AS id,
|
|
87318
87412
|
doc,
|
|
87319
87413
|
json_extract(doc, '$.rcrs') AS rawType
|
|
87320
87414
|
FROM quanta
|
|
87321
87415
|
WHERE json_extract(doc, '$.parent') = @tagId
|
|
87322
|
-
AND json_extract(doc, '$.rcrs') IS NOT NULL
|
|
87323
87416
|
ORDER BY json_extract(doc, '$.f')`);
|
|
87324
87417
|
const optionStmt = db.prepare(`SELECT _id AS id,
|
|
87325
87418
|
doc,
|
|
87326
87419
|
json_extract(doc, '$.rcre') AS rawOptionType
|
|
87327
87420
|
FROM quanta
|
|
87328
87421
|
WHERE json_extract(doc, '$.parent') = @parent
|
|
87329
|
-
AND json_extract(doc, '$.rcre') IS NOT NULL
|
|
87330
87422
|
ORDER BY json_extract(doc, '$.f')`);
|
|
87331
87423
|
const properties = [];
|
|
87332
87424
|
const optionNameById = new Map;
|
|
87333
87425
|
const propertyRows = stmt.all({ tagId });
|
|
87334
87426
|
for (const row of propertyRows) {
|
|
87335
87427
|
const doc = safeJsonParse(row.doc);
|
|
87336
|
-
|
|
87337
|
-
|
|
87338
|
-
|
|
87428
|
+
if (!isPropertyDoc(doc, propertyMarkerIds) && typeof row.rawType !== "string") {
|
|
87429
|
+
continue;
|
|
87430
|
+
}
|
|
87431
|
+
const fieldType = typeof doc?.ft === "string" ? String(doc.ft) : null;
|
|
87432
|
+
const rawType = typeof row.rawType === "string" ? row.rawType : fieldType;
|
|
87433
|
+
const typeCode = rawType ? rawType.split(".")[1] ?? rawType : null;
|
|
87339
87434
|
const summary6 = summarizeKey(doc?.key, db, { expand: false, maxDepth: 0 });
|
|
87435
|
+
const propertyKindHint = typeCode ? mapPropertyType(typeCode) : null;
|
|
87340
87436
|
const options6 = [];
|
|
87341
87437
|
const optionRows = optionStmt.all({ parent: row.id });
|
|
87342
87438
|
for (const optionRow of optionRows) {
|
|
87343
87439
|
const optionDoc = safeJsonParse(optionRow.doc);
|
|
87440
|
+
if (!isOptionDoc(optionDoc, optionRow.rawOptionType, propertyMarkerIds, propertyKindHint))
|
|
87441
|
+
continue;
|
|
87344
87442
|
const optionSummary = summarizeKey(optionDoc?.key, db, { expand: false, maxDepth: 0 });
|
|
87345
87443
|
const pdRaw = optionDoc?.pd;
|
|
87346
87444
|
const pdObject = typeof pdRaw === "string" ? safeJsonParse(pdRaw) : pdRaw;
|
|
@@ -87359,6 +87457,7 @@ function loadProperties(db, tagId) {
|
|
|
87359
87457
|
});
|
|
87360
87458
|
optionNameById.set(optionRow.id, optionSummary.text || optionRow.id);
|
|
87361
87459
|
}
|
|
87460
|
+
const kind = inferPropertyKind({ typeCode, options: options6 });
|
|
87362
87461
|
properties.push({
|
|
87363
87462
|
id: row.id,
|
|
87364
87463
|
name: summary6.text || row.id,
|
|
@@ -87372,6 +87471,50 @@ function loadProperties(db, tagId) {
|
|
|
87372
87471
|
optionNameById
|
|
87373
87472
|
};
|
|
87374
87473
|
}
|
|
87474
|
+
function loadPropertyMarkerIds(db) {
|
|
87475
|
+
const rows = db.prepare(`SELECT _id AS id
|
|
87476
|
+
FROM quanta
|
|
87477
|
+
WHERE json_extract(doc, '$.rcrt') = 'y'`).all();
|
|
87478
|
+
return new Set(rows.map((row) => String(row.id ?? "")).filter(Boolean));
|
|
87479
|
+
}
|
|
87480
|
+
function isPropertyDoc(doc, propertyMarkerIds) {
|
|
87481
|
+
if (!doc || typeof doc !== "object")
|
|
87482
|
+
return false;
|
|
87483
|
+
const tp = doc.tp;
|
|
87484
|
+
if (!tp || typeof tp !== "object" || Array.isArray(tp))
|
|
87485
|
+
return false;
|
|
87486
|
+
for (const markerId of propertyMarkerIds) {
|
|
87487
|
+
const value8 = tp[markerId];
|
|
87488
|
+
if (!value8 || typeof value8 !== "object")
|
|
87489
|
+
continue;
|
|
87490
|
+
if (value8.t === true)
|
|
87491
|
+
return true;
|
|
87492
|
+
}
|
|
87493
|
+
return false;
|
|
87494
|
+
}
|
|
87495
|
+
function isOptionDoc(doc, rawOptionType, propertyMarkerIds, propertyKindHint) {
|
|
87496
|
+
if (!doc || typeof doc !== "object")
|
|
87497
|
+
return false;
|
|
87498
|
+
if (isPropertyDoc(doc, propertyMarkerIds))
|
|
87499
|
+
return false;
|
|
87500
|
+
if (doc.tc === true)
|
|
87501
|
+
return false;
|
|
87502
|
+
if (Array.isArray(doc.value))
|
|
87503
|
+
return false;
|
|
87504
|
+
const key = doc.key;
|
|
87505
|
+
if (!Array.isArray(key) || key.length === 0)
|
|
87506
|
+
return false;
|
|
87507
|
+
if (typeof rawOptionType === "string" && rawOptionType.trim())
|
|
87508
|
+
return true;
|
|
87509
|
+
return propertyKindHint === "select" || propertyKindHint === "multi_select";
|
|
87510
|
+
}
|
|
87511
|
+
function inferPropertyKind(params3) {
|
|
87512
|
+
if (params3.typeCode)
|
|
87513
|
+
return mapPropertyType(params3.typeCode);
|
|
87514
|
+
if (params3.options.length > 0)
|
|
87515
|
+
return "unknown";
|
|
87516
|
+
return "text";
|
|
87517
|
+
}
|
|
87375
87518
|
function loadRows(db, tagId, options6) {
|
|
87376
87519
|
const countRow = db.prepare(`SELECT COUNT(*) AS total
|
|
87377
87520
|
FROM (
|
|
@@ -87401,16 +87544,22 @@ function mapPropertyType(code2) {
|
|
|
87401
87544
|
return "unknown";
|
|
87402
87545
|
switch (code2) {
|
|
87403
87546
|
case "s":
|
|
87547
|
+
case "single_select":
|
|
87404
87548
|
return "select";
|
|
87405
87549
|
case "m":
|
|
87550
|
+
case "multi_select":
|
|
87406
87551
|
return "multi_select";
|
|
87407
87552
|
case "t":
|
|
87553
|
+
case "text":
|
|
87408
87554
|
return "text";
|
|
87409
87555
|
case "n":
|
|
87556
|
+
case "number":
|
|
87410
87557
|
return "number";
|
|
87411
87558
|
case "d":
|
|
87559
|
+
case "date":
|
|
87412
87560
|
return "date";
|
|
87413
87561
|
case "c":
|
|
87562
|
+
case "checkbox":
|
|
87414
87563
|
return "checkbox";
|
|
87415
87564
|
default:
|
|
87416
87565
|
return `unknown(${code2})`;
|
|
@@ -92880,10 +93029,50 @@ var dailySummaryCommand = exports_Command.make("summary", { days: days2, maxLine
|
|
|
92880
93029
|
yield* writeSuccess({ data: result, md: result.markdown ?? "" });
|
|
92881
93030
|
}).pipe(catchAll2(writeFailure)));
|
|
92882
93031
|
|
|
92883
|
-
// src/
|
|
93032
|
+
// src/lib/apiUrls.ts
|
|
93033
|
+
function normalizeApiBasePath2(basePath) {
|
|
93034
|
+
const trimmed2 = basePath.trim();
|
|
93035
|
+
if (!trimmed2)
|
|
93036
|
+
return "/v1";
|
|
93037
|
+
const normalized = trimmed2.startsWith("/") ? trimmed2 : `/${trimmed2}`;
|
|
93038
|
+
const withoutTrailing = normalized.replace(/\/+$/, "");
|
|
93039
|
+
return withoutTrailing && withoutTrailing !== "/" ? withoutTrailing : "/";
|
|
93040
|
+
}
|
|
92884
93041
|
function normalizeBaseUrl(baseUrl) {
|
|
92885
93042
|
return baseUrl.trim().replace(/\/+$/, "");
|
|
92886
93043
|
}
|
|
93044
|
+
function resolveBasePrefix(baseUrl, fallbackBasePath) {
|
|
93045
|
+
const parsed = new URL(normalizeBaseUrl(baseUrl));
|
|
93046
|
+
const pathname = normalizeApiBasePath2(parsed.pathname);
|
|
93047
|
+
if (pathname && pathname !== "/")
|
|
93048
|
+
return normalizeApiBasePath2(pathname);
|
|
93049
|
+
return normalizeApiBasePath2(fallbackBasePath);
|
|
93050
|
+
}
|
|
93051
|
+
function normalizeRoutePath(routePath) {
|
|
93052
|
+
const trimmed2 = routePath.trim();
|
|
93053
|
+
if (!trimmed2)
|
|
93054
|
+
return "";
|
|
93055
|
+
return `/${trimmed2.replace(/^\/+/, "")}`;
|
|
93056
|
+
}
|
|
93057
|
+
function buildApiBaseUrl(baseUrl, fallbackBasePath = "/v1") {
|
|
93058
|
+
const parsed = new URL(normalizeBaseUrl(baseUrl));
|
|
93059
|
+
const prefix2 = resolveBasePrefix(baseUrl, fallbackBasePath);
|
|
93060
|
+
return prefix2 === "/" ? parsed.origin : `${parsed.origin}${prefix2}`;
|
|
93061
|
+
}
|
|
93062
|
+
function apiLocalBaseUrl(port3, basePath = "/v1") {
|
|
93063
|
+
return buildApiBaseUrl(`http://127.0.0.1:${port3}`, basePath);
|
|
93064
|
+
}
|
|
93065
|
+
function apiContainerBaseUrl(port3, basePath = "/v1") {
|
|
93066
|
+
return buildApiBaseUrl(`http://host.docker.internal:${port3}`, basePath);
|
|
93067
|
+
}
|
|
93068
|
+
function joinApiUrl(baseUrl, routePath, fallbackBasePath = "/v1") {
|
|
93069
|
+
return `${buildApiBaseUrl(baseUrl, fallbackBasePath)}${normalizeRoutePath(routePath)}`;
|
|
93070
|
+
}
|
|
93071
|
+
|
|
93072
|
+
// src/services/HostApiClient.ts
|
|
93073
|
+
function normalizeBaseUrl2(baseUrl) {
|
|
93074
|
+
return baseUrl.trim().replace(/\/+$/, "");
|
|
93075
|
+
}
|
|
92887
93076
|
function apiTimeoutError(params3) {
|
|
92888
93077
|
return new CliError({
|
|
92889
93078
|
code: "API_TIMEOUT",
|
|
@@ -92929,8 +93118,8 @@ function buildQuery(params3) {
|
|
|
92929
93118
|
}
|
|
92930
93119
|
function requestJson(params3) {
|
|
92931
93120
|
const timeoutMs = Math.max(1, params3.timeoutMs ?? 15000);
|
|
92932
|
-
const baseUrl =
|
|
92933
|
-
const url2 =
|
|
93121
|
+
const baseUrl = normalizeBaseUrl2(params3.baseUrl);
|
|
93122
|
+
const url2 = joinApiUrl(baseUrl, params3.path, params3.basePath);
|
|
92934
93123
|
return async((resume2) => {
|
|
92935
93124
|
const controller = new AbortController;
|
|
92936
93125
|
const timer2 = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -92984,289 +93173,304 @@ function requestJson(params3) {
|
|
|
92984
93173
|
|
|
92985
93174
|
class HostApiClient extends Tag2("HostApiClient")() {
|
|
92986
93175
|
}
|
|
92987
|
-
var HostApiClientLive =
|
|
92988
|
-
|
|
92989
|
-
|
|
92990
|
-
|
|
92991
|
-
|
|
92992
|
-
|
|
92993
|
-
method: "GET",
|
|
92994
|
-
timeoutMs
|
|
92995
|
-
|
|
92996
|
-
|
|
92997
|
-
|
|
92998
|
-
|
|
92999
|
-
|
|
93000
|
-
timeoutMs
|
|
93001
|
-
|
|
93002
|
-
|
|
93003
|
-
|
|
93004
|
-
|
|
93005
|
-
|
|
93006
|
-
timeoutMs
|
|
93007
|
-
|
|
93008
|
-
|
|
93009
|
-
|
|
93010
|
-
|
|
93011
|
-
|
|
93012
|
-
timeoutMs
|
|
93013
|
-
|
|
93014
|
-
|
|
93015
|
-
|
|
93016
|
-
|
|
93017
|
-
|
|
93018
|
-
timeoutMs
|
|
93019
|
-
|
|
93020
|
-
|
|
93021
|
-
|
|
93022
|
-
|
|
93023
|
-
|
|
93024
|
-
timeoutMs
|
|
93025
|
-
|
|
93026
|
-
|
|
93027
|
-
|
|
93028
|
-
|
|
93029
|
-
|
|
93030
|
-
timeoutMs
|
|
93031
|
-
|
|
93032
|
-
|
|
93033
|
-
|
|
93034
|
-
|
|
93035
|
-
|
|
93036
|
-
timeoutMs
|
|
93037
|
-
|
|
93038
|
-
|
|
93039
|
-
|
|
93040
|
-
|
|
93041
|
-
|
|
93042
|
-
|
|
93043
|
-
|
|
93044
|
-
|
|
93045
|
-
|
|
93046
|
-
baseUrl,
|
|
93047
|
-
|
|
93048
|
-
method: "
|
|
93049
|
-
timeoutMs
|
|
93050
|
-
|
|
93051
|
-
|
|
93052
|
-
|
|
93053
|
-
|
|
93054
|
-
})
|
|
93176
|
+
var HostApiClientLive = effect(HostApiClient, gen2(function* () {
|
|
93177
|
+
const cfg = yield* AppConfig;
|
|
93178
|
+
const basePath = cfg.apiBasePath ?? "/v1";
|
|
93179
|
+
const request = (params3) => requestJson({ ...params3, basePath });
|
|
93180
|
+
return {
|
|
93181
|
+
health: ({ baseUrl, timeoutMs }) => request({ baseUrl, path: "/health", method: "GET", timeoutMs }),
|
|
93182
|
+
status: ({ baseUrl, timeoutMs }) => request({ baseUrl, path: "/status", method: "GET", timeoutMs }),
|
|
93183
|
+
uiContextSnapshot: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, timeoutMs }) => request({
|
|
93184
|
+
baseUrl,
|
|
93185
|
+
path: `/plugin/ui-context/snapshot${buildQuery({ stateFile: stateFile3, staleMs: staleMs2 })}`,
|
|
93186
|
+
method: "GET",
|
|
93187
|
+
timeoutMs
|
|
93188
|
+
}),
|
|
93189
|
+
uiContextPage: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, timeoutMs }) => request({
|
|
93190
|
+
baseUrl,
|
|
93191
|
+
path: `/plugin/ui-context/page${buildQuery({ stateFile: stateFile3, staleMs: staleMs2 })}`,
|
|
93192
|
+
method: "GET",
|
|
93193
|
+
timeoutMs
|
|
93194
|
+
}),
|
|
93195
|
+
uiContextFocusedRem: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, timeoutMs }) => request({
|
|
93196
|
+
baseUrl,
|
|
93197
|
+
path: `/plugin/ui-context/focused-rem${buildQuery({ stateFile: stateFile3, staleMs: staleMs2 })}`,
|
|
93198
|
+
method: "GET",
|
|
93199
|
+
timeoutMs
|
|
93200
|
+
}),
|
|
93201
|
+
uiContextDescribe: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, selectionLimit, timeoutMs }) => request({
|
|
93202
|
+
baseUrl,
|
|
93203
|
+
path: `/plugin/ui-context/describe${buildQuery({ stateFile: stateFile3, staleMs: staleMs2, selectionLimit })}`,
|
|
93204
|
+
method: "GET",
|
|
93205
|
+
timeoutMs
|
|
93206
|
+
}),
|
|
93207
|
+
selectionSnapshot: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, timeoutMs }) => request({
|
|
93208
|
+
baseUrl,
|
|
93209
|
+
path: `/plugin/selection/snapshot${buildQuery({ stateFile: stateFile3, staleMs: staleMs2 })}`,
|
|
93210
|
+
method: "GET",
|
|
93211
|
+
timeoutMs
|
|
93212
|
+
}),
|
|
93213
|
+
selectionRoots: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, timeoutMs }) => request({
|
|
93214
|
+
baseUrl,
|
|
93215
|
+
path: `/plugin/selection/roots${buildQuery({ stateFile: stateFile3, staleMs: staleMs2 })}`,
|
|
93216
|
+
method: "GET",
|
|
93217
|
+
timeoutMs
|
|
93218
|
+
}),
|
|
93219
|
+
selectionCurrent: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, timeoutMs }) => request({
|
|
93220
|
+
baseUrl,
|
|
93221
|
+
path: `/plugin/selection/current${buildQuery({ stateFile: stateFile3, staleMs: staleMs2 })}`,
|
|
93222
|
+
method: "GET",
|
|
93223
|
+
timeoutMs
|
|
93224
|
+
}),
|
|
93225
|
+
pluginCurrent: ({ baseUrl, stateFile: stateFile3, staleMs: staleMs2, selectionLimit, timeoutMs }) => request({
|
|
93226
|
+
baseUrl,
|
|
93227
|
+
path: `/plugin/current${buildQuery({ stateFile: stateFile3, staleMs: staleMs2, selectionLimit })}`,
|
|
93228
|
+
method: "GET",
|
|
93229
|
+
timeoutMs
|
|
93230
|
+
}),
|
|
93231
|
+
selectionOutline: ({ baseUrl, body, timeoutMs }) => request({ baseUrl, path: "/plugin/selection/outline", method: "POST", body, timeoutMs }),
|
|
93232
|
+
uiContext: ({ baseUrl, timeoutMs }) => request({ baseUrl, path: "/ui-context", method: "GET", timeoutMs }),
|
|
93233
|
+
selection: ({ baseUrl, timeoutMs }) => request({ baseUrl, path: "/selection", method: "GET", timeoutMs }),
|
|
93234
|
+
searchDb: ({ baseUrl, ...body }) => request({ baseUrl, path: "/search/db", method: "POST", body }),
|
|
93235
|
+
searchPlugin: ({ baseUrl, ...body }) => request({ baseUrl, path: "/search/plugin", method: "POST", body }),
|
|
93236
|
+
writeApply: ({ baseUrl, body, timeoutMs }) => request({ baseUrl, path: "/write/apply", method: "POST", body, timeoutMs }),
|
|
93237
|
+
readOutline: ({ baseUrl, body, timeoutMs }) => request({ baseUrl, path: "/read/outline", method: "POST", body, timeoutMs }),
|
|
93238
|
+
dailyRemId: ({ baseUrl, date: date6, offsetDays, timeoutMs }) => request({
|
|
93239
|
+
baseUrl,
|
|
93240
|
+
path: `/daily/rem-id${buildQuery({ date: date6, offsetDays })}`,
|
|
93241
|
+
method: "GET",
|
|
93242
|
+
timeoutMs
|
|
93243
|
+
}),
|
|
93244
|
+
queueWait: ({ baseUrl, txnId, timeoutMs, pollMs }) => request({ baseUrl, path: "/queue/wait", method: "POST", body: { txnId, timeoutMs, pollMs } }),
|
|
93245
|
+
queueTxn: ({ baseUrl, txnId, timeoutMs }) => request({ baseUrl, path: `/queue/txns/${encodeURIComponent(txnId)}`, method: "GET", timeoutMs }),
|
|
93246
|
+
triggerSync: ({ baseUrl, timeoutMs }) => request({ baseUrl, path: "/actions/trigger-sync", method: "POST", timeoutMs })
|
|
93247
|
+
};
|
|
93248
|
+
}));
|
|
93055
93249
|
|
|
93056
|
-
// src/
|
|
93057
|
-
|
|
93250
|
+
// src/commands/read/selection/_shared.ts
|
|
93251
|
+
function normalizeId(raw4) {
|
|
93252
|
+
return typeof raw4 === "string" ? raw4.trim() : "";
|
|
93058
93253
|
}
|
|
93059
|
-
function
|
|
93060
|
-
const
|
|
93061
|
-
|
|
93062
|
-
|
|
93254
|
+
function parseSelectionInfo(raw4) {
|
|
93255
|
+
const kindRaw = typeof raw4?.kind === "string" ? raw4.kind.trim() : "";
|
|
93256
|
+
const selectionType = typeof raw4?.selectionType === "string" ? raw4.selectionType : undefined;
|
|
93257
|
+
const updatedAtRaw = Number(raw4?.updatedAt ?? 0);
|
|
93258
|
+
const updatedAt = Number.isFinite(updatedAtRaw) && updatedAtRaw > 0 ? updatedAtRaw : 0;
|
|
93259
|
+
if (kindRaw === "text" || kindRaw === "" && selectionType === "Text") {
|
|
93260
|
+
const remId = normalizeId(raw4?.remId);
|
|
93261
|
+
const startRaw = raw4?.range?.start;
|
|
93262
|
+
const endRaw = raw4?.range?.end;
|
|
93263
|
+
const start4 = typeof startRaw === "number" && Number.isFinite(startRaw) ? Math.floor(startRaw) : NaN;
|
|
93264
|
+
const end6 = typeof endRaw === "number" && Number.isFinite(endRaw) ? Math.floor(endRaw) : NaN;
|
|
93265
|
+
const isReverse = raw4?.isReverse === true;
|
|
93266
|
+
if (remId && Number.isFinite(start4) && Number.isFinite(end6) && start4 !== end6) {
|
|
93267
|
+
return { kind: "text", selectionType, remId, range: { start: start4, end: end6 }, isReverse, updatedAt };
|
|
93268
|
+
}
|
|
93269
|
+
return { kind: "none", selectionType: undefined, updatedAt };
|
|
93063
93270
|
}
|
|
93064
|
-
|
|
93271
|
+
if (kindRaw === "rem" || kindRaw === "" || selectionType === "Rem") {
|
|
93272
|
+
const totalCountRaw = Number(raw4?.totalCount ?? 0);
|
|
93273
|
+
const remIds = Array.isArray(raw4?.remIds) ? raw4.remIds.map(normalizeId).filter(Boolean) : [];
|
|
93274
|
+
const totalCount = Number.isFinite(totalCountRaw) && totalCountRaw >= 0 ? Math.floor(totalCountRaw) : remIds.length;
|
|
93275
|
+
const truncated = !!raw4?.truncated || totalCount > remIds.length;
|
|
93276
|
+
if (remIds.length > 0 || totalCount > 0) {
|
|
93277
|
+
return { kind: "rem", selectionType, totalCount, truncated, remIds, updatedAt };
|
|
93278
|
+
}
|
|
93279
|
+
}
|
|
93280
|
+
return { kind: "none", selectionType: undefined, updatedAt };
|
|
93065
93281
|
}
|
|
93066
|
-
function
|
|
93067
|
-
const
|
|
93068
|
-
const
|
|
93069
|
-
|
|
93070
|
-
|
|
93282
|
+
function loadBridgeSelectionSnapshot(params3) {
|
|
93283
|
+
const resolved = resolveStateFilePath2(params3.stateFile);
|
|
93284
|
+
const stateFilePath = resolved.path;
|
|
93285
|
+
const now2 = Date.now();
|
|
93286
|
+
const staleThreshold = resolveStaleMs2(params3.staleMs);
|
|
93287
|
+
if (resolved.disabled) {
|
|
93288
|
+
return {
|
|
93289
|
+
status: "off",
|
|
93290
|
+
state_file: stateFilePath,
|
|
93291
|
+
updatedAt: 0,
|
|
93292
|
+
now: now2,
|
|
93293
|
+
stale_ms: staleThreshold,
|
|
93294
|
+
clients: 0
|
|
93295
|
+
};
|
|
93071
93296
|
}
|
|
93072
|
-
const
|
|
93073
|
-
if (
|
|
93074
|
-
|
|
93075
|
-
|
|
93076
|
-
|
|
93077
|
-
|
|
93078
|
-
|
|
93079
|
-
|
|
93080
|
-
|
|
93081
|
-
|
|
93082
|
-
"Example: --ref title:Demo",
|
|
93083
|
-
"Example: --ref daily:today",
|
|
93084
|
-
"Example: --ref daily:-1"
|
|
93085
|
-
]
|
|
93086
|
-
});
|
|
93297
|
+
const state = readJson2(stateFilePath);
|
|
93298
|
+
if (!state) {
|
|
93299
|
+
return {
|
|
93300
|
+
status: "down",
|
|
93301
|
+
state_file: stateFilePath,
|
|
93302
|
+
updatedAt: 0,
|
|
93303
|
+
now: now2,
|
|
93304
|
+
stale_ms: staleThreshold,
|
|
93305
|
+
clients: 0
|
|
93306
|
+
};
|
|
93087
93307
|
}
|
|
93088
|
-
const
|
|
93089
|
-
const
|
|
93090
|
-
|
|
93091
|
-
|
|
93092
|
-
|
|
93093
|
-
|
|
93094
|
-
|
|
93095
|
-
|
|
93308
|
+
const updatedAt = Number(state.updatedAt ?? 0);
|
|
93309
|
+
const isStale = !Number.isFinite(updatedAt) || updatedAt <= 0 || now2 - updatedAt > staleThreshold;
|
|
93310
|
+
const clients = Array.isArray(state.clients) ? state.clients : [];
|
|
93311
|
+
const activeConnIdRaw = typeof state.activeWorkerConnId === "string" ? state.activeWorkerConnId.trim() : "";
|
|
93312
|
+
const client = pickClient2(clients, params3.connId || activeConnIdRaw || undefined);
|
|
93313
|
+
if (!client) {
|
|
93314
|
+
return {
|
|
93315
|
+
status: "no_client",
|
|
93316
|
+
state_file: stateFilePath,
|
|
93317
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
93318
|
+
now: now2,
|
|
93319
|
+
stale_ms: staleThreshold,
|
|
93320
|
+
clients: clients.length
|
|
93321
|
+
};
|
|
93096
93322
|
}
|
|
93097
|
-
|
|
93098
|
-
|
|
93099
|
-
|
|
93100
|
-
|
|
93101
|
-
|
|
93102
|
-
|
|
93323
|
+
const selection = parseSelectionInfo(client.selection);
|
|
93324
|
+
if (isStale) {
|
|
93325
|
+
return {
|
|
93326
|
+
status: "stale",
|
|
93327
|
+
state_file: stateFilePath,
|
|
93328
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
93329
|
+
now: now2,
|
|
93330
|
+
stale_ms: staleThreshold,
|
|
93331
|
+
clients: clients.length,
|
|
93332
|
+
selection
|
|
93333
|
+
};
|
|
93103
93334
|
}
|
|
93104
|
-
|
|
93105
|
-
|
|
93335
|
+
return {
|
|
93336
|
+
status: "ok",
|
|
93337
|
+
state_file: stateFilePath,
|
|
93338
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
93339
|
+
now: now2,
|
|
93340
|
+
stale_ms: staleThreshold,
|
|
93341
|
+
clients: clients.length,
|
|
93342
|
+
selection
|
|
93343
|
+
};
|
|
93344
|
+
}
|
|
93345
|
+
function requireOkSelection(snapshot2) {
|
|
93346
|
+
if (snapshot2.status === "ok" && snapshot2.selection) {
|
|
93347
|
+
return succeed8(snapshot2.selection);
|
|
93106
93348
|
}
|
|
93107
|
-
|
|
93108
|
-
|
|
93109
|
-
|
|
93110
|
-
|
|
93111
|
-
|
|
93112
|
-
|
|
93113
|
-
}
|
|
93114
|
-
function parseDailyOffset(value8) {
|
|
93115
|
-
const v = value8.trim().toLowerCase();
|
|
93116
|
-
if (v === "today" || v === "now" || v === "0")
|
|
93117
|
-
return 0;
|
|
93118
|
-
if (v === "yesterday")
|
|
93119
|
-
return -1;
|
|
93120
|
-
if (v === "tomorrow")
|
|
93121
|
-
return 1;
|
|
93122
|
-
const n = Number.parseInt(v, 10);
|
|
93123
|
-
if (!Number.isFinite(n)) {
|
|
93124
|
-
throw new CliError({
|
|
93125
|
-
code: "INVALID_ARGS",
|
|
93126
|
-
message: `Invalid daily ref: ${value8} (expected today/yesterday/tomorrow or an integer offset)`,
|
|
93127
|
-
exitCode: 2
|
|
93128
|
-
});
|
|
93129
|
-
}
|
|
93130
|
-
return n;
|
|
93349
|
+
const msg = snapshot2.status === "off" ? "WS state is disabled (REMNOTE_WS_STATE_FILE=0)" : snapshot2.status === "down" ? "WS state file not found: the daemon may not be running or has not written the state file yet" : snapshot2.status === "stale" ? "WS state is stale: the daemon may have stopped or has not updated for a long time" : snapshot2.status === "no_client" ? "No RemNote client is currently connected to the daemon" : "Selection is unavailable";
|
|
93350
|
+
return fail8(new CliError({
|
|
93351
|
+
code: "WS_UNAVAILABLE",
|
|
93352
|
+
message: msg,
|
|
93353
|
+
exitCode: 1,
|
|
93354
|
+
details: snapshot2
|
|
93355
|
+
}));
|
|
93131
93356
|
}
|
|
93132
|
-
|
|
93133
|
-
|
|
93134
|
-
|
|
93135
|
-
|
|
93136
|
-
|
|
93137
|
-
|
|
93138
|
-
});
|
|
93139
|
-
if (cfg.apiBaseUrl && parsed.kind !== "id") {
|
|
93140
|
-
return yield* fail8(remoteModeUnsupportedError({
|
|
93141
|
-
command: `ref resolution (${ref})`,
|
|
93142
|
-
reason: "this path still resolves refs by reading the local RemNote database",
|
|
93143
|
-
hints: [
|
|
93144
|
-
"Use a remote-capable command that accepts --ref and forwards it to the host API.",
|
|
93145
|
-
"If no remote endpoint exists yet, run the command on the host."
|
|
93146
|
-
],
|
|
93147
|
-
apiBaseUrl: cfg.apiBaseUrl
|
|
93148
|
-
}));
|
|
93149
|
-
}
|
|
93150
|
-
if (parsed.kind === "id")
|
|
93151
|
-
return parsed.value;
|
|
93152
|
-
const dailyOffset = parsed.kind === "daily" ? yield* try_3({
|
|
93153
|
-
try: () => parseDailyOffset(parsed.value),
|
|
93154
|
-
catch: (e) => e && typeof e === "object" && e._tag === "CliError" ? e : new CliError({
|
|
93155
|
-
code: "INVALID_ARGS",
|
|
93156
|
-
message: `Invalid daily ref: ${parsed.value}`,
|
|
93157
|
-
exitCode: 2
|
|
93158
|
-
})
|
|
93159
|
-
}) : undefined;
|
|
93160
|
-
const queryInput = parsed.kind === "title" || parsed.kind === "page" ? { query: parsed.value } : { query: "date", useCurrentDate: true, dateOffsetDays: dailyOffset };
|
|
93161
|
-
const result = yield* tryPromise2({
|
|
93162
|
-
try: async () => await executeSearchRemOverview({
|
|
93163
|
-
...queryInput,
|
|
93164
|
-
dbPath: cfg.remnoteDb,
|
|
93165
|
-
limit: 1,
|
|
93166
|
-
preferExact: true,
|
|
93167
|
-
exactFirstSingle: true,
|
|
93168
|
-
pagesOnly: parsed.kind === "page" ? true : undefined
|
|
93169
|
-
}),
|
|
93170
|
-
catch: (e) => new CliError({
|
|
93171
|
-
code: "DB_UNAVAILABLE",
|
|
93172
|
-
message: String(e?.message || e || "RemNote DB is unavailable"),
|
|
93173
|
-
exitCode: 1
|
|
93174
|
-
})
|
|
93175
|
-
});
|
|
93176
|
-
const first3 = Array.isArray(result.matches) ? result.matches[0] : undefined;
|
|
93177
|
-
const id2 = first3?.id ? String(first3.id) : "";
|
|
93178
|
-
if (!id2) {
|
|
93179
|
-
return yield* fail8(new CliError({
|
|
93357
|
+
function requireOkRemSelection(snapshot2) {
|
|
93358
|
+
return requireOkSelection(snapshot2).pipe(flatMap9((sel) => {
|
|
93359
|
+
if (sel.kind === "rem")
|
|
93360
|
+
return succeed8(sel);
|
|
93361
|
+
if (sel.kind === "text") {
|
|
93362
|
+
return fail8(new CliError({
|
|
93180
93363
|
code: "INVALID_ARGS",
|
|
93181
|
-
message:
|
|
93182
|
-
exitCode: 2
|
|
93364
|
+
message: "Current selection is text; this command requires Rem selection",
|
|
93365
|
+
exitCode: 2,
|
|
93366
|
+
details: snapshot2
|
|
93183
93367
|
}));
|
|
93184
93368
|
}
|
|
93185
|
-
return
|
|
93186
|
-
|
|
93187
|
-
|
|
93188
|
-
|
|
93189
|
-
|
|
93190
|
-
|
|
93191
|
-
|
|
93369
|
+
return fail8(new CliError({
|
|
93370
|
+
code: "INVALID_ARGS",
|
|
93371
|
+
message: "No Rem is currently selected",
|
|
93372
|
+
exitCode: 2,
|
|
93373
|
+
details: snapshot2
|
|
93374
|
+
}));
|
|
93375
|
+
}));
|
|
93192
93376
|
}
|
|
93193
|
-
|
|
93194
|
-
|
|
93195
|
-
|
|
93196
|
-
const
|
|
93197
|
-
|
|
93198
|
-
|
|
93199
|
-
|
|
93200
|
-
if (
|
|
93201
|
-
|
|
93377
|
+
|
|
93378
|
+
// src/commands/read/uiContext/_shared.ts
|
|
93379
|
+
function loadBridgeUiContextSnapshot(params3) {
|
|
93380
|
+
const resolved = resolveStateFilePath2(params3.stateFile);
|
|
93381
|
+
const stateFilePath = resolved.path;
|
|
93382
|
+
const now2 = Date.now();
|
|
93383
|
+
const staleThreshold = resolveStaleMs2(params3.staleMs);
|
|
93384
|
+
if (resolved.disabled) {
|
|
93385
|
+
return {
|
|
93386
|
+
status: "off",
|
|
93387
|
+
state_file: stateFilePath,
|
|
93388
|
+
updatedAt: 0,
|
|
93389
|
+
now: now2,
|
|
93390
|
+
stale_ms: staleThreshold,
|
|
93391
|
+
clients: 0
|
|
93392
|
+
};
|
|
93202
93393
|
}
|
|
93203
|
-
|
|
93204
|
-
|
|
93205
|
-
|
|
93206
|
-
|
|
93207
|
-
|
|
93208
|
-
|
|
93209
|
-
|
|
93394
|
+
const state = readJson2(stateFilePath);
|
|
93395
|
+
if (!state) {
|
|
93396
|
+
return {
|
|
93397
|
+
status: "down",
|
|
93398
|
+
state_file: stateFilePath,
|
|
93399
|
+
updatedAt: 0,
|
|
93400
|
+
now: now2,
|
|
93401
|
+
stale_ms: staleThreshold,
|
|
93402
|
+
clients: 0
|
|
93403
|
+
};
|
|
93210
93404
|
}
|
|
93211
|
-
const
|
|
93212
|
-
const
|
|
93213
|
-
const
|
|
93214
|
-
const
|
|
93215
|
-
|
|
93216
|
-
|
|
93217
|
-
|
|
93218
|
-
|
|
93219
|
-
|
|
93220
|
-
|
|
93221
|
-
|
|
93222
|
-
|
|
93223
|
-
|
|
93224
|
-
|
|
93225
|
-
- rem_id: ${data.remId}${data.dateString ? `
|
|
93226
|
-
- date_string: ${data.dateString}` : ""}
|
|
93227
|
-
`
|
|
93228
|
-
});
|
|
93229
|
-
return;
|
|
93405
|
+
const updatedAt = Number(state.updatedAt ?? 0);
|
|
93406
|
+
const isStale = !Number.isFinite(updatedAt) || updatedAt <= 0 || now2 - updatedAt > staleThreshold;
|
|
93407
|
+
const clients = Array.isArray(state.clients) ? state.clients : [];
|
|
93408
|
+
const activeConnIdRaw = typeof state.activeWorkerConnId === "string" ? state.activeWorkerConnId.trim() : "";
|
|
93409
|
+
const client = pickClient2(clients, params3.connId || activeConnIdRaw || undefined);
|
|
93410
|
+
if (!client) {
|
|
93411
|
+
return {
|
|
93412
|
+
status: "no_client",
|
|
93413
|
+
state_file: stateFilePath,
|
|
93414
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
93415
|
+
now: now2,
|
|
93416
|
+
stale_ms: staleThreshold,
|
|
93417
|
+
clients: clients.length
|
|
93418
|
+
};
|
|
93230
93419
|
}
|
|
93231
|
-
|
|
93232
|
-
|
|
93233
|
-
|
|
93234
|
-
|
|
93235
|
-
|
|
93236
|
-
|
|
93237
|
-
|
|
93238
|
-
|
|
93239
|
-
|
|
93240
|
-
|
|
93241
|
-
|
|
93242
|
-
|
|
93243
|
-
|
|
93244
|
-
|
|
93245
|
-
|
|
93246
|
-
|
|
93420
|
+
const url2 = typeof client.uiContext?.url === "string" ? client.uiContext.url : "";
|
|
93421
|
+
const paneId = typeof client.uiContext?.paneId === "string" ? client.uiContext.paneId : "";
|
|
93422
|
+
const pageRemId = typeof client.uiContext?.pageRemId === "string" ? client.uiContext.pageRemId : "";
|
|
93423
|
+
const focusedRemId = typeof client.uiContext?.focusedRemId === "string" ? client.uiContext.focusedRemId : "";
|
|
93424
|
+
const focusedPortalId = typeof client.uiContext?.focusedPortalId === "string" ? client.uiContext.focusedPortalId : "";
|
|
93425
|
+
const kbId = typeof client.uiContext?.kbId === "string" ? client.uiContext.kbId : undefined;
|
|
93426
|
+
const kbName = typeof client.uiContext?.kbName === "string" ? client.uiContext.kbName : undefined;
|
|
93427
|
+
const source = typeof client.uiContext?.source === "string" ? client.uiContext.source : undefined;
|
|
93428
|
+
const ctxUpdatedAtRaw = Number(client.uiContext?.updatedAt ?? 0);
|
|
93429
|
+
const ctxUpdatedAt = Number.isFinite(ctxUpdatedAtRaw) && ctxUpdatedAtRaw > 0 ? ctxUpdatedAtRaw : 0;
|
|
93430
|
+
const uiContext = {
|
|
93431
|
+
url: url2,
|
|
93432
|
+
paneId,
|
|
93433
|
+
pageRemId,
|
|
93434
|
+
focusedRemId,
|
|
93435
|
+
focusedPortalId,
|
|
93436
|
+
kbId,
|
|
93437
|
+
kbName,
|
|
93438
|
+
source,
|
|
93439
|
+
updatedAt: ctxUpdatedAt
|
|
93440
|
+
};
|
|
93441
|
+
if (isStale) {
|
|
93442
|
+
return {
|
|
93443
|
+
status: "stale",
|
|
93444
|
+
state_file: stateFilePath,
|
|
93445
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
93446
|
+
now: now2,
|
|
93447
|
+
stale_ms: staleThreshold,
|
|
93448
|
+
clients: clients.length,
|
|
93449
|
+
ui_context: uiContext
|
|
93247
93450
|
};
|
|
93248
|
-
const result = yield* tryPromise2({
|
|
93249
|
-
try: async () => await executeSearchRemOverview(searchInput),
|
|
93250
|
-
catch: (e) => cliErrorFromUnknown(e, { code: "DB_UNAVAILABLE" })
|
|
93251
|
-
});
|
|
93252
|
-
const first3 = Array.isArray(result.matches) ? result.matches[0] : undefined;
|
|
93253
|
-
remId = first3?.id ? String(first3.id) : "";
|
|
93254
|
-
ref = `daily:${date7}`;
|
|
93255
|
-
if (!remId) {
|
|
93256
|
-
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: `No Daily Rem found for date: ${date7}`, exitCode: 2 }));
|
|
93257
|
-
}
|
|
93258
|
-
} else {
|
|
93259
|
-
remId = yield* refs.resolve(ref);
|
|
93260
93451
|
}
|
|
93261
|
-
|
|
93262
|
-
|
|
93263
|
-
|
|
93264
|
-
|
|
93265
|
-
|
|
93266
|
-
|
|
93267
|
-
|
|
93268
|
-
|
|
93269
|
-
}
|
|
93452
|
+
return {
|
|
93453
|
+
status: "ok",
|
|
93454
|
+
state_file: stateFilePath,
|
|
93455
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
93456
|
+
now: now2,
|
|
93457
|
+
stale_ms: staleThreshold,
|
|
93458
|
+
clients: clients.length,
|
|
93459
|
+
ui_context: uiContext
|
|
93460
|
+
};
|
|
93461
|
+
}
|
|
93462
|
+
function requireOkUiContext(snapshot2) {
|
|
93463
|
+
if (snapshot2.status === "ok" && snapshot2.ui_context) {
|
|
93464
|
+
return succeed8(snapshot2.ui_context);
|
|
93465
|
+
}
|
|
93466
|
+
const msg = snapshot2.status === "off" ? "WS state is disabled (REMNOTE_WS_STATE_FILE=0)" : snapshot2.status === "down" ? "WS state file not found: the daemon may not be running or has not written the state file yet" : snapshot2.status === "stale" ? "WS state is stale: the daemon may have stopped or has not updated for a long time" : snapshot2.status === "no_client" ? "No RemNote client is currently connected to the daemon" : "UI context is unavailable";
|
|
93467
|
+
return fail8(new CliError({
|
|
93468
|
+
code: "WS_UNAVAILABLE",
|
|
93469
|
+
message: msg,
|
|
93470
|
+
exitCode: 1,
|
|
93471
|
+
details: snapshot2
|
|
93472
|
+
}));
|
|
93473
|
+
}
|
|
93270
93474
|
// src/kernel/write-plan/compile.ts
|
|
93271
93475
|
var ALIAS_RE = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
93272
93476
|
function getObject(value8) {
|
|
@@ -93694,23 +93898,80 @@ var PayloadLive = succeed10(Payload, {
|
|
|
93694
93898
|
normalizeKeys
|
|
93695
93899
|
});
|
|
93696
93900
|
|
|
93697
|
-
// src/commands/
|
|
93698
|
-
function
|
|
93699
|
-
|
|
93700
|
-
|
|
93701
|
-
|
|
93702
|
-
|
|
93703
|
-
|
|
93704
|
-
|
|
93705
|
-
|
|
93706
|
-
const
|
|
93707
|
-
|
|
93708
|
-
|
|
93709
|
-
|
|
93710
|
-
|
|
93711
|
-
|
|
93712
|
-
|
|
93713
|
-
|
|
93901
|
+
// src/commands/write/_propertyTypeRuntimeGuard.ts
|
|
93902
|
+
function propertyTypeCapabilityHint(scopeLabel) {
|
|
93903
|
+
return [
|
|
93904
|
+
`Create a plain ${scopeLabel} property without --type/--options if you only need the column shell.`,
|
|
93905
|
+
"Configure property type manually in the RemNote UI when you need select/number/date/checkbox behavior.",
|
|
93906
|
+
"If a property is already select-like, option mutation must run against the host/local RemNote DB rather than a caller-side remote mirror."
|
|
93907
|
+
];
|
|
93908
|
+
}
|
|
93909
|
+
function typedPropertyCreationUnsupportedError(params3) {
|
|
93910
|
+
const hasType = typeof params3.type === "string" && params3.type.trim().length > 0;
|
|
93911
|
+
return new CliError({
|
|
93912
|
+
code: "WRITE_UNAVAILABLE",
|
|
93913
|
+
message: `Typed property creation is currently unsupported in the RemNote plugin runtime for ${params3.scopeLabel} properties`,
|
|
93914
|
+
exitCode: 1,
|
|
93915
|
+
details: {
|
|
93916
|
+
scope: params3.scopeLabel,
|
|
93917
|
+
requested_type: hasType ? params3.type?.trim() : undefined,
|
|
93918
|
+
requested_options: params3.hasOptions
|
|
93919
|
+
},
|
|
93920
|
+
hint: propertyTypeCapabilityHint(params3.scopeLabel)
|
|
93921
|
+
});
|
|
93922
|
+
}
|
|
93923
|
+
function propertyTypeMutationUnsupportedError(scopeLabel) {
|
|
93924
|
+
return new CliError({
|
|
93925
|
+
code: "WRITE_UNAVAILABLE",
|
|
93926
|
+
message: `Property type mutation is currently unsupported in the RemNote plugin runtime for ${scopeLabel} properties`,
|
|
93927
|
+
exitCode: 1,
|
|
93928
|
+
details: { scope: scopeLabel },
|
|
93929
|
+
hint: propertyTypeCapabilityHint(scopeLabel)
|
|
93930
|
+
});
|
|
93931
|
+
}
|
|
93932
|
+
function assertTypedPropertyCreationSupported(params3) {
|
|
93933
|
+
const hasType = typeof params3.type === "string" && params3.type.trim().length > 0;
|
|
93934
|
+
if (!hasType && !params3.hasOptions) {
|
|
93935
|
+
return;
|
|
93936
|
+
}
|
|
93937
|
+
throw typedPropertyCreationUnsupportedError(params3);
|
|
93938
|
+
}
|
|
93939
|
+
function ensureTypedPropertyCreationSupported(params3) {
|
|
93940
|
+
return try_3({
|
|
93941
|
+
try: () => assertTypedPropertyCreationSupported(params3),
|
|
93942
|
+
catch: (error4) => isCliError(error4) ? error4 : new CliError({
|
|
93943
|
+
code: "INTERNAL",
|
|
93944
|
+
message: "Failed to validate property type runtime capability",
|
|
93945
|
+
exitCode: 1,
|
|
93946
|
+
details: { error: String(error4?.message || error4) }
|
|
93947
|
+
})
|
|
93948
|
+
});
|
|
93949
|
+
}
|
|
93950
|
+
function assertSupportedPropertyTypeMutation(scopeLabel) {
|
|
93951
|
+
throw propertyTypeMutationUnsupportedError(scopeLabel);
|
|
93952
|
+
}
|
|
93953
|
+
function failUnsupportedPropertyTypeMutation(scopeLabel) {
|
|
93954
|
+
return fail8(propertyTypeMutationUnsupportedError(scopeLabel));
|
|
93955
|
+
}
|
|
93956
|
+
|
|
93957
|
+
// src/commands/_enqueue.ts
|
|
93958
|
+
function normalizeOp(raw4, normalizer) {
|
|
93959
|
+
if (!raw4 || typeof raw4 !== "object") {
|
|
93960
|
+
throw new CliError({ code: "INVALID_PAYLOAD", message: "op must be an object", exitCode: 2 });
|
|
93961
|
+
}
|
|
93962
|
+
const type2 = typeof raw4.type === "string" ? raw4.type.trim() : "";
|
|
93963
|
+
if (!type2) {
|
|
93964
|
+
throw new CliError({ code: "INVALID_PAYLOAD", message: "op.type is required and must be a string", exitCode: 2 });
|
|
93965
|
+
}
|
|
93966
|
+
const canonicalType = canonicalizeOpType(type2);
|
|
93967
|
+
if (!canonicalType) {
|
|
93968
|
+
throw new CliError({ code: "INVALID_PAYLOAD", message: "op.type is required and must be a string", exitCode: 2 });
|
|
93969
|
+
}
|
|
93970
|
+
const payload = normalizer(raw4.payload ?? {});
|
|
93971
|
+
assertPropertyTypeRuntimeSupported(canonicalType, payload);
|
|
93972
|
+
const idempotencyKey = typeof raw4.idempotencyKey === "string" ? raw4.idempotencyKey : typeof raw4.idempotency_key === "string" ? raw4.idempotency_key : undefined;
|
|
93973
|
+
const maxAttempts = typeof raw4.maxAttempts === "number" ? raw4.maxAttempts : typeof raw4.max_attempts === "number" ? raw4.max_attempts : undefined;
|
|
93974
|
+
const deliverAfterMs = typeof raw4.deliverAfterMs === "number" ? raw4.deliverAfterMs : typeof raw4.deliver_after_ms === "number" ? raw4.deliver_after_ms : undefined;
|
|
93714
93975
|
return {
|
|
93715
93976
|
type: canonicalType,
|
|
93716
93977
|
payload,
|
|
@@ -93719,6 +93980,18 @@ function normalizeOp(raw4, normalizer) {
|
|
|
93719
93980
|
deliverAfterMs
|
|
93720
93981
|
};
|
|
93721
93982
|
}
|
|
93983
|
+
function assertPropertyTypeRuntimeSupported(canonicalType, payload) {
|
|
93984
|
+
if (canonicalType === "set_property_type") {
|
|
93985
|
+
assertSupportedPropertyTypeMutation("generic");
|
|
93986
|
+
}
|
|
93987
|
+
if (canonicalType === "add_property") {
|
|
93988
|
+
assertTypedPropertyCreationSupported({
|
|
93989
|
+
scopeLabel: "generic",
|
|
93990
|
+
type: typeof payload?.type === "string" ? payload.type : undefined,
|
|
93991
|
+
hasOptions: Array.isArray(payload?.options)
|
|
93992
|
+
});
|
|
93993
|
+
}
|
|
93994
|
+
}
|
|
93722
93995
|
var OP_TYPES_REQUIRE_PARENT_ID = new Set([
|
|
93723
93996
|
"create_rem",
|
|
93724
93997
|
"create_portal",
|
|
@@ -93868,8 +94141,535 @@ function normalizeOps(rawOps) {
|
|
|
93868
94141
|
details: { error: String(e?.message || e) }
|
|
93869
94142
|
})
|
|
93870
94143
|
});
|
|
93871
|
-
});
|
|
93872
|
-
}
|
|
94144
|
+
});
|
|
94145
|
+
}
|
|
94146
|
+
|
|
94147
|
+
// src/services/RefResolver.ts
|
|
94148
|
+
import { homedir } from "node:os";
|
|
94149
|
+
import path24 from "node:path";
|
|
94150
|
+
|
|
94151
|
+
// src/lib/workspaceResolver.ts
|
|
94152
|
+
import fs18 from "node:fs";
|
|
94153
|
+
|
|
94154
|
+
// src/services/WorkspaceBindings.ts
|
|
94155
|
+
class WorkspaceBindings extends Tag2("WorkspaceBindings")() {
|
|
94156
|
+
}
|
|
94157
|
+
function normalizeText(value8, field) {
|
|
94158
|
+
const normalized = String(value8 ?? "").trim();
|
|
94159
|
+
if (!normalized) {
|
|
94160
|
+
throw new CliError({
|
|
94161
|
+
code: "INVALID_ARGS",
|
|
94162
|
+
message: `${field} must be a non-empty string`,
|
|
94163
|
+
exitCode: 2,
|
|
94164
|
+
details: { field, value: value8 }
|
|
94165
|
+
});
|
|
94166
|
+
}
|
|
94167
|
+
return normalized;
|
|
94168
|
+
}
|
|
94169
|
+
function normalizeOptionalText(value8) {
|
|
94170
|
+
const normalized = String(value8 ?? "").trim();
|
|
94171
|
+
return normalized ? normalized : undefined;
|
|
94172
|
+
}
|
|
94173
|
+
function normalizeTimestamp(value8, fallback) {
|
|
94174
|
+
if (value8 === undefined)
|
|
94175
|
+
return fallback;
|
|
94176
|
+
if (!Number.isFinite(value8) || value8 <= 0) {
|
|
94177
|
+
throw new CliError({
|
|
94178
|
+
code: "INVALID_ARGS",
|
|
94179
|
+
message: "timestamp must be a positive integer",
|
|
94180
|
+
exitCode: 2,
|
|
94181
|
+
details: { value: value8 }
|
|
94182
|
+
});
|
|
94183
|
+
}
|
|
94184
|
+
return Math.floor(value8);
|
|
94185
|
+
}
|
|
94186
|
+
function mapStoreError(storeDbPath, error4) {
|
|
94187
|
+
const code2 = error4.code === "STORE_SCHEMA_NEWER" ? "QUEUE_SCHEMA_NEWER" : error4.code === "STORE_SCHEMA_INVALID" ? "QUEUE_SCHEMA_INVALID" : "QUEUE_SCHEMA_UNKNOWN";
|
|
94188
|
+
return new CliError({
|
|
94189
|
+
code: code2,
|
|
94190
|
+
message: error4.message,
|
|
94191
|
+
exitCode: 1,
|
|
94192
|
+
details: { store_db: storeDbPath, ...error4.details || {} },
|
|
94193
|
+
hint: [...Array.isArray(error4.nextActions) ? error4.nextActions : [], "Override the store db path with --store-db"]
|
|
94194
|
+
});
|
|
94195
|
+
}
|
|
94196
|
+
function mapRow(row) {
|
|
94197
|
+
if (!row)
|
|
94198
|
+
return;
|
|
94199
|
+
return {
|
|
94200
|
+
workspaceId: String(row.workspace_id),
|
|
94201
|
+
kbName: row.kb_name ?? undefined,
|
|
94202
|
+
dbPath: String(row.db_path),
|
|
94203
|
+
source: row.source,
|
|
94204
|
+
isCurrent: Number(row.is_current) === 1,
|
|
94205
|
+
firstSeenAt: Number(row.first_seen_at),
|
|
94206
|
+
lastVerifiedAt: Number(row.last_verified_at),
|
|
94207
|
+
lastUiContextAt: row.last_ui_context_at === null ? undefined : Number(row.last_ui_context_at),
|
|
94208
|
+
updatedAt: Number(row.updated_at)
|
|
94209
|
+
};
|
|
94210
|
+
}
|
|
94211
|
+
function withStoreDb(storeDbPath, fn) {
|
|
94212
|
+
const db = openStoreDb(storeDbPath);
|
|
94213
|
+
try {
|
|
94214
|
+
return fn(db);
|
|
94215
|
+
} finally {
|
|
94216
|
+
db.close();
|
|
94217
|
+
}
|
|
94218
|
+
}
|
|
94219
|
+
var WorkspaceBindingsLive = succeed10(WorkspaceBindings, {
|
|
94220
|
+
getCurrent: ({ storeDbPath }) => try_3({
|
|
94221
|
+
try: () => withStoreDb(storeDbPath, (db) => mapRow(db.prepare(`SELECT workspace_id, kb_name, db_path, source, is_current, first_seen_at, last_verified_at, last_ui_context_at, updated_at
|
|
94222
|
+
FROM workspace_bindings
|
|
94223
|
+
WHERE is_current = 1
|
|
94224
|
+
LIMIT 1`).get())),
|
|
94225
|
+
catch: (error4) => {
|
|
94226
|
+
if (isCliError(error4))
|
|
94227
|
+
return error4;
|
|
94228
|
+
if (error4 instanceof StoreSchemaError)
|
|
94229
|
+
return mapStoreError(storeDbPath, error4);
|
|
94230
|
+
return new CliError({
|
|
94231
|
+
code: "QUEUE_UNAVAILABLE",
|
|
94232
|
+
message: "Store database is unavailable",
|
|
94233
|
+
exitCode: 1,
|
|
94234
|
+
details: { store_db: storeDbPath, error: String(error4?.message || error4) }
|
|
94235
|
+
});
|
|
94236
|
+
}
|
|
94237
|
+
}),
|
|
94238
|
+
getByWorkspaceId: ({ storeDbPath, workspaceId }) => try_3({
|
|
94239
|
+
try: () => withStoreDb(storeDbPath, (db) => mapRow(db.prepare(`SELECT workspace_id, kb_name, db_path, source, is_current, first_seen_at, last_verified_at, last_ui_context_at, updated_at
|
|
94240
|
+
FROM workspace_bindings
|
|
94241
|
+
WHERE workspace_id = ?
|
|
94242
|
+
LIMIT 1`).get(normalizeText(workspaceId, "workspaceId")))),
|
|
94243
|
+
catch: (error4) => {
|
|
94244
|
+
if (isCliError(error4))
|
|
94245
|
+
return error4;
|
|
94246
|
+
if (error4 instanceof StoreSchemaError)
|
|
94247
|
+
return mapStoreError(storeDbPath, error4);
|
|
94248
|
+
return new CliError({
|
|
94249
|
+
code: "QUEUE_UNAVAILABLE",
|
|
94250
|
+
message: "Store database is unavailable",
|
|
94251
|
+
exitCode: 1,
|
|
94252
|
+
details: { store_db: storeDbPath, error: String(error4?.message || error4) }
|
|
94253
|
+
});
|
|
94254
|
+
}
|
|
94255
|
+
}),
|
|
94256
|
+
list: ({ storeDbPath }) => try_3({
|
|
94257
|
+
try: () => withStoreDb(storeDbPath, (db) => {
|
|
94258
|
+
const rows = db.prepare(`SELECT workspace_id, kb_name, db_path, source, is_current, first_seen_at, last_verified_at, last_ui_context_at, updated_at
|
|
94259
|
+
FROM workspace_bindings
|
|
94260
|
+
ORDER BY is_current DESC, updated_at DESC, workspace_id ASC`).all();
|
|
94261
|
+
return rows.map((row) => mapRow(row));
|
|
94262
|
+
}),
|
|
94263
|
+
catch: (error4) => {
|
|
94264
|
+
if (isCliError(error4))
|
|
94265
|
+
return error4;
|
|
94266
|
+
if (error4 instanceof StoreSchemaError)
|
|
94267
|
+
return mapStoreError(storeDbPath, error4);
|
|
94268
|
+
return new CliError({
|
|
94269
|
+
code: "QUEUE_UNAVAILABLE",
|
|
94270
|
+
message: "Store database is unavailable",
|
|
94271
|
+
exitCode: 1,
|
|
94272
|
+
details: { store_db: storeDbPath, error: String(error4?.message || error4) }
|
|
94273
|
+
});
|
|
94274
|
+
}
|
|
94275
|
+
}),
|
|
94276
|
+
upsert: (params3) => try_3({
|
|
94277
|
+
try: () => withStoreDb(params3.storeDbPath, (db) => {
|
|
94278
|
+
const workspaceId = normalizeText(params3.workspaceId, "workspaceId");
|
|
94279
|
+
const dbPath = normalizeText(params3.dbPath, "dbPath");
|
|
94280
|
+
const kbName = normalizeOptionalText(params3.kbName);
|
|
94281
|
+
const now2 = Math.max(1, Math.floor(Date.now()));
|
|
94282
|
+
const recordedAt = normalizeTimestamp(params3.recordedAt, now2);
|
|
94283
|
+
const verifiedAt = normalizeTimestamp(params3.verifiedAt, recordedAt);
|
|
94284
|
+
const lastUiContextAt = params3.lastUiContextAt === undefined ? undefined : normalizeTimestamp(params3.lastUiContextAt, recordedAt);
|
|
94285
|
+
const makeCurrent = params3.makeCurrent !== false;
|
|
94286
|
+
const tx = db.transaction(() => {
|
|
94287
|
+
const existing = db.prepare(`SELECT workspace_id, kb_name, db_path, source, is_current, first_seen_at, last_verified_at, last_ui_context_at, updated_at
|
|
94288
|
+
FROM workspace_bindings
|
|
94289
|
+
WHERE workspace_id = ?
|
|
94290
|
+
LIMIT 1`).get(workspaceId);
|
|
94291
|
+
if (makeCurrent) {
|
|
94292
|
+
db.prepare(`UPDATE workspace_bindings SET is_current = 0 WHERE workspace_id <> ? AND is_current = 1`).run(workspaceId);
|
|
94293
|
+
}
|
|
94294
|
+
const firstSeenAt = existing ? Number(existing.first_seen_at) : recordedAt;
|
|
94295
|
+
const effectiveKbName = kbName ?? (existing?.kb_name ?? undefined);
|
|
94296
|
+
const effectiveLastUiContextAt = lastUiContextAt ?? (existing?.last_ui_context_at === null ? undefined : existing?.last_ui_context_at ?? undefined);
|
|
94297
|
+
db.prepare(`INSERT INTO workspace_bindings(
|
|
94298
|
+
workspace_id, kb_name, db_path, source, is_current, first_seen_at, last_verified_at, last_ui_context_at, updated_at
|
|
94299
|
+
) VALUES(
|
|
94300
|
+
@workspace_id, @kb_name, @db_path, @source, @is_current, @first_seen_at, @last_verified_at, @last_ui_context_at, @updated_at
|
|
94301
|
+
)
|
|
94302
|
+
ON CONFLICT(workspace_id) DO UPDATE SET
|
|
94303
|
+
kb_name = excluded.kb_name,
|
|
94304
|
+
db_path = excluded.db_path,
|
|
94305
|
+
source = excluded.source,
|
|
94306
|
+
is_current = excluded.is_current,
|
|
94307
|
+
last_verified_at = excluded.last_verified_at,
|
|
94308
|
+
last_ui_context_at = excluded.last_ui_context_at,
|
|
94309
|
+
updated_at = excluded.updated_at`).run({
|
|
94310
|
+
workspace_id: workspaceId,
|
|
94311
|
+
kb_name: effectiveKbName ?? null,
|
|
94312
|
+
db_path: dbPath,
|
|
94313
|
+
source: params3.source,
|
|
94314
|
+
is_current: makeCurrent ? 1 : 0,
|
|
94315
|
+
first_seen_at: firstSeenAt,
|
|
94316
|
+
last_verified_at: verifiedAt,
|
|
94317
|
+
last_ui_context_at: effectiveLastUiContextAt ?? null,
|
|
94318
|
+
updated_at: recordedAt
|
|
94319
|
+
});
|
|
94320
|
+
return mapRow(db.prepare(`SELECT workspace_id, kb_name, db_path, source, is_current, first_seen_at, last_verified_at, last_ui_context_at, updated_at
|
|
94321
|
+
FROM workspace_bindings
|
|
94322
|
+
WHERE workspace_id = ?
|
|
94323
|
+
LIMIT 1`).get(workspaceId));
|
|
94324
|
+
});
|
|
94325
|
+
return tx();
|
|
94326
|
+
}),
|
|
94327
|
+
catch: (error4) => {
|
|
94328
|
+
if (isCliError(error4))
|
|
94329
|
+
return error4;
|
|
94330
|
+
if (error4 instanceof StoreSchemaError)
|
|
94331
|
+
return mapStoreError(params3.storeDbPath, error4);
|
|
94332
|
+
return new CliError({
|
|
94333
|
+
code: "QUEUE_UNAVAILABLE",
|
|
94334
|
+
message: "Store database is unavailable",
|
|
94335
|
+
exitCode: 1,
|
|
94336
|
+
details: { store_db: params3.storeDbPath, error: String(error4?.message || error4) }
|
|
94337
|
+
});
|
|
94338
|
+
}
|
|
94339
|
+
})
|
|
94340
|
+
});
|
|
94341
|
+
|
|
94342
|
+
// src/lib/workspaceResolver.ts
|
|
94343
|
+
function normalizeText2(value8) {
|
|
94344
|
+
const normalized = String(value8 ?? "").trim();
|
|
94345
|
+
return normalized ? normalized : undefined;
|
|
94346
|
+
}
|
|
94347
|
+
function pathExists(filePath) {
|
|
94348
|
+
if (!filePath)
|
|
94349
|
+
return false;
|
|
94350
|
+
try {
|
|
94351
|
+
return fs18.statSync(filePath).isFile();
|
|
94352
|
+
} catch {
|
|
94353
|
+
return false;
|
|
94354
|
+
}
|
|
94355
|
+
}
|
|
94356
|
+
function resolvedFromBinding(params3) {
|
|
94357
|
+
return {
|
|
94358
|
+
resolved: true,
|
|
94359
|
+
workspaceId: params3.binding.workspaceId,
|
|
94360
|
+
dbPath: params3.binding.dbPath,
|
|
94361
|
+
source: params3.source,
|
|
94362
|
+
kbName: params3.binding.kbName,
|
|
94363
|
+
bindingSource: params3.binding.source,
|
|
94364
|
+
candidates: params3.candidates ?? [],
|
|
94365
|
+
reasons: params3.reasons ?? []
|
|
94366
|
+
};
|
|
94367
|
+
}
|
|
94368
|
+
function unresolved(params3) {
|
|
94369
|
+
return {
|
|
94370
|
+
resolved: false,
|
|
94371
|
+
source: "unresolved",
|
|
94372
|
+
candidates: params3.candidates,
|
|
94373
|
+
reasons: params3.reasons
|
|
94374
|
+
};
|
|
94375
|
+
}
|
|
94376
|
+
function buildWorkspaceResolveError(params3) {
|
|
94377
|
+
const hasRequestedWorkspace = Boolean(normalizeText2(params3.requestedWorkspaceId));
|
|
94378
|
+
return new CliError({
|
|
94379
|
+
code: hasRequestedWorkspace ? "DB_UNAVAILABLE" : "WORKSPACE_UNRESOLVED",
|
|
94380
|
+
message: hasRequestedWorkspace ? `Workspace database is unavailable: ${params3.requestedWorkspaceId}` : "Workspace is unresolved",
|
|
94381
|
+
exitCode: 1,
|
|
94382
|
+
details: {
|
|
94383
|
+
requested_workspace_id: params3.requestedWorkspaceId,
|
|
94384
|
+
candidates: params3.resolution.candidates,
|
|
94385
|
+
reasons: params3.resolution.reasons
|
|
94386
|
+
},
|
|
94387
|
+
hint: hasRequestedWorkspace ? [
|
|
94388
|
+
"Open the target KB once in RemNote so the host can refresh the binding.",
|
|
94389
|
+
"Verify that the expected remnote.db file still exists on the host."
|
|
94390
|
+
] : [
|
|
94391
|
+
"Open the target KB once in RemNote so uiContext.kbId can establish a binding.",
|
|
94392
|
+
"Pass an explicit workspaceId or a RemNote deep link with /w/<workspaceId>/...."
|
|
94393
|
+
]
|
|
94394
|
+
});
|
|
94395
|
+
}
|
|
94396
|
+
function resolveWorkspaceSnapshot(params3) {
|
|
94397
|
+
return gen2(function* () {
|
|
94398
|
+
const cfg = yield* AppConfig;
|
|
94399
|
+
const bindings = yield* WorkspaceBindings;
|
|
94400
|
+
const storeDbPath = cfg.storeDb;
|
|
94401
|
+
const recordedAt = Date.now();
|
|
94402
|
+
const requestedWorkspaceId = normalizeText2(params3.workspaceId);
|
|
94403
|
+
const linkWorkspaceId = params3.ref ? normalizeText2(tryParseRemnoteLinkFromRef(params3.ref)?.workspaceId) : undefined;
|
|
94404
|
+
const explicitWorkspaceId = requestedWorkspaceId ?? linkWorkspaceId;
|
|
94405
|
+
const explicitBindingSource = requestedWorkspaceId ? "explicit" : "deep_link";
|
|
94406
|
+
const loadCandidates = () => discoverWorkspaceCandidatesSync();
|
|
94407
|
+
if (explicitWorkspaceId) {
|
|
94408
|
+
const existing = yield* bindings.getByWorkspaceId({ storeDbPath, workspaceId: explicitWorkspaceId });
|
|
94409
|
+
if (existing && pathExists(existing.dbPath)) {
|
|
94410
|
+
const refreshed = yield* bindings.upsert({
|
|
94411
|
+
storeDbPath,
|
|
94412
|
+
workspaceId: existing.workspaceId,
|
|
94413
|
+
kbName: existing.kbName,
|
|
94414
|
+
dbPath: existing.dbPath,
|
|
94415
|
+
source: existing.source,
|
|
94416
|
+
makeCurrent: true,
|
|
94417
|
+
recordedAt,
|
|
94418
|
+
verifiedAt: recordedAt,
|
|
94419
|
+
lastUiContextAt: existing.lastUiContextAt
|
|
94420
|
+
});
|
|
94421
|
+
return resolvedFromBinding({ binding: refreshed, source: "explicit" });
|
|
94422
|
+
}
|
|
94423
|
+
const canonicalPath = tryResolveRemnoteDbPathForWorkspaceIdSync(explicitWorkspaceId);
|
|
94424
|
+
if (canonicalPath) {
|
|
94425
|
+
const upserted = yield* bindings.upsert({
|
|
94426
|
+
storeDbPath,
|
|
94427
|
+
workspaceId: explicitWorkspaceId,
|
|
94428
|
+
kbName: existing?.kbName,
|
|
94429
|
+
dbPath: canonicalPath,
|
|
94430
|
+
source: explicitBindingSource,
|
|
94431
|
+
makeCurrent: true,
|
|
94432
|
+
recordedAt,
|
|
94433
|
+
verifiedAt: recordedAt,
|
|
94434
|
+
lastUiContextAt: existing?.lastUiContextAt
|
|
94435
|
+
});
|
|
94436
|
+
return resolvedFromBinding({ binding: upserted, source: "explicit" });
|
|
94437
|
+
}
|
|
94438
|
+
return unresolved({
|
|
94439
|
+
candidates: loadCandidates(),
|
|
94440
|
+
reasons: [`No readable remnote.db found for workspace ${explicitWorkspaceId}`]
|
|
94441
|
+
});
|
|
94442
|
+
}
|
|
94443
|
+
const uiSnapshot = loadBridgeUiContextSnapshot({ stateFile: params3.stateFile, staleMs: params3.staleMs });
|
|
94444
|
+
let liveBinding;
|
|
94445
|
+
const liveKbId = uiSnapshot.status === "ok" ? normalizeText2(uiSnapshot.ui_context?.kbId) : undefined;
|
|
94446
|
+
if (liveKbId) {
|
|
94447
|
+
const liveDbPath = tryResolveRemnoteDbPathForWorkspaceIdSync(liveKbId);
|
|
94448
|
+
if (liveDbPath) {
|
|
94449
|
+
liveBinding = yield* bindings.upsert({
|
|
94450
|
+
storeDbPath,
|
|
94451
|
+
workspaceId: liveKbId,
|
|
94452
|
+
kbName: normalizeText2(uiSnapshot.ui_context?.kbName),
|
|
94453
|
+
dbPath: liveDbPath,
|
|
94454
|
+
source: "live_ui_context",
|
|
94455
|
+
makeCurrent: true,
|
|
94456
|
+
recordedAt,
|
|
94457
|
+
verifiedAt: recordedAt,
|
|
94458
|
+
lastUiContextAt: Number(uiSnapshot.ui_context?.updatedAt ?? recordedAt)
|
|
94459
|
+
});
|
|
94460
|
+
}
|
|
94461
|
+
}
|
|
94462
|
+
const current2 = yield* bindings.getCurrent({ storeDbPath });
|
|
94463
|
+
if (current2 && pathExists(current2.dbPath)) {
|
|
94464
|
+
const refreshed = yield* bindings.upsert({
|
|
94465
|
+
storeDbPath,
|
|
94466
|
+
workspaceId: current2.workspaceId,
|
|
94467
|
+
kbName: current2.kbName,
|
|
94468
|
+
dbPath: current2.dbPath,
|
|
94469
|
+
source: current2.source,
|
|
94470
|
+
makeCurrent: true,
|
|
94471
|
+
recordedAt,
|
|
94472
|
+
verifiedAt: recordedAt,
|
|
94473
|
+
lastUiContextAt: current2.lastUiContextAt
|
|
94474
|
+
});
|
|
94475
|
+
return resolvedFromBinding({
|
|
94476
|
+
binding: refreshed,
|
|
94477
|
+
source: liveBinding && liveBinding.workspaceId === refreshed.workspaceId ? "live_ui_context" : "binding"
|
|
94478
|
+
});
|
|
94479
|
+
}
|
|
94480
|
+
const candidates = loadCandidates();
|
|
94481
|
+
const primaryCandidates = candidates.filter((candidate) => candidate.kind === "primary");
|
|
94482
|
+
if (primaryCandidates.length === 1) {
|
|
94483
|
+
const only = primaryCandidates[0];
|
|
94484
|
+
const upserted = yield* bindings.upsert({
|
|
94485
|
+
storeDbPath,
|
|
94486
|
+
workspaceId: only.workspaceId,
|
|
94487
|
+
dbPath: only.dbPath,
|
|
94488
|
+
source: "single_candidate_auto",
|
|
94489
|
+
makeCurrent: true,
|
|
94490
|
+
recordedAt,
|
|
94491
|
+
verifiedAt: recordedAt
|
|
94492
|
+
});
|
|
94493
|
+
return resolvedFromBinding({ binding: upserted, source: "single_candidate_auto", candidates: [only] });
|
|
94494
|
+
}
|
|
94495
|
+
const reasons = [];
|
|
94496
|
+
if (current2 && !pathExists(current2.dbPath)) {
|
|
94497
|
+
reasons.push(`Current workspace binding points to a missing file: ${current2.dbPath}`);
|
|
94498
|
+
}
|
|
94499
|
+
if (!liveBinding) {
|
|
94500
|
+
reasons.push(uiSnapshot.status === "ok" ? "UI context did not provide a resolvable kbId" : `UI context is unavailable (${uiSnapshot.status})`);
|
|
94501
|
+
}
|
|
94502
|
+
if (primaryCandidates.length > 1) {
|
|
94503
|
+
reasons.push(`Multiple primary workspace candidates found: ${primaryCandidates.length}`);
|
|
94504
|
+
}
|
|
94505
|
+
if (primaryCandidates.length === 0) {
|
|
94506
|
+
reasons.push("No primary workspace candidates were discovered");
|
|
94507
|
+
}
|
|
94508
|
+
return unresolved({ candidates, reasons });
|
|
94509
|
+
});
|
|
94510
|
+
}
|
|
94511
|
+
function requireResolvedWorkspace(params3) {
|
|
94512
|
+
return resolveWorkspaceSnapshot(params3).pipe(flatMap9((resolution) => {
|
|
94513
|
+
if (resolution.resolved)
|
|
94514
|
+
return succeed8(resolution);
|
|
94515
|
+
const requestedWorkspaceId = normalizeText2(params3.workspaceId) ?? normalizeText2(tryParseRemnoteLinkFromRef(params3.ref ?? "")?.workspaceId);
|
|
94516
|
+
return fail8(buildWorkspaceResolveError({ requestedWorkspaceId, resolution }));
|
|
94517
|
+
}));
|
|
94518
|
+
}
|
|
94519
|
+
|
|
94520
|
+
// src/services/RefResolver.ts
|
|
94521
|
+
class RefResolver extends Tag2("RefResolver")() {
|
|
94522
|
+
}
|
|
94523
|
+
function stripQuotes(s) {
|
|
94524
|
+
const t = s.trim();
|
|
94525
|
+
if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) {
|
|
94526
|
+
return t.slice(1, -1);
|
|
94527
|
+
}
|
|
94528
|
+
return t;
|
|
94529
|
+
}
|
|
94530
|
+
function parseRef(input) {
|
|
94531
|
+
const raw4 = input.trim();
|
|
94532
|
+
const link3 = tryParseRemnoteLink(raw4);
|
|
94533
|
+
if (link3?.remId) {
|
|
94534
|
+
return { kind: "id", value: link3.remId };
|
|
94535
|
+
}
|
|
94536
|
+
const idx = raw4.indexOf(":");
|
|
94537
|
+
if (idx <= 0) {
|
|
94538
|
+
throw new CliError({
|
|
94539
|
+
code: "INVALID_ARGS",
|
|
94540
|
+
message: `Invalid ref: ${input}`,
|
|
94541
|
+
exitCode: 2,
|
|
94542
|
+
hint: [
|
|
94543
|
+
"Example: --ref id:xxx",
|
|
94544
|
+
'Example: --ref "remnote://w/<workspaceId>/<remId>"',
|
|
94545
|
+
"Example: --ref page:Demo",
|
|
94546
|
+
"Example: --ref title:Demo",
|
|
94547
|
+
"Example: --ref daily:today",
|
|
94548
|
+
"Example: --ref daily:-1"
|
|
94549
|
+
]
|
|
94550
|
+
});
|
|
94551
|
+
}
|
|
94552
|
+
const kind = raw4.slice(0, idx).trim();
|
|
94553
|
+
const value8 = stripQuotes(raw4.slice(idx + 1));
|
|
94554
|
+
if (!value8) {
|
|
94555
|
+
throw new CliError({
|
|
94556
|
+
code: "INVALID_ARGS",
|
|
94557
|
+
message: `Invalid ref (missing value): ${input}`,
|
|
94558
|
+
exitCode: 2
|
|
94559
|
+
});
|
|
94560
|
+
}
|
|
94561
|
+
if (kind === "id" || kind === "title" || kind === "daily") {
|
|
94562
|
+
if (kind === "id") {
|
|
94563
|
+
const link22 = tryParseRemnoteLink(value8);
|
|
94564
|
+
return { kind, value: link22?.remId ?? value8 };
|
|
94565
|
+
}
|
|
94566
|
+
return { kind, value: value8 };
|
|
94567
|
+
}
|
|
94568
|
+
if (kind === "page") {
|
|
94569
|
+
return { kind, value: value8 };
|
|
94570
|
+
}
|
|
94571
|
+
throw new CliError({
|
|
94572
|
+
code: "INVALID_ARGS",
|
|
94573
|
+
message: `Unsupported ref: ${input}`,
|
|
94574
|
+
exitCode: 2,
|
|
94575
|
+
hint: ["Supported prefixes: id:/page:/title:/daily:"]
|
|
94576
|
+
});
|
|
94577
|
+
}
|
|
94578
|
+
function parseDailyOffset(value8) {
|
|
94579
|
+
const v = value8.trim().toLowerCase();
|
|
94580
|
+
if (v === "today" || v === "now" || v === "0")
|
|
94581
|
+
return 0;
|
|
94582
|
+
if (v === "yesterday")
|
|
94583
|
+
return -1;
|
|
94584
|
+
if (v === "tomorrow")
|
|
94585
|
+
return 1;
|
|
94586
|
+
const n = Number.parseInt(v, 10);
|
|
94587
|
+
if (!Number.isFinite(n)) {
|
|
94588
|
+
throw new CliError({
|
|
94589
|
+
code: "INVALID_ARGS",
|
|
94590
|
+
message: `Invalid daily ref: ${value8} (expected today/yesterday/tomorrow or an integer offset)`,
|
|
94591
|
+
exitCode: 2
|
|
94592
|
+
});
|
|
94593
|
+
}
|
|
94594
|
+
return n;
|
|
94595
|
+
}
|
|
94596
|
+
function normalizeDbPathInput(dbPath) {
|
|
94597
|
+
const raw4 = typeof dbPath === "string" ? dbPath.trim() : "";
|
|
94598
|
+
if (!raw4)
|
|
94599
|
+
return;
|
|
94600
|
+
const expanded = raw4 === "~" ? homedir() : raw4.startsWith("~/") || raw4.startsWith("~\\") ? path24.join(homedir(), raw4.slice(2)) : raw4;
|
|
94601
|
+
return path24.resolve(path24.normalize(expanded));
|
|
94602
|
+
}
|
|
94603
|
+
var RefResolverLive = succeed10(RefResolver, {
|
|
94604
|
+
resolve: (ref, options6) => gen2(function* () {
|
|
94605
|
+
const cfg = yield* AppConfig;
|
|
94606
|
+
const parsed = yield* try_3({
|
|
94607
|
+
try: () => parseRef(ref),
|
|
94608
|
+
catch: (e) => e && typeof e === "object" && e._tag === "CliError" ? e : new CliError({ code: "INVALID_ARGS", message: `Invalid ref: ${ref}`, exitCode: 2 })
|
|
94609
|
+
});
|
|
94610
|
+
if (cfg.apiBaseUrl && parsed.kind !== "id") {
|
|
94611
|
+
return yield* fail8(remoteModeUnsupportedError({
|
|
94612
|
+
command: `ref resolution (${ref})`,
|
|
94613
|
+
reason: "this path still resolves refs by reading the local RemNote database",
|
|
94614
|
+
hints: [
|
|
94615
|
+
"Use a remote-capable command that accepts --ref and forwards it to the host API.",
|
|
94616
|
+
"If no remote endpoint exists yet, run the command on the host."
|
|
94617
|
+
],
|
|
94618
|
+
apiBaseUrl: cfg.apiBaseUrl
|
|
94619
|
+
}));
|
|
94620
|
+
}
|
|
94621
|
+
if (parsed.kind === "id")
|
|
94622
|
+
return parsed.value;
|
|
94623
|
+
const normalizedDbPath = normalizeDbPathInput(options6?.dbPath) ?? normalizeDbPathInput(cfg.remnoteDb);
|
|
94624
|
+
const workspace = normalizedDbPath || cfg.apiBaseUrl ? undefined : yield* resolveWorkspaceSnapshot({ ref }).pipe(catchAll2(() => fail8(new CliError({
|
|
94625
|
+
code: "WORKSPACE_UNRESOLVED",
|
|
94626
|
+
message: `Workspace is unresolved for ref: ${ref}`,
|
|
94627
|
+
exitCode: 1
|
|
94628
|
+
}))));
|
|
94629
|
+
const dbPath = normalizedDbPath ?? workspace?.dbPath;
|
|
94630
|
+
if (!dbPath) {
|
|
94631
|
+
return yield* fail8(new CliError({
|
|
94632
|
+
code: "WORKSPACE_UNRESOLVED",
|
|
94633
|
+
message: `Workspace is unresolved for ref: ${ref}`,
|
|
94634
|
+
exitCode: 1
|
|
94635
|
+
}));
|
|
94636
|
+
}
|
|
94637
|
+
const dailyOffset = parsed.kind === "daily" ? yield* try_3({
|
|
94638
|
+
try: () => parseDailyOffset(parsed.value),
|
|
94639
|
+
catch: (e) => e && typeof e === "object" && e._tag === "CliError" ? e : new CliError({
|
|
94640
|
+
code: "INVALID_ARGS",
|
|
94641
|
+
message: `Invalid daily ref: ${parsed.value}`,
|
|
94642
|
+
exitCode: 2
|
|
94643
|
+
})
|
|
94644
|
+
}) : undefined;
|
|
94645
|
+
const queryInput = parsed.kind === "title" || parsed.kind === "page" ? { query: parsed.value } : { query: "date", useCurrentDate: true, dateOffsetDays: dailyOffset };
|
|
94646
|
+
const result = yield* tryPromise2({
|
|
94647
|
+
try: async () => await executeSearchRemOverview({
|
|
94648
|
+
...queryInput,
|
|
94649
|
+
dbPath,
|
|
94650
|
+
limit: 1,
|
|
94651
|
+
preferExact: true,
|
|
94652
|
+
exactFirstSingle: true,
|
|
94653
|
+
pagesOnly: parsed.kind === "page" ? true : undefined
|
|
94654
|
+
}),
|
|
94655
|
+
catch: (e) => new CliError({
|
|
94656
|
+
code: "DB_UNAVAILABLE",
|
|
94657
|
+
message: String(e?.message || e || "RemNote DB is unavailable"),
|
|
94658
|
+
exitCode: 1
|
|
94659
|
+
})
|
|
94660
|
+
});
|
|
94661
|
+
const first3 = Array.isArray(result.matches) ? result.matches[0] : undefined;
|
|
94662
|
+
const id2 = first3?.id ? String(first3.id) : "";
|
|
94663
|
+
if (!id2) {
|
|
94664
|
+
return yield* fail8(new CliError({
|
|
94665
|
+
code: "INVALID_ARGS",
|
|
94666
|
+
message: `No Rem found for ref: ${ref}`,
|
|
94667
|
+
exitCode: 2
|
|
94668
|
+
}));
|
|
94669
|
+
}
|
|
94670
|
+
return id2;
|
|
94671
|
+
})
|
|
94672
|
+
});
|
|
93873
94673
|
|
|
93874
94674
|
// src/commands/_resolveRefsInPayload.ts
|
|
93875
94675
|
function shouldResolveRef(value8) {
|
|
@@ -93892,8 +94692,8 @@ function resolveRefsInPayload(params3) {
|
|
|
93892
94692
|
const out = structuredClone(params3.payload);
|
|
93893
94693
|
const resolvedRefCache = new Map;
|
|
93894
94694
|
const idPaths = idFieldPathsForOpType(params3.opType);
|
|
93895
|
-
for (const
|
|
93896
|
-
const tokens = parsePathTokens(
|
|
94695
|
+
for (const path25 of idPaths) {
|
|
94696
|
+
const tokens = parsePathTokens(path25);
|
|
93897
94697
|
if (tokens.length === 0)
|
|
93898
94698
|
continue;
|
|
93899
94699
|
const leaves = collectLeafValues(out, tokens);
|
|
@@ -94063,274 +94863,187 @@ function compileApplyEnvelope(parsed) {
|
|
|
94063
94863
|
ops,
|
|
94064
94864
|
priority: parsed.priority,
|
|
94065
94865
|
clientId: parsed.clientId,
|
|
94066
|
-
idempotencyKey: parsed.idempotencyKey,
|
|
94067
|
-
meta: parsed.meta,
|
|
94068
|
-
notify: parsed.notify,
|
|
94069
|
-
ensureDaemon: parsed.ensureDaemon
|
|
94070
|
-
};
|
|
94071
|
-
}
|
|
94072
|
-
const compiled = yield* try_3({
|
|
94073
|
-
try: () => compileWritePlanV1({
|
|
94074
|
-
version: 1,
|
|
94075
|
-
steps: parsed.actions.map((action) => ({
|
|
94076
|
-
action: action.action,
|
|
94077
|
-
input: action.input,
|
|
94078
|
-
...action.as ? { as: action.as } : {}
|
|
94079
|
-
}))
|
|
94080
|
-
}, { makeTempId }),
|
|
94081
|
-
catch: (e) => isCliError(e) ? e : new CliError({
|
|
94082
|
-
code: "INVALID_PAYLOAD",
|
|
94083
|
-
message: String(e?.message || "Failed to compile apply actions"),
|
|
94084
|
-
exitCode: 2
|
|
94085
|
-
})
|
|
94086
|
-
});
|
|
94087
|
-
const resolvedOps = yield* forEach9(compiled.ops, (op) => resolveRefsInPayload({ opType: op.type, payload: op.payload }).pipe(map17((payload) => ({ ...op, payload }))), { concurrency: 1 });
|
|
94088
|
-
const normalizedOps = yield* try_3({
|
|
94089
|
-
try: () => resolvedOps.map((op) => normalizeOp(op, payloadSvc.normalizeKeys)),
|
|
94090
|
-
catch: (e) => isCliError(e) ? e : new CliError({
|
|
94091
|
-
code: "INVALID_PAYLOAD",
|
|
94092
|
-
message: "Failed to generate ops",
|
|
94093
|
-
exitCode: 2,
|
|
94094
|
-
details: { error: String(e?.message || e) }
|
|
94095
|
-
})
|
|
94096
|
-
});
|
|
94097
|
-
return {
|
|
94098
|
-
kind: "actions",
|
|
94099
|
-
ops: normalizedOps,
|
|
94100
|
-
aliasMap: compiled.alias_map,
|
|
94101
|
-
priority: parsed.priority,
|
|
94102
|
-
clientId: parsed.clientId,
|
|
94103
|
-
idempotencyKey: parsed.idempotencyKey,
|
|
94104
|
-
meta: parsed.meta,
|
|
94105
|
-
notify: parsed.notify,
|
|
94106
|
-
ensureDaemon: parsed.ensureDaemon
|
|
94107
|
-
};
|
|
94108
|
-
});
|
|
94109
|
-
}
|
|
94110
|
-
|
|
94111
|
-
// src/commands/read/selection/_shared.ts
|
|
94112
|
-
function normalizeId(raw4) {
|
|
94113
|
-
return typeof raw4 === "string" ? raw4.trim() : "";
|
|
94114
|
-
}
|
|
94115
|
-
function parseSelectionInfo(raw4) {
|
|
94116
|
-
const kindRaw = typeof raw4?.kind === "string" ? raw4.kind.trim() : "";
|
|
94117
|
-
const selectionType = typeof raw4?.selectionType === "string" ? raw4.selectionType : undefined;
|
|
94118
|
-
const updatedAtRaw = Number(raw4?.updatedAt ?? 0);
|
|
94119
|
-
const updatedAt = Number.isFinite(updatedAtRaw) && updatedAtRaw > 0 ? updatedAtRaw : 0;
|
|
94120
|
-
if (kindRaw === "text" || kindRaw === "" && selectionType === "Text") {
|
|
94121
|
-
const remId = normalizeId(raw4?.remId);
|
|
94122
|
-
const startRaw = raw4?.range?.start;
|
|
94123
|
-
const endRaw = raw4?.range?.end;
|
|
94124
|
-
const start4 = typeof startRaw === "number" && Number.isFinite(startRaw) ? Math.floor(startRaw) : NaN;
|
|
94125
|
-
const end6 = typeof endRaw === "number" && Number.isFinite(endRaw) ? Math.floor(endRaw) : NaN;
|
|
94126
|
-
const isReverse = raw4?.isReverse === true;
|
|
94127
|
-
if (remId && Number.isFinite(start4) && Number.isFinite(end6) && start4 !== end6) {
|
|
94128
|
-
return { kind: "text", selectionType, remId, range: { start: start4, end: end6 }, isReverse, updatedAt };
|
|
94129
|
-
}
|
|
94130
|
-
return { kind: "none", selectionType: undefined, updatedAt };
|
|
94131
|
-
}
|
|
94132
|
-
if (kindRaw === "rem" || kindRaw === "" || selectionType === "Rem") {
|
|
94133
|
-
const totalCountRaw = Number(raw4?.totalCount ?? 0);
|
|
94134
|
-
const remIds = Array.isArray(raw4?.remIds) ? raw4.remIds.map(normalizeId).filter(Boolean) : [];
|
|
94135
|
-
const totalCount = Number.isFinite(totalCountRaw) && totalCountRaw >= 0 ? Math.floor(totalCountRaw) : remIds.length;
|
|
94136
|
-
const truncated = !!raw4?.truncated || totalCount > remIds.length;
|
|
94137
|
-
if (remIds.length > 0 || totalCount > 0) {
|
|
94138
|
-
return { kind: "rem", selectionType, totalCount, truncated, remIds, updatedAt };
|
|
94139
|
-
}
|
|
94140
|
-
}
|
|
94141
|
-
return { kind: "none", selectionType: undefined, updatedAt };
|
|
94142
|
-
}
|
|
94143
|
-
function loadBridgeSelectionSnapshot(params3) {
|
|
94144
|
-
const resolved = resolveStateFilePath2(params3.stateFile);
|
|
94145
|
-
const stateFilePath = resolved.path;
|
|
94146
|
-
const now2 = Date.now();
|
|
94147
|
-
const staleThreshold = resolveStaleMs2(params3.staleMs);
|
|
94148
|
-
if (resolved.disabled) {
|
|
94149
|
-
return {
|
|
94150
|
-
status: "off",
|
|
94151
|
-
state_file: stateFilePath,
|
|
94152
|
-
updatedAt: 0,
|
|
94153
|
-
now: now2,
|
|
94154
|
-
stale_ms: staleThreshold,
|
|
94155
|
-
clients: 0
|
|
94156
|
-
};
|
|
94157
|
-
}
|
|
94158
|
-
const state = readJson2(stateFilePath);
|
|
94159
|
-
if (!state) {
|
|
94160
|
-
return {
|
|
94161
|
-
status: "down",
|
|
94162
|
-
state_file: stateFilePath,
|
|
94163
|
-
updatedAt: 0,
|
|
94164
|
-
now: now2,
|
|
94165
|
-
stale_ms: staleThreshold,
|
|
94166
|
-
clients: 0
|
|
94167
|
-
};
|
|
94168
|
-
}
|
|
94169
|
-
const updatedAt = Number(state.updatedAt ?? 0);
|
|
94170
|
-
const isStale = !Number.isFinite(updatedAt) || updatedAt <= 0 || now2 - updatedAt > staleThreshold;
|
|
94171
|
-
const clients = Array.isArray(state.clients) ? state.clients : [];
|
|
94172
|
-
const activeConnIdRaw = typeof state.activeWorkerConnId === "string" ? state.activeWorkerConnId.trim() : "";
|
|
94173
|
-
const client = pickClient2(clients, params3.connId || activeConnIdRaw || undefined);
|
|
94174
|
-
if (!client) {
|
|
94175
|
-
return {
|
|
94176
|
-
status: "no_client",
|
|
94177
|
-
state_file: stateFilePath,
|
|
94178
|
-
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
94179
|
-
now: now2,
|
|
94180
|
-
stale_ms: staleThreshold,
|
|
94181
|
-
clients: clients.length
|
|
94182
|
-
};
|
|
94183
|
-
}
|
|
94184
|
-
const selection = parseSelectionInfo(client.selection);
|
|
94185
|
-
if (isStale) {
|
|
94186
|
-
return {
|
|
94187
|
-
status: "stale",
|
|
94188
|
-
state_file: stateFilePath,
|
|
94189
|
-
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
94190
|
-
now: now2,
|
|
94191
|
-
stale_ms: staleThreshold,
|
|
94192
|
-
clients: clients.length,
|
|
94193
|
-
selection
|
|
94194
|
-
};
|
|
94195
|
-
}
|
|
94196
|
-
return {
|
|
94197
|
-
status: "ok",
|
|
94198
|
-
state_file: stateFilePath,
|
|
94199
|
-
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
94200
|
-
now: now2,
|
|
94201
|
-
stale_ms: staleThreshold,
|
|
94202
|
-
clients: clients.length,
|
|
94203
|
-
selection
|
|
94204
|
-
};
|
|
94205
|
-
}
|
|
94206
|
-
function requireOkSelection(snapshot2) {
|
|
94207
|
-
if (snapshot2.status === "ok" && snapshot2.selection) {
|
|
94208
|
-
return succeed8(snapshot2.selection);
|
|
94209
|
-
}
|
|
94210
|
-
const msg = snapshot2.status === "off" ? "WS state is disabled (REMNOTE_WS_STATE_FILE=0)" : snapshot2.status === "down" ? "WS state file not found: the daemon may not be running or has not written the state file yet" : snapshot2.status === "stale" ? "WS state is stale: the daemon may have stopped or has not updated for a long time" : snapshot2.status === "no_client" ? "No RemNote client is currently connected to the daemon" : "Selection is unavailable";
|
|
94211
|
-
return fail8(new CliError({
|
|
94212
|
-
code: "WS_UNAVAILABLE",
|
|
94213
|
-
message: msg,
|
|
94214
|
-
exitCode: 1,
|
|
94215
|
-
details: snapshot2
|
|
94216
|
-
}));
|
|
94217
|
-
}
|
|
94218
|
-
function requireOkRemSelection(snapshot2) {
|
|
94219
|
-
return requireOkSelection(snapshot2).pipe(flatMap9((sel) => {
|
|
94220
|
-
if (sel.kind === "rem")
|
|
94221
|
-
return succeed8(sel);
|
|
94222
|
-
if (sel.kind === "text") {
|
|
94223
|
-
return fail8(new CliError({
|
|
94224
|
-
code: "INVALID_ARGS",
|
|
94225
|
-
message: "Current selection is text; this command requires Rem selection",
|
|
94226
|
-
exitCode: 2,
|
|
94227
|
-
details: snapshot2
|
|
94228
|
-
}));
|
|
94229
|
-
}
|
|
94230
|
-
return fail8(new CliError({
|
|
94231
|
-
code: "INVALID_ARGS",
|
|
94232
|
-
message: "No Rem is currently selected",
|
|
94233
|
-
exitCode: 2,
|
|
94234
|
-
details: snapshot2
|
|
94235
|
-
}));
|
|
94236
|
-
}));
|
|
94237
|
-
}
|
|
94238
|
-
|
|
94239
|
-
// src/commands/read/uiContext/_shared.ts
|
|
94240
|
-
function loadBridgeUiContextSnapshot(params3) {
|
|
94241
|
-
const resolved = resolveStateFilePath2(params3.stateFile);
|
|
94242
|
-
const stateFilePath = resolved.path;
|
|
94243
|
-
const now2 = Date.now();
|
|
94244
|
-
const staleThreshold = resolveStaleMs2(params3.staleMs);
|
|
94245
|
-
if (resolved.disabled) {
|
|
94246
|
-
return {
|
|
94247
|
-
status: "off",
|
|
94248
|
-
state_file: stateFilePath,
|
|
94249
|
-
updatedAt: 0,
|
|
94250
|
-
now: now2,
|
|
94251
|
-
stale_ms: staleThreshold,
|
|
94252
|
-
clients: 0
|
|
94253
|
-
};
|
|
94254
|
-
}
|
|
94255
|
-
const state = readJson2(stateFilePath);
|
|
94256
|
-
if (!state) {
|
|
94257
|
-
return {
|
|
94258
|
-
status: "down",
|
|
94259
|
-
state_file: stateFilePath,
|
|
94260
|
-
updatedAt: 0,
|
|
94261
|
-
now: now2,
|
|
94262
|
-
stale_ms: staleThreshold,
|
|
94263
|
-
clients: 0
|
|
94264
|
-
};
|
|
94265
|
-
}
|
|
94266
|
-
const updatedAt = Number(state.updatedAt ?? 0);
|
|
94267
|
-
const isStale = !Number.isFinite(updatedAt) || updatedAt <= 0 || now2 - updatedAt > staleThreshold;
|
|
94268
|
-
const clients = Array.isArray(state.clients) ? state.clients : [];
|
|
94269
|
-
const activeConnIdRaw = typeof state.activeWorkerConnId === "string" ? state.activeWorkerConnId.trim() : "";
|
|
94270
|
-
const client = pickClient2(clients, params3.connId || activeConnIdRaw || undefined);
|
|
94271
|
-
if (!client) {
|
|
94272
|
-
return {
|
|
94273
|
-
status: "no_client",
|
|
94274
|
-
state_file: stateFilePath,
|
|
94275
|
-
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
94276
|
-
now: now2,
|
|
94277
|
-
stale_ms: staleThreshold,
|
|
94278
|
-
clients: clients.length
|
|
94279
|
-
};
|
|
94280
|
-
}
|
|
94281
|
-
const url2 = typeof client.uiContext?.url === "string" ? client.uiContext.url : "";
|
|
94282
|
-
const paneId = typeof client.uiContext?.paneId === "string" ? client.uiContext.paneId : "";
|
|
94283
|
-
const pageRemId = typeof client.uiContext?.pageRemId === "string" ? client.uiContext.pageRemId : "";
|
|
94284
|
-
const focusedRemId = typeof client.uiContext?.focusedRemId === "string" ? client.uiContext.focusedRemId : "";
|
|
94285
|
-
const focusedPortalId = typeof client.uiContext?.focusedPortalId === "string" ? client.uiContext.focusedPortalId : "";
|
|
94286
|
-
const kbId = typeof client.uiContext?.kbId === "string" ? client.uiContext.kbId : undefined;
|
|
94287
|
-
const kbName = typeof client.uiContext?.kbName === "string" ? client.uiContext.kbName : undefined;
|
|
94288
|
-
const source = typeof client.uiContext?.source === "string" ? client.uiContext.source : undefined;
|
|
94289
|
-
const ctxUpdatedAtRaw = Number(client.uiContext?.updatedAt ?? 0);
|
|
94290
|
-
const ctxUpdatedAt = Number.isFinite(ctxUpdatedAtRaw) && ctxUpdatedAtRaw > 0 ? ctxUpdatedAtRaw : 0;
|
|
94291
|
-
const uiContext = {
|
|
94292
|
-
url: url2,
|
|
94293
|
-
paneId,
|
|
94294
|
-
pageRemId,
|
|
94295
|
-
focusedRemId,
|
|
94296
|
-
focusedPortalId,
|
|
94297
|
-
kbId,
|
|
94298
|
-
kbName,
|
|
94299
|
-
source,
|
|
94300
|
-
updatedAt: ctxUpdatedAt
|
|
94301
|
-
};
|
|
94302
|
-
if (isStale) {
|
|
94866
|
+
idempotencyKey: parsed.idempotencyKey,
|
|
94867
|
+
meta: parsed.meta,
|
|
94868
|
+
notify: parsed.notify,
|
|
94869
|
+
ensureDaemon: parsed.ensureDaemon
|
|
94870
|
+
};
|
|
94871
|
+
}
|
|
94872
|
+
const compiled = yield* try_3({
|
|
94873
|
+
try: () => compileWritePlanV1({
|
|
94874
|
+
version: 1,
|
|
94875
|
+
steps: parsed.actions.map((action) => ({
|
|
94876
|
+
action: action.action,
|
|
94877
|
+
input: action.input,
|
|
94878
|
+
...action.as ? { as: action.as } : {}
|
|
94879
|
+
}))
|
|
94880
|
+
}, { makeTempId }),
|
|
94881
|
+
catch: (e) => isCliError(e) ? e : new CliError({
|
|
94882
|
+
code: "INVALID_PAYLOAD",
|
|
94883
|
+
message: String(e?.message || "Failed to compile apply actions"),
|
|
94884
|
+
exitCode: 2
|
|
94885
|
+
})
|
|
94886
|
+
});
|
|
94887
|
+
const resolvedOps = yield* forEach9(compiled.ops, (op) => resolveRefsInPayload({ opType: op.type, payload: op.payload }).pipe(map17((payload) => ({ ...op, payload }))), { concurrency: 1 });
|
|
94888
|
+
const normalizedOps = yield* try_3({
|
|
94889
|
+
try: () => resolvedOps.map((op) => normalizeOp(op, payloadSvc.normalizeKeys)),
|
|
94890
|
+
catch: (e) => isCliError(e) ? e : new CliError({
|
|
94891
|
+
code: "INVALID_PAYLOAD",
|
|
94892
|
+
message: "Failed to generate ops",
|
|
94893
|
+
exitCode: 2,
|
|
94894
|
+
details: { error: String(e?.message || e) }
|
|
94895
|
+
})
|
|
94896
|
+
});
|
|
94303
94897
|
return {
|
|
94304
|
-
|
|
94305
|
-
|
|
94306
|
-
|
|
94307
|
-
|
|
94308
|
-
|
|
94309
|
-
|
|
94310
|
-
|
|
94898
|
+
kind: "actions",
|
|
94899
|
+
ops: normalizedOps,
|
|
94900
|
+
aliasMap: compiled.alias_map,
|
|
94901
|
+
priority: parsed.priority,
|
|
94902
|
+
clientId: parsed.clientId,
|
|
94903
|
+
idempotencyKey: parsed.idempotencyKey,
|
|
94904
|
+
meta: parsed.meta,
|
|
94905
|
+
notify: parsed.notify,
|
|
94906
|
+
ensureDaemon: parsed.ensureDaemon
|
|
94311
94907
|
};
|
|
94312
|
-
}
|
|
94313
|
-
return {
|
|
94314
|
-
status: "ok",
|
|
94315
|
-
state_file: stateFilePath,
|
|
94316
|
-
updatedAt: Number.isFinite(updatedAt) ? updatedAt : 0,
|
|
94317
|
-
now: now2,
|
|
94318
|
-
stale_ms: staleThreshold,
|
|
94319
|
-
clients: clients.length,
|
|
94320
|
-
ui_context: uiContext
|
|
94321
|
-
};
|
|
94908
|
+
});
|
|
94322
94909
|
}
|
|
94323
|
-
|
|
94324
|
-
|
|
94325
|
-
|
|
94910
|
+
|
|
94911
|
+
// src/commands/write/_optionRuntimeGuard.ts
|
|
94912
|
+
function optionCapabilityHint(scopeLabel) {
|
|
94913
|
+
return [
|
|
94914
|
+
`Use the RemNote UI to convert the ${scopeLabel} property to single_select or multi_select first.`,
|
|
94915
|
+
`Only then use ${scopeLabel} option add/remove from the CLI.`,
|
|
94916
|
+
"Plain properties do not support option mutation."
|
|
94917
|
+
];
|
|
94918
|
+
}
|
|
94919
|
+
function isSupportedOptionFieldType(value8) {
|
|
94920
|
+
return value8 === "single_select" || value8 === "multi_select";
|
|
94921
|
+
}
|
|
94922
|
+
function invalidOptionTargetError(params3) {
|
|
94923
|
+
if (params3.targetKind === "option") {
|
|
94924
|
+
return new CliError({
|
|
94925
|
+
code: "INVALID_ARGS",
|
|
94926
|
+
message: `Option mutation requires option ${params3.targetId} to belong to a single_select or multi_select ${params3.scopeLabel} property`,
|
|
94927
|
+
exitCode: 2,
|
|
94928
|
+
details: {
|
|
94929
|
+
scope: params3.scopeLabel,
|
|
94930
|
+
option_id: params3.targetId,
|
|
94931
|
+
parent_property_id: params3.parentPropertyId ?? undefined,
|
|
94932
|
+
property_field_type: params3.fieldType ?? undefined
|
|
94933
|
+
},
|
|
94934
|
+
hint: optionCapabilityHint(params3.scopeLabel)
|
|
94935
|
+
});
|
|
94326
94936
|
}
|
|
94327
|
-
|
|
94328
|
-
|
|
94329
|
-
|
|
94330
|
-
|
|
94331
|
-
|
|
94332
|
-
|
|
94333
|
-
|
|
94937
|
+
return new CliError({
|
|
94938
|
+
code: "INVALID_ARGS",
|
|
94939
|
+
message: `Option mutation requires property ${params3.targetId} to have ft=single_select or ft=multi_select in the local RemNote DB`,
|
|
94940
|
+
exitCode: 2,
|
|
94941
|
+
details: {
|
|
94942
|
+
scope: params3.scopeLabel,
|
|
94943
|
+
property_id: params3.targetId,
|
|
94944
|
+
property_field_type: params3.fieldType ?? undefined
|
|
94945
|
+
},
|
|
94946
|
+
hint: optionCapabilityHint(params3.scopeLabel)
|
|
94947
|
+
});
|
|
94948
|
+
}
|
|
94949
|
+
function missingOptionTargetError(params3) {
|
|
94950
|
+
return new CliError({
|
|
94951
|
+
code: "INVALID_ARGS",
|
|
94952
|
+
message: `${params3.targetKind === "property" ? "Property" : "Option"} ${params3.targetId} was not found in the local RemNote DB`,
|
|
94953
|
+
exitCode: 2,
|
|
94954
|
+
details: {
|
|
94955
|
+
scope: params3.scopeLabel,
|
|
94956
|
+
[`${params3.targetKind}_id`]: params3.targetId
|
|
94957
|
+
},
|
|
94958
|
+
hint: optionCapabilityHint(params3.scopeLabel)
|
|
94959
|
+
});
|
|
94960
|
+
}
|
|
94961
|
+
function ensureOptionMutationSupportedForProperty(params3) {
|
|
94962
|
+
return gen2(function* () {
|
|
94963
|
+
const remDb = yield* RemDb;
|
|
94964
|
+
const cfg = yield* AppConfig;
|
|
94965
|
+
const propertyId = String(params3.propertyId ?? "").trim();
|
|
94966
|
+
if (!propertyId) {
|
|
94967
|
+
return yield* fail8(new CliError({
|
|
94968
|
+
code: "INVALID_ARGS",
|
|
94969
|
+
message: "Missing property id for option mutation",
|
|
94970
|
+
exitCode: 2
|
|
94971
|
+
}));
|
|
94972
|
+
}
|
|
94973
|
+
const result = yield* remDb.withDb(cfg.remnoteDb, (db) => {
|
|
94974
|
+
const row = db.prepare(`SELECT json_extract(doc, '$.ft') AS field_type
|
|
94975
|
+
FROM quanta
|
|
94976
|
+
WHERE _id = ?`).get(propertyId);
|
|
94977
|
+
return { found: !!row, fieldType: typeof row?.field_type === "string" ? row.field_type : null };
|
|
94978
|
+
});
|
|
94979
|
+
if (!result.result.found) {
|
|
94980
|
+
return yield* fail8(missingOptionTargetError({ scopeLabel: params3.scopeLabel, targetKind: "property", targetId: propertyId }));
|
|
94981
|
+
}
|
|
94982
|
+
if (!isSupportedOptionFieldType(result.result.fieldType)) {
|
|
94983
|
+
return yield* fail8(invalidOptionTargetError({
|
|
94984
|
+
scopeLabel: params3.scopeLabel,
|
|
94985
|
+
targetKind: "property",
|
|
94986
|
+
targetId: propertyId,
|
|
94987
|
+
fieldType: result.result.fieldType
|
|
94988
|
+
}));
|
|
94989
|
+
}
|
|
94990
|
+
});
|
|
94991
|
+
}
|
|
94992
|
+
function ensureOptionMutationSupportedForOption(params3) {
|
|
94993
|
+
return gen2(function* () {
|
|
94994
|
+
const remDb = yield* RemDb;
|
|
94995
|
+
const cfg = yield* AppConfig;
|
|
94996
|
+
const optionId = String(params3.optionId ?? "").trim();
|
|
94997
|
+
if (!optionId) {
|
|
94998
|
+
return yield* fail8(new CliError({
|
|
94999
|
+
code: "INVALID_ARGS",
|
|
95000
|
+
message: "Missing option id for option mutation",
|
|
95001
|
+
exitCode: 2
|
|
95002
|
+
}));
|
|
95003
|
+
}
|
|
95004
|
+
const result = yield* remDb.withDb(cfg.remnoteDb, (db) => {
|
|
95005
|
+
const optionRow = db.prepare(`SELECT json_extract(doc, '$.parent') AS parent_property_id
|
|
95006
|
+
FROM quanta
|
|
95007
|
+
WHERE _id = ?`).get(optionId);
|
|
95008
|
+
const parentPropertyId = typeof optionRow?.parent_property_id === "string" ? optionRow.parent_property_id.trim() : "";
|
|
95009
|
+
if (!parentPropertyId) {
|
|
95010
|
+
return { found: !!optionRow, parentPropertyId: null, fieldType: null };
|
|
95011
|
+
}
|
|
95012
|
+
const propertyRow = db.prepare(`SELECT json_extract(doc, '$.ft') AS field_type
|
|
95013
|
+
FROM quanta
|
|
95014
|
+
WHERE _id = ?`).get(parentPropertyId);
|
|
95015
|
+
return {
|
|
95016
|
+
found: !!optionRow,
|
|
95017
|
+
parentPropertyId,
|
|
95018
|
+
fieldType: typeof propertyRow?.field_type === "string" ? propertyRow.field_type : null
|
|
95019
|
+
};
|
|
95020
|
+
});
|
|
95021
|
+
if (!result.result.found) {
|
|
95022
|
+
return yield* fail8(missingOptionTargetError({ scopeLabel: params3.scopeLabel, targetKind: "option", targetId: optionId }));
|
|
95023
|
+
}
|
|
95024
|
+
if (!isSupportedOptionFieldType(result.result.fieldType)) {
|
|
95025
|
+
return yield* fail8(invalidOptionTargetError({
|
|
95026
|
+
scopeLabel: params3.scopeLabel,
|
|
95027
|
+
targetKind: "option",
|
|
95028
|
+
targetId: optionId,
|
|
95029
|
+
parentPropertyId: result.result.parentPropertyId,
|
|
95030
|
+
fieldType: result.result.fieldType
|
|
95031
|
+
}));
|
|
95032
|
+
}
|
|
95033
|
+
});
|
|
95034
|
+
}
|
|
95035
|
+
function validateOptionMutationOps(params3) {
|
|
95036
|
+
return forEach9(params3.ops, (op) => {
|
|
95037
|
+
if (op.type === "add_option") {
|
|
95038
|
+
const propertyId = typeof op.payload?.property_id === "string" ? op.payload.property_id : "";
|
|
95039
|
+
return ensureOptionMutationSupportedForProperty({ scopeLabel: params3.scopeLabel, propertyId });
|
|
95040
|
+
}
|
|
95041
|
+
if (op.type === "remove_option") {
|
|
95042
|
+
const optionId = typeof op.payload?.option_id === "string" ? op.payload.option_id : "";
|
|
95043
|
+
return ensureOptionMutationSupportedForOption({ scopeLabel: params3.scopeLabel, optionId });
|
|
95044
|
+
}
|
|
95045
|
+
return _void;
|
|
95046
|
+
}, { concurrency: 1, discard: true });
|
|
94334
95047
|
}
|
|
94335
95048
|
|
|
94336
95049
|
// src/commands/_waitTxn.ts
|
|
@@ -94464,14 +95177,6 @@ function waitForTxn(params3) {
|
|
|
94464
95177
|
});
|
|
94465
95178
|
}
|
|
94466
95179
|
|
|
94467
|
-
// src/lib/apiUrls.ts
|
|
94468
|
-
function apiLocalBaseUrl(port3) {
|
|
94469
|
-
return `http://127.0.0.1:${port3}`;
|
|
94470
|
-
}
|
|
94471
|
-
function apiContainerBaseUrl(port3) {
|
|
94472
|
-
return `http://host.docker.internal:${port3}`;
|
|
94473
|
-
}
|
|
94474
|
-
|
|
94475
95180
|
// src/lib/text.ts
|
|
94476
95181
|
function trimBoundaryBlankLines(input) {
|
|
94477
95182
|
const normalized = input.replace(/\r\n?/g, `
|
|
@@ -94512,7 +95217,7 @@ function clampInt3(value8, min5, max7) {
|
|
|
94512
95217
|
return min5;
|
|
94513
95218
|
return Math.max(min5, Math.min(max7, Math.floor(value8)));
|
|
94514
95219
|
}
|
|
94515
|
-
function
|
|
95220
|
+
function parseDateInput(raw4) {
|
|
94516
95221
|
const trimmed2 = raw4.trim();
|
|
94517
95222
|
const match24 = /^(\d{4})-(\d{2})-(\d{2})$/.exec(trimmed2);
|
|
94518
95223
|
const value8 = match24 ? new Date(Number(match24[1]), Number(match24[2]) - 1, Number(match24[3])) : new Date(trimmed2);
|
|
@@ -94532,10 +95237,11 @@ function executeDbSearchUseCase(params3) {
|
|
|
94532
95237
|
return gen2(function* () {
|
|
94533
95238
|
const cfg = yield* AppConfig;
|
|
94534
95239
|
const effectiveTimeoutMs = clampInt3(params3.timeoutMs ?? 30000, 1, 30000);
|
|
95240
|
+
const workspace = cfg.remnoteDb ? undefined : yield* requireResolvedWorkspace({});
|
|
94535
95241
|
return yield* tryPromise2({
|
|
94536
95242
|
try: async () => await executeSearchRemOverview({
|
|
94537
95243
|
query: params3.query,
|
|
94538
|
-
dbPath: cfg.remnoteDb,
|
|
95244
|
+
dbPath: cfg.remnoteDb ?? workspace.dbPath,
|
|
94539
95245
|
timeRange: params3.timeRange,
|
|
94540
95246
|
parentId: params3.parentId,
|
|
94541
95247
|
pagesOnly: params3.pagesOnly,
|
|
@@ -94585,19 +95291,20 @@ function executePluginSearchUseCase(params3) {
|
|
|
94585
95291
|
}
|
|
94586
95292
|
function executeReadOutlineUseCase(params3) {
|
|
94587
95293
|
return gen2(function* () {
|
|
94588
|
-
const cfg = yield* AppConfig;
|
|
94589
95294
|
const refs = yield* RefResolver;
|
|
95295
|
+
const cfg = yield* AppConfig;
|
|
94590
95296
|
if (params3.id && params3.ref) {
|
|
94591
95297
|
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "Choose only one of --id or --ref", exitCode: 2 }));
|
|
94592
95298
|
}
|
|
94593
|
-
const
|
|
95299
|
+
const workspace = cfg.remnoteDb ? undefined : yield* requireResolvedWorkspace({ ref: params3.ref });
|
|
95300
|
+
const resolvedId = params3.ref ? yield* refs.resolve(params3.ref, { dbPath: cfg.remnoteDb ?? workspace?.dbPath }) : params3.id;
|
|
94594
95301
|
if (!resolvedId) {
|
|
94595
95302
|
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "You must provide --id or --ref", exitCode: 2 }));
|
|
94596
95303
|
}
|
|
94597
95304
|
return yield* tryPromise2({
|
|
94598
95305
|
try: async () => await executeOutlineRemSubtree({
|
|
94599
95306
|
id: resolvedId,
|
|
94600
|
-
dbPath: cfg.remnoteDb,
|
|
95307
|
+
dbPath: cfg.remnoteDb ?? workspace.dbPath,
|
|
94601
95308
|
maxDepth: params3.depth,
|
|
94602
95309
|
startOffset: params3.offset,
|
|
94603
95310
|
maxNodes: params3.nodes,
|
|
@@ -94617,22 +95324,24 @@ function executeDailyRemIdUseCase(params3) {
|
|
|
94617
95324
|
if (params3.date && params3.offsetDays !== undefined) {
|
|
94618
95325
|
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "Choose only one of --date or --offset-days", exitCode: 2 }));
|
|
94619
95326
|
}
|
|
94620
|
-
const cfg = yield* AppConfig;
|
|
94621
95327
|
const refs = yield* RefResolver;
|
|
94622
95328
|
const remDb = yield* RemDb;
|
|
95329
|
+
const cfg = yield* AppConfig;
|
|
95330
|
+
const workspace = cfg.remnoteDb ? undefined : yield* requireResolvedWorkspace({});
|
|
95331
|
+
const dbPath = cfg.remnoteDb ?? workspace.dbPath;
|
|
94623
95332
|
let ref = `daily:${params3.offsetDays ?? 0}`;
|
|
94624
95333
|
let remId = "";
|
|
94625
95334
|
let dateString;
|
|
94626
95335
|
if (params3.date) {
|
|
94627
|
-
const target2 =
|
|
94628
|
-
dateString = yield* remDb.withDb(
|
|
95336
|
+
const target2 = parseDateInput(params3.date);
|
|
95337
|
+
dateString = yield* remDb.withDb(dbPath, async (db) => {
|
|
94629
95338
|
const format9 = await getDateFormatting(db) ?? "yyyy/MM/dd";
|
|
94630
95339
|
return formatDateWithPattern(target2, format9);
|
|
94631
95340
|
}).pipe(map17((result2) => result2.result), catchAll2(() => succeed8(formatDateWithPattern(target2, "yyyy/MM/dd"))));
|
|
94632
95341
|
const result = yield* tryPromise2({
|
|
94633
95342
|
try: async () => await executeSearchRemOverview({
|
|
94634
95343
|
query: dateString,
|
|
94635
|
-
dbPath
|
|
95344
|
+
dbPath,
|
|
94636
95345
|
limit: 1,
|
|
94637
95346
|
preferExact: true,
|
|
94638
95347
|
exactFirstSingle: true,
|
|
@@ -94653,10 +95362,10 @@ function executeDailyRemIdUseCase(params3) {
|
|
|
94653
95362
|
} else {
|
|
94654
95363
|
const offset = params3.offsetDays ?? 0;
|
|
94655
95364
|
ref = `daily:${offset}`;
|
|
94656
|
-
remId = yield* refs.resolve(ref);
|
|
95365
|
+
remId = yield* refs.resolve(ref, { dbPath });
|
|
94657
95366
|
const target2 = todayAtMidnight();
|
|
94658
95367
|
target2.setDate(target2.getDate() + offset);
|
|
94659
|
-
dateString = yield* remDb.withDb(
|
|
95368
|
+
dateString = yield* remDb.withDb(dbPath, async (db) => {
|
|
94660
95369
|
const format9 = await getDateFormatting(db) ?? "yyyy/MM/dd";
|
|
94661
95370
|
return formatDateWithPattern(target2, format9);
|
|
94662
95371
|
}).pipe(map17((result) => result.result), catchAll2(() => succeed8(undefined)));
|
|
@@ -94666,6 +95375,7 @@ function executeDailyRemIdUseCase(params3) {
|
|
|
94666
95375
|
}
|
|
94667
95376
|
function executeWriteApplyUseCase(params3) {
|
|
94668
95377
|
return gen2(function* () {
|
|
95378
|
+
const cfg = yield* AppConfig;
|
|
94669
95379
|
const payloadSvc = yield* Payload;
|
|
94670
95380
|
const parsed = yield* try_3({
|
|
94671
95381
|
try: () => parseApplyEnvelope(payloadSvc.normalizeKeys(params3.raw)),
|
|
@@ -94676,6 +95386,7 @@ function executeWriteApplyUseCase(params3) {
|
|
|
94676
95386
|
})
|
|
94677
95387
|
});
|
|
94678
95388
|
const compiled = yield* compileApplyEnvelope(parsed);
|
|
95389
|
+
yield* validateOptionMutationOps({ scopeLabel: "generic", ops: compiled.ops });
|
|
94679
95390
|
if (compiled.ops.length > 500) {
|
|
94680
95391
|
return yield* fail8(new CliError({
|
|
94681
95392
|
code: "PAYLOAD_TOO_LARGE",
|
|
@@ -94731,9 +95442,13 @@ function collectApiHealthUseCase(params3) {
|
|
|
94731
95442
|
wsUrl: cfg.wsUrl
|
|
94732
95443
|
},
|
|
94733
95444
|
activeWorkerConnId: clientsRes._tag === "Right" ? clientsRes.right.activeWorkerConnId ?? null : null,
|
|
94734
|
-
queue: queueStats2._tag === "Right" ? {
|
|
94735
|
-
|
|
94736
|
-
|
|
95445
|
+
queue: queueStats2._tag === "Right" ? {
|
|
95446
|
+
available: true,
|
|
95447
|
+
pending: queueStats2.right.pending ?? 0,
|
|
95448
|
+
in_flight: queueStats2.right.in_flight ?? 0
|
|
95449
|
+
} : { available: false, pending: 0, in_flight: 0 },
|
|
95450
|
+
localBaseUrl: apiLocalBaseUrl(params3.port, params3.basePath),
|
|
95451
|
+
containerBaseUrl: apiContainerBaseUrl(params3.port, params3.basePath),
|
|
94737
95452
|
basePath: params3.basePath,
|
|
94738
95453
|
host: params3.host,
|
|
94739
95454
|
port: params3.port
|
|
@@ -94742,17 +95457,50 @@ function collectApiHealthUseCase(params3) {
|
|
|
94742
95457
|
}
|
|
94743
95458
|
function collectApiStatusUseCase(params3) {
|
|
94744
95459
|
return gen2(function* () {
|
|
95460
|
+
const cfg = yield* AppConfig;
|
|
94745
95461
|
const health = yield* collectApiHealthUseCase(params3);
|
|
94746
95462
|
const uiContext = loadBridgeUiContextSnapshot({ stateFile: undefined, staleMs: undefined, connId: undefined });
|
|
94747
95463
|
const selection = loadBridgeSelectionSnapshot({ stateFile: undefined, staleMs: undefined, connId: undefined });
|
|
95464
|
+
const workspaceResolution = yield* resolveWorkspaceSnapshot({});
|
|
95465
|
+
const pluginRpcReady = health.daemon.healthy === true && typeof health.activeWorkerConnId === "string" && health.activeWorkerConnId.length > 0;
|
|
95466
|
+
const uiSessionReady = uiContext.status === "ok" || selection.status === "ok";
|
|
95467
|
+
const effectiveDbPath = workspaceResolution.dbPath ?? cfg.remnoteDb ?? null;
|
|
95468
|
+
const dbReadReady = workspaceResolution.resolved === true || !!cfg.remnoteDb;
|
|
95469
|
+
const queueReady = health.queue?.available === true;
|
|
95470
|
+
const writeReady = queueReady && pluginRpcReady;
|
|
95471
|
+
const bindingSource = workspaceResolution.bindingSource ?? (cfg.remnoteDb ? "config" : workspaceResolution.source === "unresolved" ? undefined : workspaceResolution.source);
|
|
94748
95472
|
return {
|
|
94749
95473
|
...health,
|
|
95474
|
+
capabilities: {
|
|
95475
|
+
db_read_ready: dbReadReady,
|
|
95476
|
+
plugin_rpc_ready: pluginRpcReady,
|
|
95477
|
+
write_ready: writeReady,
|
|
95478
|
+
ui_session_ready: uiSessionReady
|
|
95479
|
+
},
|
|
95480
|
+
workspace: {
|
|
95481
|
+
resolved: workspaceResolution.resolved,
|
|
95482
|
+
currentWorkspaceId: workspaceResolution.workspaceId ?? null,
|
|
95483
|
+
currentDbPath: effectiveDbPath,
|
|
95484
|
+
bindingSource: bindingSource ?? null,
|
|
95485
|
+
resolutionSource: cfg.remnoteDb && workspaceResolution.resolved !== true ? "config" : workspaceResolution.source,
|
|
95486
|
+
candidateWorkspaces: workspaceResolution.candidates,
|
|
95487
|
+
reasons: workspaceResolution.reasons
|
|
95488
|
+
},
|
|
95489
|
+
plugin: {
|
|
95490
|
+
ws_healthy: health.daemon.healthy,
|
|
95491
|
+
active_worker_conn_id: health.activeWorkerConnId
|
|
95492
|
+
},
|
|
95493
|
+
write: {
|
|
95494
|
+
daemon_ready: health.daemon.healthy,
|
|
95495
|
+
queue_ready: queueReady,
|
|
95496
|
+
worker_ready: pluginRpcReady
|
|
95497
|
+
},
|
|
94750
95498
|
uiContext,
|
|
94751
95499
|
selection
|
|
94752
95500
|
};
|
|
94753
95501
|
});
|
|
94754
95502
|
}
|
|
94755
|
-
function
|
|
95503
|
+
function normalizeText3(value8) {
|
|
94756
95504
|
return typeof value8 === "string" ? value8.trim() : "";
|
|
94757
95505
|
}
|
|
94758
95506
|
function truncateText(value8, maxLength) {
|
|
@@ -94764,8 +95512,8 @@ function truncateText(value8, maxLength) {
|
|
|
94764
95512
|
return `${normalized.slice(0, maxLength)}…`;
|
|
94765
95513
|
}
|
|
94766
95514
|
function pickTitle(kt, ke, r) {
|
|
94767
|
-
const combined = [kt, ke].map(
|
|
94768
|
-
const raw4 = combined ||
|
|
95515
|
+
const combined = [kt, ke].map(normalizeText3).filter(Boolean).join(" | ");
|
|
95516
|
+
const raw4 = combined || normalizeText3(r);
|
|
94769
95517
|
if (!raw4)
|
|
94770
95518
|
return "";
|
|
94771
95519
|
const normalized = raw4.replace(/\s+/g, " ").trim();
|
|
@@ -94875,8 +95623,8 @@ function collectPluginCurrentUseCase(params3) {
|
|
|
94875
95623
|
const selectionSnapshot = loadBridgeSelectionSnapshot({ stateFile: params3.stateFile, staleMs: params3.staleMs });
|
|
94876
95624
|
const ui = uiSnapshot.ui_context;
|
|
94877
95625
|
const selection = selectionSnapshot.selection;
|
|
94878
|
-
const pageRemId =
|
|
94879
|
-
const focusedRemId =
|
|
95626
|
+
const pageRemId = normalizeText3(ui?.pageRemId);
|
|
95627
|
+
const focusedRemId = normalizeText3(ui?.focusedRemId);
|
|
94880
95628
|
const selectionKind = selection?.kind ?? "none";
|
|
94881
95629
|
const selectionIds = selection?.kind === "rem" ? uniqueNonEmpty(selection.remIds.map(String)) : selection?.kind === "text" ? uniqueNonEmpty([selection.remId]) : [];
|
|
94882
95630
|
const selectionTotalCountRaw = selection?.kind === "rem" ? Number(selection.totalCount ?? 0) : selection?.kind === "text" ? 1 : 0;
|
|
@@ -94888,10 +95636,11 @@ function collectPluginCurrentUseCase(params3) {
|
|
|
94888
95636
|
const selectionShownIds = selectionIds.slice(0, selectionLimitEffective);
|
|
94889
95637
|
const idsToResolve = uniqueNonEmpty([currentId, pageRemId, focusedRemId, ...selectionShownIds]);
|
|
94890
95638
|
const warnings = [];
|
|
94891
|
-
const
|
|
94892
|
-
|
|
94893
|
-
|
|
94894
|
-
})();
|
|
95639
|
+
const workspace = yield* resolveWorkspaceSnapshot({
|
|
95640
|
+
stateFile: params3.stateFile,
|
|
95641
|
+
staleMs: params3.staleMs
|
|
95642
|
+
}).pipe(catchAll2(() => succeed8(undefined)));
|
|
95643
|
+
const dbPathCandidate = cfg.remnoteDb ?? (workspace?.resolved ? workspace.dbPath : undefined);
|
|
94895
95644
|
const titles = yield* gen2(function* () {
|
|
94896
95645
|
if (!dbPathCandidate || idsToResolve.length === 0)
|
|
94897
95646
|
return new Map;
|
|
@@ -94930,15 +95679,16 @@ function collectSelectionCurrentUseCase(params3) {
|
|
|
94930
95679
|
}
|
|
94931
95680
|
const uiSnapshot = loadBridgeUiContextSnapshot({ stateFile: params3.stateFile, staleMs: params3.staleMs });
|
|
94932
95681
|
const ui = uiSnapshot.ui_context;
|
|
94933
|
-
const pageRemId =
|
|
94934
|
-
const focusedRemId =
|
|
95682
|
+
const pageRemId = normalizeText3(ui?.pageRemId);
|
|
95683
|
+
const focusedRemId = normalizeText3(ui?.focusedRemId);
|
|
94935
95684
|
const currentId = ids3[0] ?? "";
|
|
94936
95685
|
const idsToResolve = uniqueNonEmpty([currentId, pageRemId, focusedRemId]);
|
|
94937
95686
|
const warnings = [];
|
|
94938
|
-
const
|
|
94939
|
-
|
|
94940
|
-
|
|
94941
|
-
})();
|
|
95687
|
+
const workspace = yield* resolveWorkspaceSnapshot({
|
|
95688
|
+
stateFile: params3.stateFile,
|
|
95689
|
+
staleMs: params3.staleMs
|
|
95690
|
+
}).pipe(catchAll2(() => succeed8(undefined)));
|
|
95691
|
+
const dbPathCandidate = cfg.remnoteDb ?? (workspace?.resolved ? workspace.dbPath : undefined);
|
|
94942
95692
|
const titles = yield* gen2(function* () {
|
|
94943
95693
|
if (!dbPathCandidate || idsToResolve.length === 0)
|
|
94944
95694
|
return new Map;
|
|
@@ -94968,6 +95718,8 @@ function collectSelectionOutlineUseCase(params3) {
|
|
|
94968
95718
|
const cfg = yield* AppConfig;
|
|
94969
95719
|
const snapshot2 = loadBridgeSelectionSnapshot({ stateFile: params3.stateFile, staleMs: params3.staleMs });
|
|
94970
95720
|
const selection = yield* requireOkRemSelection(snapshot2);
|
|
95721
|
+
const workspace = cfg.remnoteDb ? undefined : yield* requireResolvedWorkspace({ stateFile: params3.stateFile, staleMs: params3.staleMs });
|
|
95722
|
+
const dbPath = cfg.remnoteDb ?? workspace.dbPath;
|
|
94971
95723
|
const rootIds = selection.remIds.map(String);
|
|
94972
95724
|
if (rootIds.length === 0) {
|
|
94973
95725
|
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "No Rem is currently selected", exitCode: 2, details: snapshot2 }));
|
|
@@ -94984,7 +95736,7 @@ function collectSelectionOutlineUseCase(params3) {
|
|
|
94984
95736
|
const result = yield* tryPromise2({
|
|
94985
95737
|
try: async () => await executeOutlineRemSubtree({
|
|
94986
95738
|
id: rootId,
|
|
94987
|
-
dbPath
|
|
95739
|
+
dbPath,
|
|
94988
95740
|
maxDepth: maxDepthValue,
|
|
94989
95741
|
startOffset: 0,
|
|
94990
95742
|
maxNodes: perRootMax,
|
|
@@ -94995,7 +95747,14 @@ function collectSelectionOutlineUseCase(params3) {
|
|
|
94995
95747
|
maxReferenceDepth: params3.maxReferenceDepth,
|
|
94996
95748
|
detail: params3.detail === true
|
|
94997
95749
|
}),
|
|
94998
|
-
catch: (e) => cliErrorFromUnknown(e, {
|
|
95750
|
+
catch: (e) => cliErrorFromUnknown(e, {
|
|
95751
|
+
code: "DB_UNAVAILABLE",
|
|
95752
|
+
details: {
|
|
95753
|
+
root_id: rootId,
|
|
95754
|
+
db_path: dbPath,
|
|
95755
|
+
workspace_id: workspace?.workspaceId
|
|
95756
|
+
}
|
|
95757
|
+
})
|
|
94999
95758
|
});
|
|
95000
95759
|
const nodeCount = Number(result.nodeCount ?? 0);
|
|
95001
95760
|
const n = Number.isFinite(nodeCount) && nodeCount >= 0 ? Math.floor(nodeCount) : 0;
|
|
@@ -95032,26 +95791,27 @@ function collectUiContextDescribeUseCase(params3) {
|
|
|
95032
95791
|
const selectionSnapshot = loadBridgeSelectionSnapshot({ stateFile: params3.stateFile, staleMs: params3.staleMs });
|
|
95033
95792
|
const ui = uiSnapshot.ui_context;
|
|
95034
95793
|
const selection = selectionSnapshot.selection;
|
|
95035
|
-
const pageRemId =
|
|
95036
|
-
const focusedPortalId =
|
|
95037
|
-
const focusedRemId =
|
|
95794
|
+
const pageRemId = normalizeText3(ui?.pageRemId);
|
|
95795
|
+
const focusedPortalId = normalizeText3(ui?.focusedPortalId);
|
|
95796
|
+
const focusedRemId = normalizeText3(ui?.focusedRemId);
|
|
95038
95797
|
const kind = computePortalKind(pageRemId, focusedPortalId);
|
|
95039
95798
|
const selectionKind = selection?.kind ?? "none";
|
|
95040
95799
|
const selectionIds = uniqueNonEmpty(selection?.kind === "rem" ? selection.remIds.map(String) : []);
|
|
95041
95800
|
const selectionTotalCountRaw = selection?.kind === "rem" ? Number(selection.totalCount ?? 0) : selection?.kind === "text" ? 1 : 0;
|
|
95042
95801
|
const selectionTotalCount = Number.isFinite(selectionTotalCountRaw) && selectionTotalCountRaw >= 0 ? Math.floor(selectionTotalCountRaw) : 0;
|
|
95043
95802
|
const selectionTruncated = selection?.kind === "rem" ? selection.truncated === true : false;
|
|
95044
|
-
const selectionTextRemId = selection?.kind === "text" ?
|
|
95803
|
+
const selectionTextRemId = selection?.kind === "text" ? normalizeText3(selection.remId) : "";
|
|
95045
95804
|
const anchorSource = focusedRemId ? "focus" : selection?.kind === "rem" && selectionIds.length > 0 ? "selection" : selection?.kind === "text" && selectionTextRemId ? "selection" : "none";
|
|
95046
95805
|
const anchorRemId = anchorSource === "focus" ? focusedRemId : anchorSource === "selection" ? selection?.kind === "rem" ? selectionIds[0] ?? "" : selectionTextRemId : "";
|
|
95047
95806
|
const selectionLimitEffective = clampInt3(params3.selectionLimit ?? 5, 1, 50);
|
|
95048
95807
|
const selectionShownIds = selectionIds.slice(0, selectionLimitEffective);
|
|
95049
95808
|
const idsToResolve = uniqueNonEmpty([pageRemId, focusedPortalId, focusedRemId, anchorRemId, ...selectionShownIds]);
|
|
95050
95809
|
const warnings = [];
|
|
95051
|
-
const
|
|
95052
|
-
|
|
95053
|
-
|
|
95054
|
-
})();
|
|
95810
|
+
const workspace = yield* resolveWorkspaceSnapshot({
|
|
95811
|
+
stateFile: params3.stateFile,
|
|
95812
|
+
staleMs: params3.staleMs
|
|
95813
|
+
}).pipe(catchAll2(() => succeed8(undefined)));
|
|
95814
|
+
const dbPathCandidate = cfg.remnoteDb ?? (workspace?.resolved ? workspace.dbPath : undefined);
|
|
95055
95815
|
const titles = yield* gen2(function* () {
|
|
95056
95816
|
if (!dbPathCandidate || idsToResolve.length === 0)
|
|
95057
95817
|
return new Map;
|
|
@@ -95087,6 +95847,45 @@ function collectUiContextDescribeUseCase(params3) {
|
|
|
95087
95847
|
});
|
|
95088
95848
|
}
|
|
95089
95849
|
|
|
95850
|
+
// src/commands/daily/rem-id.ts
|
|
95851
|
+
function optionToUndefined10(opt) {
|
|
95852
|
+
return isSome2(opt) ? opt.value : undefined;
|
|
95853
|
+
}
|
|
95854
|
+
var date6 = text9("date").pipe(optional5, map34(optionToUndefined10));
|
|
95855
|
+
var offsetDays = integer7("offset-days").pipe(optional5, map34(optionToUndefined10));
|
|
95856
|
+
var dailyRemIdCommand = exports_Command.make("rem-id", { date: date6, offsetDays }, ({ date: date7, offsetDays: offsetDays2 }) => gen2(function* () {
|
|
95857
|
+
if (date7 && offsetDays2 !== undefined) {
|
|
95858
|
+
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "Choose only one of --date or --offset-days", exitCode: 2 }));
|
|
95859
|
+
}
|
|
95860
|
+
const cfg = yield* AppConfig;
|
|
95861
|
+
const hostApi = yield* HostApiClient;
|
|
95862
|
+
if (cfg.apiBaseUrl) {
|
|
95863
|
+
const data2 = yield* hostApi.dailyRemId({
|
|
95864
|
+
baseUrl: cfg.apiBaseUrl,
|
|
95865
|
+
date: date7,
|
|
95866
|
+
offsetDays: offsetDays2
|
|
95867
|
+
});
|
|
95868
|
+
yield* writeSuccess({
|
|
95869
|
+
data: data2,
|
|
95870
|
+
ids: [data2.remId],
|
|
95871
|
+
md: `- ref: ${data2.ref}
|
|
95872
|
+
- rem_id: ${data2.remId}${data2.dateString ? `
|
|
95873
|
+
- date_string: ${data2.dateString}` : ""}
|
|
95874
|
+
`
|
|
95875
|
+
});
|
|
95876
|
+
return;
|
|
95877
|
+
}
|
|
95878
|
+
const data = yield* executeDailyRemIdUseCase({ date: date7, offsetDays: offsetDays2 });
|
|
95879
|
+
yield* writeSuccess({
|
|
95880
|
+
data,
|
|
95881
|
+
ids: [data.remId],
|
|
95882
|
+
md: `- ref: ${data.ref}
|
|
95883
|
+
- rem_id: ${data.remId}${data.dateString ? `
|
|
95884
|
+
- date_string: ${data.dateString}` : ""}
|
|
95885
|
+
`
|
|
95886
|
+
});
|
|
95887
|
+
}).pipe(catchAll2(writeFailure)));
|
|
95888
|
+
|
|
95090
95889
|
// src/commands/daily/write.ts
|
|
95091
95890
|
function optionToUndefined11(opt) {
|
|
95092
95891
|
return isSome2(opt) ? opt.value : undefined;
|
|
@@ -95114,7 +95913,7 @@ var bulk = choice5("bulk", ["auto", "always", "never"]).pipe(optional5, map34(op
|
|
|
95114
95913
|
var bundleTitle = readOptionalText("bundle-title");
|
|
95115
95914
|
var BULK_THRESHOLD_LINES = 80;
|
|
95116
95915
|
var BULK_THRESHOLD_CHARS = 5000;
|
|
95117
|
-
function
|
|
95916
|
+
function parseDateInput2(raw4) {
|
|
95118
95917
|
const trimmed2 = raw4.trim();
|
|
95119
95918
|
const match24 = /^(\d{4})-(\d{2})-(\d{2})$/.exec(trimmed2);
|
|
95120
95919
|
const d = match24 ? new Date(Number(match24[1]), Number(match24[2]) - 1, Number(match24[3])) : new Date(trimmed2);
|
|
@@ -95231,7 +96030,7 @@ var dailyWriteCommand = exports_Command.make("write", {
|
|
|
95231
96030
|
exitCode: 2
|
|
95232
96031
|
}));
|
|
95233
96032
|
}
|
|
95234
|
-
const target2 = date8 ?
|
|
96033
|
+
const target2 = date8 ? parseDateInput2(date8) : null;
|
|
95235
96034
|
const createIfMissingBool = noCreateIfMissing2 ? false : createIfMissing2 ? true : undefined;
|
|
95236
96035
|
const content = markdownValue ?? textValue ?? "";
|
|
95237
96036
|
const lines3 = content.split(`
|
|
@@ -95703,19 +96502,22 @@ var applyCommand = exports_Command.make("apply", {
|
|
|
95703
96502
|
timeoutMs: timeoutMs3,
|
|
95704
96503
|
pollMs: pollMs3
|
|
95705
96504
|
}
|
|
95706
|
-
}) : yield*
|
|
95707
|
-
|
|
95708
|
-
|
|
95709
|
-
|
|
95710
|
-
|
|
95711
|
-
|
|
95712
|
-
|
|
95713
|
-
|
|
95714
|
-
|
|
95715
|
-
|
|
95716
|
-
|
|
95717
|
-
|
|
95718
|
-
|
|
96505
|
+
}) : yield* gen2(function* () {
|
|
96506
|
+
yield* validateOptionMutationOps({ scopeLabel: "generic", ops: compiled.ops });
|
|
96507
|
+
return yield* executeWriteApplyUseCase({
|
|
96508
|
+
raw: {
|
|
96509
|
+
...raw4,
|
|
96510
|
+
priority: resolvedPriority,
|
|
96511
|
+
clientId: resolvedClientId,
|
|
96512
|
+
idempotencyKey: resolvedIdempotencyKey,
|
|
96513
|
+
meta: metaValue,
|
|
96514
|
+
notify: notify3 ?? compiled.notify ?? true,
|
|
96515
|
+
ensureDaemon: ensureDaemon4 ?? compiled.ensureDaemon ?? true
|
|
96516
|
+
},
|
|
96517
|
+
wait: wait3,
|
|
96518
|
+
timeoutMs: timeoutMs3,
|
|
96519
|
+
pollMs: pollMs3
|
|
96520
|
+
});
|
|
95719
96521
|
});
|
|
95720
96522
|
const out = compiled.kind === "actions" ? { ...data, alias_map: compiled.aliasMap } : data;
|
|
95721
96523
|
yield* writeSuccess({
|
|
@@ -95730,12 +96532,12 @@ var applyCommand = exports_Command.make("apply", {
|
|
|
95730
96532
|
}).pipe(catchAll2(writeFailure)));
|
|
95731
96533
|
|
|
95732
96534
|
// src/services/ApiDaemonFiles.ts
|
|
95733
|
-
import { promises as
|
|
95734
|
-
import
|
|
96535
|
+
import { promises as fs19 } from "node:fs";
|
|
96536
|
+
import path25 from "node:path";
|
|
95735
96537
|
class ApiDaemonFiles extends Tag2("ApiDaemonFiles")() {
|
|
95736
96538
|
}
|
|
95737
96539
|
function ensureDir9(p3) {
|
|
95738
|
-
return
|
|
96540
|
+
return fs19.mkdir(path25.dirname(p3), { recursive: true }).then(() => {
|
|
95739
96541
|
return;
|
|
95740
96542
|
});
|
|
95741
96543
|
}
|
|
@@ -95743,19 +96545,19 @@ function defaultPidFile2() {
|
|
|
95743
96545
|
const envPidFile = process.env.REMNOTE_API_PID_FILE;
|
|
95744
96546
|
if (typeof envPidFile === "string" && envPidFile.trim())
|
|
95745
96547
|
return resolveUserFilePath(envPidFile);
|
|
95746
|
-
return
|
|
96548
|
+
return path25.join(homeDir(), ".agent-remnote", "api.pid");
|
|
95747
96549
|
}
|
|
95748
96550
|
function defaultLogFile2() {
|
|
95749
96551
|
const envLogFile = process.env.REMNOTE_API_LOG_FILE;
|
|
95750
96552
|
if (typeof envLogFile === "string" && envLogFile.trim())
|
|
95751
96553
|
return resolveUserFilePath(envLogFile);
|
|
95752
|
-
return
|
|
96554
|
+
return path25.join(homeDir(), ".agent-remnote", "api.log");
|
|
95753
96555
|
}
|
|
95754
96556
|
function defaultStateFile2() {
|
|
95755
96557
|
const envStateFile = process.env.REMNOTE_API_STATE_FILE;
|
|
95756
96558
|
if (typeof envStateFile === "string" && envStateFile.trim())
|
|
95757
96559
|
return resolveUserFilePath(envStateFile);
|
|
95758
|
-
return
|
|
96560
|
+
return path25.join(homeDir(), ".agent-remnote", "api.state.json");
|
|
95759
96561
|
}
|
|
95760
96562
|
function parseJson2(raw4, filePath) {
|
|
95761
96563
|
try {
|
|
@@ -95776,7 +96578,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
|
|
|
95776
96578
|
readPidFile: (pidFilePath) => tryPromise2({
|
|
95777
96579
|
try: async () => {
|
|
95778
96580
|
const resolved = resolveUserFilePath(pidFilePath);
|
|
95779
|
-
const raw4 = await
|
|
96581
|
+
const raw4 = await fs19.readFile(resolved, "utf8");
|
|
95780
96582
|
return parseJson2(raw4, resolved);
|
|
95781
96583
|
},
|
|
95782
96584
|
catch: (error4) => {
|
|
@@ -95801,7 +96603,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
|
|
|
95801
96603
|
try: async () => {
|
|
95802
96604
|
const resolved = resolveUserFilePath(pidFilePath);
|
|
95803
96605
|
await ensureDir9(resolved);
|
|
95804
|
-
await
|
|
96606
|
+
await fs19.writeFile(resolved, `${JSON.stringify(value8, null, 2)}
|
|
95805
96607
|
`, "utf8");
|
|
95806
96608
|
},
|
|
95807
96609
|
catch: (error4) => new CliError({
|
|
@@ -95814,7 +96616,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
|
|
|
95814
96616
|
deletePidFile: (pidFilePath) => tryPromise2({
|
|
95815
96617
|
try: async () => {
|
|
95816
96618
|
const resolved = resolveUserFilePath(pidFilePath);
|
|
95817
|
-
await
|
|
96619
|
+
await fs19.rm(resolved, { force: true });
|
|
95818
96620
|
},
|
|
95819
96621
|
catch: (error4) => new CliError({
|
|
95820
96622
|
code: "INTERNAL",
|
|
@@ -95826,7 +96628,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
|
|
|
95826
96628
|
readStateFile: (stateFilePath) => tryPromise2({
|
|
95827
96629
|
try: async () => {
|
|
95828
96630
|
const resolved = resolveUserFilePath(stateFilePath);
|
|
95829
|
-
const raw4 = await
|
|
96631
|
+
const raw4 = await fs19.readFile(resolved, "utf8");
|
|
95830
96632
|
return parseJson2(raw4, resolved);
|
|
95831
96633
|
},
|
|
95832
96634
|
catch: (error4) => {
|
|
@@ -95851,7 +96653,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
|
|
|
95851
96653
|
try: async () => {
|
|
95852
96654
|
const resolved = resolveUserFilePath(stateFilePath);
|
|
95853
96655
|
await ensureDir9(resolved);
|
|
95854
|
-
await
|
|
96656
|
+
await fs19.writeFile(resolved, `${JSON.stringify(value8, null, 2)}
|
|
95855
96657
|
`, "utf8");
|
|
95856
96658
|
},
|
|
95857
96659
|
catch: (error4) => new CliError({
|
|
@@ -95864,7 +96666,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
|
|
|
95864
96666
|
deleteStateFile: (stateFilePath) => tryPromise2({
|
|
95865
96667
|
try: async () => {
|
|
95866
96668
|
const resolved = resolveUserFilePath(stateFilePath);
|
|
95867
|
-
await
|
|
96669
|
+
await fs19.rm(resolved, { force: true });
|
|
95868
96670
|
},
|
|
95869
96671
|
catch: (error4) => new CliError({
|
|
95870
96672
|
code: "INTERNAL",
|
|
@@ -95894,6 +96696,7 @@ function childCommandLine2(params3) {
|
|
|
95894
96696
|
const args2 = [...execArgv, script, "--daemon-url", params3.wsUrl, "--store-db", params3.storeDb];
|
|
95895
96697
|
if (params3.remnoteDb)
|
|
95896
96698
|
args2.push("--remnote-db", params3.remnoteDb);
|
|
96699
|
+
args2.push("--api-base-path", params3.basePath);
|
|
95897
96700
|
args2.push("api", "serve", "--host", params3.host, "--port", String(params3.port), "--state-file", params3.stateFile);
|
|
95898
96701
|
return { command, args: args2 };
|
|
95899
96702
|
}
|
|
@@ -95947,10 +96750,11 @@ function startApiDaemon(params3) {
|
|
|
95947
96750
|
const proc = yield* Process;
|
|
95948
96751
|
const host = params3.host ?? cfg.apiHost ?? "0.0.0.0";
|
|
95949
96752
|
const port3 = params3.port ?? cfg.apiPort ?? 3000;
|
|
96753
|
+
const basePath2 = cfg.apiBasePath ?? "/v1";
|
|
95950
96754
|
const pidFilePath = resolveUserFilePath(params3.pidFile ?? apiFiles.defaultPidFile());
|
|
95951
96755
|
const logFilePath = resolveUserFilePath(params3.logFile ?? apiFiles.defaultLogFile());
|
|
95952
96756
|
const stateFilePath = resolveUserFilePath(params3.stateFile ?? apiFiles.defaultStateFile());
|
|
95953
|
-
const localBaseUrl = apiLocalBaseUrl(port3);
|
|
96757
|
+
const localBaseUrl = apiLocalBaseUrl(port3, basePath2);
|
|
95954
96758
|
const existing = yield* apiFiles.readPidFile(pidFilePath);
|
|
95955
96759
|
if (existing) {
|
|
95956
96760
|
const alive = yield* proc.isPidRunning(existing.pid);
|
|
@@ -95984,6 +96788,7 @@ function startApiDaemon(params3) {
|
|
|
95984
96788
|
remnoteDb: cfg.remnoteDb,
|
|
95985
96789
|
host,
|
|
95986
96790
|
port: port3,
|
|
96791
|
+
basePath: basePath2,
|
|
95987
96792
|
stateFile: stateFilePath
|
|
95988
96793
|
}),
|
|
95989
96794
|
catch: (e) => isCliError(e) ? e : new CliError({
|
|
@@ -95999,7 +96804,7 @@ function startApiDaemon(params3) {
|
|
|
95999
96804
|
startedAt: Date.now(),
|
|
96000
96805
|
host,
|
|
96001
96806
|
port: port3,
|
|
96002
|
-
basePath:
|
|
96807
|
+
basePath: basePath2,
|
|
96003
96808
|
logFile: logFilePath,
|
|
96004
96809
|
stateFile: stateFilePath,
|
|
96005
96810
|
cmd: [cmd.command, ...cmd.args]
|
|
@@ -96022,10 +96827,11 @@ function ensureApiDaemon(params3) {
|
|
|
96022
96827
|
const apiFiles = yield* ApiDaemonFiles;
|
|
96023
96828
|
const proc = yield* Process;
|
|
96024
96829
|
const port3 = params3.port ?? cfg.apiPort ?? 3000;
|
|
96830
|
+
const basePath2 = cfg.apiBasePath ?? "/v1";
|
|
96025
96831
|
const pidFilePath = resolveUserFilePath(params3.pidFile ?? apiFiles.defaultPidFile());
|
|
96026
96832
|
const logFilePath = resolveUserFilePath(params3.logFile ?? apiFiles.defaultLogFile());
|
|
96027
96833
|
const stateFilePath = resolveUserFilePath(params3.stateFile ?? apiFiles.defaultStateFile());
|
|
96028
|
-
const localBaseUrl = apiLocalBaseUrl(port3);
|
|
96834
|
+
const localBaseUrl = apiLocalBaseUrl(port3, basePath2);
|
|
96029
96835
|
const pre = yield* api.health({ baseUrl: localBaseUrl, timeoutMs: API_HEALTH_TIMEOUT_MS }).pipe(either3);
|
|
96030
96836
|
if (isRight2(pre)) {
|
|
96031
96837
|
const existing = yield* apiFiles.readPidFile(pidFilePath);
|
|
@@ -96198,9 +97004,13 @@ function statusCodeFromCliError(error4) {
|
|
|
96198
97004
|
case "INVALID_PAYLOAD":
|
|
96199
97005
|
case "PAYLOAD_TOO_LARGE":
|
|
96200
97006
|
return 400;
|
|
97007
|
+
case "WORKSPACE_UNRESOLVED":
|
|
96201
97008
|
case "TXN_FAILED":
|
|
96202
97009
|
case "ID_MAP_CONFLICT":
|
|
96203
97010
|
return 409;
|
|
97011
|
+
case "PLUGIN_UNAVAILABLE":
|
|
97012
|
+
case "WRITE_UNAVAILABLE":
|
|
97013
|
+
case "UI_SESSION_UNAVAILABLE":
|
|
96204
97014
|
case "WS_UNAVAILABLE":
|
|
96205
97015
|
case "WS_TIMEOUT":
|
|
96206
97016
|
case "DB_UNAVAILABLE":
|
|
@@ -96262,6 +97072,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96262
97072
|
return gen2(function* () {
|
|
96263
97073
|
const cfg = yield* AppConfig;
|
|
96264
97074
|
const runtimeCfg = { ...cfg, apiBaseUrl: undefined };
|
|
97075
|
+
const basePath2 = normalizeApiBasePath2(cfg.apiBasePath ?? "/v1");
|
|
96265
97076
|
const apiFiles = yield* ApiDaemonFiles;
|
|
96266
97077
|
const daemonFiles = yield* DaemonFiles;
|
|
96267
97078
|
const ws = yield* WsClient;
|
|
@@ -96269,6 +97080,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96269
97080
|
const payload = yield* Payload;
|
|
96270
97081
|
const refs = yield* RefResolver;
|
|
96271
97082
|
const hostApi = yield* HostApiClient;
|
|
97083
|
+
const workspaceBindings = yield* WorkspaceBindings;
|
|
96272
97084
|
const remDb = yield* RemDb;
|
|
96273
97085
|
const processSvc = yield* Process;
|
|
96274
97086
|
const supervisorState = yield* SupervisorState;
|
|
@@ -96277,10 +97089,20 @@ function runHttpApiRuntime(params3) {
|
|
|
96277
97089
|
const configuredPort = params3?.port ?? cfg.apiPort ?? 3000;
|
|
96278
97090
|
const stateFilePath = params3?.stateFile ?? cfg.apiStateFile ?? apiFiles.defaultStateFile();
|
|
96279
97091
|
const startedAt = Date.now();
|
|
96280
|
-
const provide6 = (effect4) => effect4.pipe(provideService2(AppConfig, runtimeCfg), provideService2(ApiDaemonFiles, apiFiles), provideService2(DaemonFiles, daemonFiles), provideService2(WsClient, ws), provideService2(Queue, queue), provideService2(Payload, payload), provideService2(RefResolver, refs), provideService2(HostApiClient, hostApi), provideService2(RemDb, remDb), provideService2(Process, processSvc), provideService2(SupervisorState, supervisorState), provideService2(StatusLineController, statusLine));
|
|
97092
|
+
const provide6 = (effect4) => effect4.pipe(provideService2(AppConfig, runtimeCfg), provideService2(ApiDaemonFiles, apiFiles), provideService2(DaemonFiles, daemonFiles), provideService2(WsClient, ws), provideService2(Queue, queue), provideService2(Payload, payload), provideService2(RefResolver, refs), provideService2(HostApiClient, hostApi), provideService2(WorkspaceBindings, workspaceBindings), provideService2(RemDb, remDb), provideService2(Process, processSvc), provideService2(SupervisorState, supervisorState), provideService2(StatusLineController, statusLine));
|
|
97093
|
+
const routePathFor = (pathname) => {
|
|
97094
|
+
if (basePath2 === "/")
|
|
97095
|
+
return pathname || "/";
|
|
97096
|
+
if (pathname === basePath2)
|
|
97097
|
+
return "/";
|
|
97098
|
+
if (pathname.startsWith(`${basePath2}/`))
|
|
97099
|
+
return pathname.slice(basePath2.length) || "/";
|
|
97100
|
+
return null;
|
|
97101
|
+
};
|
|
96281
97102
|
const server = createServer((req, res) => {
|
|
96282
97103
|
const url2 = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
|
|
96283
97104
|
const method = req.method || "GET";
|
|
97105
|
+
const routePath = routePathFor(url2.pathname);
|
|
96284
97106
|
const run12 = async (effect4, statusCode = 200) => {
|
|
96285
97107
|
const exit3 = await runPromiseExit(provide6(effect4));
|
|
96286
97108
|
if (isSuccess(exit3)) {
|
|
@@ -96295,60 +97117,60 @@ function runHttpApiRuntime(params3) {
|
|
|
96295
97117
|
});
|
|
96296
97118
|
sendJson2(res, statusCodeFromCliError(cliError), fail21(toJsonError(cliError), cliError.hint));
|
|
96297
97119
|
};
|
|
96298
|
-
if (method === "GET" &&
|
|
97120
|
+
if (method === "GET" && routePath === "/health") {
|
|
96299
97121
|
run12(gen2(function* () {
|
|
96300
97122
|
return yield* collectApiHealthUseCase({
|
|
96301
97123
|
pid: process.pid,
|
|
96302
97124
|
host: host3,
|
|
96303
97125
|
port: currentPort(),
|
|
96304
|
-
basePath:
|
|
97126
|
+
basePath: basePath2,
|
|
96305
97127
|
startedAt
|
|
96306
97128
|
});
|
|
96307
97129
|
}));
|
|
96308
97130
|
return;
|
|
96309
97131
|
}
|
|
96310
|
-
if (method === "GET" &&
|
|
97132
|
+
if (method === "GET" && routePath === "/status") {
|
|
96311
97133
|
run12(gen2(function* () {
|
|
96312
97134
|
return yield* collectApiStatusUseCase({
|
|
96313
97135
|
pid: process.pid,
|
|
96314
97136
|
host: host3,
|
|
96315
97137
|
port: currentPort(),
|
|
96316
|
-
basePath:
|
|
97138
|
+
basePath: basePath2,
|
|
96317
97139
|
startedAt
|
|
96318
97140
|
});
|
|
96319
97141
|
}));
|
|
96320
97142
|
return;
|
|
96321
97143
|
}
|
|
96322
|
-
if (method === "GET" &&
|
|
97144
|
+
if (method === "GET" && routePath === "/ui-context") {
|
|
96323
97145
|
sendJson2(res, 200, ok(loadBridgeUiContextSnapshot({})));
|
|
96324
97146
|
return;
|
|
96325
97147
|
}
|
|
96326
|
-
if (method === "GET" &&
|
|
97148
|
+
if (method === "GET" && routePath === "/selection") {
|
|
96327
97149
|
sendJson2(res, 200, ok(loadBridgeSelectionSnapshot({})));
|
|
96328
97150
|
return;
|
|
96329
97151
|
}
|
|
96330
|
-
if (method === "GET" &&
|
|
97152
|
+
if (method === "GET" && routePath === "/plugin/ui-context/snapshot") {
|
|
96331
97153
|
run12(collectUiContextSnapshotUseCase({
|
|
96332
97154
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96333
97155
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined
|
|
96334
97156
|
}));
|
|
96335
97157
|
return;
|
|
96336
97158
|
}
|
|
96337
|
-
if (method === "GET" &&
|
|
97159
|
+
if (method === "GET" && routePath === "/plugin/ui-context/page") {
|
|
96338
97160
|
run12(collectUiContextPageUseCase({
|
|
96339
97161
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96340
97162
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined
|
|
96341
97163
|
}));
|
|
96342
97164
|
return;
|
|
96343
97165
|
}
|
|
96344
|
-
if (method === "GET" &&
|
|
97166
|
+
if (method === "GET" && routePath === "/plugin/ui-context/focused-rem") {
|
|
96345
97167
|
run12(collectUiContextFocusedRemUseCase({
|
|
96346
97168
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96347
97169
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined
|
|
96348
97170
|
}));
|
|
96349
97171
|
return;
|
|
96350
97172
|
}
|
|
96351
|
-
if (method === "GET" &&
|
|
97173
|
+
if (method === "GET" && routePath === "/plugin/ui-context/describe") {
|
|
96352
97174
|
run12(collectUiContextDescribeUseCase({
|
|
96353
97175
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96354
97176
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined,
|
|
@@ -96356,28 +97178,28 @@ function runHttpApiRuntime(params3) {
|
|
|
96356
97178
|
}));
|
|
96357
97179
|
return;
|
|
96358
97180
|
}
|
|
96359
|
-
if (method === "GET" &&
|
|
97181
|
+
if (method === "GET" && routePath === "/plugin/selection/snapshot") {
|
|
96360
97182
|
run12(collectSelectionSnapshotUseCase({
|
|
96361
97183
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96362
97184
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined
|
|
96363
97185
|
}));
|
|
96364
97186
|
return;
|
|
96365
97187
|
}
|
|
96366
|
-
if (method === "GET" &&
|
|
97188
|
+
if (method === "GET" && routePath === "/plugin/selection/roots") {
|
|
96367
97189
|
run12(collectSelectionRootsUseCase({
|
|
96368
97190
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96369
97191
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined
|
|
96370
97192
|
}));
|
|
96371
97193
|
return;
|
|
96372
97194
|
}
|
|
96373
|
-
if (method === "GET" &&
|
|
97195
|
+
if (method === "GET" && routePath === "/plugin/selection/current") {
|
|
96374
97196
|
run12(collectSelectionCurrentUseCase({
|
|
96375
97197
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96376
97198
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined
|
|
96377
97199
|
}));
|
|
96378
97200
|
return;
|
|
96379
97201
|
}
|
|
96380
|
-
if (method === "GET" &&
|
|
97202
|
+
if (method === "GET" && routePath === "/plugin/current") {
|
|
96381
97203
|
run12(collectPluginCurrentUseCase({
|
|
96382
97204
|
stateFile: url2.searchParams.get("stateFile") ?? undefined,
|
|
96383
97205
|
staleMs: url2.searchParams.get("staleMs") ? Number(url2.searchParams.get("staleMs")) : undefined,
|
|
@@ -96385,14 +97207,14 @@ function runHttpApiRuntime(params3) {
|
|
|
96385
97207
|
}));
|
|
96386
97208
|
return;
|
|
96387
97209
|
}
|
|
96388
|
-
if (method === "GET" &&
|
|
97210
|
+
if (method === "GET" && routePath === "/daily/rem-id") {
|
|
96389
97211
|
run12(executeDailyRemIdUseCase({
|
|
96390
97212
|
date: url2.searchParams.get("date") ?? undefined,
|
|
96391
97213
|
offsetDays: url2.searchParams.get("offsetDays") ? Number(url2.searchParams.get("offsetDays")) : undefined
|
|
96392
97214
|
}));
|
|
96393
97215
|
return;
|
|
96394
97216
|
}
|
|
96395
|
-
if (method === "POST" &&
|
|
97217
|
+
if (method === "POST" && routePath === "/plugin/selection/outline") {
|
|
96396
97218
|
(async () => {
|
|
96397
97219
|
try {
|
|
96398
97220
|
const body = await runPromise(readJsonBody(req));
|
|
@@ -96419,7 +97241,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96419
97241
|
})();
|
|
96420
97242
|
return;
|
|
96421
97243
|
}
|
|
96422
|
-
if (method === "POST" &&
|
|
97244
|
+
if (method === "POST" && routePath === "/search/db") {
|
|
96423
97245
|
(async () => {
|
|
96424
97246
|
try {
|
|
96425
97247
|
const body = await runPromise(readJsonBody(req));
|
|
@@ -96445,7 +97267,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96445
97267
|
})();
|
|
96446
97268
|
return;
|
|
96447
97269
|
}
|
|
96448
|
-
if (method === "POST" &&
|
|
97270
|
+
if (method === "POST" && routePath === "/read/outline") {
|
|
96449
97271
|
(async () => {
|
|
96450
97272
|
try {
|
|
96451
97273
|
const body = await runPromise(readJsonBody(req));
|
|
@@ -96474,7 +97296,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96474
97296
|
})();
|
|
96475
97297
|
return;
|
|
96476
97298
|
}
|
|
96477
|
-
if (method === "POST" &&
|
|
97299
|
+
if (method === "POST" && routePath === "/search/plugin") {
|
|
96478
97300
|
(async () => {
|
|
96479
97301
|
try {
|
|
96480
97302
|
const body = await runPromise(readJsonBody(req));
|
|
@@ -96497,7 +97319,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96497
97319
|
})();
|
|
96498
97320
|
return;
|
|
96499
97321
|
}
|
|
96500
|
-
if (method === "POST" &&
|
|
97322
|
+
if (method === "POST" && routePath === "/write/apply") {
|
|
96501
97323
|
(async () => {
|
|
96502
97324
|
try {
|
|
96503
97325
|
const body = await runPromise(readJsonBody(req));
|
|
@@ -96525,7 +97347,7 @@ function runHttpApiRuntime(params3) {
|
|
|
96525
97347
|
})();
|
|
96526
97348
|
return;
|
|
96527
97349
|
}
|
|
96528
|
-
if (method === "POST" &&
|
|
97350
|
+
if (method === "POST" && routePath === "/queue/wait") {
|
|
96529
97351
|
(async () => {
|
|
96530
97352
|
try {
|
|
96531
97353
|
const body = await runPromise(readJsonBody(req));
|
|
@@ -96542,12 +97364,12 @@ function runHttpApiRuntime(params3) {
|
|
|
96542
97364
|
})();
|
|
96543
97365
|
return;
|
|
96544
97366
|
}
|
|
96545
|
-
if (method === "GET" &&
|
|
96546
|
-
const txnId = decodeURIComponent(
|
|
97367
|
+
if (method === "GET" && typeof routePath === "string" && routePath.startsWith("/queue/txns/")) {
|
|
97368
|
+
const txnId = decodeURIComponent(routePath.slice("/queue/txns/".length));
|
|
96547
97369
|
run12(executeQueueTxnUseCase({ txnId }));
|
|
96548
97370
|
return;
|
|
96549
97371
|
}
|
|
96550
|
-
if (method === "POST" &&
|
|
97372
|
+
if (method === "POST" && routePath === "/actions/trigger-sync") {
|
|
96551
97373
|
run12(executeTriggerSyncUseCase());
|
|
96552
97374
|
return;
|
|
96553
97375
|
}
|
|
@@ -96590,10 +97412,10 @@ function runHttpApiRuntime(params3) {
|
|
|
96590
97412
|
pid: process.pid,
|
|
96591
97413
|
host: host3,
|
|
96592
97414
|
port: actualPort,
|
|
96593
|
-
basePath:
|
|
97415
|
+
basePath: basePath2,
|
|
96594
97416
|
startedAt,
|
|
96595
|
-
localBaseUrl: apiLocalBaseUrl(actualPort),
|
|
96596
|
-
containerBaseUrl: apiContainerBaseUrl(actualPort),
|
|
97417
|
+
localBaseUrl: apiLocalBaseUrl(actualPort, basePath2),
|
|
97418
|
+
containerBaseUrl: apiContainerBaseUrl(actualPort, basePath2),
|
|
96597
97419
|
daemon: { healthy: daemonHealth._tag === "Right", wsUrl: cfg.wsUrl }
|
|
96598
97420
|
});
|
|
96599
97421
|
const waitForStop = async((resume2) => {
|
|
@@ -96680,7 +97502,8 @@ var apiStatusCommand = exports_Command.make("status", { pidFile: pidFile12, stat
|
|
|
96680
97502
|
const pid = pidInfo?.pid;
|
|
96681
97503
|
const running4 = typeof pid === "number" ? yield* proc.isPidRunning(pid) : false;
|
|
96682
97504
|
const port7 = pidInfo?.port ?? state?.port ?? cfg.apiPort ?? 3000;
|
|
96683
|
-
const
|
|
97505
|
+
const basePath2 = pidInfo?.base_path ?? state?.basePath ?? cfg.apiBasePath ?? "/v1";
|
|
97506
|
+
const localBaseUrl = apiLocalBaseUrl(port7, basePath2);
|
|
96684
97507
|
const health = yield* api.health({ baseUrl: localBaseUrl, timeoutMs: API_HEALTH_TIMEOUT_MS }).pipe(either3);
|
|
96685
97508
|
const status2 = yield* api.status({ baseUrl: localBaseUrl, timeoutMs: API_HEALTH_TIMEOUT_MS }).pipe(either3);
|
|
96686
97509
|
const data = {
|
|
@@ -96696,6 +97519,7 @@ var apiStatusCommand = exports_Command.make("status", { pidFile: pidFile12, stat
|
|
|
96696
97519
|
api: {
|
|
96697
97520
|
healthy: health._tag === "Right",
|
|
96698
97521
|
base_url: localBaseUrl,
|
|
97522
|
+
base_path: basePath2,
|
|
96699
97523
|
status: status2._tag === "Right" ? status2.right : null,
|
|
96700
97524
|
error: health._tag === "Left" ? health.left.message : undefined
|
|
96701
97525
|
}
|
|
@@ -96708,7 +97532,16 @@ var apiStatusCommand = exports_Command.make("status", { pidFile: pidFile12, stat
|
|
|
96708
97532
|
`- state_file: ${data.service.state_file}`,
|
|
96709
97533
|
`- started_at: ${data.service.started_at ?? ""}`,
|
|
96710
97534
|
`- api_healthy: ${data.api.healthy}`,
|
|
96711
|
-
`- base_url: ${data.api.base_url}
|
|
97535
|
+
`- base_url: ${data.api.base_url}`,
|
|
97536
|
+
`- base_path: ${data.api.base_path}`,
|
|
97537
|
+
`- db_read_ready: ${data.api.status?.capabilities?.db_read_ready ?? ""}`,
|
|
97538
|
+
`- plugin_rpc_ready: ${data.api.status?.capabilities?.plugin_rpc_ready ?? ""}`,
|
|
97539
|
+
`- write_ready: ${data.api.status?.capabilities?.write_ready ?? ""}`,
|
|
97540
|
+
`- ui_session_ready: ${data.api.status?.capabilities?.ui_session_ready ?? ""}`,
|
|
97541
|
+
`- workspace_resolved: ${data.api.status?.workspace?.resolved ?? ""}`,
|
|
97542
|
+
`- current_workspace_id: ${data.api.status?.workspace?.currentWorkspaceId ?? ""}`,
|
|
97543
|
+
`- current_db_path: ${data.api.status?.workspace?.currentDbPath ?? ""}`,
|
|
97544
|
+
`- binding_source: ${data.api.status?.workspace?.bindingSource ?? ""}`
|
|
96712
97545
|
].join(`
|
|
96713
97546
|
`);
|
|
96714
97547
|
yield* writeSuccess({ data, md });
|
|
@@ -97101,7 +97934,7 @@ function optionToUndefined26(opt) {
|
|
|
97101
97934
|
var stateFile13 = text9("state-file").pipe(optional5, map34(optionToUndefined26));
|
|
97102
97935
|
var staleMs6 = integer7("stale-ms").pipe(optional5, map34(optionToUndefined26));
|
|
97103
97936
|
var selectionLimit = integer7("selection-limit").pipe(withDefault5(5));
|
|
97104
|
-
function
|
|
97937
|
+
function normalizeText4(value8) {
|
|
97105
97938
|
return typeof value8 === "string" ? value8.trim() : "";
|
|
97106
97939
|
}
|
|
97107
97940
|
function clampInt5(value8, min5, max7) {
|
|
@@ -97118,8 +97951,8 @@ function truncateText2(value8, maxLength) {
|
|
|
97118
97951
|
return `${normalized.slice(0, maxLength)}…`;
|
|
97119
97952
|
}
|
|
97120
97953
|
function pickTitle2(kt, ke, r) {
|
|
97121
|
-
const combined = [kt, ke].map(
|
|
97122
|
-
const raw4 = combined ||
|
|
97954
|
+
const combined = [kt, ke].map(normalizeText4).filter(Boolean).join(" | ");
|
|
97955
|
+
const raw4 = combined || normalizeText4(r);
|
|
97123
97956
|
if (!raw4)
|
|
97124
97957
|
return "";
|
|
97125
97958
|
const normalized = raw4.replace(/\s+/g, " ").trim();
|
|
@@ -97203,16 +98036,16 @@ var readUiContextDescribeCommand = exports_Command.make("describe", { stateFile:
|
|
|
97203
98036
|
const selectionSnapshot = loadBridgeSelectionSnapshot({ stateFile: stateFile14, staleMs: staleMs7 });
|
|
97204
98037
|
const ui = uiSnapshot.ui_context;
|
|
97205
98038
|
const selection = selectionSnapshot.selection;
|
|
97206
|
-
const pageRemId =
|
|
97207
|
-
const focusedPortalId =
|
|
97208
|
-
const focusedRemId =
|
|
98039
|
+
const pageRemId = normalizeText4(ui?.pageRemId);
|
|
98040
|
+
const focusedPortalId = normalizeText4(ui?.focusedPortalId);
|
|
98041
|
+
const focusedRemId = normalizeText4(ui?.focusedRemId);
|
|
97209
98042
|
const kind = computePortalKind2(pageRemId, focusedPortalId);
|
|
97210
98043
|
const selectionKind = selection?.kind ?? "none";
|
|
97211
98044
|
const selectionIds = uniqueNonEmpty2(selection?.kind === "rem" ? selection.remIds.map(String) : []);
|
|
97212
98045
|
const selectionTotalCountRaw = selection?.kind === "rem" ? Number(selection.totalCount ?? 0) : selection?.kind === "text" ? 1 : 0;
|
|
97213
98046
|
const selectionTotalCount = Number.isFinite(selectionTotalCountRaw) && selectionTotalCountRaw >= 0 ? Math.floor(selectionTotalCountRaw) : 0;
|
|
97214
98047
|
const selectionTruncated = selection?.kind === "rem" ? selection.truncated === true : false;
|
|
97215
|
-
const selectionTextRemId = selection?.kind === "text" ?
|
|
98048
|
+
const selectionTextRemId = selection?.kind === "text" ? normalizeText4(selection.remId) : "";
|
|
97216
98049
|
const selectionTextRange = selection?.kind === "text" ? {
|
|
97217
98050
|
start: Number.isFinite(selection.range?.start) ? Math.floor(selection.range.start) : NaN,
|
|
97218
98051
|
end: Number.isFinite(selection.range?.end) ? Math.floor(selection.range.end) : NaN,
|
|
@@ -97230,10 +98063,8 @@ var readUiContextDescribeCommand = exports_Command.make("describe", { stateFile:
|
|
|
97230
98063
|
...selectionShownIds
|
|
97231
98064
|
]);
|
|
97232
98065
|
const warnings = [];
|
|
97233
|
-
const
|
|
97234
|
-
|
|
97235
|
-
return kbId ? remnoteDbPathForWorkspaceId(kbId) : undefined;
|
|
97236
|
-
})();
|
|
98066
|
+
const workspace = yield* resolveWorkspaceSnapshot({ stateFile: stateFile14, staleMs: staleMs7 }).pipe(catchAll2(() => succeed8(undefined)));
|
|
98067
|
+
const dbPathCandidate = cfg.remnoteDb ?? (workspace?.resolved ? workspace.dbPath : undefined);
|
|
97237
98068
|
const titles = yield* gen2(function* () {
|
|
97238
98069
|
if (!dbPathCandidate || idsToResolve.length === 0)
|
|
97239
98070
|
return new Map;
|
|
@@ -98481,6 +99312,8 @@ var writePowerupOptionAddCommand = exports_Command.make("add", {
|
|
|
98481
99312
|
exitCode: 2
|
|
98482
99313
|
}));
|
|
98483
99314
|
}
|
|
99315
|
+
const cfg = yield* AppConfig;
|
|
99316
|
+
const hostApi = yield* HostApiClient;
|
|
98484
99317
|
const payloadSvc = yield* Payload;
|
|
98485
99318
|
const op = yield* try_3({
|
|
98486
99319
|
try: () => normalizeOp({ type: "add_option", payload: { propertyId: property, text: text15 } }, payloadSvc.normalizeKeys),
|
|
@@ -98492,6 +99325,53 @@ var writePowerupOptionAddCommand = exports_Command.make("add", {
|
|
|
98492
99325
|
})
|
|
98493
99326
|
});
|
|
98494
99327
|
const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
|
|
99328
|
+
if (cfg.apiBaseUrl) {
|
|
99329
|
+
if (dryRun) {
|
|
99330
|
+
yield* writeSuccess({
|
|
99331
|
+
data: { dry_run: true, ops: [op], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
99332
|
+
md: `- dry_run: true
|
|
99333
|
+
- op: add_option
|
|
99334
|
+
- property_id: ${property}
|
|
99335
|
+
`
|
|
99336
|
+
});
|
|
99337
|
+
return;
|
|
99338
|
+
}
|
|
99339
|
+
const data2 = yield* hostApi.writeApply({
|
|
99340
|
+
baseUrl: cfg.apiBaseUrl,
|
|
99341
|
+
body: {
|
|
99342
|
+
version: 1,
|
|
99343
|
+
kind: "ops",
|
|
99344
|
+
ops: [op],
|
|
99345
|
+
priority: priority3,
|
|
99346
|
+
clientId: clientId3,
|
|
99347
|
+
idempotencyKey: idempotencyKey3,
|
|
99348
|
+
meta: metaValue,
|
|
99349
|
+
notify: notify3,
|
|
99350
|
+
ensureDaemon: ensureDaemon5
|
|
99351
|
+
}
|
|
99352
|
+
});
|
|
99353
|
+
const waited2 = wait3 ? yield* hostApi.queueWait({
|
|
99354
|
+
baseUrl: cfg.apiBaseUrl,
|
|
99355
|
+
txnId: String(data2.txn_id),
|
|
99356
|
+
timeoutMs: timeoutMs4,
|
|
99357
|
+
pollMs: pollMs3
|
|
99358
|
+
}) : null;
|
|
99359
|
+
const out2 = waited2 ? { ...data2, ...waited2 } : data2;
|
|
99360
|
+
yield* writeSuccess({
|
|
99361
|
+
data: out2,
|
|
99362
|
+
ids: [data2.txn_id, ...data2.op_ids],
|
|
99363
|
+
md: [
|
|
99364
|
+
`- txn_id: ${data2.txn_id}`,
|
|
99365
|
+
`- op_ids: ${data2.op_ids.length}`,
|
|
99366
|
+
`- notified: ${data2.notified}`,
|
|
99367
|
+
`- sent: ${data2.sent ?? ""}`,
|
|
99368
|
+
...waited2 ? [`- status: ${waited2.status}`, `- elapsed_ms: ${waited2.elapsed_ms}`] : []
|
|
99369
|
+
].join(`
|
|
99370
|
+
`)
|
|
99371
|
+
});
|
|
99372
|
+
return;
|
|
99373
|
+
}
|
|
99374
|
+
yield* ensureOptionMutationSupportedForProperty({ scopeLabel: "powerup", propertyId: property });
|
|
98495
99375
|
if (dryRun) {
|
|
98496
99376
|
yield* writeSuccess({
|
|
98497
99377
|
data: { dry_run: true, ops: [op], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
@@ -98555,17 +99435,66 @@ var writePowerupOptionRemoveCommand = exports_Command.make("remove", {
|
|
|
98555
99435
|
exitCode: 2
|
|
98556
99436
|
}));
|
|
98557
99437
|
}
|
|
98558
|
-
const
|
|
98559
|
-
const
|
|
98560
|
-
|
|
98561
|
-
|
|
98562
|
-
|
|
98563
|
-
|
|
98564
|
-
|
|
98565
|
-
|
|
98566
|
-
|
|
98567
|
-
|
|
98568
|
-
|
|
99438
|
+
const cfg = yield* AppConfig;
|
|
99439
|
+
const hostApi = yield* HostApiClient;
|
|
99440
|
+
const payloadSvc = yield* Payload;
|
|
99441
|
+
const op = yield* try_3({
|
|
99442
|
+
try: () => normalizeOp({ type: "remove_option", payload: { optionId: option6 } }, payloadSvc.normalizeKeys),
|
|
99443
|
+
catch: (e) => isCliError(e) ? e : new CliError({
|
|
99444
|
+
code: "INVALID_PAYLOAD",
|
|
99445
|
+
message: "Failed to generate op",
|
|
99446
|
+
exitCode: 2,
|
|
99447
|
+
details: { error: String(e?.message || e) }
|
|
99448
|
+
})
|
|
99449
|
+
});
|
|
99450
|
+
const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
|
|
99451
|
+
if (cfg.apiBaseUrl) {
|
|
99452
|
+
if (dryRun) {
|
|
99453
|
+
yield* writeSuccess({
|
|
99454
|
+
data: { dry_run: true, ops: [op], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
99455
|
+
md: `- dry_run: true
|
|
99456
|
+
- op: remove_option
|
|
99457
|
+
- option_id: ${option6}
|
|
99458
|
+
`
|
|
99459
|
+
});
|
|
99460
|
+
return;
|
|
99461
|
+
}
|
|
99462
|
+
const data2 = yield* hostApi.writeApply({
|
|
99463
|
+
baseUrl: cfg.apiBaseUrl,
|
|
99464
|
+
body: {
|
|
99465
|
+
version: 1,
|
|
99466
|
+
kind: "ops",
|
|
99467
|
+
ops: [op],
|
|
99468
|
+
priority: priority3,
|
|
99469
|
+
clientId: clientId3,
|
|
99470
|
+
idempotencyKey: idempotencyKey3,
|
|
99471
|
+
meta: metaValue,
|
|
99472
|
+
notify: notify3,
|
|
99473
|
+
ensureDaemon: ensureDaemon5
|
|
99474
|
+
}
|
|
99475
|
+
});
|
|
99476
|
+
const waited2 = wait3 ? yield* hostApi.queueWait({
|
|
99477
|
+
baseUrl: cfg.apiBaseUrl,
|
|
99478
|
+
txnId: String(data2.txn_id),
|
|
99479
|
+
timeoutMs: timeoutMs4,
|
|
99480
|
+
pollMs: pollMs3
|
|
99481
|
+
}) : null;
|
|
99482
|
+
const out2 = waited2 ? { ...data2, ...waited2 } : data2;
|
|
99483
|
+
yield* writeSuccess({
|
|
99484
|
+
data: out2,
|
|
99485
|
+
ids: [data2.txn_id, ...data2.op_ids],
|
|
99486
|
+
md: [
|
|
99487
|
+
`- txn_id: ${data2.txn_id}`,
|
|
99488
|
+
`- op_ids: ${data2.op_ids.length}`,
|
|
99489
|
+
`- notified: ${data2.notified}`,
|
|
99490
|
+
`- sent: ${data2.sent ?? ""}`,
|
|
99491
|
+
...waited2 ? [`- status: ${waited2.status}`, `- elapsed_ms: ${waited2.elapsed_ms}`] : []
|
|
99492
|
+
].join(`
|
|
99493
|
+
`)
|
|
99494
|
+
});
|
|
99495
|
+
return;
|
|
99496
|
+
}
|
|
99497
|
+
yield* ensureOptionMutationSupportedForOption({ scopeLabel: "powerup", optionId: option6 });
|
|
98569
99498
|
if (dryRun) {
|
|
98570
99499
|
yield* writeSuccess({
|
|
98571
99500
|
data: { dry_run: true, ops: [op], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
@@ -98666,6 +99595,11 @@ var writePowerupPropertyAddCommand = exports_Command.make("add", {
|
|
|
98666
99595
|
exitCode: 2
|
|
98667
99596
|
}));
|
|
98668
99597
|
}
|
|
99598
|
+
yield* ensureTypedPropertyCreationSupported({
|
|
99599
|
+
scopeLabel: "powerup",
|
|
99600
|
+
type: type2,
|
|
99601
|
+
hasOptions: typeof options6 === "string" && options6.trim().length > 0
|
|
99602
|
+
});
|
|
98669
99603
|
const payloadSvc = yield* Payload;
|
|
98670
99604
|
const resolved = powerup2 ? yield* resolvePowerup(powerup2) : null;
|
|
98671
99605
|
const resolvedTagId = resolved ? resolved.id : normalizeRemIdInput(tagId);
|
|
@@ -98761,78 +99695,8 @@ var writePowerupPropertySetTypeCommand = exports_Command.make("set-type", {
|
|
|
98761
99695
|
clientId: writeCommonOptions.clientId,
|
|
98762
99696
|
idempotencyKey: writeCommonOptions.idempotencyKey,
|
|
98763
99697
|
meta: writeCommonOptions.meta
|
|
98764
|
-
}, ({
|
|
98765
|
-
|
|
98766
|
-
type: type2,
|
|
98767
|
-
notify: notify3,
|
|
98768
|
-
ensureDaemon: ensureDaemon5,
|
|
98769
|
-
wait: wait3,
|
|
98770
|
-
timeoutMs: timeoutMs4,
|
|
98771
|
-
pollMs: pollMs3,
|
|
98772
|
-
dryRun,
|
|
98773
|
-
priority: priority3,
|
|
98774
|
-
clientId: clientId3,
|
|
98775
|
-
idempotencyKey: idempotencyKey3,
|
|
98776
|
-
meta
|
|
98777
|
-
}) => gen2(function* () {
|
|
98778
|
-
if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
|
|
98779
|
-
return yield* fail8(new CliError({
|
|
98780
|
-
code: "INVALID_ARGS",
|
|
98781
|
-
message: "Use --wait to enable --timeout-ms/--poll-ms",
|
|
98782
|
-
exitCode: 2
|
|
98783
|
-
}));
|
|
98784
|
-
}
|
|
98785
|
-
if (dryRun && wait3) {
|
|
98786
|
-
return yield* fail8(new CliError({
|
|
98787
|
-
code: "INVALID_ARGS",
|
|
98788
|
-
message: "--wait is not compatible with --dry-run",
|
|
98789
|
-
exitCode: 2
|
|
98790
|
-
}));
|
|
98791
|
-
}
|
|
98792
|
-
const payloadSvc = yield* Payload;
|
|
98793
|
-
const op = yield* try_3({
|
|
98794
|
-
try: () => normalizeOp({ type: "set_property_type", payload: { propertyId: property, type: type2 } }, payloadSvc.normalizeKeys),
|
|
98795
|
-
catch: (e) => isCliError(e) ? e : new CliError({
|
|
98796
|
-
code: "INVALID_PAYLOAD",
|
|
98797
|
-
message: "Failed to generate op",
|
|
98798
|
-
exitCode: 2,
|
|
98799
|
-
details: { error: String(e?.message || e) }
|
|
98800
|
-
})
|
|
98801
|
-
});
|
|
98802
|
-
const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
|
|
98803
|
-
if (dryRun) {
|
|
98804
|
-
yield* writeSuccess({
|
|
98805
|
-
data: { dry_run: true, ops: [op], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
98806
|
-
md: `- dry_run: true
|
|
98807
|
-
- op: set_property_type
|
|
98808
|
-
- property_id: ${property}
|
|
98809
|
-
`
|
|
98810
|
-
});
|
|
98811
|
-
return;
|
|
98812
|
-
}
|
|
98813
|
-
const data = yield* enqueueOps({
|
|
98814
|
-
ops: [op],
|
|
98815
|
-
priority: priority3,
|
|
98816
|
-
clientId: clientId3,
|
|
98817
|
-
idempotencyKey: idempotencyKey3,
|
|
98818
|
-
meta: metaValue,
|
|
98819
|
-
notify: notify3,
|
|
98820
|
-
ensureDaemon: ensureDaemon5
|
|
98821
|
-
});
|
|
98822
|
-
const waited = wait3 ? yield* waitForTxn({ txnId: data.txn_id, timeoutMs: timeoutMs4, pollMs: pollMs3 }) : null;
|
|
98823
|
-
const out = waited ? { ...data, ...waited } : data;
|
|
98824
|
-
yield* writeSuccess({
|
|
98825
|
-
data: out,
|
|
98826
|
-
ids: [data.txn_id, ...data.op_ids],
|
|
98827
|
-
md: [
|
|
98828
|
-
`- txn_id: ${data.txn_id}`,
|
|
98829
|
-
`- op_ids: ${data.op_ids.length}`,
|
|
98830
|
-
`- notified: ${data.notified}`,
|
|
98831
|
-
`- sent: ${data.sent ?? ""}`,
|
|
98832
|
-
...waited ? [`- status: ${waited.status}`, `- elapsed_ms: ${waited.elapsed_ms}`] : []
|
|
98833
|
-
].join(`
|
|
98834
|
-
`)
|
|
98835
|
-
});
|
|
99698
|
+
}, () => gen2(function* () {
|
|
99699
|
+
return yield* failUnsupportedPropertyTypeMutation("powerup");
|
|
98836
99700
|
}).pipe(catchAll2(writeFailure)));
|
|
98837
99701
|
|
|
98838
99702
|
// src/commands/write/powerup/property/index.ts
|
|
@@ -100015,7 +100879,6 @@ var readOutlineCommand = exports_Command.make("outline", {
|
|
|
100015
100879
|
}) => gen2(function* () {
|
|
100016
100880
|
const cfg = yield* AppConfig;
|
|
100017
100881
|
const hostApi = yield* HostApiClient;
|
|
100018
|
-
const refs = yield* RefResolver;
|
|
100019
100882
|
if (id4 && ref2) {
|
|
100020
100883
|
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "Choose only one of --id or --ref", exitCode: 2 }));
|
|
100021
100884
|
}
|
|
@@ -100042,28 +100905,18 @@ var readOutlineCommand = exports_Command.make("outline", {
|
|
|
100042
100905
|
yield* writeSuccess({ data, md: data.markdown ?? "" });
|
|
100043
100906
|
return;
|
|
100044
100907
|
}
|
|
100045
|
-
const
|
|
100046
|
-
|
|
100047
|
-
|
|
100048
|
-
|
|
100049
|
-
|
|
100050
|
-
|
|
100051
|
-
|
|
100052
|
-
|
|
100053
|
-
|
|
100054
|
-
|
|
100055
|
-
|
|
100056
|
-
|
|
100057
|
-
startOffset: offset6,
|
|
100058
|
-
maxNodes: nodes2,
|
|
100059
|
-
format: format10 === "json" ? "json" : "markdown",
|
|
100060
|
-
excludeProperties,
|
|
100061
|
-
includeEmpty,
|
|
100062
|
-
expandReferences: expandReferences === false ? false : undefined,
|
|
100063
|
-
maxReferenceDepth: maxReferenceDepth2,
|
|
100064
|
-
detail
|
|
100065
|
-
}),
|
|
100066
|
-
catch: (e) => cliErrorFromUnknown(e, { code: "DB_UNAVAILABLE" })
|
|
100908
|
+
const result = yield* executeReadOutlineUseCase({
|
|
100909
|
+
id: id4,
|
|
100910
|
+
ref: ref2,
|
|
100911
|
+
depth: depth2,
|
|
100912
|
+
offset: offset6,
|
|
100913
|
+
nodes: nodes2,
|
|
100914
|
+
format: format10,
|
|
100915
|
+
excludeProperties,
|
|
100916
|
+
includeEmpty,
|
|
100917
|
+
expandReferences,
|
|
100918
|
+
maxReferenceDepth: maxReferenceDepth2,
|
|
100919
|
+
detail
|
|
100067
100920
|
});
|
|
100068
100921
|
yield* writeSuccess({ data: result, md: result.markdown ?? "" });
|
|
100069
100922
|
}).pipe(catchAll2(writeFailure)));
|
|
@@ -100095,13 +100948,12 @@ var readPageIdCommand = exports_Command.make("page-id", { ref: ref2, id: id4, ma
|
|
|
100095
100948
|
]
|
|
100096
100949
|
}));
|
|
100097
100950
|
}
|
|
100951
|
+
const dbPath = cfg.remnoteDb ?? (yield* requireResolvedWorkspace({ ref: hasRef ? ref3 : undefined })).dbPath;
|
|
100098
100952
|
const link3 = hasRef ? tryParseRemnoteLinkFromRef(ref3) : undefined;
|
|
100099
|
-
const ids3 = hasRef ? [link3?.remId ?? (yield* refs.resolve(ref3))] : id5.map(String);
|
|
100953
|
+
const ids3 = hasRef ? [link3?.remId ?? (yield* refs.resolve(ref3, { dbPath }))] : id5.map(String);
|
|
100100
100954
|
if (ids3.length === 0) {
|
|
100101
100955
|
return yield* fail8(new CliError({ code: "INVALID_ARGS", message: "Provide at least one Rem ID via --id", exitCode: 2 }));
|
|
100102
100956
|
}
|
|
100103
|
-
const inferredDbPath = link3?.workspaceId ? tryResolveRemnoteDbPathForWorkspaceIdSync(link3.workspaceId) : undefined;
|
|
100104
|
-
const dbPath = cfg.remnoteDb ?? inferredDbPath;
|
|
100105
100957
|
const result = yield* tryPromise2({
|
|
100106
100958
|
try: async () => await executeResolveRemPage({
|
|
100107
100959
|
ids: ids3,
|
|
@@ -101813,34 +102665,15 @@ var readSearchCommand = exports_Command.make("search", {
|
|
|
101813
102665
|
limit: limit8,
|
|
101814
102666
|
offset: offset7,
|
|
101815
102667
|
timeoutMs: effectiveTimeoutMs
|
|
101816
|
-
}) : yield*
|
|
101817
|
-
|
|
101818
|
-
|
|
101819
|
-
|
|
101820
|
-
|
|
101821
|
-
|
|
101822
|
-
|
|
101823
|
-
|
|
101824
|
-
|
|
101825
|
-
offset: offset7,
|
|
101826
|
-
timeoutMs: effectiveTimeoutMs
|
|
101827
|
-
}),
|
|
101828
|
-
catch: (e) => {
|
|
101829
|
-
if (e?.code === "TIMEOUT") {
|
|
101830
|
-
return new CliError({
|
|
101831
|
-
code: "TIMEOUT",
|
|
101832
|
-
message: `DB query timed out after ${effectiveTimeoutMs}ms`,
|
|
101833
|
-
exitCode: 1,
|
|
101834
|
-
details: { timeoutMs: effectiveTimeoutMs },
|
|
101835
|
-
hint: [
|
|
101836
|
-
"Narrow the search scope (e.g. add --time 30d, or --parent <remId>)",
|
|
101837
|
-
"Reduce the result count (e.g. --limit 10)",
|
|
101838
|
-
'Try plugin candidates: agent-remnote plugin search --query "<keywords>"'
|
|
101839
|
-
]
|
|
101840
|
-
});
|
|
101841
|
-
}
|
|
101842
|
-
return cliErrorFromUnknown(e, { code: "DB_UNAVAILABLE" });
|
|
101843
|
-
}
|
|
102668
|
+
}) : yield* executeDbSearchUseCase({
|
|
102669
|
+
query: query2,
|
|
102670
|
+
timeRange: timeRange3,
|
|
102671
|
+
parentId: parentId2,
|
|
102672
|
+
pagesOnly,
|
|
102673
|
+
excludePages,
|
|
102674
|
+
limit: limit8,
|
|
102675
|
+
offset: offset7,
|
|
102676
|
+
timeoutMs: effectiveTimeoutMs
|
|
101844
102677
|
});
|
|
101845
102678
|
yield* writeSuccess({ data: result, md: result.markdown ?? "" });
|
|
101846
102679
|
}).pipe(catchAll2(writeFailure)));
|
|
@@ -102047,6 +102880,8 @@ var writeTableOptionAddCommand = exports_Command.make("add", {
|
|
|
102047
102880
|
exitCode: 2
|
|
102048
102881
|
}));
|
|
102049
102882
|
}
|
|
102883
|
+
const cfg = yield* AppConfig;
|
|
102884
|
+
const hostApi = yield* HostApiClient;
|
|
102050
102885
|
const payloadSvc = yield* Payload;
|
|
102051
102886
|
const op2 = yield* try_3({
|
|
102052
102887
|
try: () => normalizeOp({ type: "add_option", payload: { propertyId: property, text: text16 } }, payloadSvc.normalizeKeys),
|
|
@@ -102058,6 +102893,53 @@ var writeTableOptionAddCommand = exports_Command.make("add", {
|
|
|
102058
102893
|
})
|
|
102059
102894
|
});
|
|
102060
102895
|
const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
|
|
102896
|
+
if (cfg.apiBaseUrl) {
|
|
102897
|
+
if (dryRun) {
|
|
102898
|
+
yield* writeSuccess({
|
|
102899
|
+
data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
102900
|
+
md: `- dry_run: true
|
|
102901
|
+
- op: add_option
|
|
102902
|
+
- property_id: ${property}
|
|
102903
|
+
`
|
|
102904
|
+
});
|
|
102905
|
+
return;
|
|
102906
|
+
}
|
|
102907
|
+
const data2 = yield* hostApi.writeApply({
|
|
102908
|
+
baseUrl: cfg.apiBaseUrl,
|
|
102909
|
+
body: {
|
|
102910
|
+
version: 1,
|
|
102911
|
+
kind: "ops",
|
|
102912
|
+
ops: [op2],
|
|
102913
|
+
priority: priority5,
|
|
102914
|
+
clientId: clientId5,
|
|
102915
|
+
idempotencyKey: idempotencyKey5,
|
|
102916
|
+
meta: metaValue,
|
|
102917
|
+
notify: notify5,
|
|
102918
|
+
ensureDaemon: ensureDaemon7
|
|
102919
|
+
}
|
|
102920
|
+
});
|
|
102921
|
+
const waited2 = wait5 ? yield* hostApi.queueWait({
|
|
102922
|
+
baseUrl: cfg.apiBaseUrl,
|
|
102923
|
+
txnId: String(data2.txn_id),
|
|
102924
|
+
timeoutMs: timeoutMs7,
|
|
102925
|
+
pollMs: pollMs5
|
|
102926
|
+
}) : null;
|
|
102927
|
+
const out2 = waited2 ? { ...data2, ...waited2 } : data2;
|
|
102928
|
+
yield* writeSuccess({
|
|
102929
|
+
data: out2,
|
|
102930
|
+
ids: [data2.txn_id, ...data2.op_ids],
|
|
102931
|
+
md: [
|
|
102932
|
+
`- txn_id: ${data2.txn_id}`,
|
|
102933
|
+
`- op_ids: ${data2.op_ids.length}`,
|
|
102934
|
+
`- notified: ${data2.notified}`,
|
|
102935
|
+
`- sent: ${data2.sent ?? ""}`,
|
|
102936
|
+
...waited2 ? [`- status: ${waited2.status}`, `- elapsed_ms: ${waited2.elapsed_ms}`] : []
|
|
102937
|
+
].join(`
|
|
102938
|
+
`)
|
|
102939
|
+
});
|
|
102940
|
+
return;
|
|
102941
|
+
}
|
|
102942
|
+
yield* ensureOptionMutationSupportedForProperty({ scopeLabel: "table", propertyId: property });
|
|
102061
102943
|
if (dryRun) {
|
|
102062
102944
|
yield* writeSuccess({
|
|
102063
102945
|
data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
@@ -102121,6 +103003,8 @@ var writeTableOptionRemoveCommand = exports_Command.make("remove", {
|
|
|
102121
103003
|
exitCode: 2
|
|
102122
103004
|
}));
|
|
102123
103005
|
}
|
|
103006
|
+
const cfg = yield* AppConfig;
|
|
103007
|
+
const hostApi = yield* HostApiClient;
|
|
102124
103008
|
const payloadSvc = yield* Payload;
|
|
102125
103009
|
const op2 = yield* try_3({
|
|
102126
103010
|
try: () => normalizeOp({ type: "remove_option", payload: { optionId: option6 } }, payloadSvc.normalizeKeys),
|
|
@@ -102132,6 +103016,53 @@ var writeTableOptionRemoveCommand = exports_Command.make("remove", {
|
|
|
102132
103016
|
})
|
|
102133
103017
|
});
|
|
102134
103018
|
const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
|
|
103019
|
+
if (cfg.apiBaseUrl) {
|
|
103020
|
+
if (dryRun) {
|
|
103021
|
+
yield* writeSuccess({
|
|
103022
|
+
data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
103023
|
+
md: `- dry_run: true
|
|
103024
|
+
- op: remove_option
|
|
103025
|
+
- option_id: ${option6}
|
|
103026
|
+
`
|
|
103027
|
+
});
|
|
103028
|
+
return;
|
|
103029
|
+
}
|
|
103030
|
+
const data2 = yield* hostApi.writeApply({
|
|
103031
|
+
baseUrl: cfg.apiBaseUrl,
|
|
103032
|
+
body: {
|
|
103033
|
+
version: 1,
|
|
103034
|
+
kind: "ops",
|
|
103035
|
+
ops: [op2],
|
|
103036
|
+
priority: priority5,
|
|
103037
|
+
clientId: clientId5,
|
|
103038
|
+
idempotencyKey: idempotencyKey5,
|
|
103039
|
+
meta: metaValue,
|
|
103040
|
+
notify: notify5,
|
|
103041
|
+
ensureDaemon: ensureDaemon7
|
|
103042
|
+
}
|
|
103043
|
+
});
|
|
103044
|
+
const waited2 = wait5 ? yield* hostApi.queueWait({
|
|
103045
|
+
baseUrl: cfg.apiBaseUrl,
|
|
103046
|
+
txnId: String(data2.txn_id),
|
|
103047
|
+
timeoutMs: timeoutMs7,
|
|
103048
|
+
pollMs: pollMs5
|
|
103049
|
+
}) : null;
|
|
103050
|
+
const out2 = waited2 ? { ...data2, ...waited2 } : data2;
|
|
103051
|
+
yield* writeSuccess({
|
|
103052
|
+
data: out2,
|
|
103053
|
+
ids: [data2.txn_id, ...data2.op_ids],
|
|
103054
|
+
md: [
|
|
103055
|
+
`- txn_id: ${data2.txn_id}`,
|
|
103056
|
+
`- op_ids: ${data2.op_ids.length}`,
|
|
103057
|
+
`- notified: ${data2.notified}`,
|
|
103058
|
+
`- sent: ${data2.sent ?? ""}`,
|
|
103059
|
+
...waited2 ? [`- status: ${waited2.status}`, `- elapsed_ms: ${waited2.elapsed_ms}`] : []
|
|
103060
|
+
].join(`
|
|
103061
|
+
`)
|
|
103062
|
+
});
|
|
103063
|
+
return;
|
|
103064
|
+
}
|
|
103065
|
+
yield* ensureOptionMutationSupportedForOption({ scopeLabel: "table", optionId: option6 });
|
|
102135
103066
|
if (dryRun) {
|
|
102136
103067
|
yield* writeSuccess({
|
|
102137
103068
|
data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
@@ -102216,6 +103147,11 @@ var writeTablePropertyAddCommand = exports_Command.make("add", {
|
|
|
102216
103147
|
exitCode: 2
|
|
102217
103148
|
}));
|
|
102218
103149
|
}
|
|
103150
|
+
yield* ensureTypedPropertyCreationSupported({
|
|
103151
|
+
scopeLabel: "table",
|
|
103152
|
+
type: type2,
|
|
103153
|
+
hasOptions: typeof options6 === "string" && options6.trim().length > 0
|
|
103154
|
+
});
|
|
102219
103155
|
const payloadSvc = yield* Payload;
|
|
102220
103156
|
const optionsRaw = options6 ? yield* payloadSvc.readJson(options6) : undefined;
|
|
102221
103157
|
const optionNames = optionsRaw !== undefined ? yield* try_3({
|
|
@@ -102296,78 +103232,8 @@ var writeTablePropertySetTypeCommand = exports_Command.make("set-type", {
|
|
|
102296
103232
|
clientId: writeCommonOptions.clientId,
|
|
102297
103233
|
idempotencyKey: writeCommonOptions.idempotencyKey,
|
|
102298
103234
|
meta: writeCommonOptions.meta
|
|
102299
|
-
}, ({
|
|
102300
|
-
|
|
102301
|
-
type: type2,
|
|
102302
|
-
notify: notify5,
|
|
102303
|
-
ensureDaemon: ensureDaemon7,
|
|
102304
|
-
wait: wait5,
|
|
102305
|
-
timeoutMs: timeoutMs7,
|
|
102306
|
-
pollMs: pollMs5,
|
|
102307
|
-
dryRun,
|
|
102308
|
-
priority: priority5,
|
|
102309
|
-
clientId: clientId5,
|
|
102310
|
-
idempotencyKey: idempotencyKey5,
|
|
102311
|
-
meta
|
|
102312
|
-
}) => gen2(function* () {
|
|
102313
|
-
if (!wait5 && (timeoutMs7 !== undefined || pollMs5 !== undefined)) {
|
|
102314
|
-
return yield* fail8(new CliError({
|
|
102315
|
-
code: "INVALID_ARGS",
|
|
102316
|
-
message: "Use --wait to enable --timeout-ms/--poll-ms",
|
|
102317
|
-
exitCode: 2
|
|
102318
|
-
}));
|
|
102319
|
-
}
|
|
102320
|
-
if (dryRun && wait5) {
|
|
102321
|
-
return yield* fail8(new CliError({
|
|
102322
|
-
code: "INVALID_ARGS",
|
|
102323
|
-
message: "--wait is not compatible with --dry-run",
|
|
102324
|
-
exitCode: 2
|
|
102325
|
-
}));
|
|
102326
|
-
}
|
|
102327
|
-
const payloadSvc = yield* Payload;
|
|
102328
|
-
const op2 = yield* try_3({
|
|
102329
|
-
try: () => normalizeOp({ type: "set_property_type", payload: { propertyId: property, type: type2 } }, payloadSvc.normalizeKeys),
|
|
102330
|
-
catch: (e) => isCliError(e) ? e : new CliError({
|
|
102331
|
-
code: "INVALID_PAYLOAD",
|
|
102332
|
-
message: "Failed to generate op",
|
|
102333
|
-
exitCode: 2,
|
|
102334
|
-
details: { error: String(e?.message || e) }
|
|
102335
|
-
})
|
|
102336
|
-
});
|
|
102337
|
-
const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
|
|
102338
|
-
if (dryRun) {
|
|
102339
|
-
yield* writeSuccess({
|
|
102340
|
-
data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
|
|
102341
|
-
md: `- dry_run: true
|
|
102342
|
-
- op: set_property_type
|
|
102343
|
-
- property_id: ${property}
|
|
102344
|
-
`
|
|
102345
|
-
});
|
|
102346
|
-
return;
|
|
102347
|
-
}
|
|
102348
|
-
const data = yield* enqueueOps({
|
|
102349
|
-
ops: [op2],
|
|
102350
|
-
priority: priority5,
|
|
102351
|
-
clientId: clientId5,
|
|
102352
|
-
idempotencyKey: idempotencyKey5,
|
|
102353
|
-
meta: metaValue,
|
|
102354
|
-
notify: notify5,
|
|
102355
|
-
ensureDaemon: ensureDaemon7
|
|
102356
|
-
});
|
|
102357
|
-
const waited = wait5 ? yield* waitForTxn({ txnId: data.txn_id, timeoutMs: timeoutMs7, pollMs: pollMs5 }) : null;
|
|
102358
|
-
const out = waited ? { ...data, ...waited } : data;
|
|
102359
|
-
yield* writeSuccess({
|
|
102360
|
-
data: out,
|
|
102361
|
-
ids: [data.txn_id, ...data.op_ids],
|
|
102362
|
-
md: [
|
|
102363
|
-
`- txn_id: ${data.txn_id}`,
|
|
102364
|
-
`- op_ids: ${data.op_ids.length}`,
|
|
102365
|
-
`- notified: ${data.notified}`,
|
|
102366
|
-
`- sent: ${data.sent ?? ""}`,
|
|
102367
|
-
...waited ? [`- status: ${waited.status}`, `- elapsed_ms: ${waited.elapsed_ms}`] : []
|
|
102368
|
-
].join(`
|
|
102369
|
-
`)
|
|
102370
|
-
});
|
|
103235
|
+
}, () => gen2(function* () {
|
|
103236
|
+
return yield* failUnsupportedPropertyTypeMutation("table");
|
|
102371
103237
|
}).pipe(catchAll2(writeFailure)));
|
|
102372
103238
|
|
|
102373
103239
|
// src/commands/write/table/property/index.ts
|
|
@@ -103822,7 +104688,7 @@ var stackEnsureCommand = exports_Command.make("ensure", {
|
|
|
103822
104688
|
}).pipe(catchAll2(writeFailure)));
|
|
103823
104689
|
|
|
103824
104690
|
// src/commands/stack/status.ts
|
|
103825
|
-
import
|
|
104691
|
+
import path26 from "node:path";
|
|
103826
104692
|
var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function* () {
|
|
103827
104693
|
const cfg = yield* AppConfig;
|
|
103828
104694
|
const daemonFiles = yield* DaemonFiles;
|
|
@@ -103839,10 +104705,11 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
|
|
|
103839
104705
|
const apiPidFile = resolveUserFilePath(apiFiles.defaultPidFile());
|
|
103840
104706
|
const apiPidInfo = yield* apiFiles.readPidFile(apiPidFile);
|
|
103841
104707
|
const apiRunning = apiPidInfo ? yield* proc.isPidRunning(apiPidInfo.pid) : false;
|
|
103842
|
-
const
|
|
104708
|
+
const apiBasePath = apiPidInfo?.base_path ?? cfg.apiBasePath ?? "/v1";
|
|
104709
|
+
const apiBaseUrl = apiLocalBaseUrl(apiPidInfo?.port ?? cfg.apiPort ?? 3000, apiBasePath);
|
|
103843
104710
|
const apiStatus = yield* api.status({ baseUrl: apiBaseUrl, timeoutMs: 2000 }).pipe(either3);
|
|
103844
104711
|
const queueStats2 = yield* queue.stats({ dbPath: cfg.storeDb }).pipe(either3);
|
|
103845
|
-
const stateFilePath = resolveUserFilePath(daemonPidInfo?.state_file ??
|
|
104712
|
+
const stateFilePath = resolveUserFilePath(daemonPidInfo?.state_file ?? path26.join(path26.dirname(daemonPidFile), "ws.state.json"));
|
|
103846
104713
|
const data = {
|
|
103847
104714
|
daemon: {
|
|
103848
104715
|
running: daemonRunning,
|
|
@@ -103857,6 +104724,7 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
|
|
|
103857
104724
|
pid: apiPidInfo?.pid ?? null,
|
|
103858
104725
|
pid_file: apiPidFile,
|
|
103859
104726
|
base_url: apiBaseUrl,
|
|
104727
|
+
base_path: apiBasePath,
|
|
103860
104728
|
healthy: apiStatus._tag === "Right",
|
|
103861
104729
|
status: apiStatus._tag === "Right" ? apiStatus.right : null
|
|
103862
104730
|
},
|
|
@@ -103871,6 +104739,13 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
|
|
|
103871
104739
|
`- api_pid: ${data.api.pid ?? ""}`,
|
|
103872
104740
|
`- api_healthy: ${data.api.healthy}`,
|
|
103873
104741
|
`- api_base_url: ${data.api.base_url}`,
|
|
104742
|
+
`- api_base_path: ${data.api.base_path}`,
|
|
104743
|
+
`- db_read_ready: ${data.api.status?.capabilities?.db_read_ready ?? ""}`,
|
|
104744
|
+
`- plugin_rpc_ready: ${data.api.status?.capabilities?.plugin_rpc_ready ?? ""}`,
|
|
104745
|
+
`- write_ready: ${data.api.status?.capabilities?.write_ready ?? ""}`,
|
|
104746
|
+
`- ui_session_ready: ${data.api.status?.capabilities?.ui_session_ready ?? ""}`,
|
|
104747
|
+
`- workspace_resolved: ${data.api.status?.workspace?.resolved ?? ""}`,
|
|
104748
|
+
`- current_workspace_id: ${data.api.status?.workspace?.currentWorkspaceId ?? ""}`,
|
|
103874
104749
|
`- active_worker_conn_id: ${data.active_worker_conn_id ?? ""}`,
|
|
103875
104750
|
`- queue_pending: ${data.queue?.pending ?? ""}`,
|
|
103876
104751
|
`- queue_in_flight: ${data.queue?.in_flight ?? ""}`
|
|
@@ -103880,7 +104755,7 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
|
|
|
103880
104755
|
}).pipe(catchAll2(writeFailure)));
|
|
103881
104756
|
|
|
103882
104757
|
// src/commands/stack/stop.ts
|
|
103883
|
-
import
|
|
104758
|
+
import path27 from "node:path";
|
|
103884
104759
|
var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* () {
|
|
103885
104760
|
const apiFiles = yield* ApiDaemonFiles;
|
|
103886
104761
|
const daemonFiles = yield* DaemonFiles;
|
|
@@ -103917,7 +104792,7 @@ var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* ()
|
|
|
103917
104792
|
}
|
|
103918
104793
|
}
|
|
103919
104794
|
yield* daemonFiles.deletePidFile(daemonPidFile).pipe(catchAll2(() => _void));
|
|
103920
|
-
yield* supervisorState.deleteStateFile(resolveUserFilePath(daemonPidInfo?.state_file ??
|
|
104795
|
+
yield* supervisorState.deleteStateFile(resolveUserFilePath(daemonPidInfo?.state_file ?? path27.join(path27.dirname(daemonPidFile), "ws.state.json"))).pipe(catchAll2(() => _void));
|
|
103921
104796
|
yield* writeSuccess({
|
|
103922
104797
|
data: { stopped: true, api_stopped: apiStopped, daemon_stopped: daemonStopped },
|
|
103923
104798
|
md: `- stopped: true
|
|
@@ -103947,7 +104822,7 @@ var configFile = text9("config-file").pipe(optional5, map34(optionToUndefined49)
|
|
|
103947
104822
|
var appConfigLive = effect(AppConfig, resolveConfig());
|
|
103948
104823
|
var statusLineUpdaterLive = StatusLineUpdaterLive.pipe(provide3([appConfigLive, QueueLive, StatusLineFileLive, TmuxLive, WsBridgeStateLive]));
|
|
103949
104824
|
var statusLineLive = StatusLineControllerLive.pipe(provide3(statusLineUpdaterLive), provide3(appConfigLive));
|
|
103950
|
-
var servicesLive = mergeAll5(appConfigLive, OutputLive, FileInputLive, FsAccessLive, LogWriterFactoryLive, PayloadLive, DaemonFilesLive, ApiDaemonFilesLive, ProcessLive, ChildProcessLive, WsClientLive, HostApiClientLive, UserConfigFileLive, QueueLive, RefResolverLive, RemDbLive, StatusLineFileLive, SubprocessLive, SupervisorStateLive, WsBridgeServerLive, WsBridgeStateFileLive, statusLineLive);
|
|
104825
|
+
var servicesLive = mergeAll5(appConfigLive, OutputLive, FileInputLive, FsAccessLive, LogWriterFactoryLive, PayloadLive, DaemonFilesLive, ApiDaemonFilesLive, ProcessLive, ChildProcessLive, WsClientLive, HostApiClientLive.pipe(provide3(appConfigLive)), UserConfigFileLive, WorkspaceBindingsLive, QueueLive, RefResolverLive, RemDbLive, StatusLineFileLive, SubprocessLive, SupervisorStateLive, WsBridgeServerLive, WsBridgeStateFileLive, statusLineLive);
|
|
103951
104826
|
var rootCommand = exports_Command.make("agent-remnote", {
|
|
103952
104827
|
json: boolean8("json"),
|
|
103953
104828
|
md: boolean8("md"),
|