@paigy/harness 0.3.32 → 0.3.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +832 -441
- package/dist/main.js +664 -292
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -901,14 +901,14 @@ var require_regex = __commonJS({
|
|
|
901
901
|
var TEST_KANJI = new RegExp("^" + kanji + "$");
|
|
902
902
|
var TEST_NUMERIC = new RegExp("^" + numeric + "$");
|
|
903
903
|
var TEST_ALPHANUMERIC = new RegExp("^[A-Z0-9 $%*+\\-./:]+$");
|
|
904
|
-
exports.testKanji = function testKanji(
|
|
905
|
-
return TEST_KANJI.test(
|
|
904
|
+
exports.testKanji = function testKanji(str3) {
|
|
905
|
+
return TEST_KANJI.test(str3);
|
|
906
906
|
};
|
|
907
|
-
exports.testNumeric = function testNumeric(
|
|
908
|
-
return TEST_NUMERIC.test(
|
|
907
|
+
exports.testNumeric = function testNumeric(str3) {
|
|
908
|
+
return TEST_NUMERIC.test(str3);
|
|
909
909
|
};
|
|
910
|
-
exports.testAlphanumeric = function testAlphanumeric(
|
|
911
|
-
return TEST_ALPHANUMERIC.test(
|
|
910
|
+
exports.testAlphanumeric = function testAlphanumeric(str3) {
|
|
911
|
+
return TEST_ALPHANUMERIC.test(str3);
|
|
912
912
|
};
|
|
913
913
|
}
|
|
914
914
|
});
|
|
@@ -1358,11 +1358,11 @@ var require_dijkstra = __commonJS({
|
|
|
1358
1358
|
*/
|
|
1359
1359
|
PriorityQueue: {
|
|
1360
1360
|
make: function(opts) {
|
|
1361
|
-
var T = dijkstra.PriorityQueue, t = {},
|
|
1361
|
+
var T = dijkstra.PriorityQueue, t = {}, key3;
|
|
1362
1362
|
opts = opts || {};
|
|
1363
|
-
for (
|
|
1364
|
-
if (T.hasOwnProperty(
|
|
1365
|
-
t[
|
|
1363
|
+
for (key3 in T) {
|
|
1364
|
+
if (T.hasOwnProperty(key3)) {
|
|
1365
|
+
t[key3] = T[key3];
|
|
1366
1366
|
}
|
|
1367
1367
|
}
|
|
1368
1368
|
t.queue = [];
|
|
@@ -1410,13 +1410,13 @@ var require_segments = __commonJS({
|
|
|
1410
1410
|
var Regex = require_regex();
|
|
1411
1411
|
var Utils = require_utils();
|
|
1412
1412
|
var dijkstra = require_dijkstra();
|
|
1413
|
-
function getStringByteLength(
|
|
1414
|
-
return unescape(encodeURIComponent(
|
|
1413
|
+
function getStringByteLength(str3) {
|
|
1414
|
+
return unescape(encodeURIComponent(str3)).length;
|
|
1415
1415
|
}
|
|
1416
|
-
function getSegments(regex, mode,
|
|
1416
|
+
function getSegments(regex, mode, str3) {
|
|
1417
1417
|
const segments = [];
|
|
1418
1418
|
let result;
|
|
1419
|
-
while ((result = regex.exec(
|
|
1419
|
+
while ((result = regex.exec(str3)) !== null) {
|
|
1420
1420
|
segments.push({
|
|
1421
1421
|
data: result[0],
|
|
1422
1422
|
index: result.index,
|
|
@@ -1513,18 +1513,18 @@ var require_segments = __commonJS({
|
|
|
1513
1513
|
const currentNodeIds = [];
|
|
1514
1514
|
for (let j = 0; j < nodeGroup.length; j++) {
|
|
1515
1515
|
const node = nodeGroup[j];
|
|
1516
|
-
const
|
|
1517
|
-
currentNodeIds.push(
|
|
1518
|
-
table[
|
|
1519
|
-
graph[
|
|
1516
|
+
const key3 = "" + i + j;
|
|
1517
|
+
currentNodeIds.push(key3);
|
|
1518
|
+
table[key3] = { node, lastCount: 0 };
|
|
1519
|
+
graph[key3] = {};
|
|
1520
1520
|
for (let n = 0; n < prevNodeIds.length; n++) {
|
|
1521
1521
|
const prevNodeId = prevNodeIds[n];
|
|
1522
1522
|
if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {
|
|
1523
|
-
graph[prevNodeId][
|
|
1523
|
+
graph[prevNodeId][key3] = getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) - getSegmentBitsLength(table[prevNodeId].lastCount, node.mode);
|
|
1524
1524
|
table[prevNodeId].lastCount += node.length;
|
|
1525
1525
|
} else {
|
|
1526
1526
|
if (table[prevNodeId]) table[prevNodeId].lastCount = node.length;
|
|
1527
|
-
graph[prevNodeId][
|
|
1527
|
+
graph[prevNodeId][key3] = getSegmentBitsLength(node.length, node.mode) + 4 + Mode.getCharCountIndicator(node.mode, version);
|
|
1528
1528
|
}
|
|
1529
1529
|
}
|
|
1530
1530
|
}
|
|
@@ -4250,13 +4250,13 @@ var require_svg_tag = __commonJS({
|
|
|
4250
4250
|
var Utils = require_utils2();
|
|
4251
4251
|
function getColorAttrib(color, attrib) {
|
|
4252
4252
|
const alpha = color.a / 255;
|
|
4253
|
-
const
|
|
4254
|
-
return alpha < 1 ?
|
|
4253
|
+
const str3 = attrib + '="' + color.hex + '"';
|
|
4254
|
+
return alpha < 1 ? str3 + " " + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"' : str3;
|
|
4255
4255
|
}
|
|
4256
4256
|
function svgCmd(cmd, x, y) {
|
|
4257
|
-
let
|
|
4258
|
-
if (typeof y !== "undefined")
|
|
4259
|
-
return
|
|
4257
|
+
let str3 = cmd + x;
|
|
4258
|
+
if (typeof y !== "undefined") str3 += " " + y;
|
|
4259
|
+
return str3;
|
|
4260
4260
|
}
|
|
4261
4261
|
function qrToPath(data, size, margin) {
|
|
4262
4262
|
let path = "";
|
|
@@ -4738,9 +4738,9 @@ var util;
|
|
|
4738
4738
|
};
|
|
4739
4739
|
util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
|
|
4740
4740
|
const keys = [];
|
|
4741
|
-
for (const
|
|
4742
|
-
if (Object.prototype.hasOwnProperty.call(object,
|
|
4743
|
-
keys.push(
|
|
4741
|
+
for (const key3 in object) {
|
|
4742
|
+
if (Object.prototype.hasOwnProperty.call(object, key3)) {
|
|
4743
|
+
keys.push(key3);
|
|
4744
4744
|
}
|
|
4745
4745
|
}
|
|
4746
4746
|
return keys;
|
|
@@ -5140,10 +5140,10 @@ var ParseStatus = class _ParseStatus {
|
|
|
5140
5140
|
static async mergeObjectAsync(status, pairs) {
|
|
5141
5141
|
const syncPairs = [];
|
|
5142
5142
|
for (const pair of pairs) {
|
|
5143
|
-
const
|
|
5143
|
+
const key3 = await pair.key;
|
|
5144
5144
|
const value = await pair.value;
|
|
5145
5145
|
syncPairs.push({
|
|
5146
|
-
key,
|
|
5146
|
+
key: key3,
|
|
5147
5147
|
value
|
|
5148
5148
|
});
|
|
5149
5149
|
}
|
|
@@ -5152,17 +5152,17 @@ var ParseStatus = class _ParseStatus {
|
|
|
5152
5152
|
static mergeObjectSync(status, pairs) {
|
|
5153
5153
|
const finalObject = {};
|
|
5154
5154
|
for (const pair of pairs) {
|
|
5155
|
-
const { key, value } = pair;
|
|
5156
|
-
if (
|
|
5155
|
+
const { key: key3, value } = pair;
|
|
5156
|
+
if (key3.status === "aborted")
|
|
5157
5157
|
return INVALID;
|
|
5158
5158
|
if (value.status === "aborted")
|
|
5159
5159
|
return INVALID;
|
|
5160
|
-
if (
|
|
5160
|
+
if (key3.status === "dirty")
|
|
5161
5161
|
status.dirty();
|
|
5162
5162
|
if (value.status === "dirty")
|
|
5163
5163
|
status.dirty();
|
|
5164
|
-
if (
|
|
5165
|
-
finalObject[
|
|
5164
|
+
if (key3.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
|
|
5165
|
+
finalObject[key3.value] = value.value;
|
|
5166
5166
|
}
|
|
5167
5167
|
}
|
|
5168
5168
|
return { status: status.value, value: finalObject };
|
|
@@ -5187,12 +5187,12 @@ var errorUtil;
|
|
|
5187
5187
|
|
|
5188
5188
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
5189
5189
|
var ParseInputLazyPath = class {
|
|
5190
|
-
constructor(parent, value, path,
|
|
5190
|
+
constructor(parent, value, path, key3) {
|
|
5191
5191
|
this._cachedPath = [];
|
|
5192
5192
|
this.parent = parent;
|
|
5193
5193
|
this.data = value;
|
|
5194
5194
|
this._path = path;
|
|
5195
|
-
this._key =
|
|
5195
|
+
this._key = key3;
|
|
5196
5196
|
}
|
|
5197
5197
|
get path() {
|
|
5198
5198
|
if (!this._cachedPath.length) {
|
|
@@ -5471,8 +5471,8 @@ var ZodType = class {
|
|
|
5471
5471
|
promise() {
|
|
5472
5472
|
return ZodPromise.create(this, this._def);
|
|
5473
5473
|
}
|
|
5474
|
-
or(
|
|
5475
|
-
return ZodUnion.create([this,
|
|
5474
|
+
or(option3) {
|
|
5475
|
+
return ZodUnion.create([this, option3], this._def);
|
|
5476
5476
|
}
|
|
5477
5477
|
and(incoming) {
|
|
5478
5478
|
return ZodIntersection.create(this, incoming, this._def);
|
|
@@ -6937,9 +6937,9 @@ ZodArray.create = (schema, params) => {
|
|
|
6937
6937
|
function deepPartialify(schema) {
|
|
6938
6938
|
if (schema instanceof ZodObject) {
|
|
6939
6939
|
const newShape = {};
|
|
6940
|
-
for (const
|
|
6941
|
-
const fieldSchema = schema.shape[
|
|
6942
|
-
newShape[
|
|
6940
|
+
for (const key3 in schema.shape) {
|
|
6941
|
+
const fieldSchema = schema.shape[key3];
|
|
6942
|
+
newShape[key3] = ZodOptional.create(deepPartialify(fieldSchema));
|
|
6943
6943
|
}
|
|
6944
6944
|
return new ZodObject({
|
|
6945
6945
|
...schema._def,
|
|
@@ -6990,29 +6990,29 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
6990
6990
|
const { shape, keys: shapeKeys } = this._getCached();
|
|
6991
6991
|
const extraKeys = [];
|
|
6992
6992
|
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
|
6993
|
-
for (const
|
|
6994
|
-
if (!shapeKeys.includes(
|
|
6995
|
-
extraKeys.push(
|
|
6993
|
+
for (const key3 in ctx.data) {
|
|
6994
|
+
if (!shapeKeys.includes(key3)) {
|
|
6995
|
+
extraKeys.push(key3);
|
|
6996
6996
|
}
|
|
6997
6997
|
}
|
|
6998
6998
|
}
|
|
6999
6999
|
const pairs = [];
|
|
7000
|
-
for (const
|
|
7001
|
-
const keyValidator = shape[
|
|
7002
|
-
const value = ctx.data[
|
|
7000
|
+
for (const key3 of shapeKeys) {
|
|
7001
|
+
const keyValidator = shape[key3];
|
|
7002
|
+
const value = ctx.data[key3];
|
|
7003
7003
|
pairs.push({
|
|
7004
|
-
key: { status: "valid", value:
|
|
7005
|
-
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path,
|
|
7006
|
-
alwaysSet:
|
|
7004
|
+
key: { status: "valid", value: key3 },
|
|
7005
|
+
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key3)),
|
|
7006
|
+
alwaysSet: key3 in ctx.data
|
|
7007
7007
|
});
|
|
7008
7008
|
}
|
|
7009
7009
|
if (this._def.catchall instanceof ZodNever) {
|
|
7010
7010
|
const unknownKeys = this._def.unknownKeys;
|
|
7011
7011
|
if (unknownKeys === "passthrough") {
|
|
7012
|
-
for (const
|
|
7012
|
+
for (const key3 of extraKeys) {
|
|
7013
7013
|
pairs.push({
|
|
7014
|
-
key: { status: "valid", value:
|
|
7015
|
-
value: { status: "valid", value: ctx.data[
|
|
7014
|
+
key: { status: "valid", value: key3 },
|
|
7015
|
+
value: { status: "valid", value: ctx.data[key3] }
|
|
7016
7016
|
});
|
|
7017
7017
|
}
|
|
7018
7018
|
} else if (unknownKeys === "strict") {
|
|
@@ -7029,15 +7029,15 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7029
7029
|
}
|
|
7030
7030
|
} else {
|
|
7031
7031
|
const catchall = this._def.catchall;
|
|
7032
|
-
for (const
|
|
7033
|
-
const value = ctx.data[
|
|
7032
|
+
for (const key3 of extraKeys) {
|
|
7033
|
+
const value = ctx.data[key3];
|
|
7034
7034
|
pairs.push({
|
|
7035
|
-
key: { status: "valid", value:
|
|
7035
|
+
key: { status: "valid", value: key3 },
|
|
7036
7036
|
value: catchall._parse(
|
|
7037
|
-
new ParseInputLazyPath(ctx, value, ctx.path,
|
|
7037
|
+
new ParseInputLazyPath(ctx, value, ctx.path, key3)
|
|
7038
7038
|
//, ctx.child(key), value, getParsedType(value)
|
|
7039
7039
|
),
|
|
7040
|
-
alwaysSet:
|
|
7040
|
+
alwaysSet: key3 in ctx.data
|
|
7041
7041
|
});
|
|
7042
7042
|
}
|
|
7043
7043
|
}
|
|
@@ -7045,10 +7045,10 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7045
7045
|
return Promise.resolve().then(async () => {
|
|
7046
7046
|
const syncPairs = [];
|
|
7047
7047
|
for (const pair of pairs) {
|
|
7048
|
-
const
|
|
7048
|
+
const key3 = await pair.key;
|
|
7049
7049
|
const value = await pair.value;
|
|
7050
7050
|
syncPairs.push({
|
|
7051
|
-
key,
|
|
7051
|
+
key: key3,
|
|
7052
7052
|
value,
|
|
7053
7053
|
alwaysSet: pair.alwaysSet
|
|
7054
7054
|
});
|
|
@@ -7173,8 +7173,8 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7173
7173
|
// }) as any;
|
|
7174
7174
|
// return merged;
|
|
7175
7175
|
// }
|
|
7176
|
-
setKey(
|
|
7177
|
-
return this.augment({ [
|
|
7176
|
+
setKey(key3, schema) {
|
|
7177
|
+
return this.augment({ [key3]: schema });
|
|
7178
7178
|
}
|
|
7179
7179
|
// merge<Incoming extends AnyZodObject>(
|
|
7180
7180
|
// merging: Incoming
|
|
@@ -7205,9 +7205,9 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7205
7205
|
}
|
|
7206
7206
|
pick(mask) {
|
|
7207
7207
|
const shape = {};
|
|
7208
|
-
for (const
|
|
7209
|
-
if (mask[
|
|
7210
|
-
shape[
|
|
7208
|
+
for (const key3 of util.objectKeys(mask)) {
|
|
7209
|
+
if (mask[key3] && this.shape[key3]) {
|
|
7210
|
+
shape[key3] = this.shape[key3];
|
|
7211
7211
|
}
|
|
7212
7212
|
}
|
|
7213
7213
|
return new _ZodObject({
|
|
@@ -7217,9 +7217,9 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7217
7217
|
}
|
|
7218
7218
|
omit(mask) {
|
|
7219
7219
|
const shape = {};
|
|
7220
|
-
for (const
|
|
7221
|
-
if (!mask[
|
|
7222
|
-
shape[
|
|
7220
|
+
for (const key3 of util.objectKeys(this.shape)) {
|
|
7221
|
+
if (!mask[key3]) {
|
|
7222
|
+
shape[key3] = this.shape[key3];
|
|
7223
7223
|
}
|
|
7224
7224
|
}
|
|
7225
7225
|
return new _ZodObject({
|
|
@@ -7235,12 +7235,12 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7235
7235
|
}
|
|
7236
7236
|
partial(mask) {
|
|
7237
7237
|
const newShape = {};
|
|
7238
|
-
for (const
|
|
7239
|
-
const fieldSchema = this.shape[
|
|
7240
|
-
if (mask && !mask[
|
|
7241
|
-
newShape[
|
|
7238
|
+
for (const key3 of util.objectKeys(this.shape)) {
|
|
7239
|
+
const fieldSchema = this.shape[key3];
|
|
7240
|
+
if (mask && !mask[key3]) {
|
|
7241
|
+
newShape[key3] = fieldSchema;
|
|
7242
7242
|
} else {
|
|
7243
|
-
newShape[
|
|
7243
|
+
newShape[key3] = fieldSchema.optional();
|
|
7244
7244
|
}
|
|
7245
7245
|
}
|
|
7246
7246
|
return new _ZodObject({
|
|
@@ -7250,16 +7250,16 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
7250
7250
|
}
|
|
7251
7251
|
required(mask) {
|
|
7252
7252
|
const newShape = {};
|
|
7253
|
-
for (const
|
|
7254
|
-
if (mask && !mask[
|
|
7255
|
-
newShape[
|
|
7253
|
+
for (const key3 of util.objectKeys(this.shape)) {
|
|
7254
|
+
if (mask && !mask[key3]) {
|
|
7255
|
+
newShape[key3] = this.shape[key3];
|
|
7256
7256
|
} else {
|
|
7257
|
-
const fieldSchema = this.shape[
|
|
7257
|
+
const fieldSchema = this.shape[key3];
|
|
7258
7258
|
let newField = fieldSchema;
|
|
7259
7259
|
while (newField instanceof ZodOptional) {
|
|
7260
7260
|
newField = newField._def.innerType;
|
|
7261
7261
|
}
|
|
7262
|
-
newShape[
|
|
7262
|
+
newShape[key3] = newField;
|
|
7263
7263
|
}
|
|
7264
7264
|
}
|
|
7265
7265
|
return new _ZodObject({
|
|
@@ -7322,7 +7322,7 @@ var ZodUnion = class extends ZodType {
|
|
|
7322
7322
|
return INVALID;
|
|
7323
7323
|
}
|
|
7324
7324
|
if (ctx.common.async) {
|
|
7325
|
-
return Promise.all(options.map(async (
|
|
7325
|
+
return Promise.all(options.map(async (option3) => {
|
|
7326
7326
|
const childCtx = {
|
|
7327
7327
|
...ctx,
|
|
7328
7328
|
common: {
|
|
@@ -7332,7 +7332,7 @@ var ZodUnion = class extends ZodType {
|
|
|
7332
7332
|
parent: null
|
|
7333
7333
|
};
|
|
7334
7334
|
return {
|
|
7335
|
-
result: await
|
|
7335
|
+
result: await option3._parseAsync({
|
|
7336
7336
|
data: ctx.data,
|
|
7337
7337
|
path: ctx.path,
|
|
7338
7338
|
parent: childCtx
|
|
@@ -7343,7 +7343,7 @@ var ZodUnion = class extends ZodType {
|
|
|
7343
7343
|
} else {
|
|
7344
7344
|
let dirty = void 0;
|
|
7345
7345
|
const issues = [];
|
|
7346
|
-
for (const
|
|
7346
|
+
for (const option3 of options) {
|
|
7347
7347
|
const childCtx = {
|
|
7348
7348
|
...ctx,
|
|
7349
7349
|
common: {
|
|
@@ -7352,7 +7352,7 @@ var ZodUnion = class extends ZodType {
|
|
|
7352
7352
|
},
|
|
7353
7353
|
parent: null
|
|
7354
7354
|
};
|
|
7355
|
-
const result =
|
|
7355
|
+
const result = option3._parseSync({
|
|
7356
7356
|
data: ctx.data,
|
|
7357
7357
|
path: ctx.path,
|
|
7358
7358
|
parent: childCtx
|
|
@@ -7433,8 +7433,8 @@ var ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType {
|
|
|
7433
7433
|
}
|
|
7434
7434
|
const discriminator = this.discriminator;
|
|
7435
7435
|
const discriminatorValue = ctx.data[discriminator];
|
|
7436
|
-
const
|
|
7437
|
-
if (!
|
|
7436
|
+
const option3 = this.optionsMap.get(discriminatorValue);
|
|
7437
|
+
if (!option3) {
|
|
7438
7438
|
addIssueToContext(ctx, {
|
|
7439
7439
|
code: ZodIssueCode.invalid_union_discriminator,
|
|
7440
7440
|
options: Array.from(this.optionsMap.keys()),
|
|
@@ -7443,13 +7443,13 @@ var ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType {
|
|
|
7443
7443
|
return INVALID;
|
|
7444
7444
|
}
|
|
7445
7445
|
if (ctx.common.async) {
|
|
7446
|
-
return
|
|
7446
|
+
return option3._parseAsync({
|
|
7447
7447
|
data: ctx.data,
|
|
7448
7448
|
path: ctx.path,
|
|
7449
7449
|
parent: ctx
|
|
7450
7450
|
});
|
|
7451
7451
|
} else {
|
|
7452
|
-
return
|
|
7452
|
+
return option3._parseSync({
|
|
7453
7453
|
data: ctx.data,
|
|
7454
7454
|
path: ctx.path,
|
|
7455
7455
|
parent: ctx
|
|
@@ -7503,14 +7503,14 @@ function mergeValues(a, b) {
|
|
|
7503
7503
|
return { valid: true, data: a };
|
|
7504
7504
|
} else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
|
|
7505
7505
|
const bKeys = util.objectKeys(b);
|
|
7506
|
-
const sharedKeys = util.objectKeys(a).filter((
|
|
7506
|
+
const sharedKeys = util.objectKeys(a).filter((key3) => bKeys.indexOf(key3) !== -1);
|
|
7507
7507
|
const newObj = { ...a, ...b };
|
|
7508
|
-
for (const
|
|
7509
|
-
const sharedValue = mergeValues(a[
|
|
7508
|
+
for (const key3 of sharedKeys) {
|
|
7509
|
+
const sharedValue = mergeValues(a[key3], b[key3]);
|
|
7510
7510
|
if (!sharedValue.valid) {
|
|
7511
7511
|
return { valid: false };
|
|
7512
7512
|
}
|
|
7513
|
-
newObj[
|
|
7513
|
+
newObj[key3] = sharedValue.data;
|
|
7514
7514
|
}
|
|
7515
7515
|
return { valid: true, data: newObj };
|
|
7516
7516
|
} else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
|
|
@@ -7674,11 +7674,11 @@ var ZodRecord = class _ZodRecord extends ZodType {
|
|
|
7674
7674
|
const pairs = [];
|
|
7675
7675
|
const keyType = this._def.keyType;
|
|
7676
7676
|
const valueType = this._def.valueType;
|
|
7677
|
-
for (const
|
|
7677
|
+
for (const key3 in ctx.data) {
|
|
7678
7678
|
pairs.push({
|
|
7679
|
-
key: keyType._parse(new ParseInputLazyPath(ctx,
|
|
7680
|
-
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[
|
|
7681
|
-
alwaysSet:
|
|
7679
|
+
key: keyType._parse(new ParseInputLazyPath(ctx, key3, ctx.path, key3)),
|
|
7680
|
+
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key3], ctx.path, key3)),
|
|
7681
|
+
alwaysSet: key3 in ctx.data
|
|
7682
7682
|
});
|
|
7683
7683
|
}
|
|
7684
7684
|
if (ctx.common.async) {
|
|
@@ -7726,9 +7726,9 @@ var ZodMap = class extends ZodType {
|
|
|
7726
7726
|
}
|
|
7727
7727
|
const keyType = this._def.keyType;
|
|
7728
7728
|
const valueType = this._def.valueType;
|
|
7729
|
-
const pairs = [...ctx.data.entries()].map(([
|
|
7729
|
+
const pairs = [...ctx.data.entries()].map(([key3, value], index) => {
|
|
7730
7730
|
return {
|
|
7731
|
-
key: keyType._parse(new ParseInputLazyPath(ctx,
|
|
7731
|
+
key: keyType._parse(new ParseInputLazyPath(ctx, key3, ctx.path, [index, "key"])),
|
|
7732
7732
|
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
|
|
7733
7733
|
};
|
|
7734
7734
|
});
|
|
@@ -7736,30 +7736,30 @@ var ZodMap = class extends ZodType {
|
|
|
7736
7736
|
const finalMap = /* @__PURE__ */ new Map();
|
|
7737
7737
|
return Promise.resolve().then(async () => {
|
|
7738
7738
|
for (const pair of pairs) {
|
|
7739
|
-
const
|
|
7739
|
+
const key3 = await pair.key;
|
|
7740
7740
|
const value = await pair.value;
|
|
7741
|
-
if (
|
|
7741
|
+
if (key3.status === "aborted" || value.status === "aborted") {
|
|
7742
7742
|
return INVALID;
|
|
7743
7743
|
}
|
|
7744
|
-
if (
|
|
7744
|
+
if (key3.status === "dirty" || value.status === "dirty") {
|
|
7745
7745
|
status.dirty();
|
|
7746
7746
|
}
|
|
7747
|
-
finalMap.set(
|
|
7747
|
+
finalMap.set(key3.value, value.value);
|
|
7748
7748
|
}
|
|
7749
7749
|
return { status: status.value, value: finalMap };
|
|
7750
7750
|
});
|
|
7751
7751
|
} else {
|
|
7752
7752
|
const finalMap = /* @__PURE__ */ new Map();
|
|
7753
7753
|
for (const pair of pairs) {
|
|
7754
|
-
const
|
|
7754
|
+
const key3 = pair.key;
|
|
7755
7755
|
const value = pair.value;
|
|
7756
|
-
if (
|
|
7756
|
+
if (key3.status === "aborted" || value.status === "aborted") {
|
|
7757
7757
|
return INVALID;
|
|
7758
7758
|
}
|
|
7759
|
-
if (
|
|
7759
|
+
if (key3.status === "dirty" || value.status === "dirty") {
|
|
7760
7760
|
status.dirty();
|
|
7761
7761
|
}
|
|
7762
|
-
finalMap.set(
|
|
7762
|
+
finalMap.set(key3.value, value.value);
|
|
7763
7763
|
}
|
|
7764
7764
|
return { status: status.value, value: finalMap };
|
|
7765
7765
|
}
|
|
@@ -8641,7 +8641,7 @@ import { join as join2 } from "path";
|
|
|
8641
8641
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
8642
8642
|
var import_undici = __toESM(require_undici(), 1);
|
|
8643
8643
|
var require2 = __sdkCreateRequire(import.meta.url);
|
|
8644
|
-
var CODEX_ENV = ["CODEX_THREAD_ID", "CODEX_SESSION_ID", "PAIGY_TOKEN", "PAIGY_SESSION_ID", "PAIGY_HARNESS", "PAIGY_INSTANCE_ID"];
|
|
8644
|
+
var CODEX_ENV = ["CODEX_THREAD_ID", "CODEX_SESSION_ID", "CODEX_HOME", "PAIGY_TOKEN", "PAIGY_SESSION_ID", "PAIGY_HARNESS", "PAIGY_INSTANCE_ID", "PAIGY_ON_WAKE"];
|
|
8645
8645
|
var BACKEND_URL = process.env.PAIGY_BACKEND_URL ?? "https://paigy.ai";
|
|
8646
8646
|
var NETWORK_MSG = `Can't reach ${BACKEND_URL} \u2014 the connection was blocked or dropped before an HTTP response. If this agent runs in a sandboxed environment with a network allowlist (e.g. Claude Code on the web, CI), ask the user to add the Paigy domain (paigy.ai) to the environment's allowed domains, then retry.`;
|
|
8647
8647
|
var PROXY_ENV = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"];
|
|
@@ -8658,8 +8658,8 @@ var WORKSPACE_ID = (() => {
|
|
|
8658
8658
|
return INSTANCE_ID;
|
|
8659
8659
|
}
|
|
8660
8660
|
})();
|
|
8661
|
-
var envSession = (
|
|
8662
|
-
const v = process.env[
|
|
8661
|
+
var envSession = (key22) => {
|
|
8662
|
+
const v = process.env[key22];
|
|
8663
8663
|
return v && v.trim() ? v : void 0;
|
|
8664
8664
|
};
|
|
8665
8665
|
function parentOf(pid) {
|
|
@@ -8699,12 +8699,14 @@ async function reach(url, init) {
|
|
|
8699
8699
|
function reachAs(session, instance) {
|
|
8700
8700
|
return (url, init) => send(url, init, session, instance);
|
|
8701
8701
|
}
|
|
8702
|
+
var CLIENT;
|
|
8702
8703
|
async function send(url, init, session, instance = envSession("PAIGY_INSTANCE_ID") ?? INSTANCE_ID) {
|
|
8703
8704
|
try {
|
|
8704
8705
|
const headers = {
|
|
8705
8706
|
...init?.headers,
|
|
8706
8707
|
"x-paigy-instance": instance,
|
|
8707
|
-
"x-paigy-session": session
|
|
8708
|
+
"x-paigy-session": session,
|
|
8709
|
+
...CLIENT ? { "x-paigy-client": CLIENT } : {}
|
|
8708
8710
|
};
|
|
8709
8711
|
return await fetch(url, { ...init, headers, dispatcher: await proxy() });
|
|
8710
8712
|
} catch (e) {
|
|
@@ -8762,19 +8764,19 @@ var getRefs = (options) => {
|
|
|
8762
8764
|
]))
|
|
8763
8765
|
};
|
|
8764
8766
|
};
|
|
8765
|
-
function addErrorMessage(res,
|
|
8767
|
+
function addErrorMessage(res, key22, errorMessage, refs) {
|
|
8766
8768
|
if (!refs?.errorMessages)
|
|
8767
8769
|
return;
|
|
8768
8770
|
if (errorMessage) {
|
|
8769
8771
|
res.errorMessage = {
|
|
8770
8772
|
...res.errorMessage,
|
|
8771
|
-
[
|
|
8773
|
+
[key22]: errorMessage
|
|
8772
8774
|
};
|
|
8773
8775
|
}
|
|
8774
8776
|
}
|
|
8775
|
-
function setResponseValueAndErrors(res,
|
|
8776
|
-
res[
|
|
8777
|
-
addErrorMessage(res,
|
|
8777
|
+
function setResponseValueAndErrors(res, key22, value, errorMessage, refs) {
|
|
8778
|
+
res[key22] = value;
|
|
8779
|
+
addErrorMessage(res, key22, errorMessage, refs);
|
|
8778
8780
|
}
|
|
8779
8781
|
var getRelativePath = (pathA, pathB) => {
|
|
8780
8782
|
let i = 0;
|
|
@@ -9336,11 +9338,11 @@ function parseRecordDef(def, refs) {
|
|
|
9336
9338
|
return {
|
|
9337
9339
|
type: "object",
|
|
9338
9340
|
required: def.keyType._def.values,
|
|
9339
|
-
properties: def.keyType._def.values.reduce((acc,
|
|
9341
|
+
properties: def.keyType._def.values.reduce((acc, key22) => ({
|
|
9340
9342
|
...acc,
|
|
9341
|
-
[
|
|
9343
|
+
[key22]: parseDef(def.valueType._def, {
|
|
9342
9344
|
...refs,
|
|
9343
|
-
currentPath: [...refs.currentPath, "properties",
|
|
9345
|
+
currentPath: [...refs.currentPath, "properties", key22]
|
|
9344
9346
|
}) ?? parseAnyDef(refs)
|
|
9345
9347
|
}), {}),
|
|
9346
9348
|
additionalProperties: refs.rejectedAdditionalProperties
|
|
@@ -9403,10 +9405,10 @@ function parseMapDef(def, refs) {
|
|
|
9403
9405
|
}
|
|
9404
9406
|
function parseNativeEnumDef(def) {
|
|
9405
9407
|
const object = def.values;
|
|
9406
|
-
const actualKeys = Object.keys(def.values).filter((
|
|
9407
|
-
return typeof object[object[
|
|
9408
|
+
const actualKeys = Object.keys(def.values).filter((key22) => {
|
|
9409
|
+
return typeof object[object[key22]] !== "number";
|
|
9408
9410
|
});
|
|
9409
|
-
const actualValues = actualKeys.map((
|
|
9411
|
+
const actualValues = actualKeys.map((key22) => object[key22]);
|
|
9410
9412
|
const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values)));
|
|
9411
9413
|
return {
|
|
9412
9414
|
type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : ["string", "number"],
|
|
@@ -9971,32 +9973,31 @@ function mcpInputSchema(s) {
|
|
|
9971
9973
|
}
|
|
9972
9974
|
var AskInputSchema = external_exports.object({
|
|
9973
9975
|
id: external_exports.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
|
|
9974
|
-
parentId: external_exports.string().uuid().optional().describe("The Goal this question is about \u2014 usually the one you are working on. The question goes onto that Goal and its answer comes back there. Omit it and
|
|
9976
|
+
parentId: external_exports.string().uuid().optional().describe("The Goal this question is about \u2014 usually the one you are working on. The question goes onto that Goal and its answer comes back there. Omit it and the question starts a new Goal of yours."),
|
|
9975
9977
|
repo: external_exports.string().optional().describe("Optional repository context."),
|
|
9976
9978
|
ask: external_exports.string().trim().min(1).max(1e4).describe(
|
|
9977
|
-
"ONE question, and only what is needed to answer it. Several questions are several asks in the array, one each: an answer settles the one ask it was given in the shape that ask declares, so a person who answers the part of a bundled ask that interested them settles nothing and is asked again. Paigy
|
|
9979
|
+
"ONE question, and only what is needed to answer it. Several questions are several asks in the array, one each: an answer settles the one ask it was given in the shape that ask declares, so a person who answers the part of a bundled ask that interested them settles nothing and is asked again. Paigy sends each ask exactly as you wrote it: a bundled ask arrives as one card. News, progress and findings are their own contact; ANY contact for a person already on a call JOINS that call, whatever channel you asked for, so several arrive as one call."
|
|
9978
9980
|
),
|
|
9979
9981
|
options: external_exports.array(OptionInputSchema).min(1).max(6).optional(),
|
|
9980
|
-
//
|
|
9981
|
-
//
|
|
9982
|
-
//
|
|
9983
|
-
//
|
|
9984
|
-
// shape (`goal/intake.ts` `answerOf`), and this reaches it as the agent's view, weighed, not obeyed.
|
|
9982
|
+
// HOW THE OPTIONS ARE ANSWERED, SAID BY THE AGENT (owner, 2026-10-02: "one and many makes sense";
|
|
9983
|
+
// brain_prompts.md §1: structured agent questions need no model). Every card was pick-one while no
|
|
9984
|
+
// agent sent this; no read reshapes cards any more, so this is the card's shape, and the
|
|
9985
|
+
// description says so plainly.
|
|
9985
9986
|
select: external_exports.enum(["one", "many"]).optional().describe(
|
|
9986
|
-
|
|
9987
|
+
'How the options are answered: "many" makes a checklist (they may want several, e.g. independent fixes), "one" (the default) a pick (choosing one rules out the others). Send "many" whenever more than one option could be wanted at once. The person can always answer in their own words as well. Ignored without options.'
|
|
9987
9988
|
),
|
|
9988
9989
|
answers: external_exports.string().trim().regex(/^[0-9a-fA-F-]{8,36}$/).optional().describe(
|
|
9989
|
-
"Your reply answers a question the person asked you: the id the conversation shows for it (8 characters or whole). Their question closes with this reply as its answer, and any decision of yours it was holding back goes back to them.
|
|
9990
|
+
"Your reply answers a question the person asked you: the id the conversation shows for it (8 characters or whole). Their question closes with this reply as its answer, and any decision of yours it was holding back goes back to them. parentId is optional here: the question's own Goal is used. The reply is sent to them as it is; to also ask something new, send that as its own ask."
|
|
9990
9991
|
)
|
|
9991
9992
|
}).strict();
|
|
9992
9993
|
var StartContactSchema = external_exports.object({
|
|
9993
|
-
asks: external_exports.array(AskInputSchema).min(1).describe("The questions to pose, one per object. An ask with a parentId is filed on that Goal as it is;
|
|
9994
|
+
asks: external_exports.array(AskInputSchema).min(1).describe("The questions to pose, one per object. An ask with a parentId is filed on that Goal as it is; an ask naming no Goal starts a new Goal of yours."),
|
|
9994
9995
|
waiting: external_exports.enum(["none", "hard"]).default("none").describe("hard requests a call even when channel is notification; user permissions and ring cooldowns still apply."),
|
|
9995
9996
|
channel: external_exports.enum(["notification", "call"]).default("notification")
|
|
9996
9997
|
}).strict();
|
|
9997
9998
|
var ContactSchema = external_exports.union([StartContactSchema, external_exports.object({ deliveryId: external_exports.string().uuid() }).strict()]);
|
|
9998
9999
|
var CONTACT_SCHEMA = { type: "object", ...mcpInputSchema(ContactSchema) };
|
|
9999
|
-
var CONTACT_DESCRIPTION = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'select', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. An ask that names a Goal (parentId) goes onto that Goal; one that names none
|
|
10000
|
+
var CONTACT_DESCRIPTION = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'select', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. An ask that names a Goal (parentId) goes onto that Goal; one that names none starts a new Goal of yours. Notification returns immediately; collect durable answers with check_replies. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. One question per 'ask'; several questions are several objects in 'asks'. Each ask is sent exactly as written, with no reading in between: a bundled ask arrives as one card, so separate questions are separate asks. An ask with no options that is not blocking is a report, and a report is an UPDATE, never a claim on them: it reaches them and is listed apart from what waits on them, so no answer is owed and none should be awaited. On a Goal whose report card is still open it is added to that card, with no new push; Where your work stands while under way is progress: report it with update_goal, not contact. Send options (or waiting:'hard') when you actually need an answer. Each option's label must stand on its own \u2014 the person may see only the labels \u2014 so never a label that points into your text ('All three', 'Option 2', '1 and 3 only'). select:'many' makes the card a checklist, for independent options they may want several of; select:'one' (the default) a pick, for alternatives. The person can always answer in their own words, so never add an 'Other' option. If the person is already on a call, your contact joins that call automatically \u2014 whatever channel you asked for, with no ring \u2014 and the Delivery it returns IS that call: reread it with contact({deliveryId}) to see everything answered on it so far, and contact again while it is live to add information or a further question to the same call.";
|
|
10000
10001
|
var CreateGoalSchema = external_exports.object({
|
|
10001
10002
|
outcome: external_exports.string().trim().min(1).max(1e4),
|
|
10002
10003
|
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
|
|
@@ -10070,6 +10071,153 @@ var AGENT_TOOLS = [
|
|
|
10070
10071
|
{ name: "update_goal", description: UPDATE_GOAL_DESCRIPTION, inputSchema: mcpInputSchema(UpdateGoalToolSchema) }
|
|
10071
10072
|
];
|
|
10072
10073
|
var AGENT_TOOL_NAMES = AGENT_TOOLS.map((t) => t.name);
|
|
10074
|
+
var id = external_exports.string().uuid();
|
|
10075
|
+
var key = external_exports.string().min(1).max(40);
|
|
10076
|
+
var participant = external_exports.string().regex(/^(human|agent):.+$/, "a participant ID such as agent:<uuid>");
|
|
10077
|
+
var SourceSchema = external_exports.object({ entryId: id }).strict();
|
|
10078
|
+
var ResultRefSchema = external_exports.union([external_exports.object({ id }).strict(), external_exports.object({ local: key }).strict()]);
|
|
10079
|
+
var NodeRefSchema = external_exports.object({ type: external_exports.enum(["goal", "question"]), id }).strict();
|
|
10080
|
+
var DependencySchema = external_exports.object({
|
|
10081
|
+
blocker: NodeRefSchema,
|
|
10082
|
+
blocked: NodeRefSchema,
|
|
10083
|
+
action: external_exports.enum(["start", "complete", "answer"]),
|
|
10084
|
+
reason: external_exports.string().max(500).optional()
|
|
10085
|
+
}).strict();
|
|
10086
|
+
var goalState = external_exports.enum(["open", "completed", "canceled"]);
|
|
10087
|
+
var existingGoalChanges = [
|
|
10088
|
+
external_exports.object({ kind: external_exports.literal("edit"), goalId: id, title: external_exports.string().min(1).max(120).optional(), outcome: external_exports.string().min(1).optional() }).strict().refine((c) => c.title !== void 0 || c.outcome !== void 0, "an edit changes the title or the outcome"),
|
|
10089
|
+
external_exports.object({ kind: external_exports.literal("state"), goalId: id, state: goalState }).strict(),
|
|
10090
|
+
external_exports.object({ kind: external_exports.literal("assign"), goalId: id, ownerId: participant }).strict(),
|
|
10091
|
+
external_exports.object({ kind: external_exports.literal("defer"), goalId: id, until: external_exports.string().datetime().nullable() }).strict(),
|
|
10092
|
+
external_exports.object({ kind: external_exports.literal("move"), goalId: id, parentGoalId: id.nullable() }).strict(),
|
|
10093
|
+
external_exports.object({
|
|
10094
|
+
kind: external_exports.literal("dependency"),
|
|
10095
|
+
change: external_exports.enum(["add", "remove"]),
|
|
10096
|
+
goalId: id,
|
|
10097
|
+
dependsOnGoalId: id,
|
|
10098
|
+
action: external_exports.enum(["start", "complete"]),
|
|
10099
|
+
reason: external_exports.string().max(500).optional()
|
|
10100
|
+
}).strict()
|
|
10101
|
+
];
|
|
10102
|
+
var GoalChangeSchema = external_exports.union([
|
|
10103
|
+
external_exports.object({
|
|
10104
|
+
kind: external_exports.literal("create"),
|
|
10105
|
+
title: external_exports.string().min(1).max(120),
|
|
10106
|
+
outcome: external_exports.string().min(1),
|
|
10107
|
+
ownerId: participant,
|
|
10108
|
+
parentGoalId: id.optional(),
|
|
10109
|
+
sourceEntryIds: external_exports.array(id)
|
|
10110
|
+
}).strict(),
|
|
10111
|
+
...existingGoalChanges
|
|
10112
|
+
]);
|
|
10113
|
+
var BrainGoalChangeSchema = external_exports.union([
|
|
10114
|
+
// newSession: Paigy starts a session to own it (owner, 2026-10-06); until it has, the person owns it.
|
|
10115
|
+
external_exports.object({
|
|
10116
|
+
kind: external_exports.literal("create"),
|
|
10117
|
+
outcome: external_exports.string().min(1),
|
|
10118
|
+
title: external_exports.string().min(1).max(120),
|
|
10119
|
+
ownerId: participant,
|
|
10120
|
+
parentGoal: ResultRefSchema.nullable(),
|
|
10121
|
+
newSession: external_exports.literal(true).optional()
|
|
10122
|
+
}).strict(),
|
|
10123
|
+
...existingGoalChanges
|
|
10124
|
+
]);
|
|
10125
|
+
var option = external_exports.object({ id: external_exports.string().min(1).max(40), label: external_exports.string().min(1), hint: external_exports.string().optional() }).strict();
|
|
10126
|
+
var QuestionChangeSchema = external_exports.union([
|
|
10127
|
+
external_exports.object({
|
|
10128
|
+
kind: external_exports.literal("create"),
|
|
10129
|
+
text: external_exports.string().min(1),
|
|
10130
|
+
answererId: participant,
|
|
10131
|
+
goal: ResultRefSchema.optional(),
|
|
10132
|
+
blocks: external_exports.array(external_exports.object({ question: ResultRefSchema }).strict()),
|
|
10133
|
+
options: external_exports.array(option).min(2).optional(),
|
|
10134
|
+
pickMode: external_exports.enum(["one", "many", "rank"]).optional()
|
|
10135
|
+
}).strict().refine((c) => c.options === void 0 === (c.pickMode === void 0), "options and pickMode come together"),
|
|
10136
|
+
external_exports.object({ kind: external_exports.literal("edit"), questionId: id, text: external_exports.string().min(1) }).strict(),
|
|
10137
|
+
external_exports.object({ kind: external_exports.literal("assign"), questionId: id, answererId: participant }).strict(),
|
|
10138
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), questionId: id }).strict(),
|
|
10139
|
+
external_exports.object({ kind: external_exports.literal("dependency"), change: external_exports.enum(["add", "remove"]), edge: DependencySchema }).strict()
|
|
10140
|
+
]);
|
|
10141
|
+
var lessonScope = external_exports.union([
|
|
10142
|
+
external_exports.object({ kind: external_exports.literal("user") }).strict(),
|
|
10143
|
+
external_exports.object({ kind: external_exports.literal("goal"), goal: ResultRefSchema }).strict()
|
|
10144
|
+
]);
|
|
10145
|
+
var LessonChangeSchema = external_exports.union([
|
|
10146
|
+
external_exports.object({ kind: external_exports.literal("remember"), text: external_exports.string().min(1), scope: lessonScope }).strict(),
|
|
10147
|
+
external_exports.object({ kind: external_exports.literal("revise"), lessonId: id, text: external_exports.string().min(1), scope: lessonScope }).strict(),
|
|
10148
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), lessonId: id }).strict()
|
|
10149
|
+
]);
|
|
10150
|
+
var BrainNextSchema = external_exports.object({
|
|
10151
|
+
instructions: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key).min(1) }).strict()),
|
|
10152
|
+
say: external_exports.array(key),
|
|
10153
|
+
then: external_exports.enum(["listen", "hold", "end", "none"]),
|
|
10154
|
+
waitFor: external_exports.array(ResultRefSchema),
|
|
10155
|
+
reason: external_exports.string()
|
|
10156
|
+
}).strict();
|
|
10157
|
+
var messageBase = {
|
|
10158
|
+
key,
|
|
10159
|
+
text: external_exports.string().min(1),
|
|
10160
|
+
goals: external_exports.array(ResultRefSchema),
|
|
10161
|
+
questions: external_exports.array(ResultRefSchema),
|
|
10162
|
+
entryKeys: external_exports.array(key),
|
|
10163
|
+
obligationIds: external_exports.array(id)
|
|
10164
|
+
};
|
|
10165
|
+
var BrainMessageSchema = external_exports.union([
|
|
10166
|
+
external_exports.object({ ...messageBase, to: external_exports.object({ kind: external_exports.literal("user") }).strict() }).strict(),
|
|
10167
|
+
external_exports.object({
|
|
10168
|
+
...messageBase,
|
|
10169
|
+
to: external_exports.object({ kind: external_exports.literal("agent"), agentId: external_exports.string().regex(/^agent:(?!paigy$)\S+$/) }).strict(),
|
|
10170
|
+
call: external_exports.object({ callId: id, listen: external_exports.literal(true) }).strict().optional()
|
|
10171
|
+
}).strict()
|
|
10172
|
+
]);
|
|
10173
|
+
var BrainSearchSchema = external_exports.object({
|
|
10174
|
+
query: external_exports.string().min(1).max(500),
|
|
10175
|
+
within: external_exports.array(external_exports.enum(["entries", "goals", "answers"])).min(1),
|
|
10176
|
+
goalId: id.optional()
|
|
10177
|
+
}).strict();
|
|
10178
|
+
var BrainResultSchema = external_exports.object({
|
|
10179
|
+
messages: external_exports.array(BrainMessageSchema),
|
|
10180
|
+
entries: external_exports.array(external_exports.object({ key, sources: external_exports.array(SourceSchema).min(1), goals: external_exports.array(ResultRefSchema) }).strict()),
|
|
10181
|
+
questions: external_exports.array(external_exports.object({ key, entryKeys: external_exports.array(key), change: QuestionChangeSchema }).strict()),
|
|
10182
|
+
answers: external_exports.array(external_exports.object({
|
|
10183
|
+
question: ResultRefSchema,
|
|
10184
|
+
entryKeys: external_exports.array(key).min(1),
|
|
10185
|
+
summary: external_exports.string().min(1),
|
|
10186
|
+
selectedOptionIds: external_exports.array(external_exports.string().min(1)).optional()
|
|
10187
|
+
}).strict()),
|
|
10188
|
+
goals: external_exports.array(external_exports.object({ key, entryKeys: external_exports.array(key), change: BrainGoalChangeSchema }).strict()),
|
|
10189
|
+
feedback: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key).min(1) }).strict()),
|
|
10190
|
+
lessons: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key).min(1), change: LessonChangeSchema }).strict()),
|
|
10191
|
+
next: BrainNextSchema,
|
|
10192
|
+
search: BrainSearchSchema.optional()
|
|
10193
|
+
}).strict();
|
|
10194
|
+
var str = external_exports.string();
|
|
10195
|
+
var strs = external_exports.array(external_exports.string());
|
|
10196
|
+
var CompactResultSchema = external_exports.object({
|
|
10197
|
+
next: external_exports.object({ say: strs, then: external_exports.enum(["listen", "hold", "end", "none"]), waitFor: strs, reason: str, instructions: strs }).strict(),
|
|
10198
|
+
messages: external_exports.array(external_exports.object({ key: str, to: str, text: str, about: strs, entries: strs, owed: strs, inviteToCall: external_exports.boolean() }).strict()),
|
|
10199
|
+
entries: external_exports.array(external_exports.object({ key: str, from: str, on: strs }).strict()),
|
|
10200
|
+
answers: external_exports.array(external_exports.object({ question: str, entries: strs, summary: str, picked: strs }).strict()),
|
|
10201
|
+
changes: external_exports.array(external_exports.object({
|
|
10202
|
+
key: str,
|
|
10203
|
+
what: external_exports.enum(["goal", "question", "lesson"]),
|
|
10204
|
+
op: external_exports.enum(["create", "edit", "assign", "open", "complete", "cancel", "defer", "move", "block", "unblock", "withdraw", "remember", "revise"]),
|
|
10205
|
+
id: str,
|
|
10206
|
+
text: str,
|
|
10207
|
+
title: str,
|
|
10208
|
+
who: str,
|
|
10209
|
+
under: str,
|
|
10210
|
+
gate: external_exports.enum(["start", "complete", "answer", "none"]),
|
|
10211
|
+
options: external_exports.array(external_exports.object({ id: str, label: str }).strict()),
|
|
10212
|
+
pick: external_exports.enum(["one", "many", "rank", "words"]),
|
|
10213
|
+
entries: strs
|
|
10214
|
+
}).strict()),
|
|
10215
|
+
feedback: external_exports.array(strs),
|
|
10216
|
+
search: external_exports.object({ query: str, within: strs, goal: str }).strict()
|
|
10217
|
+
}).strict();
|
|
10218
|
+
var COMPACT_RESULT_JSON_SCHEMA = (({ $schema: _, ...rest }) => rest)(
|
|
10219
|
+
zodToJsonSchema(CompactResultSchema, { $refStrategy: "none" })
|
|
10220
|
+
);
|
|
10073
10221
|
var LIVE_MS = 3 * 6e4;
|
|
10074
10222
|
var WORKING_MS = 60 * 6e4;
|
|
10075
10223
|
var ContextSchema = external_exports.object({
|
|
@@ -10289,7 +10437,7 @@ var IntentSchema = external_exports.object({
|
|
|
10289
10437
|
* (`parseDelay`, #1292), and a value here simply wins over that reading. */
|
|
10290
10438
|
dueInSeconds: external_exports.number().int().positive().optional(),
|
|
10291
10439
|
/** Feedback only (#812): WHICH failure the complaint names — typed by the mapper that
|
|
10292
|
-
* already read the utterance, so `
|
|
10440
|
+
* already read the utterance, so `signals.kind` stops defaulting to
|
|
10293
10441
|
* 'other' on every row. A table that records that something was wrong and nothing
|
|
10294
10442
|
* about what cannot answer "is the bot looping less this week?". */
|
|
10295
10443
|
fault: external_exports.enum(["loop", "unanswered", "overridden", "misheard", "slow", "other"]).optional()
|
|
@@ -10573,7 +10721,18 @@ var InboxItemSchema = external_exports.object({
|
|
|
10573
10721
|
/** THAT GOAL'S NAME (#2416) — what Activity's row is headed by, since a row there is one Goal
|
|
10574
10722
|
* and the cards it holds sit behind it. Stamped by the same read as `goalState`. */
|
|
10575
10723
|
goalTitle: external_exports.string().optional()
|
|
10576
|
-
}).optional()
|
|
10724
|
+
}).optional(),
|
|
10725
|
+
/** WHAT THIS CARD IS, IN TWELVE CHARACTERS (#3019) — the hash of every other field on it, stamped
|
|
10726
|
+
* by the one read that serves the open list (`apps/api/src/inbox/project.ts` `inboxFor`). It is
|
|
10727
|
+
* how the incremental read knows a card has not moved: the phone echoes back the revs it holds
|
|
10728
|
+
* (`POST /api/inbox/changes`) and is sent only the cards whose rev differs.
|
|
10729
|
+
*
|
|
10730
|
+
* THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK — the same mechanism as `QueueItem.rev`
|
|
10731
|
+
* (#2928) and an entry's (#3018), for the same reason: a card shows facts no `updated_at` of its
|
|
10732
|
+
* own moves (its Goal's state and name, how cold the work behind it has gone, whether a ring is
|
|
10733
|
+
* live). Optional, so a fixture, the demo and the archive lens need not spell one, and a card
|
|
10734
|
+
* with no rev is simply always re-sent. */
|
|
10735
|
+
rev: external_exports.string().optional()
|
|
10577
10736
|
});
|
|
10578
10737
|
var APNS_TOKEN_RE = /^[0-9a-fA-F]{64}$/;
|
|
10579
10738
|
var PushTokenSchema = external_exports.object({
|
|
@@ -10785,39 +10944,22 @@ var ReassignResultSchema = external_exports.object({
|
|
|
10785
10944
|
moved: external_exports.object({ asks: external_exports.number(), answered: external_exports.number(), requests: external_exports.number(), goals: external_exports.number(), callbacks: external_exports.number() }),
|
|
10786
10945
|
parentId: external_exports.string().nullable()
|
|
10787
10946
|
});
|
|
10788
|
-
var
|
|
10789
|
-
var
|
|
10947
|
+
var LessonStateSchema = external_exports.enum(["active", "proposed", "retired"]);
|
|
10948
|
+
var LessonViewSchema = external_exports.object({
|
|
10790
10949
|
id: external_exports.string(),
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
/** The
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
rationale: external_exports.string().nullable(),
|
|
10798
|
-
/** Where the ruling lives: a repo/workspace, or 'global'. */
|
|
10799
|
-
scope: external_exports.string(),
|
|
10800
|
-
ring: MoveRingSchema,
|
|
10801
|
-
/** True = the user pinned it with `always` (travel granted by hand, not by evidence). */
|
|
10950
|
+
text: external_exports.string(),
|
|
10951
|
+
state: LessonStateSchema,
|
|
10952
|
+
/** The Goal it is scoped to; null = the whole account. */
|
|
10953
|
+
scopeGoalId: external_exports.string().nullable(),
|
|
10954
|
+
goalTitle: external_exports.string().nullable(),
|
|
10955
|
+
version: external_exports.number(),
|
|
10802
10956
|
pinned: external_exports.boolean(),
|
|
10803
|
-
/**
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
lastUsedAt: external_exports.string().nullable(),
|
|
10810
|
-
/** How many asks it has answered. Instrumentation — deliberately NOT an input to the
|
|
10811
|
-
* evidence curve: firing says the question keeps arising, not that the ruling is right. */
|
|
10812
|
-
usedCount: external_exports.number(),
|
|
10813
|
-
/** Ledger: outcomes that said it held up. Saturating — the tenth is worth almost nothing. */
|
|
10814
|
-
confirms: external_exports.number(),
|
|
10815
|
-
/** Ledger: contradictions, in signal units (a full override = 1, weaker signals less).
|
|
10816
|
-
* Linear and priced above the entire confirmation budget, so any full counter wins. */
|
|
10817
|
-
counters: external_exports.number(),
|
|
10818
|
-
/** The agent that asked the question this move came from, when known. Null for a move
|
|
10819
|
-
* distilled from a clarify ruling (those carry no agent) or one whose source rows are gone. */
|
|
10820
|
-
learnedFrom: external_exports.object({ id: external_exports.string(), name: external_exports.string() }).nullable()
|
|
10957
|
+
/** When the person last wrote its text themselves. */
|
|
10958
|
+
editedAt: external_exports.string().nullable(),
|
|
10959
|
+
createdAt: external_exports.string(),
|
|
10960
|
+
updatedAt: external_exports.string(),
|
|
10961
|
+
/** The Entries it came from, oldest first; `words` is null when an Entry has none to show (sealed). */
|
|
10962
|
+
sources: external_exports.array(external_exports.object({ entryId: external_exports.string(), words: external_exports.string().nullable(), at: external_exports.string() }))
|
|
10821
10963
|
});
|
|
10822
10964
|
var QueueQuestionSchema = external_exports.object({
|
|
10823
10965
|
/** The decision need's id — what an answer is accepted against. */
|
|
@@ -10945,7 +11087,22 @@ var QueueItemSchema = external_exports.object({
|
|
|
10945
11087
|
* minute after the person speaks erases their instant from it, and the durable traces the client
|
|
10946
11088
|
* can see (`replies`, `questions[].answeredAt`) miss a spontaneous note entirely — a `request`
|
|
10947
11089
|
* Entry with no `about_id` is in neither. */
|
|
10948
|
-
lastPersonAt: external_exports.string().nullable().optional()
|
|
11090
|
+
lastPersonAt: external_exports.string().nullable().optional(),
|
|
11091
|
+
/** WHAT THIS ROW IS, IN TWELVE CHARACTERS (#2928) — the hash of every other field on it, stamped
|
|
11092
|
+
* by the one projection that builds the row (`apps/api/src/goal/queue.ts`). It is how the
|
|
11093
|
+
* incremental read knows a row has not moved: the phone echoes back the revs it holds
|
|
11094
|
+
* (`POST /api/goals/changes`) and is sent only the rows whose rev differs.
|
|
11095
|
+
*
|
|
11096
|
+
* IT IS THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK. Nothing here reasons about which
|
|
11097
|
+
* writes change which field — the comparison is over the bytes the phone is holding, so a fact
|
|
11098
|
+
* the row shows that no `updated_at` moves for (a lease lapsing, a dependency's state, a
|
|
11099
|
+
* sibling appearing in `childGoalIds`) cannot go unnoticed. Optional because a hand-built
|
|
11100
|
+
* queue (a fixture, the demo) spells none, and a row with no rev is simply always re-sent. */
|
|
11101
|
+
rev: external_exports.string().optional()
|
|
11102
|
+
});
|
|
11103
|
+
var QueueDeltaSchema = external_exports.object({
|
|
11104
|
+
ids: external_exports.array(external_exports.string()),
|
|
11105
|
+
items: external_exports.array(QueueItemSchema)
|
|
10949
11106
|
});
|
|
10950
11107
|
var COLD_AFTER_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
10951
11108
|
var NoteSourceSchema = external_exports.enum(["app", "call"]);
|
|
@@ -11118,6 +11275,11 @@ var DeviceTokenSchema = external_exports.object({
|
|
|
11118
11275
|
/** Local host recovery must preserve the launch's runtime and Paigy identity. */
|
|
11119
11276
|
harness: external_exports.enum(["claude", "codex", "agy"]).optional(),
|
|
11120
11277
|
session_id: external_exports.string().uuid().optional(),
|
|
11278
|
+
/** A conversation the host must not resume: its context is full, so every turn fails
|
|
11279
|
+
* ("Prompt is too long"). Written when a run hits it (`run.ts` `onFull`); the host skips a slot
|
|
11280
|
+
* whose resumable session is this one, so its Goals reach the dead-agent handoff instead of a
|
|
11281
|
+
* copy that types the person's words into a turn that cannot run (Calls, 2026-10-06). */
|
|
11282
|
+
full_session: external_exports.string().optional(),
|
|
11121
11283
|
uik_pub: external_exports.string().nullable().optional()
|
|
11122
11284
|
});
|
|
11123
11285
|
var SupportRequestSchema = external_exports.object({
|
|
@@ -11263,8 +11425,8 @@ var CallRecapSchema = external_exports.object({
|
|
|
11263
11425
|
more: external_exports.object({ lines: external_exports.number(), entries: external_exports.number(), topics: external_exports.number() })
|
|
11264
11426
|
});
|
|
11265
11427
|
function sessionSlot(sessionId2) {
|
|
11266
|
-
const
|
|
11267
|
-
return `session:${
|
|
11428
|
+
const id22 = sessionId2 ?? sessionId();
|
|
11429
|
+
return `session:${id22.slice(0, 8)}`;
|
|
11268
11430
|
}
|
|
11269
11431
|
function agentName() {
|
|
11270
11432
|
return process.env.PAIGY_AGENT || sessionSlot();
|
|
@@ -11321,7 +11483,7 @@ function updateSlot(agent2, patch) {
|
|
|
11321
11483
|
}
|
|
11322
11484
|
function slotIdentity(agent2) {
|
|
11323
11485
|
const t = readTokenFile()[agent2];
|
|
11324
|
-
return { name: t?.name ?? null, voice: t?.voice ?? null, tokenId: t?.token_id ?? null, workspace: t?.workspace ?? null, harness: t?.harness ?? null, sessionId: t?.session_id ?? null };
|
|
11486
|
+
return { name: t?.name ?? null, voice: t?.voice ?? null, tokenId: t?.token_id ?? null, workspace: t?.workspace ?? null, harness: t?.harness ?? null, sessionId: t?.session_id ?? null, fullSession: t?.full_session ?? null };
|
|
11325
11487
|
}
|
|
11326
11488
|
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
11327
11489
|
function readToken(agent2 = agentName()) {
|
|
@@ -11483,7 +11645,9 @@ async function recordDecision(decision, opts = {}) {
|
|
|
11483
11645
|
async function heartbeat(runtime, opts = {}) {
|
|
11484
11646
|
const body = {
|
|
11485
11647
|
...runtime !== void 0 ? { runtime } : {},
|
|
11486
|
-
...opts.activity !== void 0 ? { activity: opts.activity } : {}
|
|
11648
|
+
...opts.activity !== void 0 ? { activity: opts.activity } : {},
|
|
11649
|
+
// A listener's beat (`paigy-listen`): stamps when it last swept, and is not presence.
|
|
11650
|
+
...opts.listening ? { listening: true } : {}
|
|
11487
11651
|
};
|
|
11488
11652
|
const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/presence`, {
|
|
11489
11653
|
method: "POST",
|
|
@@ -11575,6 +11739,7 @@ function currentRepo(cwd = process.cwd()) {
|
|
|
11575
11739
|
return asked;
|
|
11576
11740
|
}
|
|
11577
11741
|
var NOT_SENT = "Recorded as progress, not sent: nobody was notified. If the person should see it (a result, something to try or check, a finding), contact again and say so; report progress with update_goal.";
|
|
11742
|
+
var DEMOTED = "Delivered as a card, not a call: the person's settings do not allow a call right now (silent, quiet hours, or a mode). It has reached them; do not send it again, with or without a Goal.";
|
|
11578
11743
|
async function contact(input, opts = {}) {
|
|
11579
11744
|
const parsed = ContactSchema.parse(input);
|
|
11580
11745
|
opts.signal?.throwIfAborted();
|
|
@@ -11583,6 +11748,7 @@ async function contact(input, opts = {}) {
|
|
|
11583
11748
|
let deliveryId;
|
|
11584
11749
|
let deliveries = [];
|
|
11585
11750
|
let recorded = [];
|
|
11751
|
+
let demoted;
|
|
11586
11752
|
if ("deliveryId" in parsed) {
|
|
11587
11753
|
deliveryId = parsed.deliveryId;
|
|
11588
11754
|
} else {
|
|
@@ -11613,13 +11779,14 @@ async function contact(input, opts = {}) {
|
|
|
11613
11779
|
if (!res.ok) await fail("batch contact", res);
|
|
11614
11780
|
const receipt = await res.json();
|
|
11615
11781
|
deliveries = receipt.deliveries ?? [];
|
|
11782
|
+
if (parsed.channel === "call" && receipt.channel && receipt.channel !== "call") demoted = DEMOTED;
|
|
11616
11783
|
recorded = receipt.recorded ?? [];
|
|
11617
11784
|
if (deliveries.length === 0 && recorded.length) return { sent: false, recorded, message: NOT_SENT };
|
|
11618
11785
|
if (deliveries.length === 0) throw new Error("Goal contact returned no Delivery identities");
|
|
11619
11786
|
deliveryId = deliveries[0]?.deliveryId ?? "";
|
|
11620
11787
|
if (!deliveryId) throw new Error("Goal contact returned no valid Delivery identity");
|
|
11621
11788
|
}
|
|
11622
|
-
const all = deliveries.filter((d) => !!d.deliveryId && !!d.goalId).map(({ id, deliveryId: deliveryId2, goalId }) => ({ ...
|
|
11789
|
+
const all = deliveries.filter((d) => !!d.deliveryId && !!d.goalId).map(({ id: id22, deliveryId: deliveryId2, goalId }) => ({ ...id22 ? { id: id22 } : {}, deliveryId: deliveryId2, goalId }));
|
|
11623
11790
|
const joinedCard = deliveries[0]?.joinedCard === true;
|
|
11624
11791
|
const joinedCall = deliveries[0]?.joinedCall === true;
|
|
11625
11792
|
const read = async (signal2) => {
|
|
@@ -11631,7 +11798,8 @@ async function contact(input, opts = {}) {
|
|
|
11631
11798
|
...all.length > 1 ? { deliveries: all } : {},
|
|
11632
11799
|
...recorded.length ? { recorded, notSent: NOT_SENT } : {},
|
|
11633
11800
|
...joinedCard ? { joinedCard: true } : {},
|
|
11634
|
-
...joinedCall ? { joinedCall: true } : {}
|
|
11801
|
+
...joinedCall ? { joinedCall: true } : {},
|
|
11802
|
+
...demoted ? { demoted } : {}
|
|
11635
11803
|
};
|
|
11636
11804
|
};
|
|
11637
11805
|
const settled = (d) => d.kind === "notification" || d.state === "closed" || d.answers.length > 0 || d.entries.some((e) => e.kind === "contribution");
|
|
@@ -11768,9 +11936,9 @@ function connect(line) {
|
|
|
11768
11936
|
ws.addEventListener("error", again);
|
|
11769
11937
|
}
|
|
11770
11938
|
function subscribeRealtime(args) {
|
|
11771
|
-
const
|
|
11772
|
-
let line = lines.get(
|
|
11773
|
-
if (!line) lines.set(
|
|
11939
|
+
const key22 = `${args.url} ${args.anonKey}`;
|
|
11940
|
+
let line = lines.get(key22);
|
|
11941
|
+
if (!line) lines.set(key22, line = { url: args.url, anonKey: args.anonKey, open: false, attempt: 0, ref: 0, topics: /* @__PURE__ */ new Map() });
|
|
11774
11942
|
let t = line.topics.get(args.topic);
|
|
11775
11943
|
if (!t) {
|
|
11776
11944
|
line.topics.set(args.topic, t = { listeners: /* @__PURE__ */ new Set(), joined: false, attempt: 0 });
|
|
@@ -11792,7 +11960,7 @@ function subscribeRealtime(args) {
|
|
|
11792
11960
|
if (line.open) frame(line, `realtime:${args.topic}`, "phx_leave", {});
|
|
11793
11961
|
return;
|
|
11794
11962
|
}
|
|
11795
|
-
lines.delete(
|
|
11963
|
+
lines.delete(key22);
|
|
11796
11964
|
stop(line);
|
|
11797
11965
|
try {
|
|
11798
11966
|
line.ws?.close();
|
|
@@ -12241,16 +12409,16 @@ function parseVerdicts(raw, knownIds, knownAgents) {
|
|
|
12241
12409
|
const seen = /* @__PURE__ */ new Set();
|
|
12242
12410
|
for (const row of rows) {
|
|
12243
12411
|
const r = row;
|
|
12244
|
-
const
|
|
12245
|
-
if (!
|
|
12412
|
+
const id3 = typeof r?.id === "string" ? r.id : "";
|
|
12413
|
+
if (!id3) {
|
|
12246
12414
|
dropped.push({ row, reason: "no id" });
|
|
12247
12415
|
continue;
|
|
12248
12416
|
}
|
|
12249
|
-
if (!knownIds.has(
|
|
12417
|
+
if (!knownIds.has(id3)) {
|
|
12250
12418
|
dropped.push({ row, reason: "id is not a note in this queue" });
|
|
12251
12419
|
continue;
|
|
12252
12420
|
}
|
|
12253
|
-
if (seen.has(
|
|
12421
|
+
if (seen.has(id3)) {
|
|
12254
12422
|
dropped.push({ row, reason: "duplicate verdict for this note" });
|
|
12255
12423
|
continue;
|
|
12256
12424
|
}
|
|
@@ -12265,12 +12433,12 @@ function parseVerdicts(raw, knownIds, knownAgents) {
|
|
|
12265
12433
|
continue;
|
|
12266
12434
|
}
|
|
12267
12435
|
verdicts.push({
|
|
12268
|
-
id,
|
|
12436
|
+
id: id3,
|
|
12269
12437
|
verdict,
|
|
12270
12438
|
agent: verdict === "assign" ? agent2 : null,
|
|
12271
12439
|
why: typeof r?.why === "string" ? r.why.trim().slice(0, 200) : null
|
|
12272
12440
|
});
|
|
12273
|
-
seen.add(
|
|
12441
|
+
seen.add(id3);
|
|
12274
12442
|
}
|
|
12275
12443
|
return { ok: true, verdicts, dropped };
|
|
12276
12444
|
}
|
|
@@ -12425,7 +12593,7 @@ async function runTriage(opts, deps = {}) {
|
|
|
12425
12593
|
const acted = suggested(run);
|
|
12426
12594
|
log2(acted === 0 ? "Nothing to suggest \u2014 sent, so your phone shows the queue as clean." : `Sent to your phone \u2014 accept it there (${plural(acted, "suggestion")}).`);
|
|
12427
12595
|
if (!opts.apply) return 0;
|
|
12428
|
-
const accept = deps.accept ?? ((
|
|
12596
|
+
const accept = deps.accept ?? ((id3, body) => acceptTriage(id3, body));
|
|
12429
12597
|
const groups = [
|
|
12430
12598
|
{ body: { group: "close" }, label: `close ${plural(run.close.length, "note")}`, count: run.close.length, preapproved: opts.yes.close },
|
|
12431
12599
|
{ body: { group: "stale" }, label: `close ${plural(run.stale.length, "stale note")}`, count: run.stale.length, preapproved: opts.yes.stale },
|
|
@@ -12848,19 +13016,19 @@ var getRefs2 = (options) => {
|
|
|
12848
13016
|
};
|
|
12849
13017
|
|
|
12850
13018
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/errorMessages.js
|
|
12851
|
-
function addErrorMessage2(res,
|
|
13019
|
+
function addErrorMessage2(res, key3, errorMessage, refs) {
|
|
12852
13020
|
if (!refs?.errorMessages)
|
|
12853
13021
|
return;
|
|
12854
13022
|
if (errorMessage) {
|
|
12855
13023
|
res.errorMessage = {
|
|
12856
13024
|
...res.errorMessage,
|
|
12857
|
-
[
|
|
13025
|
+
[key3]: errorMessage
|
|
12858
13026
|
};
|
|
12859
13027
|
}
|
|
12860
13028
|
}
|
|
12861
|
-
function setResponseValueAndErrors2(res,
|
|
12862
|
-
res[
|
|
12863
|
-
addErrorMessage2(res,
|
|
13029
|
+
function setResponseValueAndErrors2(res, key3, value, errorMessage, refs) {
|
|
13030
|
+
res[key3] = value;
|
|
13031
|
+
addErrorMessage2(res, key3, errorMessage, refs);
|
|
12864
13032
|
}
|
|
12865
13033
|
|
|
12866
13034
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js
|
|
@@ -13452,11 +13620,11 @@ function parseRecordDef2(def, refs) {
|
|
|
13452
13620
|
return {
|
|
13453
13621
|
type: "object",
|
|
13454
13622
|
required: def.keyType._def.values,
|
|
13455
|
-
properties: def.keyType._def.values.reduce((acc,
|
|
13623
|
+
properties: def.keyType._def.values.reduce((acc, key3) => ({
|
|
13456
13624
|
...acc,
|
|
13457
|
-
[
|
|
13625
|
+
[key3]: parseDef2(def.valueType._def, {
|
|
13458
13626
|
...refs,
|
|
13459
|
-
currentPath: [...refs.currentPath, "properties",
|
|
13627
|
+
currentPath: [...refs.currentPath, "properties", key3]
|
|
13460
13628
|
}) ?? parseAnyDef2(refs)
|
|
13461
13629
|
}), {}),
|
|
13462
13630
|
additionalProperties: refs.rejectedAdditionalProperties
|
|
@@ -13523,10 +13691,10 @@ function parseMapDef2(def, refs) {
|
|
|
13523
13691
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js
|
|
13524
13692
|
function parseNativeEnumDef2(def) {
|
|
13525
13693
|
const object = def.values;
|
|
13526
|
-
const actualKeys = Object.keys(def.values).filter((
|
|
13527
|
-
return typeof object[object[
|
|
13694
|
+
const actualKeys = Object.keys(def.values).filter((key3) => {
|
|
13695
|
+
return typeof object[object[key3]] !== "number";
|
|
13528
13696
|
});
|
|
13529
|
-
const actualValues = actualKeys.map((
|
|
13697
|
+
const actualValues = actualKeys.map((key3) => object[key3]);
|
|
13530
13698
|
const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values)));
|
|
13531
13699
|
return {
|
|
13532
13700
|
type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : ["string", "number"],
|
|
@@ -14127,32 +14295,31 @@ function mcpInputSchema2(s) {
|
|
|
14127
14295
|
}
|
|
14128
14296
|
var AskInputSchema2 = external_exports.object({
|
|
14129
14297
|
id: external_exports.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
|
|
14130
|
-
parentId: external_exports.string().uuid().optional().describe("The Goal this question is about \u2014 usually the one you are working on. The question goes onto that Goal and its answer comes back there. Omit it and
|
|
14298
|
+
parentId: external_exports.string().uuid().optional().describe("The Goal this question is about \u2014 usually the one you are working on. The question goes onto that Goal and its answer comes back there. Omit it and the question starts a new Goal of yours."),
|
|
14131
14299
|
repo: external_exports.string().optional().describe("Optional repository context."),
|
|
14132
14300
|
ask: external_exports.string().trim().min(1).max(1e4).describe(
|
|
14133
|
-
"ONE question, and only what is needed to answer it. Several questions are several asks in the array, one each: an answer settles the one ask it was given in the shape that ask declares, so a person who answers the part of a bundled ask that interested them settles nothing and is asked again. Paigy
|
|
14301
|
+
"ONE question, and only what is needed to answer it. Several questions are several asks in the array, one each: an answer settles the one ask it was given in the shape that ask declares, so a person who answers the part of a bundled ask that interested them settles nothing and is asked again. Paigy sends each ask exactly as you wrote it: a bundled ask arrives as one card. News, progress and findings are their own contact; ANY contact for a person already on a call JOINS that call, whatever channel you asked for, so several arrive as one call."
|
|
14134
14302
|
),
|
|
14135
14303
|
options: external_exports.array(OptionInputSchema2).min(1).max(6).optional(),
|
|
14136
|
-
//
|
|
14137
|
-
//
|
|
14138
|
-
//
|
|
14139
|
-
//
|
|
14140
|
-
// shape (`goal/intake.ts` `answerOf`), and this reaches it as the agent's view, weighed, not obeyed.
|
|
14304
|
+
// HOW THE OPTIONS ARE ANSWERED, SAID BY THE AGENT (owner, 2026-10-02: "one and many makes sense";
|
|
14305
|
+
// brain_prompts.md §1: structured agent questions need no model). Every card was pick-one while no
|
|
14306
|
+
// agent sent this; no read reshapes cards any more, so this is the card's shape, and the
|
|
14307
|
+
// description says so plainly.
|
|
14141
14308
|
select: external_exports.enum(["one", "many"]).optional().describe(
|
|
14142
|
-
|
|
14309
|
+
'How the options are answered: "many" makes a checklist (they may want several, e.g. independent fixes), "one" (the default) a pick (choosing one rules out the others). Send "many" whenever more than one option could be wanted at once. The person can always answer in their own words as well. Ignored without options.'
|
|
14143
14310
|
),
|
|
14144
14311
|
answers: external_exports.string().trim().regex(/^[0-9a-fA-F-]{8,36}$/).optional().describe(
|
|
14145
|
-
"Your reply answers a question the person asked you: the id the conversation shows for it (8 characters or whole). Their question closes with this reply as its answer, and any decision of yours it was holding back goes back to them.
|
|
14312
|
+
"Your reply answers a question the person asked you: the id the conversation shows for it (8 characters or whole). Their question closes with this reply as its answer, and any decision of yours it was holding back goes back to them. parentId is optional here: the question's own Goal is used. The reply is sent to them as it is; to also ask something new, send that as its own ask."
|
|
14146
14313
|
)
|
|
14147
14314
|
}).strict();
|
|
14148
14315
|
var StartContactSchema2 = external_exports.object({
|
|
14149
|
-
asks: external_exports.array(AskInputSchema2).min(1).describe("The questions to pose, one per object. An ask with a parentId is filed on that Goal as it is;
|
|
14316
|
+
asks: external_exports.array(AskInputSchema2).min(1).describe("The questions to pose, one per object. An ask with a parentId is filed on that Goal as it is; an ask naming no Goal starts a new Goal of yours."),
|
|
14150
14317
|
waiting: external_exports.enum(["none", "hard"]).default("none").describe("hard requests a call even when channel is notification; user permissions and ring cooldowns still apply."),
|
|
14151
14318
|
channel: external_exports.enum(["notification", "call"]).default("notification")
|
|
14152
14319
|
}).strict();
|
|
14153
14320
|
var ContactSchema2 = external_exports.union([StartContactSchema2, external_exports.object({ deliveryId: external_exports.string().uuid() }).strict()]);
|
|
14154
14321
|
var CONTACT_SCHEMA2 = { type: "object", ...mcpInputSchema2(ContactSchema2) };
|
|
14155
|
-
var CONTACT_DESCRIPTION2 = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'select', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. An ask that names a Goal (parentId) goes onto that Goal; one that names none
|
|
14322
|
+
var CONTACT_DESCRIPTION2 = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'select', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. An ask that names a Goal (parentId) goes onto that Goal; one that names none starts a new Goal of yours. Notification returns immediately; collect durable answers with check_replies. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. One question per 'ask'; several questions are several objects in 'asks'. Each ask is sent exactly as written, with no reading in between: a bundled ask arrives as one card, so separate questions are separate asks. An ask with no options that is not blocking is a report, and a report is an UPDATE, never a claim on them: it reaches them and is listed apart from what waits on them, so no answer is owed and none should be awaited. On a Goal whose report card is still open it is added to that card, with no new push; Where your work stands while under way is progress: report it with update_goal, not contact. Send options (or waiting:'hard') when you actually need an answer. Each option's label must stand on its own \u2014 the person may see only the labels \u2014 so never a label that points into your text ('All three', 'Option 2', '1 and 3 only'). select:'many' makes the card a checklist, for independent options they may want several of; select:'one' (the default) a pick, for alternatives. The person can always answer in their own words, so never add an 'Other' option. If the person is already on a call, your contact joins that call automatically \u2014 whatever channel you asked for, with no ring \u2014 and the Delivery it returns IS that call: reread it with contact({deliveryId}) to see everything answered on it so far, and contact again while it is live to add information or a further question to the same call.";
|
|
14156
14323
|
var CreateGoalSchema2 = external_exports.object({
|
|
14157
14324
|
outcome: external_exports.string().trim().min(1).max(1e4),
|
|
14158
14325
|
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
|
|
@@ -14226,6 +14393,153 @@ var AGENT_TOOLS2 = [
|
|
|
14226
14393
|
{ name: "update_goal", description: UPDATE_GOAL_DESCRIPTION2, inputSchema: mcpInputSchema2(UpdateGoalToolSchema2) }
|
|
14227
14394
|
];
|
|
14228
14395
|
var AGENT_TOOL_NAMES2 = AGENT_TOOLS2.map((t) => t.name);
|
|
14396
|
+
var id2 = external_exports.string().uuid();
|
|
14397
|
+
var key2 = external_exports.string().min(1).max(40);
|
|
14398
|
+
var participant2 = external_exports.string().regex(/^(human|agent):.+$/, "a participant ID such as agent:<uuid>");
|
|
14399
|
+
var SourceSchema2 = external_exports.object({ entryId: id2 }).strict();
|
|
14400
|
+
var ResultRefSchema2 = external_exports.union([external_exports.object({ id: id2 }).strict(), external_exports.object({ local: key2 }).strict()]);
|
|
14401
|
+
var NodeRefSchema2 = external_exports.object({ type: external_exports.enum(["goal", "question"]), id: id2 }).strict();
|
|
14402
|
+
var DependencySchema2 = external_exports.object({
|
|
14403
|
+
blocker: NodeRefSchema2,
|
|
14404
|
+
blocked: NodeRefSchema2,
|
|
14405
|
+
action: external_exports.enum(["start", "complete", "answer"]),
|
|
14406
|
+
reason: external_exports.string().max(500).optional()
|
|
14407
|
+
}).strict();
|
|
14408
|
+
var goalState2 = external_exports.enum(["open", "completed", "canceled"]);
|
|
14409
|
+
var existingGoalChanges2 = [
|
|
14410
|
+
external_exports.object({ kind: external_exports.literal("edit"), goalId: id2, title: external_exports.string().min(1).max(120).optional(), outcome: external_exports.string().min(1).optional() }).strict().refine((c) => c.title !== void 0 || c.outcome !== void 0, "an edit changes the title or the outcome"),
|
|
14411
|
+
external_exports.object({ kind: external_exports.literal("state"), goalId: id2, state: goalState2 }).strict(),
|
|
14412
|
+
external_exports.object({ kind: external_exports.literal("assign"), goalId: id2, ownerId: participant2 }).strict(),
|
|
14413
|
+
external_exports.object({ kind: external_exports.literal("defer"), goalId: id2, until: external_exports.string().datetime().nullable() }).strict(),
|
|
14414
|
+
external_exports.object({ kind: external_exports.literal("move"), goalId: id2, parentGoalId: id2.nullable() }).strict(),
|
|
14415
|
+
external_exports.object({
|
|
14416
|
+
kind: external_exports.literal("dependency"),
|
|
14417
|
+
change: external_exports.enum(["add", "remove"]),
|
|
14418
|
+
goalId: id2,
|
|
14419
|
+
dependsOnGoalId: id2,
|
|
14420
|
+
action: external_exports.enum(["start", "complete"]),
|
|
14421
|
+
reason: external_exports.string().max(500).optional()
|
|
14422
|
+
}).strict()
|
|
14423
|
+
];
|
|
14424
|
+
var GoalChangeSchema2 = external_exports.union([
|
|
14425
|
+
external_exports.object({
|
|
14426
|
+
kind: external_exports.literal("create"),
|
|
14427
|
+
title: external_exports.string().min(1).max(120),
|
|
14428
|
+
outcome: external_exports.string().min(1),
|
|
14429
|
+
ownerId: participant2,
|
|
14430
|
+
parentGoalId: id2.optional(),
|
|
14431
|
+
sourceEntryIds: external_exports.array(id2)
|
|
14432
|
+
}).strict(),
|
|
14433
|
+
...existingGoalChanges2
|
|
14434
|
+
]);
|
|
14435
|
+
var BrainGoalChangeSchema2 = external_exports.union([
|
|
14436
|
+
// newSession: Paigy starts a session to own it (owner, 2026-10-06); until it has, the person owns it.
|
|
14437
|
+
external_exports.object({
|
|
14438
|
+
kind: external_exports.literal("create"),
|
|
14439
|
+
outcome: external_exports.string().min(1),
|
|
14440
|
+
title: external_exports.string().min(1).max(120),
|
|
14441
|
+
ownerId: participant2,
|
|
14442
|
+
parentGoal: ResultRefSchema2.nullable(),
|
|
14443
|
+
newSession: external_exports.literal(true).optional()
|
|
14444
|
+
}).strict(),
|
|
14445
|
+
...existingGoalChanges2
|
|
14446
|
+
]);
|
|
14447
|
+
var option2 = external_exports.object({ id: external_exports.string().min(1).max(40), label: external_exports.string().min(1), hint: external_exports.string().optional() }).strict();
|
|
14448
|
+
var QuestionChangeSchema2 = external_exports.union([
|
|
14449
|
+
external_exports.object({
|
|
14450
|
+
kind: external_exports.literal("create"),
|
|
14451
|
+
text: external_exports.string().min(1),
|
|
14452
|
+
answererId: participant2,
|
|
14453
|
+
goal: ResultRefSchema2.optional(),
|
|
14454
|
+
blocks: external_exports.array(external_exports.object({ question: ResultRefSchema2 }).strict()),
|
|
14455
|
+
options: external_exports.array(option2).min(2).optional(),
|
|
14456
|
+
pickMode: external_exports.enum(["one", "many", "rank"]).optional()
|
|
14457
|
+
}).strict().refine((c) => c.options === void 0 === (c.pickMode === void 0), "options and pickMode come together"),
|
|
14458
|
+
external_exports.object({ kind: external_exports.literal("edit"), questionId: id2, text: external_exports.string().min(1) }).strict(),
|
|
14459
|
+
external_exports.object({ kind: external_exports.literal("assign"), questionId: id2, answererId: participant2 }).strict(),
|
|
14460
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), questionId: id2 }).strict(),
|
|
14461
|
+
external_exports.object({ kind: external_exports.literal("dependency"), change: external_exports.enum(["add", "remove"]), edge: DependencySchema2 }).strict()
|
|
14462
|
+
]);
|
|
14463
|
+
var lessonScope2 = external_exports.union([
|
|
14464
|
+
external_exports.object({ kind: external_exports.literal("user") }).strict(),
|
|
14465
|
+
external_exports.object({ kind: external_exports.literal("goal"), goal: ResultRefSchema2 }).strict()
|
|
14466
|
+
]);
|
|
14467
|
+
var LessonChangeSchema2 = external_exports.union([
|
|
14468
|
+
external_exports.object({ kind: external_exports.literal("remember"), text: external_exports.string().min(1), scope: lessonScope2 }).strict(),
|
|
14469
|
+
external_exports.object({ kind: external_exports.literal("revise"), lessonId: id2, text: external_exports.string().min(1), scope: lessonScope2 }).strict(),
|
|
14470
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), lessonId: id2 }).strict()
|
|
14471
|
+
]);
|
|
14472
|
+
var BrainNextSchema2 = external_exports.object({
|
|
14473
|
+
instructions: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key2).min(1) }).strict()),
|
|
14474
|
+
say: external_exports.array(key2),
|
|
14475
|
+
then: external_exports.enum(["listen", "hold", "end", "none"]),
|
|
14476
|
+
waitFor: external_exports.array(ResultRefSchema2),
|
|
14477
|
+
reason: external_exports.string()
|
|
14478
|
+
}).strict();
|
|
14479
|
+
var messageBase2 = {
|
|
14480
|
+
key: key2,
|
|
14481
|
+
text: external_exports.string().min(1),
|
|
14482
|
+
goals: external_exports.array(ResultRefSchema2),
|
|
14483
|
+
questions: external_exports.array(ResultRefSchema2),
|
|
14484
|
+
entryKeys: external_exports.array(key2),
|
|
14485
|
+
obligationIds: external_exports.array(id2)
|
|
14486
|
+
};
|
|
14487
|
+
var BrainMessageSchema2 = external_exports.union([
|
|
14488
|
+
external_exports.object({ ...messageBase2, to: external_exports.object({ kind: external_exports.literal("user") }).strict() }).strict(),
|
|
14489
|
+
external_exports.object({
|
|
14490
|
+
...messageBase2,
|
|
14491
|
+
to: external_exports.object({ kind: external_exports.literal("agent"), agentId: external_exports.string().regex(/^agent:(?!paigy$)\S+$/) }).strict(),
|
|
14492
|
+
call: external_exports.object({ callId: id2, listen: external_exports.literal(true) }).strict().optional()
|
|
14493
|
+
}).strict()
|
|
14494
|
+
]);
|
|
14495
|
+
var BrainSearchSchema2 = external_exports.object({
|
|
14496
|
+
query: external_exports.string().min(1).max(500),
|
|
14497
|
+
within: external_exports.array(external_exports.enum(["entries", "goals", "answers"])).min(1),
|
|
14498
|
+
goalId: id2.optional()
|
|
14499
|
+
}).strict();
|
|
14500
|
+
var BrainResultSchema2 = external_exports.object({
|
|
14501
|
+
messages: external_exports.array(BrainMessageSchema2),
|
|
14502
|
+
entries: external_exports.array(external_exports.object({ key: key2, sources: external_exports.array(SourceSchema2).min(1), goals: external_exports.array(ResultRefSchema2) }).strict()),
|
|
14503
|
+
questions: external_exports.array(external_exports.object({ key: key2, entryKeys: external_exports.array(key2), change: QuestionChangeSchema2 }).strict()),
|
|
14504
|
+
answers: external_exports.array(external_exports.object({
|
|
14505
|
+
question: ResultRefSchema2,
|
|
14506
|
+
entryKeys: external_exports.array(key2).min(1),
|
|
14507
|
+
summary: external_exports.string().min(1),
|
|
14508
|
+
selectedOptionIds: external_exports.array(external_exports.string().min(1)).optional()
|
|
14509
|
+
}).strict()),
|
|
14510
|
+
goals: external_exports.array(external_exports.object({ key: key2, entryKeys: external_exports.array(key2), change: BrainGoalChangeSchema2 }).strict()),
|
|
14511
|
+
feedback: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key2).min(1) }).strict()),
|
|
14512
|
+
lessons: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key2).min(1), change: LessonChangeSchema2 }).strict()),
|
|
14513
|
+
next: BrainNextSchema2,
|
|
14514
|
+
search: BrainSearchSchema2.optional()
|
|
14515
|
+
}).strict();
|
|
14516
|
+
var str2 = external_exports.string();
|
|
14517
|
+
var strs2 = external_exports.array(external_exports.string());
|
|
14518
|
+
var CompactResultSchema2 = external_exports.object({
|
|
14519
|
+
next: external_exports.object({ say: strs2, then: external_exports.enum(["listen", "hold", "end", "none"]), waitFor: strs2, reason: str2, instructions: strs2 }).strict(),
|
|
14520
|
+
messages: external_exports.array(external_exports.object({ key: str2, to: str2, text: str2, about: strs2, entries: strs2, owed: strs2, inviteToCall: external_exports.boolean() }).strict()),
|
|
14521
|
+
entries: external_exports.array(external_exports.object({ key: str2, from: str2, on: strs2 }).strict()),
|
|
14522
|
+
answers: external_exports.array(external_exports.object({ question: str2, entries: strs2, summary: str2, picked: strs2 }).strict()),
|
|
14523
|
+
changes: external_exports.array(external_exports.object({
|
|
14524
|
+
key: str2,
|
|
14525
|
+
what: external_exports.enum(["goal", "question", "lesson"]),
|
|
14526
|
+
op: external_exports.enum(["create", "edit", "assign", "open", "complete", "cancel", "defer", "move", "block", "unblock", "withdraw", "remember", "revise"]),
|
|
14527
|
+
id: str2,
|
|
14528
|
+
text: str2,
|
|
14529
|
+
title: str2,
|
|
14530
|
+
who: str2,
|
|
14531
|
+
under: str2,
|
|
14532
|
+
gate: external_exports.enum(["start", "complete", "answer", "none"]),
|
|
14533
|
+
options: external_exports.array(external_exports.object({ id: str2, label: str2 }).strict()),
|
|
14534
|
+
pick: external_exports.enum(["one", "many", "rank", "words"]),
|
|
14535
|
+
entries: strs2
|
|
14536
|
+
}).strict()),
|
|
14537
|
+
feedback: external_exports.array(strs2),
|
|
14538
|
+
search: external_exports.object({ query: str2, within: strs2, goal: str2 }).strict()
|
|
14539
|
+
}).strict();
|
|
14540
|
+
var COMPACT_RESULT_JSON_SCHEMA2 = (({ $schema: _, ...rest }) => rest)(
|
|
14541
|
+
zodToJsonSchema2(CompactResultSchema2, { $refStrategy: "none" })
|
|
14542
|
+
);
|
|
14229
14543
|
function entryWords(entry) {
|
|
14230
14544
|
const content = entry.content;
|
|
14231
14545
|
if (content && "sealed" in content) return "";
|
|
@@ -14238,6 +14552,8 @@ function entryWords(entry) {
|
|
|
14238
14552
|
const description = plain.description;
|
|
14239
14553
|
const parts = [title, ...Array.isArray(description) ? description : []].filter((v) => typeof v === "string");
|
|
14240
14554
|
if (parts.length) return parts.join("\n\n");
|
|
14555
|
+
const line = plain.line;
|
|
14556
|
+
if (typeof line === "string" && line.trim()) return line;
|
|
14241
14557
|
}
|
|
14242
14558
|
return entry.sources.map((source) => source.text).join("\n");
|
|
14243
14559
|
}
|
|
@@ -14460,7 +14776,7 @@ var IntentSchema2 = external_exports.object({
|
|
|
14460
14776
|
* (`parseDelay`, #1292), and a value here simply wins over that reading. */
|
|
14461
14777
|
dueInSeconds: external_exports.number().int().positive().optional(),
|
|
14462
14778
|
/** Feedback only (#812): WHICH failure the complaint names — typed by the mapper that
|
|
14463
|
-
* already read the utterance, so `
|
|
14779
|
+
* already read the utterance, so `signals.kind` stops defaulting to
|
|
14464
14780
|
* 'other' on every row. A table that records that something was wrong and nothing
|
|
14465
14781
|
* about what cannot answer "is the bot looping less this week?". */
|
|
14466
14782
|
fault: external_exports.enum(["loop", "unanswered", "overridden", "misheard", "slow", "other"]).optional()
|
|
@@ -14744,7 +15060,18 @@ var InboxItemSchema2 = external_exports.object({
|
|
|
14744
15060
|
/** THAT GOAL'S NAME (#2416) — what Activity's row is headed by, since a row there is one Goal
|
|
14745
15061
|
* and the cards it holds sit behind it. Stamped by the same read as `goalState`. */
|
|
14746
15062
|
goalTitle: external_exports.string().optional()
|
|
14747
|
-
}).optional()
|
|
15063
|
+
}).optional(),
|
|
15064
|
+
/** WHAT THIS CARD IS, IN TWELVE CHARACTERS (#3019) — the hash of every other field on it, stamped
|
|
15065
|
+
* by the one read that serves the open list (`apps/api/src/inbox/project.ts` `inboxFor`). It is
|
|
15066
|
+
* how the incremental read knows a card has not moved: the phone echoes back the revs it holds
|
|
15067
|
+
* (`POST /api/inbox/changes`) and is sent only the cards whose rev differs.
|
|
15068
|
+
*
|
|
15069
|
+
* THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK — the same mechanism as `QueueItem.rev`
|
|
15070
|
+
* (#2928) and an entry's (#3018), for the same reason: a card shows facts no `updated_at` of its
|
|
15071
|
+
* own moves (its Goal's state and name, how cold the work behind it has gone, whether a ring is
|
|
15072
|
+
* live). Optional, so a fixture, the demo and the archive lens need not spell one, and a card
|
|
15073
|
+
* with no rev is simply always re-sent. */
|
|
15074
|
+
rev: external_exports.string().optional()
|
|
14748
15075
|
});
|
|
14749
15076
|
var APNS_TOKEN_RE2 = /^[0-9a-fA-F]{64}$/;
|
|
14750
15077
|
var PushTokenSchema2 = external_exports.object({
|
|
@@ -14956,39 +15283,22 @@ var ReassignResultSchema2 = external_exports.object({
|
|
|
14956
15283
|
moved: external_exports.object({ asks: external_exports.number(), answered: external_exports.number(), requests: external_exports.number(), goals: external_exports.number(), callbacks: external_exports.number() }),
|
|
14957
15284
|
parentId: external_exports.string().nullable()
|
|
14958
15285
|
});
|
|
14959
|
-
var
|
|
14960
|
-
var
|
|
15286
|
+
var LessonStateSchema2 = external_exports.enum(["active", "proposed", "retired"]);
|
|
15287
|
+
var LessonViewSchema2 = external_exports.object({
|
|
14961
15288
|
id: external_exports.string(),
|
|
14962
|
-
|
|
14963
|
-
|
|
14964
|
-
/** The
|
|
14965
|
-
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
rationale: external_exports.string().nullable(),
|
|
14969
|
-
/** Where the ruling lives: a repo/workspace, or 'global'. */
|
|
14970
|
-
scope: external_exports.string(),
|
|
14971
|
-
ring: MoveRingSchema2,
|
|
14972
|
-
/** True = the user pinned it with `always` (travel granted by hand, not by evidence). */
|
|
15289
|
+
text: external_exports.string(),
|
|
15290
|
+
state: LessonStateSchema2,
|
|
15291
|
+
/** The Goal it is scoped to; null = the whole account. */
|
|
15292
|
+
scopeGoalId: external_exports.string().nullable(),
|
|
15293
|
+
goalTitle: external_exports.string().nullable(),
|
|
15294
|
+
version: external_exports.number(),
|
|
14973
15295
|
pinned: external_exports.boolean(),
|
|
14974
|
-
/**
|
|
14975
|
-
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
14979
|
-
|
|
14980
|
-
lastUsedAt: external_exports.string().nullable(),
|
|
14981
|
-
/** How many asks it has answered. Instrumentation — deliberately NOT an input to the
|
|
14982
|
-
* evidence curve: firing says the question keeps arising, not that the ruling is right. */
|
|
14983
|
-
usedCount: external_exports.number(),
|
|
14984
|
-
/** Ledger: outcomes that said it held up. Saturating — the tenth is worth almost nothing. */
|
|
14985
|
-
confirms: external_exports.number(),
|
|
14986
|
-
/** Ledger: contradictions, in signal units (a full override = 1, weaker signals less).
|
|
14987
|
-
* Linear and priced above the entire confirmation budget, so any full counter wins. */
|
|
14988
|
-
counters: external_exports.number(),
|
|
14989
|
-
/** The agent that asked the question this move came from, when known. Null for a move
|
|
14990
|
-
* distilled from a clarify ruling (those carry no agent) or one whose source rows are gone. */
|
|
14991
|
-
learnedFrom: external_exports.object({ id: external_exports.string(), name: external_exports.string() }).nullable()
|
|
15296
|
+
/** When the person last wrote its text themselves. */
|
|
15297
|
+
editedAt: external_exports.string().nullable(),
|
|
15298
|
+
createdAt: external_exports.string(),
|
|
15299
|
+
updatedAt: external_exports.string(),
|
|
15300
|
+
/** The Entries it came from, oldest first; `words` is null when an Entry has none to show (sealed). */
|
|
15301
|
+
sources: external_exports.array(external_exports.object({ entryId: external_exports.string(), words: external_exports.string().nullable(), at: external_exports.string() }))
|
|
14992
15302
|
});
|
|
14993
15303
|
var QueueQuestionSchema2 = external_exports.object({
|
|
14994
15304
|
/** The decision need's id — what an answer is accepted against. */
|
|
@@ -15116,7 +15426,22 @@ var QueueItemSchema2 = external_exports.object({
|
|
|
15116
15426
|
* minute after the person speaks erases their instant from it, and the durable traces the client
|
|
15117
15427
|
* can see (`replies`, `questions[].answeredAt`) miss a spontaneous note entirely — a `request`
|
|
15118
15428
|
* Entry with no `about_id` is in neither. */
|
|
15119
|
-
lastPersonAt: external_exports.string().nullable().optional()
|
|
15429
|
+
lastPersonAt: external_exports.string().nullable().optional(),
|
|
15430
|
+
/** WHAT THIS ROW IS, IN TWELVE CHARACTERS (#2928) — the hash of every other field on it, stamped
|
|
15431
|
+
* by the one projection that builds the row (`apps/api/src/goal/queue.ts`). It is how the
|
|
15432
|
+
* incremental read knows a row has not moved: the phone echoes back the revs it holds
|
|
15433
|
+
* (`POST /api/goals/changes`) and is sent only the rows whose rev differs.
|
|
15434
|
+
*
|
|
15435
|
+
* IT IS THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK. Nothing here reasons about which
|
|
15436
|
+
* writes change which field — the comparison is over the bytes the phone is holding, so a fact
|
|
15437
|
+
* the row shows that no `updated_at` moves for (a lease lapsing, a dependency's state, a
|
|
15438
|
+
* sibling appearing in `childGoalIds`) cannot go unnoticed. Optional because a hand-built
|
|
15439
|
+
* queue (a fixture, the demo) spells none, and a row with no rev is simply always re-sent. */
|
|
15440
|
+
rev: external_exports.string().optional()
|
|
15441
|
+
});
|
|
15442
|
+
var QueueDeltaSchema2 = external_exports.object({
|
|
15443
|
+
ids: external_exports.array(external_exports.string()),
|
|
15444
|
+
items: external_exports.array(QueueItemSchema2)
|
|
15120
15445
|
});
|
|
15121
15446
|
var COLD_AFTER_MS2 = 3 * 24 * 60 * 60 * 1e3;
|
|
15122
15447
|
var NoteSourceSchema2 = external_exports.enum(["app", "call"]);
|
|
@@ -15287,6 +15612,11 @@ var DeviceTokenSchema2 = external_exports.object({
|
|
|
15287
15612
|
/** Local host recovery must preserve the launch's runtime and Paigy identity. */
|
|
15288
15613
|
harness: external_exports.enum(["claude", "codex", "agy"]).optional(),
|
|
15289
15614
|
session_id: external_exports.string().uuid().optional(),
|
|
15615
|
+
/** A conversation the host must not resume: its context is full, so every turn fails
|
|
15616
|
+
* ("Prompt is too long"). Written when a run hits it (`run.ts` `onFull`); the host skips a slot
|
|
15617
|
+
* whose resumable session is this one, so its Goals reach the dead-agent handoff instead of a
|
|
15618
|
+
* copy that types the person's words into a turn that cannot run (Calls, 2026-10-06). */
|
|
15619
|
+
full_session: external_exports.string().optional(),
|
|
15290
15620
|
uik_pub: external_exports.string().nullable().optional()
|
|
15291
15621
|
});
|
|
15292
15622
|
var SupportRequestSchema2 = external_exports.object({
|
|
@@ -15532,10 +15862,10 @@ var AcpDriver = class {
|
|
|
15532
15862
|
return this.flush();
|
|
15533
15863
|
}
|
|
15534
15864
|
/** Answer a PermissionEvent (ask mode). The id is the request's JSON-RPC id as a string. */
|
|
15535
|
-
respond(
|
|
15536
|
-
const request = this.pending.get(
|
|
15865
|
+
respond(id3, decision) {
|
|
15866
|
+
const request = this.pending.get(id3);
|
|
15537
15867
|
if (!request) return [];
|
|
15538
|
-
this.pending.delete(
|
|
15868
|
+
this.pending.delete(id3);
|
|
15539
15869
|
const optionId = optionFor(request.options, decision);
|
|
15540
15870
|
return [
|
|
15541
15871
|
optionId ? frame2({ id: request.id, result: { outcome: { outcome: "selected", optionId } } }) : frame2({ id: request.id, result: { outcome: { outcome: "cancelled" } } })
|
|
@@ -15689,7 +16019,7 @@ var AcpDriver = class {
|
|
|
15689
16019
|
writes: [frame2({ id: msg.id, error: { code: -32601, message: `Method not found: ${msg.method}` } })]
|
|
15690
16020
|
};
|
|
15691
16021
|
}
|
|
15692
|
-
const
|
|
16022
|
+
const id3 = msg.id;
|
|
15693
16023
|
const options = msg.params?.options ?? [];
|
|
15694
16024
|
const title = msg.params?.toolCall?.title?.trim() || "a tool call";
|
|
15695
16025
|
const tool = msg.params?.toolCall?.kind ?? "tool";
|
|
@@ -15700,21 +16030,21 @@ var AcpDriver = class {
|
|
|
15700
16030
|
// means "don't stall the agent", never "don't tell the user".
|
|
15701
16031
|
events: [{ kind: "turn", role: "agent", text: `auto-approved: ${title}`, tools: [tool] }],
|
|
15702
16032
|
writes: [
|
|
15703
|
-
optionId ? frame2({ id, result: { outcome: { outcome: "selected", optionId } } }) : frame2({ id, result: { outcome: { outcome: "cancelled" } } })
|
|
16033
|
+
optionId ? frame2({ id: id3, result: { outcome: { outcome: "selected", optionId } } }) : frame2({ id: id3, result: { outcome: { outcome: "cancelled" } } })
|
|
15704
16034
|
]
|
|
15705
16035
|
};
|
|
15706
16036
|
}
|
|
15707
|
-
this.pending.set(String(
|
|
16037
|
+
this.pending.set(String(id3), { id: id3, options });
|
|
15708
16038
|
return {
|
|
15709
|
-
events: [{ kind: "permission", id: String(
|
|
16039
|
+
events: [{ kind: "permission", id: String(id3), tool, summary: title }],
|
|
15710
16040
|
writes: []
|
|
15711
16041
|
};
|
|
15712
16042
|
}
|
|
15713
16043
|
/** The frame that opens the conversation: a resume of `resume` while there is one to try,
|
|
15714
16044
|
* else a new session. */
|
|
15715
|
-
opening(
|
|
16045
|
+
opening(id3) {
|
|
15716
16046
|
const params = { cwd: this.cwd, mcpServers: [], ...this.meta ? { _meta: this.meta } : {} };
|
|
15717
|
-
return this.resume ? { id, method: "session/resume", params: { sessionId: this.resume, ...params } } : { id, method: "session/new", params };
|
|
16047
|
+
return this.resume ? { id: id3, method: "session/resume", params: { sessionId: this.resume, ...params } } : { id: id3, method: "session/new", params };
|
|
15718
16048
|
}
|
|
15719
16049
|
/** Send the queued prompts as one turn, if the agent can take one right now. */
|
|
15720
16050
|
flush() {
|
|
@@ -15832,7 +16162,7 @@ function startSession(opts) {
|
|
|
15832
16162
|
}
|
|
15833
16163
|
const codexConfig = opts.harness === "codex" ? JSON.parse(process.env.CODEX_CONFIG || "{}") : null;
|
|
15834
16164
|
if (codexConfig) {
|
|
15835
|
-
const
|
|
16165
|
+
const key3 = "mcp_servers.paigy.env_vars";
|
|
15836
16166
|
const configPath = join9(process.env.CODEX_HOME || join9(homedir9(), ".codex"), "config.toml");
|
|
15837
16167
|
const saved = existsSync4(configPath) ? readFileSync5(configPath, "utf8") : "";
|
|
15838
16168
|
const registered = /\[mcp_servers\.paigy\][\s\S]*?(?=\n\[|$)/.exec(saved)?.[0];
|
|
@@ -15843,7 +16173,7 @@ function startSession(opts) {
|
|
|
15843
16173
|
}
|
|
15844
16174
|
const savedVars = registered?.match(/env_vars\s*=\s*\[([\s\S]*?)\]/)?.[1] ?? "";
|
|
15845
16175
|
const inherited = [...savedVars.matchAll(/["']([A-Za-z_][A-Za-z0-9_]*)["']/g)].map((match) => match[1]);
|
|
15846
|
-
codexConfig[
|
|
16176
|
+
codexConfig[key3] = [.../* @__PURE__ */ new Set([...inherited, ...codexConfig[key3] ?? codexConfig.mcp_servers?.paigy?.env_vars ?? [], ...CODEX_ENV])];
|
|
15847
16177
|
}
|
|
15848
16178
|
const child = (opts.spawnFn ?? spawn)(opts.bin ?? ADAPTER_BIN[opts.harness], [], {
|
|
15849
16179
|
cwd,
|
|
@@ -15919,8 +16249,8 @@ function startSession(opts) {
|
|
|
15919
16249
|
send(text) {
|
|
15920
16250
|
write(driver.send(text));
|
|
15921
16251
|
},
|
|
15922
|
-
respond(
|
|
15923
|
-
write(driver.respond(
|
|
16252
|
+
respond(id3, decision) {
|
|
16253
|
+
write(driver.respond(id3, decision));
|
|
15924
16254
|
},
|
|
15925
16255
|
stop() {
|
|
15926
16256
|
write(driver.close());
|
|
@@ -16140,17 +16470,31 @@ async function finish(result, state, rail, opts) {
|
|
|
16140
16470
|
}
|
|
16141
16471
|
async function cannotWork(report, state, rail, opts) {
|
|
16142
16472
|
state.resting = true;
|
|
16473
|
+
const say = (parentId) => rail.contact({ asks: [{ ask: report, ...parentId ? { parentId } : {} }], waiting: "none", channel: "notification" });
|
|
16143
16474
|
try {
|
|
16144
16475
|
if (!state.goal) {
|
|
16145
|
-
const claimed = await rail.claim();
|
|
16146
|
-
if (
|
|
16147
|
-
|
|
16476
|
+
const claimed = await rail.claim().catch(() => void 0);
|
|
16477
|
+
if (claimed?.goalId && claimed.revision !== void 0) state.goal = { id: claimed.goalId, revision: claimed.revision };
|
|
16478
|
+
}
|
|
16479
|
+
if (!state.goal) {
|
|
16480
|
+
await say();
|
|
16481
|
+
return;
|
|
16482
|
+
}
|
|
16483
|
+
try {
|
|
16484
|
+
await say(state.goal.id);
|
|
16485
|
+
} catch (error) {
|
|
16486
|
+
if (!/goal_parent_invalid/.test(error.message)) throw error;
|
|
16487
|
+
opts?.log?.(`\u26A0 the held Goal ${state.goal.id.slice(0, 8)} refused the notice (goal_parent_invalid) \u2014 saying it unplaced`);
|
|
16488
|
+
await say();
|
|
16148
16489
|
}
|
|
16149
|
-
await rail.contact({ asks: [{ ask: report, parentId: state.goal.id }], waiting: "none", channel: "notification" });
|
|
16150
16490
|
} catch (error) {
|
|
16151
16491
|
opts?.log?.(`\u26A0 could not say the agent cannot work: ${error.message}`);
|
|
16152
16492
|
}
|
|
16153
16493
|
}
|
|
16494
|
+
function conversationFull(result) {
|
|
16495
|
+
return /prompt is too long/i.test(result ?? "");
|
|
16496
|
+
}
|
|
16497
|
+
var FULL_NOTICE = "This agent's conversation is full, so it can no longer take a turn. Its session has ended and will not be resumed; its Goals go to the dead-agent handoff.";
|
|
16154
16498
|
async function afterTurn(event, state, rail, opts) {
|
|
16155
16499
|
if (event.failed) {
|
|
16156
16500
|
const limit = limitIn(event.result, (opts?.now ?? Date.now)());
|
|
@@ -16163,6 +16507,11 @@ async function afterTurn(event, state, rail, opts) {
|
|
|
16163
16507
|
opts?.log?.(`\u23F8 paused by the usage limit until ${limit.resets}: nothing is typed in until then, and it carries on by itself`);
|
|
16164
16508
|
return limit;
|
|
16165
16509
|
}
|
|
16510
|
+
if (conversationFull(event.result)) {
|
|
16511
|
+
if (!state.full) await cannotWork(FULL_NOTICE, state, rail, opts);
|
|
16512
|
+
state.full = true;
|
|
16513
|
+
return void 0;
|
|
16514
|
+
}
|
|
16166
16515
|
await cannotWork(`The agent stopped without finishing.
|
|
16167
16516
|
|
|
16168
16517
|
${event.result?.trim() || "No result reported."}`, state, rail, opts);
|
|
@@ -16232,9 +16581,9 @@ function unheard(brief, state, since = null, after = -1, reviewSince) {
|
|
|
16232
16581
|
if (text) words2.push(text);
|
|
16233
16582
|
}
|
|
16234
16583
|
if (pendingAt !== null) for (const answer of brief.answers ?? []) {
|
|
16235
|
-
const
|
|
16236
|
-
if (seen.has(
|
|
16237
|
-
seen.add(
|
|
16584
|
+
const key3 = `answer:${answer.decisionNeedId}`;
|
|
16585
|
+
if (seen.has(key3) || Date.parse(answer.acceptedAt) < pendingAt) continue;
|
|
16586
|
+
seen.add(key3);
|
|
16238
16587
|
words2.push(`Answer to question ${answer.decisionNeedId}: ${JSON.stringify(answer.result)}`);
|
|
16239
16588
|
}
|
|
16240
16589
|
return words2;
|
|
@@ -16279,16 +16628,16 @@ async function gather(state, rail, held) {
|
|
|
16279
16628
|
const listed = /* @__PURE__ */ new Set();
|
|
16280
16629
|
const announced = state.announced ??= /* @__PURE__ */ new Set();
|
|
16281
16630
|
if (waiting) {
|
|
16282
|
-
for (const
|
|
16631
|
+
for (const id3 of announced) if (!(waiting.assigned ?? []).some((g) => g.goalId === id3)) announced.delete(id3);
|
|
16283
16632
|
}
|
|
16284
16633
|
for (const g of waiting?.assigned ?? []) if (g.goalId !== state.goal.id && !announced.has(g.goalId)) look2(g.goalId, "assigned", g.title);
|
|
16285
16634
|
for (const g of waiting?.review ?? []) {
|
|
16286
16635
|
listed.add(g.goalId);
|
|
16287
16636
|
look2(g.goalId, "waiting work", g.title);
|
|
16288
16637
|
}
|
|
16289
|
-
for (const d of waiting?.deliveries ?? []) for (const
|
|
16290
|
-
listed.add(
|
|
16291
|
-
look2(
|
|
16638
|
+
for (const d of waiting?.deliveries ?? []) for (const id3 of d.goalIds) {
|
|
16639
|
+
listed.add(id3);
|
|
16640
|
+
look2(id3, "waiting work");
|
|
16292
16641
|
}
|
|
16293
16642
|
const moved = movedBelow(held, state);
|
|
16294
16643
|
for (const { goal, since } of moved) look2(goal.goalId, "subtree", goal.title, since);
|
|
@@ -16326,7 +16675,7 @@ var block = (h) => [
|
|
|
16326
16675
|
...h.note ? [`The last note on it, from the agent before you: ${h.note}`] : [],
|
|
16327
16676
|
...h.words
|
|
16328
16677
|
].join("\n\n");
|
|
16329
|
-
var short = (ids) => ids.map((
|
|
16678
|
+
var short = (ids) => ids.map((id3) => id3.slice(0, 8)).join(", ");
|
|
16330
16679
|
var given = (heard) => heard.filter((h) => h.via === "assigned").map((h) => h.goalId);
|
|
16331
16680
|
async function hear(session, state, rail, held, opts) {
|
|
16332
16681
|
const log2 = opts?.log;
|
|
@@ -16590,7 +16939,12 @@ ${event.message}`, state, rail, { log: opts.log });
|
|
|
16590
16939
|
tail = [];
|
|
16591
16940
|
const carried = state.carriedOn && !event.failed;
|
|
16592
16941
|
if (await afterTurn(event, state, rail, { log: opts.log })) LIMITS.paused(name, Date.now());
|
|
16593
|
-
else if (
|
|
16942
|
+
else if (state.full) {
|
|
16943
|
+
opts.log(`\u25A0 ${name}'s conversation is full \u2014 ending this run; it will not be resumed`);
|
|
16944
|
+
opts.onFull?.(speaksAs);
|
|
16945
|
+
stop2();
|
|
16946
|
+
return;
|
|
16947
|
+
} else if (carried) runningAgain();
|
|
16594
16948
|
clock4.nudge("rest");
|
|
16595
16949
|
}
|
|
16596
16950
|
}
|
|
@@ -16751,26 +17105,33 @@ var claimedRun = (sessionId2) => {
|
|
|
16751
17105
|
return { slot, key: runKey(slot) };
|
|
16752
17106
|
};
|
|
16753
17107
|
var launchRun = (spec) => ({ session: spec.sessionId });
|
|
17108
|
+
var BOUND_ELSEWHERE_MS = 10 * 6e4;
|
|
17109
|
+
var boundElsewhere = /* @__PURE__ */ new Map();
|
|
17110
|
+
var BOUND_SKIP = "is bound to the session it was paired in, which this host cannot name \u2014 run `paigy-harness handoff` as it, in its folder, to record it";
|
|
16754
17111
|
var NOTHING_WAITING = "has nothing waiting";
|
|
16755
17112
|
async function waitingWork(token, session) {
|
|
17113
|
+
const quiet = boundElsewhere.get(token);
|
|
17114
|
+
if (quiet !== void 0 && Date.now() < quiet) return { skip: BOUND_SKIP };
|
|
16756
17115
|
let found;
|
|
16757
17116
|
try {
|
|
16758
17117
|
found = await checkReplies({ token, ...session ? { reach: reachAs(session) } : {} });
|
|
16759
17118
|
} catch (error) {
|
|
16760
17119
|
if (error instanceof RevokedError) return { skip: "was revoked: its credential is gone for good", revoked: true };
|
|
16761
17120
|
if (error instanceof ApiError && error.body?.error === "identity_session_mismatch") {
|
|
16762
|
-
|
|
17121
|
+
boundElsewhere.set(token, Date.now() + BOUND_ELSEWHERE_MS);
|
|
17122
|
+
return { skip: BOUND_SKIP };
|
|
16763
17123
|
}
|
|
16764
17124
|
return { skip: `could not read what is waiting (${error.message})` };
|
|
16765
17125
|
}
|
|
17126
|
+
boundElsewhere.delete(token);
|
|
16766
17127
|
const next = found.claimable;
|
|
16767
17128
|
const about = next ? { goalId: next.goalId, ...next.since ? { since: next.since } : {} } : {};
|
|
16768
17129
|
const n = found.deliveries.length;
|
|
16769
17130
|
if (n) return { waiting: n === 1 ? "a message" : `${n} messages`, ...about };
|
|
16770
17131
|
return next ? { waiting: `Goal ${next.goalId.slice(0, 8)}${next.title ? ` "${next.title}"` : ""}`, ...about } : { skip: NOTHING_WAITING };
|
|
16771
17132
|
}
|
|
16772
|
-
function evict(runs,
|
|
16773
|
-
if (runs.get(
|
|
17133
|
+
function evict(runs, key3, run) {
|
|
17134
|
+
if (runs.get(key3)?.run === run) runs.delete(key3);
|
|
16774
17135
|
}
|
|
16775
17136
|
var PRESENCE_FRESH_MS = 3 * 6e4;
|
|
16776
17137
|
var IDLE_HOLDER_MS = 30 * 6e4;
|
|
@@ -16813,9 +17174,9 @@ function startHost(opts) {
|
|
|
16813
17174
|
const agent2 = slotIdentity(slot).tokenId;
|
|
16814
17175
|
if (!agent2) return;
|
|
16815
17176
|
const goalId = found?.goalId;
|
|
16816
|
-
const
|
|
16817
|
-
if (recorded.get(slot) ===
|
|
16818
|
-
recorded.set(slot,
|
|
17177
|
+
const key3 = `${decision}:${goalId ?? ""}`;
|
|
17178
|
+
if (recorded.get(slot) === key3) return;
|
|
17179
|
+
recorded.set(slot, key3);
|
|
16819
17180
|
void recordDecision({
|
|
16820
17181
|
agent: agent2,
|
|
16821
17182
|
decision,
|
|
@@ -16865,7 +17226,7 @@ function startHost(opts) {
|
|
|
16865
17226
|
const specs = await claimSessions(asHost).catch(() => []);
|
|
16866
17227
|
for (const spec of specs) {
|
|
16867
17228
|
const label = spec.name ?? spec.harness;
|
|
16868
|
-
const { slot, key } = claimedRun(spec.sessionId);
|
|
17229
|
+
const { slot, key: key3 } = claimedRun(spec.sessionId);
|
|
16869
17230
|
const log2 = (line) => opts.log(`[${label}] ${line}`);
|
|
16870
17231
|
try {
|
|
16871
17232
|
saveToken({
|
|
@@ -16888,14 +17249,17 @@ function startHost(opts) {
|
|
|
16888
17249
|
token: spec.token,
|
|
16889
17250
|
...launchRun(spec),
|
|
16890
17251
|
onExit: () => {
|
|
16891
|
-
evict(runs,
|
|
17252
|
+
evict(runs, key3, run);
|
|
16892
17253
|
goneAt.set(slot, Date.now());
|
|
16893
17254
|
opts.log(`\u2716 ${label} ended`);
|
|
16894
17255
|
},
|
|
17256
|
+
onFull: (session) => {
|
|
17257
|
+
updateSlot(slot, { full_session: session });
|
|
17258
|
+
},
|
|
16895
17259
|
name: label,
|
|
16896
17260
|
log: log2
|
|
16897
17261
|
});
|
|
16898
|
-
runs.set(
|
|
17262
|
+
runs.set(key3, { run, label, token: spec.token });
|
|
16899
17263
|
void heartbeat(void 0, { token: spec.token }).catch(() => {
|
|
16900
17264
|
});
|
|
16901
17265
|
void refreshIdentities();
|
|
@@ -16947,9 +17311,9 @@ function startHost(opts) {
|
|
|
16947
17311
|
let lastHolders = /* @__PURE__ */ new Map();
|
|
16948
17312
|
async function wakeSlot(slot, { presence, holders }, cause = "sweep") {
|
|
16949
17313
|
{
|
|
16950
|
-
const
|
|
17314
|
+
const key3 = runKey(slot);
|
|
16951
17315
|
if (slot === "Desktop" || isRevoked(slot)) return;
|
|
16952
|
-
const live = runs.get(
|
|
17316
|
+
const live = runs.get(key3);
|
|
16953
17317
|
if (live) {
|
|
16954
17318
|
const theirs = (localHolderPids().get(slot) ?? []).map((p) => p.pid).filter((pid) => !descendsFrom(pid, process.pid));
|
|
16955
17319
|
if (theirs.length) {
|
|
@@ -16984,6 +17348,11 @@ function startHost(opts) {
|
|
|
16984
17348
|
}
|
|
16985
17349
|
const identity = slotIdentity(slot);
|
|
16986
17350
|
const owner = !identity.harness || identity.harness === "claude" ? ownerSession(slot) : null;
|
|
17351
|
+
const resumes = owner?.sessionId ?? identity.sessionId;
|
|
17352
|
+
if (resumes && identity.fullSession === resumes) {
|
|
17353
|
+
skip(`has a full conversation (${resumes.slice(0, 8)}) \u2014 not resuming it; its Goals go to the dead-agent handoff`);
|
|
17354
|
+
return;
|
|
17355
|
+
}
|
|
16987
17356
|
const read = async () => {
|
|
16988
17357
|
const got = await waitingWork(token, identity.sessionId ?? owner?.sessionId);
|
|
16989
17358
|
if (!("skip" in got)) return got;
|
|
@@ -17024,7 +17393,7 @@ function startHost(opts) {
|
|
|
17024
17393
|
}
|
|
17025
17394
|
found ??= await read() ?? void 0;
|
|
17026
17395
|
if (!found) return;
|
|
17027
|
-
if (runs.has(
|
|
17396
|
+
if (runs.has(key3)) {
|
|
17028
17397
|
skip("was started by the wake that read it first");
|
|
17029
17398
|
return;
|
|
17030
17399
|
}
|
|
@@ -17040,14 +17409,17 @@ function startHost(opts) {
|
|
|
17040
17409
|
// A dead run must not squat the slot — evict so the next wake can respawn. Only ITS entry:
|
|
17041
17410
|
// a run that is no longer the slot's must not take the live one's place away with it.
|
|
17042
17411
|
onExit: () => {
|
|
17043
|
-
evict(runs,
|
|
17412
|
+
evict(runs, key3, run);
|
|
17044
17413
|
goneAt.set(slot, Date.now());
|
|
17045
17414
|
opts.log(`\u2716 ${label} ended`);
|
|
17046
17415
|
},
|
|
17416
|
+
onFull: (session) => {
|
|
17417
|
+
updateSlot(slot, { full_session: session });
|
|
17418
|
+
},
|
|
17047
17419
|
name: label,
|
|
17048
17420
|
log: log2
|
|
17049
17421
|
});
|
|
17050
|
-
runs.set(
|
|
17422
|
+
runs.set(key3, { run, label, token });
|
|
17051
17423
|
void heartbeat(void 0, { token }).catch(() => {
|
|
17052
17424
|
});
|
|
17053
17425
|
const woke = `\u25B6 ${owner ? "resumed" : "woke"} ${label} (${harness}) \u2014 ${found.waiting} was waiting, in ${workspace}${decided.why === "gone" ? " (its process here ended; its last heartbeat was not waited out)" : taking}`;
|
|
@@ -17100,17 +17472,17 @@ function startHost(opts) {
|
|
|
17100
17472
|
void heartbeat(void 0, { token, activity: { lines: lines2, at: (/* @__PURE__ */ new Date()).toISOString() } }).catch(() => {
|
|
17101
17473
|
});
|
|
17102
17474
|
};
|
|
17103
|
-
for (const [
|
|
17475
|
+
for (const [key3, r] of runs) {
|
|
17104
17476
|
if (!r.token) continue;
|
|
17105
17477
|
const lines2 = r.run.tail();
|
|
17106
|
-
const was = published.get(
|
|
17478
|
+
const was = published.get(key3);
|
|
17107
17479
|
if (was && sameTail(was.lines, lines2)) continue;
|
|
17108
|
-
published.set(
|
|
17480
|
+
published.set(key3, { token: r.token, lines: lines2 });
|
|
17109
17481
|
publishTail(r.token, lines2);
|
|
17110
17482
|
}
|
|
17111
|
-
for (const [
|
|
17112
|
-
if (runs.has(
|
|
17113
|
-
published.delete(
|
|
17483
|
+
for (const [key3, was] of published) {
|
|
17484
|
+
if (runs.has(key3)) continue;
|
|
17485
|
+
published.delete(key3);
|
|
17114
17486
|
if (was.lines.length > 0) publishTail(was.token, []);
|
|
17115
17487
|
}
|
|
17116
17488
|
};
|
|
@@ -17141,25 +17513,25 @@ function startHost(opts) {
|
|
|
17141
17513
|
})));
|
|
17142
17514
|
};
|
|
17143
17515
|
const api = {
|
|
17144
|
-
sessions: () => [...runs.entries()].map(([
|
|
17516
|
+
sessions: () => [...runs.entries()].map(([id3, r]) => [id3, r.label]),
|
|
17145
17517
|
// Every identity this machine holds, plus what it's doing right now. Slots are the
|
|
17146
17518
|
// roster (hatched agents, the terminal tools, claimed sessions); a run makes one of
|
|
17147
17519
|
// them live, and a run mid-turn makes it working.
|
|
17148
17520
|
roster: () => {
|
|
17149
17521
|
const live = new Map([...runs.values()].map((r) => [r.label, r.run]));
|
|
17150
17522
|
const names2 = /* @__PURE__ */ new Map();
|
|
17151
|
-
for (const
|
|
17523
|
+
for (const key3 of listSlots()) if (key3 !== "Desktop" && !isRevoked(key3)) names2.set(slotName(key3) ?? key3, key3);
|
|
17152
17524
|
for (const label of live.keys()) if (!names2.has(label)) names2.set(label, null);
|
|
17153
17525
|
return [...names2.entries()].map(([name, slot]) => {
|
|
17154
|
-
const
|
|
17526
|
+
const id3 = slot ? slotIdentity(slot) : { voice: null, tokenId: null };
|
|
17155
17527
|
return {
|
|
17156
17528
|
name,
|
|
17157
17529
|
// The slot key rides along so the window's agent page can speak AS this agent —
|
|
17158
17530
|
// its pending reads (`checkReplies`, the same pure read the sweep does) need the
|
|
17159
17531
|
// slot's own token, and the display name is not a key.
|
|
17160
17532
|
slot,
|
|
17161
|
-
tokenId:
|
|
17162
|
-
voice:
|
|
17533
|
+
tokenId: id3.tokenId,
|
|
17534
|
+
voice: id3.voice,
|
|
17163
17535
|
// RUNNING IS ABOUT THE IDENTITY, NOT ABOUT US (owner, 2026-09-14). This was
|
|
17164
17536
|
// `live.has(name)` — "this host spawned it and it has not exited" — which is a fact
|
|
17165
17537
|
// about our own process table, not about the agent. An ordinary terminal session
|
|
@@ -17167,7 +17539,7 @@ function startHost(opts) {
|
|
|
17167
17539
|
// sessions we started ourselves. The server already knows: `last_seen_at` on the
|
|
17168
17540
|
// agent's own token, the same evidence `wakeAction` stands back for. So: a run we
|
|
17169
17541
|
// hold, OR a process the server heard from inside `PRESENCE_FRESH_MS`.
|
|
17170
|
-
running: live.has(name) || !!slot && lastHolders.has(slot) || !!
|
|
17542
|
+
running: live.has(name) || !!slot && lastHolders.has(slot) || !!id3.tokenId && Date.now() - (lastPresence.get(id3.tokenId) ?? 0) < PRESENCE_FRESH_MS,
|
|
17171
17543
|
// `working` stays ours alone — it means a run WE hold is mid-turn, which is the only
|
|
17172
17544
|
// thing a tail can tell us. A process we did not spawn has no tail here to read.
|
|
17173
17545
|
working: live.get(name)?.working() ?? false
|
|
@@ -17349,11 +17721,11 @@ ipcMain.handle("paigy:triage-accept", async (_e, opts) => {
|
|
|
17349
17721
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
17350
17722
|
}
|
|
17351
17723
|
});
|
|
17352
|
-
ipcMain.handle("paigy:triage-dismiss", async (_e,
|
|
17724
|
+
ipcMain.handle("paigy:triage-dismiss", async (_e, id3) => {
|
|
17353
17725
|
const token = deviceToken();
|
|
17354
17726
|
if (!token) return { ok: false, error: "This Mac isn't paired yet." };
|
|
17355
17727
|
try {
|
|
17356
|
-
await dismissTriage(
|
|
17728
|
+
await dismissTriage(id3, { token });
|
|
17357
17729
|
return { ok: true };
|
|
17358
17730
|
} catch (e) {
|
|
17359
17731
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|