@mp-lb/berth 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/berth.js +218 -194
- package/package.json +1 -1
package/dist/berth.js
CHANGED
|
@@ -5995,7 +5995,7 @@ var require_lib = __commonJS({
|
|
|
5995
5995
|
});
|
|
5996
5996
|
|
|
5997
5997
|
// package.json
|
|
5998
|
-
var version = "0.1.
|
|
5998
|
+
var version = "0.1.2";
|
|
5999
5999
|
|
|
6000
6000
|
// src/runAuthCommand.ts
|
|
6001
6001
|
import { spawn } from "node:child_process";
|
|
@@ -22749,9 +22749,6 @@ var runDeliveryCommand = async (args2) => {
|
|
|
22749
22749
|
throw new Error("Use berth delivery start, complete, record or schema.");
|
|
22750
22750
|
};
|
|
22751
22751
|
|
|
22752
|
-
// src/runInstanceCommand.ts
|
|
22753
|
-
import { hostname as hostname4 } from "node:os";
|
|
22754
|
-
|
|
22755
22752
|
// ../../packages/core/src/work/schemas/slugSchema.ts
|
|
22756
22753
|
var slugSchema = external_exports.string().trim().min(1).max(80).regex(
|
|
22757
22754
|
/^[a-z0-9]+(?:-[a-z0-9]+)*$/,
|
|
@@ -22968,8 +22965,7 @@ var prepareInstance = async (value) => {
|
|
|
22968
22965
|
|
|
22969
22966
|
// src/readTaskLaunchContext.ts
|
|
22970
22967
|
import { realpath as realpath4 } from "node:fs/promises";
|
|
22971
|
-
import {
|
|
22972
|
-
import { basename, dirname as dirname3, join as join5 } from "node:path";
|
|
22968
|
+
import { hostname as hostname3 } from "node:os";
|
|
22973
22969
|
|
|
22974
22970
|
// ../../packages/core/src/work/inspectPreparedInstance.ts
|
|
22975
22971
|
import { execFile as execFile3 } from "node:child_process";
|
|
@@ -23066,6 +23062,66 @@ var inspectPreparedInstance = async (value) => {
|
|
|
23066
23062
|
return { directory, repositories };
|
|
23067
23063
|
};
|
|
23068
23064
|
|
|
23065
|
+
// ../../packages/core/src/work/machineIdentity.ts
|
|
23066
|
+
import { randomUUID } from "node:crypto";
|
|
23067
|
+
import {
|
|
23068
|
+
existsSync as existsSync2,
|
|
23069
|
+
linkSync,
|
|
23070
|
+
mkdirSync,
|
|
23071
|
+
readFileSync,
|
|
23072
|
+
unlinkSync,
|
|
23073
|
+
writeFileSync
|
|
23074
|
+
} from "node:fs";
|
|
23075
|
+
import { homedir as homedir5 } from "node:os";
|
|
23076
|
+
import { join as join5 } from "node:path";
|
|
23077
|
+
var identitySchema = external_exports.object({ id: external_exports.uuid() });
|
|
23078
|
+
var machineIdentity = (home = homedir5(), legacyFile) => {
|
|
23079
|
+
const folder = join5(home, ".berth");
|
|
23080
|
+
const path2 = join5(folder, "identity.json");
|
|
23081
|
+
const read2 = () => identitySchema.parse(JSON.parse(readFileSync(path2, "utf8")));
|
|
23082
|
+
if (existsSync2(path2)) return read2();
|
|
23083
|
+
const appData = process.platform === "darwin" ? join5(home, "Library", "Application Support") : process.platform === "win32" ? process.env.APPDATA : join5(home, ".config");
|
|
23084
|
+
const current = appData && join5(appData, "Berth");
|
|
23085
|
+
const legacy = appData && join5(appData, "Factory");
|
|
23086
|
+
const desktopFolder = current && legacy && !existsSync2(current) && existsSync2(legacy) ? legacy : current;
|
|
23087
|
+
const oldFile = legacyFile ?? (desktopFolder ? join5(desktopFolder, "machine-id") : void 0);
|
|
23088
|
+
let id = randomUUID();
|
|
23089
|
+
if (oldFile && existsSync2(oldFile))
|
|
23090
|
+
id = external_exports.uuid().parse(readFileSync(oldFile, "utf8").trim());
|
|
23091
|
+
mkdirSync(folder, { recursive: true, mode: 448 });
|
|
23092
|
+
const temporary = join5(folder, `.identity-${randomUUID()}`);
|
|
23093
|
+
try {
|
|
23094
|
+
writeFileSync(temporary, `${JSON.stringify({ id }, null, 2)}
|
|
23095
|
+
`, {
|
|
23096
|
+
mode: 384,
|
|
23097
|
+
flag: "wx"
|
|
23098
|
+
});
|
|
23099
|
+
try {
|
|
23100
|
+
linkSync(temporary, path2);
|
|
23101
|
+
} catch (error51) {
|
|
23102
|
+
if (error51.code !== "EEXIST") throw error51;
|
|
23103
|
+
}
|
|
23104
|
+
} finally {
|
|
23105
|
+
if (existsSync2(temporary)) unlinkSync(temporary);
|
|
23106
|
+
}
|
|
23107
|
+
return read2();
|
|
23108
|
+
};
|
|
23109
|
+
|
|
23110
|
+
// src/resolveSessionMachine.ts
|
|
23111
|
+
var resolveSessionMachine = (config2) => {
|
|
23112
|
+
const { id } = machineIdentity();
|
|
23113
|
+
if (process.env.BERTH_MACHINE_ID && process.env.BERTH_MACHINE_ID !== id)
|
|
23114
|
+
throw new Error(
|
|
23115
|
+
`BERTH_MACHINE_ID does not match this machine's identity (${id}).`
|
|
23116
|
+
);
|
|
23117
|
+
const machine = config2.workMachines.find((item) => item.id === id);
|
|
23118
|
+
if (!machine)
|
|
23119
|
+
throw new Error(
|
|
23120
|
+
`This machine (${id}) is not configured. Configure it in Berth desktop work machine settings.`
|
|
23121
|
+
);
|
|
23122
|
+
return machine;
|
|
23123
|
+
};
|
|
23124
|
+
|
|
23069
23125
|
// src/readTaskLaunchContext.ts
|
|
23070
23126
|
var readTaskLaunchContext = async (value) => {
|
|
23071
23127
|
const taskUuid = external_exports.uuid().parse(value);
|
|
@@ -23080,29 +23136,8 @@ var readTaskLaunchContext = async (value) => {
|
|
|
23080
23136
|
throw new Error("Task project is unavailable.");
|
|
23081
23137
|
const config2 = await client.config.read.query();
|
|
23082
23138
|
const osHostname = hostname3();
|
|
23083
|
-
const configuredId = process.env.BERTH_MACHINE_ID;
|
|
23084
23139
|
const currentCwd = await realpath4(process.cwd()).catch(() => null);
|
|
23085
|
-
const
|
|
23086
|
-
if (!configuredId && currentCwd) {
|
|
23087
|
-
for (const item of config2.workMachines) {
|
|
23088
|
-
const folder = item.instancesFolder === "~" ? homedir5() : item.instancesFolder.startsWith("~/") ? join5(homedir5(), item.instancesFolder.slice(2)) : item.instancesFolder;
|
|
23089
|
-
const root = await realpath4(folder).catch(() => null);
|
|
23090
|
-
if (!root || dirname3(currentCwd) !== root) continue;
|
|
23091
|
-
const registered = await listInstances(item.instancesFolder);
|
|
23092
|
-
if (registered.some(
|
|
23093
|
-
(instance) => instance.taskId === taskUuid && instance.slug === basename(currentCwd)
|
|
23094
|
-
))
|
|
23095
|
-
cwdMatches.push(item);
|
|
23096
|
-
}
|
|
23097
|
-
}
|
|
23098
|
-
const matches = config2.workMachines.filter(
|
|
23099
|
-
(item) => configuredId ? item.id === configuredId : item.name === osHostname
|
|
23100
|
-
);
|
|
23101
|
-
const machine = configuredId ? matches.length === 1 ? matches[0] : void 0 : cwdMatches.length === 1 ? cwdMatches[0] : cwdMatches.length > 1 ? void 0 : matches.length === 1 ? matches[0] : config2.workMachines.length === 1 ? config2.workMachines[0] : void 0;
|
|
23102
|
-
if (!machine)
|
|
23103
|
-
throw new Error(
|
|
23104
|
-
"Work machine is ambiguous. Set BERTH_MACHINE_ID to a configured machine UUID."
|
|
23105
|
-
);
|
|
23140
|
+
const machine = resolveSessionMachine(config2);
|
|
23106
23141
|
const all = await listInstances(machine.instancesFolder);
|
|
23107
23142
|
const linked = all.filter((instance) => instance.taskId === taskUuid);
|
|
23108
23143
|
if (linked.some((instance) => instance.projectId !== task.projectId))
|
|
@@ -23205,14 +23240,7 @@ var runInstanceCommand = async (args2) => {
|
|
|
23205
23240
|
`Task ${taskSlug} has no immutable ID; migrate it before linking an instance.`
|
|
23206
23241
|
);
|
|
23207
23242
|
const config2 = await client.config.read.query();
|
|
23208
|
-
const
|
|
23209
|
-
(machine2) => machine2.id === process.env.BERTH_MACHINE_ID || !process.env.BERTH_MACHINE_ID && machine2.name === hostname4()
|
|
23210
|
-
);
|
|
23211
|
-
const machine = matches.length === 1 ? matches[0] : !process.env.BERTH_MACHINE_ID && config2.workMachines.length === 1 ? config2.workMachines[0] : void 0;
|
|
23212
|
-
if (!machine)
|
|
23213
|
-
throw new Error(
|
|
23214
|
-
"Configure a work machine for this hostname, or set BERTH_MACHINE_ID to select one."
|
|
23215
|
-
);
|
|
23243
|
+
const machine = resolveSessionMachine(config2);
|
|
23216
23244
|
return prepareInstance({
|
|
23217
23245
|
projectId: project.id,
|
|
23218
23246
|
slug,
|
|
@@ -23255,9 +23283,142 @@ var messageCreateSchema = external_exports.strictObject({
|
|
|
23255
23283
|
body: external_exports.string().trim().min(1).max(8e3)
|
|
23256
23284
|
});
|
|
23257
23285
|
|
|
23286
|
+
// ../../packages/core/src/work/schemas/workerSchema.ts
|
|
23287
|
+
var workerSchema = external_exports.strictObject({
|
|
23288
|
+
threadId: external_exports.string().trim().min(1).max(200).describe("Stable worker thread ID."),
|
|
23289
|
+
host: external_exports.string().trim().min(1).max(200).describe("Host identifier for the worker thread, such as local.")
|
|
23290
|
+
}).describe(
|
|
23291
|
+
"Structured worker destination; an identifier is not authentication or credential approval."
|
|
23292
|
+
);
|
|
23293
|
+
|
|
23294
|
+
// ../../packages/core/src/work/schemas/blockerHandoffReceiptSchema.ts
|
|
23295
|
+
var blockerHandoffReceiptSchema = external_exports.strictObject({
|
|
23296
|
+
updateCount: external_exports.number().int().positive().describe(
|
|
23297
|
+
"Blocker update-log length identifying the original unblocked cycle."
|
|
23298
|
+
),
|
|
23299
|
+
consumer: slugSchema.describe("Controller that reserved this cycle."),
|
|
23300
|
+
worker: workerSchema,
|
|
23301
|
+
reservedAt: external_exports.iso.datetime().describe("Time the reservation was saved."),
|
|
23302
|
+
delivery: external_exports.strictObject({
|
|
23303
|
+
receiptId: external_exports.string().trim().min(1).max(200).describe("External admitted turn or delivery receipt ID."),
|
|
23304
|
+
confirmedAt: external_exports.iso.datetime().describe("Time delivery was recorded."),
|
|
23305
|
+
sourceUpdateId: external_exports.uuid().optional().describe(
|
|
23306
|
+
"Existing informational update used to import a historical receipt."
|
|
23307
|
+
)
|
|
23308
|
+
}).nullable().describe(
|
|
23309
|
+
"Null means delivery is uncertain or pending; reconcile before sending. A populated delivery must not be resent."
|
|
23310
|
+
)
|
|
23311
|
+
}).describe(
|
|
23312
|
+
"Durable handoff receipt keyed by blocker update cycle; retained when reblocked."
|
|
23313
|
+
);
|
|
23314
|
+
|
|
23315
|
+
// ../../packages/core/src/work/schemas/blockerEventSchema.ts
|
|
23316
|
+
var blockerEventSchema = external_exports.strictObject({
|
|
23317
|
+
state: external_exports.enum(["blocked", "unblocked"]).describe(
|
|
23318
|
+
"blocked is recorded by controller; unblocked is recorded by user."
|
|
23319
|
+
),
|
|
23320
|
+
notes: external_exports.string().max(4e3).describe("Feedback or resolution notes for this change. Markdown.")
|
|
23321
|
+
}).describe(
|
|
23322
|
+
"An append-only update in the blocker\u2019s embedded log, oldest first."
|
|
23323
|
+
);
|
|
23324
|
+
|
|
23258
23325
|
// ../../packages/core/src/work/schemas/messageStatusSchema.ts
|
|
23259
23326
|
var messageStatusSchema = external_exports.enum(["active", "later", "unblocked", "archived"]).describe(
|
|
23260
|
-
"Message lifecycle: active, later, unblocked or archived.
|
|
23327
|
+
"Message lifecycle: active, later, unblocked or archived. Berth applies no type-specific transitions."
|
|
23328
|
+
);
|
|
23329
|
+
|
|
23330
|
+
// ../../packages/core/src/work/schemas/blockerStatusSchema.ts
|
|
23331
|
+
var blockerStatusSchema = messageStatusSchema.describe(
|
|
23332
|
+
"active: user queue; later: deferred, still blocking; unblocked: resolved by the user, awaiting controller acknowledgment (whether claimed or not); archived: acknowledged. Use queue commands to transition."
|
|
23333
|
+
);
|
|
23334
|
+
|
|
23335
|
+
// ../../packages/core/src/work/schemas/blockerBaseSchema.ts
|
|
23336
|
+
var blockerBaseSchema = external_exports.strictObject({
|
|
23337
|
+
id: external_exports.uuid().describe(
|
|
23338
|
+
"Immutable UUID generated by the server when this item is created."
|
|
23339
|
+
),
|
|
23340
|
+
taskSlug: taskSlugSchema.describe(
|
|
23341
|
+
"The existing task this blocker belongs to."
|
|
23342
|
+
),
|
|
23343
|
+
status: blockerStatusSchema,
|
|
23344
|
+
updates: external_exports.array(blockerEventSchema).min(1).describe(
|
|
23345
|
+
"Embedded state change log, oldest first. Appended only by state-transition commands."
|
|
23346
|
+
),
|
|
23347
|
+
handoffs: external_exports.array(blockerHandoffReceiptSchema).default([]).describe(
|
|
23348
|
+
"Durable diagnostics handoffs, one per unblocked update cycle."
|
|
23349
|
+
),
|
|
23350
|
+
createdAt: external_exports.iso.datetime().nullable().describe(
|
|
23351
|
+
"Creation time in UTC, or null for imported records whose time is unknown."
|
|
23352
|
+
),
|
|
23353
|
+
completedAt: external_exports.iso.datetime().nullable().describe(
|
|
23354
|
+
"Time the user marked unblocked; null before unblocking or for legacy completions."
|
|
23355
|
+
),
|
|
23356
|
+
acknowledgedAt: external_exports.iso.datetime().nullable().describe(
|
|
23357
|
+
"Time the consumer acknowledged the item, or null before acknowledgment."
|
|
23358
|
+
),
|
|
23359
|
+
dismissedAt: external_exports.iso.datetime().nullable().optional().describe(
|
|
23360
|
+
"Time the user hid this pending-review cycle from the web inbox; controller acknowledgment is independent."
|
|
23361
|
+
),
|
|
23362
|
+
consumer: slugSchema.nullable().describe(
|
|
23363
|
+
"Controller consumer owning this acknowledgment queue item. Set atomically by pull; null before pulling."
|
|
23364
|
+
),
|
|
23365
|
+
outcome: external_exports.string().max(4e3).describe(
|
|
23366
|
+
"User completion note or legacy resolution; may be empty. Markdown."
|
|
23367
|
+
),
|
|
23368
|
+
selectedOptionIndex: external_exports.number().int().min(-1).nullable().describe(
|
|
23369
|
+
"Zero-based chosen decision option, or -1 for None of the above. Null for actions or decisions without a recorded choice."
|
|
23370
|
+
)
|
|
23371
|
+
}).describe(
|
|
23372
|
+
"Server-managed identity, queue state and completion receipt for a blocker."
|
|
23373
|
+
);
|
|
23374
|
+
|
|
23375
|
+
// ../../packages/core/src/work/schemas/prioritySchema.ts
|
|
23376
|
+
var prioritySchema = external_exports.enum(["high", "medium", "low", "unset"]).describe("Priority: high, medium, low, or unset when not assigned.");
|
|
23377
|
+
|
|
23378
|
+
// ../../packages/core/src/work/schemas/decisionOptionSchema.ts
|
|
23379
|
+
var decisionOptionSchema = external_exports.strictObject({
|
|
23380
|
+
title: external_exports.string().trim().min(1).max(120).describe("Short name for this choice."),
|
|
23381
|
+
body: external_exports.string().trim().min(1).max(4e3).describe(
|
|
23382
|
+
"Explain this option, its consequences and tradeoffs. Markdown."
|
|
23383
|
+
),
|
|
23384
|
+
priority: prioritySchema.describe(
|
|
23385
|
+
"Preference for this option: high, medium, low or unset. High is the strongest recommendation."
|
|
23386
|
+
)
|
|
23387
|
+
}).describe("One selectable option in a decision.");
|
|
23388
|
+
|
|
23389
|
+
// ../../packages/core/src/work/schemas/decisionSchema.ts
|
|
23390
|
+
var decisionSchema = external_exports.strictObject({
|
|
23391
|
+
background: external_exports.string().trim().min(1).max(4e3).describe("Context the user needs to understand the decision. Markdown."),
|
|
23392
|
+
problem: external_exports.string().trim().min(1).max(4e3).describe("The problem or question that needs a decision. Markdown."),
|
|
23393
|
+
options: external_exports.array(decisionOptionSchema).max(12).describe(
|
|
23394
|
+
"Predefined choices presented to the user. The UI always adds None of the above; do not include it in this array. New decisions require at least one option; legacy decisions may have none. Completion records the chosen index or -1 for None of the above."
|
|
23395
|
+
)
|
|
23396
|
+
}).describe("Decision content: background, problem, and prioritized options.");
|
|
23397
|
+
|
|
23398
|
+
// ../../packages/core/src/work/schemas/actionSchema.ts
|
|
23399
|
+
var actionSchema = external_exports.strictObject({
|
|
23400
|
+
background: external_exports.string().trim().min(1).max(4e3).describe("Context explaining why this action is needed. Markdown."),
|
|
23401
|
+
instructions: external_exports.string().trim().min(1).max(6e3).describe(
|
|
23402
|
+
"Concrete instructions for the user to carry out before marking done. Markdown."
|
|
23403
|
+
)
|
|
23404
|
+
}).describe("Action content: background and instructions.");
|
|
23405
|
+
|
|
23406
|
+
// ../../packages/core/src/work/schemas/blockerSchema.ts
|
|
23407
|
+
var blockerSchema = external_exports.discriminatedUnion("type", [
|
|
23408
|
+
blockerBaseSchema.extend({
|
|
23409
|
+
...decisionSchema.shape,
|
|
23410
|
+
type: external_exports.literal("decision").describe(
|
|
23411
|
+
"A one-time decision. Once submitted its choice is final; create a new decision for a new question."
|
|
23412
|
+
)
|
|
23413
|
+
}),
|
|
23414
|
+
blockerBaseSchema.extend({
|
|
23415
|
+
...actionSchema.shape,
|
|
23416
|
+
type: external_exports.literal("action").describe(
|
|
23417
|
+
"An action requiring instructions to be carried out. It may be returned with feedback and actioned again."
|
|
23418
|
+
)
|
|
23419
|
+
})
|
|
23420
|
+
]).describe(
|
|
23421
|
+
"A typed blocker and its queue lifecycle. Completed content is immutable until archived so consumers receive stable results."
|
|
23261
23422
|
);
|
|
23262
23423
|
|
|
23263
23424
|
// ../../packages/core/src/work/schemas/messageSchema.ts
|
|
@@ -23274,7 +23435,8 @@ var messageSchema = external_exports.strictObject({
|
|
|
23274
23435
|
status: messageStatusSchema,
|
|
23275
23436
|
claimedAt: external_exports.iso.datetime().nullable(),
|
|
23276
23437
|
consumer: external_exports.string().nullable(),
|
|
23277
|
-
sourceId: external_exports.string()
|
|
23438
|
+
sourceId: external_exports.string(),
|
|
23439
|
+
blocker: blockerSchema.optional()
|
|
23278
23440
|
});
|
|
23279
23441
|
|
|
23280
23442
|
// ../../packages/core/src/work/schemas/messageUpdateSchema.ts
|
|
@@ -23389,6 +23551,12 @@ var globalConfigSchema = external_exports.strictObject({
|
|
|
23389
23551
|
"Shared workspace configuration. An empty workerLinkTemplate disables generated Worker links."
|
|
23390
23552
|
);
|
|
23391
23553
|
|
|
23554
|
+
// ../../packages/core/src/work/schemas/configUpdateSchema.ts
|
|
23555
|
+
var configUpdateSchema = globalConfigSchema.partial().extend({
|
|
23556
|
+
// A missing field in a patch must not apply the read schema's [] default.
|
|
23557
|
+
workMachines: external_exports.array(workMachineSchema).optional()
|
|
23558
|
+
});
|
|
23559
|
+
|
|
23392
23560
|
// src/importConfiguration.ts
|
|
23393
23561
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
23394
23562
|
|
|
@@ -23457,9 +23625,6 @@ var projectReleaseTargetSchema = external_exports.strictObject({
|
|
|
23457
23625
|
"One independently released part of a project: its icon, name, and URL."
|
|
23458
23626
|
);
|
|
23459
23627
|
|
|
23460
|
-
// ../../packages/core/src/work/schemas/prioritySchema.ts
|
|
23461
|
-
var prioritySchema = external_exports.enum(["high", "medium", "low", "unset"]).describe("Priority: high, medium, low, or unset when not assigned.");
|
|
23462
|
-
|
|
23463
23628
|
// ../../packages/core/src/work/schemas/projectRepoSchema.ts
|
|
23464
23629
|
var projectRepoSchema = external_exports.strictObject({
|
|
23465
23630
|
url: linkSchema.refine((url2) => url2.length > 0, "Enter a repo URL."),
|
|
@@ -23556,6 +23721,9 @@ var projectSchema = external_exports.object({
|
|
|
23556
23721
|
),
|
|
23557
23722
|
source: external_exports.string().trim().max(2e3).describe(
|
|
23558
23723
|
"Where tasks for this project are usually found, such as a workboard. This is project context, not the nullable source on each task."
|
|
23724
|
+
),
|
|
23725
|
+
notes: external_exports.string().max(2e4).default("").describe(
|
|
23726
|
+
"Free-form Markdown notes about the project. Missing notes read as an empty string."
|
|
23559
23727
|
)
|
|
23560
23728
|
}).describe("A project with its identity, work source and useful links.");
|
|
23561
23729
|
|
|
@@ -23609,14 +23777,14 @@ var runConfigCommand = async (args2) => {
|
|
|
23609
23777
|
const [action, input, ...extra] = args2;
|
|
23610
23778
|
if (!extra.length && action === "schema" && (!input || ["read", "update"].includes(input)))
|
|
23611
23779
|
return external_exports.toJSONSchema(
|
|
23612
|
-
input === "read" ? globalConfigSchema :
|
|
23780
|
+
input === "read" ? globalConfigSchema : configUpdateSchema,
|
|
23613
23781
|
{ io: "input" }
|
|
23614
23782
|
);
|
|
23615
23783
|
if (action === "read" && !input)
|
|
23616
23784
|
return createWorkClient().config.read.query();
|
|
23617
23785
|
if (action === "update" && input && !extra.length)
|
|
23618
23786
|
return createWorkClient().config.update.mutate(
|
|
23619
|
-
|
|
23787
|
+
configUpdateSchema.parse(JSON.parse(input))
|
|
23620
23788
|
);
|
|
23621
23789
|
if (action === "import" && input && !extra.length)
|
|
23622
23790
|
return importConfiguration(input);
|
|
@@ -23682,17 +23850,9 @@ var taskSignOffSchema = external_exports.strictObject({
|
|
|
23682
23850
|
"User sign-off for a task. Set only through the sign-off endpoint, never through task CRUD."
|
|
23683
23851
|
);
|
|
23684
23852
|
|
|
23685
|
-
// ../../packages/core/src/work/schemas/workerSchema.ts
|
|
23686
|
-
var workerSchema = external_exports.strictObject({
|
|
23687
|
-
threadId: external_exports.string().trim().min(1).max(200).describe("Stable worker thread ID."),
|
|
23688
|
-
host: external_exports.string().trim().min(1).max(200).describe("Host identifier for the worker thread, such as local.")
|
|
23689
|
-
}).describe(
|
|
23690
|
-
"Structured worker destination; an identifier is not authentication or credential approval."
|
|
23691
|
-
);
|
|
23692
|
-
|
|
23693
23853
|
// ../../packages/core/src/work/schemas/terminalWorkerSchema.ts
|
|
23694
23854
|
var terminalWorkerSchema = external_exports.strictObject({
|
|
23695
|
-
sessionId: external_exports.uuid().describe("
|
|
23855
|
+
sessionId: external_exports.uuid().describe("Berth terminal session UUID."),
|
|
23696
23856
|
machineId: external_exports.uuid().describe("Configured work machine UUID.")
|
|
23697
23857
|
});
|
|
23698
23858
|
|
|
@@ -23716,7 +23876,7 @@ var taskSchema = external_exports.strictObject({
|
|
|
23716
23876
|
),
|
|
23717
23877
|
signOffRequestHistory: external_exports.array(taskSignOffRequestSchema).optional(),
|
|
23718
23878
|
signOffRequest: taskSignOffRequestSchema.optional().describe(
|
|
23719
|
-
"Explicit controller request;
|
|
23879
|
+
"Explicit controller request; Berth does not decide release readiness."
|
|
23720
23880
|
),
|
|
23721
23881
|
signOffRequestedAt: external_exports.iso.datetime().optional().describe("Server-managed time this sign-off cycle entered the inbox."),
|
|
23722
23882
|
workerRun: external_exports.strictObject({
|
|
@@ -23795,7 +23955,7 @@ var promptVariableDefinitions = [
|
|
|
23795
23955
|
{
|
|
23796
23956
|
name: "definitionOfDone",
|
|
23797
23957
|
optional: false,
|
|
23798
|
-
description: "
|
|
23958
|
+
description: "Berth's default task completion guidance."
|
|
23799
23959
|
},
|
|
23800
23960
|
{
|
|
23801
23961
|
name: "documentLocations",
|
|
@@ -23910,8 +24070,8 @@ var import_handlebars = __toESM(require_lib(), 1);
|
|
|
23910
24070
|
// ../../packages/core/src/work/data/agentPromptDefaults.json
|
|
23911
24071
|
var agentPromptDefaults_default = {
|
|
23912
24072
|
workerLaunch: "Run fm read 'worker.md' --store 'mp-lb/roles' and follow its instructions for task {{taskId}}.",
|
|
23913
|
-
roleMessage: "You have a new
|
|
23914
|
-
reassignedRoleMessage: "
|
|
24073
|
+
roleMessage: "You have a new Berth message ({{messageId}}). Read it with berth message read {{messageId}}.",
|
|
24074
|
+
reassignedRoleMessage: "Berth message {{messageId}} is ready for you. Read it with berth message read {{messageId}}."
|
|
23915
24075
|
};
|
|
23916
24076
|
|
|
23917
24077
|
// ../../packages/core/src/work/data/defaultAgentPrompts.ts
|
|
@@ -24017,21 +24177,6 @@ var prepareTaskWorkerInstance = async (taskId, instanceSlug) => {
|
|
|
24017
24177
|
return workerTypeId;
|
|
24018
24178
|
};
|
|
24019
24179
|
|
|
24020
|
-
// src/resolveSessionMachine.ts
|
|
24021
|
-
import { hostname as hostname5 } from "node:os";
|
|
24022
|
-
var resolveSessionMachine = (config2) => {
|
|
24023
|
-
const configured = process.env.BERTH_MACHINE_ID;
|
|
24024
|
-
const matches = config2.workMachines.filter(
|
|
24025
|
-
(item) => configured ? item.id === configured : item.name === hostname5()
|
|
24026
|
-
);
|
|
24027
|
-
const machine = matches.length === 1 ? matches[0] : !configured && config2.workMachines.length === 1 ? config2.workMachines[0] : void 0;
|
|
24028
|
-
if (!machine)
|
|
24029
|
-
throw new Error(
|
|
24030
|
-
"Work machine is ambiguous. Set BERTH_MACHINE_ID to a configured machine UUID."
|
|
24031
|
-
);
|
|
24032
|
-
return machine;
|
|
24033
|
-
};
|
|
24034
|
-
|
|
24035
24180
|
// src/tmuxSession.ts
|
|
24036
24181
|
import { spawnSync } from "node:child_process";
|
|
24037
24182
|
var tmuxSessionExists = (name) => {
|
|
@@ -24439,128 +24584,6 @@ var signOffRequestSchema = external_exports.strictObject({
|
|
|
24439
24584
|
)
|
|
24440
24585
|
});
|
|
24441
24586
|
|
|
24442
|
-
// ../../packages/core/src/work/schemas/blockerHandoffReceiptSchema.ts
|
|
24443
|
-
var blockerHandoffReceiptSchema = external_exports.strictObject({
|
|
24444
|
-
updateCount: external_exports.number().int().positive().describe(
|
|
24445
|
-
"Blocker update-log length identifying the original unblocked cycle."
|
|
24446
|
-
),
|
|
24447
|
-
consumer: slugSchema.describe("Controller that reserved this cycle."),
|
|
24448
|
-
worker: workerSchema,
|
|
24449
|
-
reservedAt: external_exports.iso.datetime().describe("Time the reservation was saved."),
|
|
24450
|
-
delivery: external_exports.strictObject({
|
|
24451
|
-
receiptId: external_exports.string().trim().min(1).max(200).describe("External admitted turn or delivery receipt ID."),
|
|
24452
|
-
confirmedAt: external_exports.iso.datetime().describe("Time delivery was recorded."),
|
|
24453
|
-
sourceUpdateId: external_exports.uuid().optional().describe(
|
|
24454
|
-
"Existing informational update used to import a historical receipt."
|
|
24455
|
-
)
|
|
24456
|
-
}).nullable().describe(
|
|
24457
|
-
"Null means delivery is uncertain or pending; reconcile before sending. A populated delivery must not be resent."
|
|
24458
|
-
)
|
|
24459
|
-
}).describe(
|
|
24460
|
-
"Durable handoff receipt keyed by blocker update cycle; retained when reblocked."
|
|
24461
|
-
);
|
|
24462
|
-
|
|
24463
|
-
// ../../packages/core/src/work/schemas/blockerEventSchema.ts
|
|
24464
|
-
var blockerEventSchema = external_exports.strictObject({
|
|
24465
|
-
state: external_exports.enum(["blocked", "unblocked"]).describe(
|
|
24466
|
-
"blocked is recorded by controller; unblocked is recorded by user."
|
|
24467
|
-
),
|
|
24468
|
-
notes: external_exports.string().max(4e3).describe("Feedback or resolution notes for this change. Markdown.")
|
|
24469
|
-
}).describe(
|
|
24470
|
-
"An append-only update in the blocker\u2019s embedded log, oldest first."
|
|
24471
|
-
);
|
|
24472
|
-
|
|
24473
|
-
// ../../packages/core/src/work/schemas/blockerStatusSchema.ts
|
|
24474
|
-
var blockerStatusSchema = messageStatusSchema.describe(
|
|
24475
|
-
"active: user queue; later: deferred, still blocking; unblocked: resolved by the user, awaiting controller acknowledgment (whether claimed or not); archived: acknowledged. Use queue commands to transition."
|
|
24476
|
-
);
|
|
24477
|
-
|
|
24478
|
-
// ../../packages/core/src/work/schemas/blockerBaseSchema.ts
|
|
24479
|
-
var blockerBaseSchema = external_exports.strictObject({
|
|
24480
|
-
id: external_exports.uuid().describe(
|
|
24481
|
-
"Immutable UUID generated by the server when this item is created."
|
|
24482
|
-
),
|
|
24483
|
-
taskSlug: taskSlugSchema.describe(
|
|
24484
|
-
"The existing task this blocker belongs to."
|
|
24485
|
-
),
|
|
24486
|
-
status: blockerStatusSchema,
|
|
24487
|
-
updates: external_exports.array(blockerEventSchema).min(1).describe(
|
|
24488
|
-
"Embedded state change log, oldest first. Appended only by state-transition commands."
|
|
24489
|
-
),
|
|
24490
|
-
handoffs: external_exports.array(blockerHandoffReceiptSchema).default([]).describe(
|
|
24491
|
-
"Durable diagnostics handoffs, one per unblocked update cycle."
|
|
24492
|
-
),
|
|
24493
|
-
createdAt: external_exports.iso.datetime().nullable().describe(
|
|
24494
|
-
"Creation time in UTC, or null for imported records whose time is unknown."
|
|
24495
|
-
),
|
|
24496
|
-
completedAt: external_exports.iso.datetime().nullable().describe(
|
|
24497
|
-
"Time the user marked unblocked; null before unblocking or for legacy completions."
|
|
24498
|
-
),
|
|
24499
|
-
acknowledgedAt: external_exports.iso.datetime().nullable().describe(
|
|
24500
|
-
"Time the consumer acknowledged the item, or null before acknowledgment."
|
|
24501
|
-
),
|
|
24502
|
-
dismissedAt: external_exports.iso.datetime().nullable().optional().describe(
|
|
24503
|
-
"Time the user hid this pending-review cycle from the web inbox; controller acknowledgment is independent."
|
|
24504
|
-
),
|
|
24505
|
-
consumer: slugSchema.nullable().describe(
|
|
24506
|
-
"Controller consumer owning this acknowledgment queue item. Set atomically by pull; null before pulling."
|
|
24507
|
-
),
|
|
24508
|
-
outcome: external_exports.string().max(4e3).describe(
|
|
24509
|
-
"User completion note or legacy resolution; may be empty. Markdown."
|
|
24510
|
-
),
|
|
24511
|
-
selectedOptionIndex: external_exports.number().int().min(-1).nullable().describe(
|
|
24512
|
-
"Zero-based chosen decision option, or -1 for None of the above. Null for actions or decisions without a recorded choice."
|
|
24513
|
-
)
|
|
24514
|
-
}).describe(
|
|
24515
|
-
"Server-managed identity, queue state and completion receipt for a blocker."
|
|
24516
|
-
);
|
|
24517
|
-
|
|
24518
|
-
// ../../packages/core/src/work/schemas/decisionOptionSchema.ts
|
|
24519
|
-
var decisionOptionSchema = external_exports.strictObject({
|
|
24520
|
-
title: external_exports.string().trim().min(1).max(120).describe("Short name for this choice."),
|
|
24521
|
-
body: external_exports.string().trim().min(1).max(4e3).describe(
|
|
24522
|
-
"Explain this option, its consequences and tradeoffs. Markdown."
|
|
24523
|
-
),
|
|
24524
|
-
priority: prioritySchema.describe(
|
|
24525
|
-
"Preference for this option: high, medium, low or unset. High is the strongest recommendation."
|
|
24526
|
-
)
|
|
24527
|
-
}).describe("One selectable option in a decision.");
|
|
24528
|
-
|
|
24529
|
-
// ../../packages/core/src/work/schemas/decisionSchema.ts
|
|
24530
|
-
var decisionSchema = external_exports.strictObject({
|
|
24531
|
-
background: external_exports.string().trim().min(1).max(4e3).describe("Context the user needs to understand the decision. Markdown."),
|
|
24532
|
-
problem: external_exports.string().trim().min(1).max(4e3).describe("The problem or question that needs a decision. Markdown."),
|
|
24533
|
-
options: external_exports.array(decisionOptionSchema).max(12).describe(
|
|
24534
|
-
"Predefined choices presented to the user. The UI always adds None of the above; do not include it in this array. New decisions require at least one option; legacy decisions may have none. Completion records the chosen index or -1 for None of the above."
|
|
24535
|
-
)
|
|
24536
|
-
}).describe("Decision content: background, problem, and prioritized options.");
|
|
24537
|
-
|
|
24538
|
-
// ../../packages/core/src/work/schemas/actionSchema.ts
|
|
24539
|
-
var actionSchema = external_exports.strictObject({
|
|
24540
|
-
background: external_exports.string().trim().min(1).max(4e3).describe("Context explaining why this action is needed. Markdown."),
|
|
24541
|
-
instructions: external_exports.string().trim().min(1).max(6e3).describe(
|
|
24542
|
-
"Concrete instructions for the user to carry out before marking done. Markdown."
|
|
24543
|
-
)
|
|
24544
|
-
}).describe("Action content: background and instructions.");
|
|
24545
|
-
|
|
24546
|
-
// ../../packages/core/src/work/schemas/blockerSchema.ts
|
|
24547
|
-
var blockerSchema = external_exports.discriminatedUnion("type", [
|
|
24548
|
-
blockerBaseSchema.extend({
|
|
24549
|
-
...decisionSchema.shape,
|
|
24550
|
-
type: external_exports.literal("decision").describe(
|
|
24551
|
-
"A one-time decision. Once submitted its choice is final; create a new decision for a new question."
|
|
24552
|
-
)
|
|
24553
|
-
}),
|
|
24554
|
-
blockerBaseSchema.extend({
|
|
24555
|
-
...actionSchema.shape,
|
|
24556
|
-
type: external_exports.literal("action").describe(
|
|
24557
|
-
"An action requiring instructions to be carried out. It may be returned with feedback and actioned again."
|
|
24558
|
-
)
|
|
24559
|
-
})
|
|
24560
|
-
]).describe(
|
|
24561
|
-
"A typed blocker and its queue lifecycle. Completed content is immutable until archived so consumers receive stable results."
|
|
24562
|
-
);
|
|
24563
|
-
|
|
24564
24587
|
// ../../packages/core/src/work/schemas/blockerPollSchema.ts
|
|
24565
24588
|
var blockerPollSchema = external_exports.strictObject({
|
|
24566
24589
|
id: external_exports.uuid(),
|
|
@@ -24676,7 +24699,8 @@ var taskColumnMoveSchema = external_exports.strictObject({
|
|
|
24676
24699
|
// ../../packages/core/src/work/schemas/projectUpdateSchema.ts
|
|
24677
24700
|
var projectUpdateSchema = projectSchema.omit({ uuid: true, lastWorkedOnAt: true }).partial().extend({
|
|
24678
24701
|
tags: external_exports.array(external_exports.string().trim().min(1).max(100)).optional(),
|
|
24679
|
-
company: external_exports.string().trim().max(100).optional()
|
|
24702
|
+
company: external_exports.string().trim().max(100).optional(),
|
|
24703
|
+
notes: external_exports.string().max(2e4).optional()
|
|
24680
24704
|
}).required({ id: true }).describe(
|
|
24681
24705
|
"Edit an existing project by id. Only supplied fields change. Both user and controller can edit projects."
|
|
24682
24706
|
);
|