@paigy/harness 0.3.31 → 0.3.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/dist/cli.js +966 -464
- package/dist/main.js +733 -271
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -24,9 +24,9 @@ var __export = (target, all) => {
|
|
|
24
24
|
};
|
|
25
25
|
var __copyProps = (to, from, except, desc) => {
|
|
26
26
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
27
|
-
for (let
|
|
28
|
-
if (!__hasOwnProp.call(to,
|
|
29
|
-
__defProp(to,
|
|
27
|
+
for (let key3 of __getOwnPropNames(from))
|
|
28
|
+
if (!__hasOwnProp.call(to, key3) && key3 !== except)
|
|
29
|
+
__defProp(to, key3, { get: () => from[key3], enumerable: !(desc = __getOwnPropDesc(from, key3)) || desc.enumerable });
|
|
30
30
|
}
|
|
31
31
|
return to;
|
|
32
32
|
};
|
|
@@ -172,9 +172,9 @@ var init_util = __esm({
|
|
|
172
172
|
};
|
|
173
173
|
util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
|
|
174
174
|
const keys = [];
|
|
175
|
-
for (const
|
|
176
|
-
if (Object.prototype.hasOwnProperty.call(object,
|
|
177
|
-
keys.push(
|
|
175
|
+
for (const key3 in object) {
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(object, key3)) {
|
|
177
|
+
keys.push(key3);
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
return keys;
|
|
@@ -603,10 +603,10 @@ var init_parseUtil = __esm({
|
|
|
603
603
|
static async mergeObjectAsync(status, pairs) {
|
|
604
604
|
const syncPairs = [];
|
|
605
605
|
for (const pair of pairs) {
|
|
606
|
-
const
|
|
606
|
+
const key3 = await pair.key;
|
|
607
607
|
const value = await pair.value;
|
|
608
608
|
syncPairs.push({
|
|
609
|
-
key,
|
|
609
|
+
key: key3,
|
|
610
610
|
value
|
|
611
611
|
});
|
|
612
612
|
}
|
|
@@ -615,17 +615,17 @@ var init_parseUtil = __esm({
|
|
|
615
615
|
static mergeObjectSync(status, pairs) {
|
|
616
616
|
const finalObject = {};
|
|
617
617
|
for (const pair of pairs) {
|
|
618
|
-
const { key, value } = pair;
|
|
619
|
-
if (
|
|
618
|
+
const { key: key3, value } = pair;
|
|
619
|
+
if (key3.status === "aborted")
|
|
620
620
|
return INVALID;
|
|
621
621
|
if (value.status === "aborted")
|
|
622
622
|
return INVALID;
|
|
623
|
-
if (
|
|
623
|
+
if (key3.status === "dirty")
|
|
624
624
|
status.dirty();
|
|
625
625
|
if (value.status === "dirty")
|
|
626
626
|
status.dirty();
|
|
627
|
-
if (
|
|
628
|
-
finalObject[
|
|
627
|
+
if (key3.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
|
|
628
|
+
finalObject[key3.value] = value.value;
|
|
629
629
|
}
|
|
630
630
|
}
|
|
631
631
|
return { status: status.value, value: finalObject };
|
|
@@ -759,9 +759,9 @@ function floatSafeRemainder(val, step2) {
|
|
|
759
759
|
function deepPartialify(schema) {
|
|
760
760
|
if (schema instanceof ZodObject) {
|
|
761
761
|
const newShape = {};
|
|
762
|
-
for (const
|
|
763
|
-
const fieldSchema = schema.shape[
|
|
764
|
-
newShape[
|
|
762
|
+
for (const key3 in schema.shape) {
|
|
763
|
+
const fieldSchema = schema.shape[key3];
|
|
764
|
+
newShape[key3] = ZodOptional.create(deepPartialify(fieldSchema));
|
|
765
765
|
}
|
|
766
766
|
return new ZodObject({
|
|
767
767
|
...schema._def,
|
|
@@ -789,14 +789,14 @@ function mergeValues(a, b) {
|
|
|
789
789
|
return { valid: true, data: a };
|
|
790
790
|
} else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
|
|
791
791
|
const bKeys = util.objectKeys(b);
|
|
792
|
-
const sharedKeys = util.objectKeys(a).filter((
|
|
792
|
+
const sharedKeys = util.objectKeys(a).filter((key3) => bKeys.indexOf(key3) !== -1);
|
|
793
793
|
const newObj = { ...a, ...b };
|
|
794
|
-
for (const
|
|
795
|
-
const sharedValue = mergeValues(a[
|
|
794
|
+
for (const key3 of sharedKeys) {
|
|
795
|
+
const sharedValue = mergeValues(a[key3], b[key3]);
|
|
796
796
|
if (!sharedValue.valid) {
|
|
797
797
|
return { valid: false };
|
|
798
798
|
}
|
|
799
|
-
newObj[
|
|
799
|
+
newObj[key3] = sharedValue.data;
|
|
800
800
|
}
|
|
801
801
|
return { valid: true, data: newObj };
|
|
802
802
|
} else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
|
|
@@ -864,12 +864,12 @@ var init_types = __esm({
|
|
|
864
864
|
init_parseUtil();
|
|
865
865
|
init_util();
|
|
866
866
|
ParseInputLazyPath = class {
|
|
867
|
-
constructor(parent, value, path,
|
|
867
|
+
constructor(parent, value, path, key3) {
|
|
868
868
|
this._cachedPath = [];
|
|
869
869
|
this.parent = parent;
|
|
870
870
|
this.data = value;
|
|
871
871
|
this._path = path;
|
|
872
|
-
this._key =
|
|
872
|
+
this._key = key3;
|
|
873
873
|
}
|
|
874
874
|
get path() {
|
|
875
875
|
if (!this._cachedPath.length) {
|
|
@@ -1125,8 +1125,8 @@ var init_types = __esm({
|
|
|
1125
1125
|
promise() {
|
|
1126
1126
|
return ZodPromise.create(this, this._def);
|
|
1127
1127
|
}
|
|
1128
|
-
or(
|
|
1129
|
-
return ZodUnion.create([this,
|
|
1128
|
+
or(option3) {
|
|
1129
|
+
return ZodUnion.create([this, option3], this._def);
|
|
1130
1130
|
}
|
|
1131
1131
|
and(incoming) {
|
|
1132
1132
|
return ZodIntersection.create(this, incoming, this._def);
|
|
@@ -2547,29 +2547,29 @@ var init_types = __esm({
|
|
|
2547
2547
|
const { shape, keys: shapeKeys } = this._getCached();
|
|
2548
2548
|
const extraKeys = [];
|
|
2549
2549
|
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
|
2550
|
-
for (const
|
|
2551
|
-
if (!shapeKeys.includes(
|
|
2552
|
-
extraKeys.push(
|
|
2550
|
+
for (const key3 in ctx.data) {
|
|
2551
|
+
if (!shapeKeys.includes(key3)) {
|
|
2552
|
+
extraKeys.push(key3);
|
|
2553
2553
|
}
|
|
2554
2554
|
}
|
|
2555
2555
|
}
|
|
2556
2556
|
const pairs = [];
|
|
2557
|
-
for (const
|
|
2558
|
-
const keyValidator = shape[
|
|
2559
|
-
const value = ctx.data[
|
|
2557
|
+
for (const key3 of shapeKeys) {
|
|
2558
|
+
const keyValidator = shape[key3];
|
|
2559
|
+
const value = ctx.data[key3];
|
|
2560
2560
|
pairs.push({
|
|
2561
|
-
key: { status: "valid", value:
|
|
2562
|
-
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path,
|
|
2563
|
-
alwaysSet:
|
|
2561
|
+
key: { status: "valid", value: key3 },
|
|
2562
|
+
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key3)),
|
|
2563
|
+
alwaysSet: key3 in ctx.data
|
|
2564
2564
|
});
|
|
2565
2565
|
}
|
|
2566
2566
|
if (this._def.catchall instanceof ZodNever) {
|
|
2567
2567
|
const unknownKeys = this._def.unknownKeys;
|
|
2568
2568
|
if (unknownKeys === "passthrough") {
|
|
2569
|
-
for (const
|
|
2569
|
+
for (const key3 of extraKeys) {
|
|
2570
2570
|
pairs.push({
|
|
2571
|
-
key: { status: "valid", value:
|
|
2572
|
-
value: { status: "valid", value: ctx.data[
|
|
2571
|
+
key: { status: "valid", value: key3 },
|
|
2572
|
+
value: { status: "valid", value: ctx.data[key3] }
|
|
2573
2573
|
});
|
|
2574
2574
|
}
|
|
2575
2575
|
} else if (unknownKeys === "strict") {
|
|
@@ -2586,15 +2586,15 @@ var init_types = __esm({
|
|
|
2586
2586
|
}
|
|
2587
2587
|
} else {
|
|
2588
2588
|
const catchall = this._def.catchall;
|
|
2589
|
-
for (const
|
|
2590
|
-
const value = ctx.data[
|
|
2589
|
+
for (const key3 of extraKeys) {
|
|
2590
|
+
const value = ctx.data[key3];
|
|
2591
2591
|
pairs.push({
|
|
2592
|
-
key: { status: "valid", value:
|
|
2592
|
+
key: { status: "valid", value: key3 },
|
|
2593
2593
|
value: catchall._parse(
|
|
2594
|
-
new ParseInputLazyPath(ctx, value, ctx.path,
|
|
2594
|
+
new ParseInputLazyPath(ctx, value, ctx.path, key3)
|
|
2595
2595
|
//, ctx.child(key), value, getParsedType(value)
|
|
2596
2596
|
),
|
|
2597
|
-
alwaysSet:
|
|
2597
|
+
alwaysSet: key3 in ctx.data
|
|
2598
2598
|
});
|
|
2599
2599
|
}
|
|
2600
2600
|
}
|
|
@@ -2602,10 +2602,10 @@ var init_types = __esm({
|
|
|
2602
2602
|
return Promise.resolve().then(async () => {
|
|
2603
2603
|
const syncPairs = [];
|
|
2604
2604
|
for (const pair of pairs) {
|
|
2605
|
-
const
|
|
2605
|
+
const key3 = await pair.key;
|
|
2606
2606
|
const value = await pair.value;
|
|
2607
2607
|
syncPairs.push({
|
|
2608
|
-
key,
|
|
2608
|
+
key: key3,
|
|
2609
2609
|
value,
|
|
2610
2610
|
alwaysSet: pair.alwaysSet
|
|
2611
2611
|
});
|
|
@@ -2730,8 +2730,8 @@ var init_types = __esm({
|
|
|
2730
2730
|
// }) as any;
|
|
2731
2731
|
// return merged;
|
|
2732
2732
|
// }
|
|
2733
|
-
setKey(
|
|
2734
|
-
return this.augment({ [
|
|
2733
|
+
setKey(key3, schema) {
|
|
2734
|
+
return this.augment({ [key3]: schema });
|
|
2735
2735
|
}
|
|
2736
2736
|
// merge<Incoming extends AnyZodObject>(
|
|
2737
2737
|
// merging: Incoming
|
|
@@ -2762,9 +2762,9 @@ var init_types = __esm({
|
|
|
2762
2762
|
}
|
|
2763
2763
|
pick(mask) {
|
|
2764
2764
|
const shape = {};
|
|
2765
|
-
for (const
|
|
2766
|
-
if (mask[
|
|
2767
|
-
shape[
|
|
2765
|
+
for (const key3 of util.objectKeys(mask)) {
|
|
2766
|
+
if (mask[key3] && this.shape[key3]) {
|
|
2767
|
+
shape[key3] = this.shape[key3];
|
|
2768
2768
|
}
|
|
2769
2769
|
}
|
|
2770
2770
|
return new _ZodObject({
|
|
@@ -2774,9 +2774,9 @@ var init_types = __esm({
|
|
|
2774
2774
|
}
|
|
2775
2775
|
omit(mask) {
|
|
2776
2776
|
const shape = {};
|
|
2777
|
-
for (const
|
|
2778
|
-
if (!mask[
|
|
2779
|
-
shape[
|
|
2777
|
+
for (const key3 of util.objectKeys(this.shape)) {
|
|
2778
|
+
if (!mask[key3]) {
|
|
2779
|
+
shape[key3] = this.shape[key3];
|
|
2780
2780
|
}
|
|
2781
2781
|
}
|
|
2782
2782
|
return new _ZodObject({
|
|
@@ -2792,12 +2792,12 @@ var init_types = __esm({
|
|
|
2792
2792
|
}
|
|
2793
2793
|
partial(mask) {
|
|
2794
2794
|
const newShape = {};
|
|
2795
|
-
for (const
|
|
2796
|
-
const fieldSchema = this.shape[
|
|
2797
|
-
if (mask && !mask[
|
|
2798
|
-
newShape[
|
|
2795
|
+
for (const key3 of util.objectKeys(this.shape)) {
|
|
2796
|
+
const fieldSchema = this.shape[key3];
|
|
2797
|
+
if (mask && !mask[key3]) {
|
|
2798
|
+
newShape[key3] = fieldSchema;
|
|
2799
2799
|
} else {
|
|
2800
|
-
newShape[
|
|
2800
|
+
newShape[key3] = fieldSchema.optional();
|
|
2801
2801
|
}
|
|
2802
2802
|
}
|
|
2803
2803
|
return new _ZodObject({
|
|
@@ -2807,16 +2807,16 @@ var init_types = __esm({
|
|
|
2807
2807
|
}
|
|
2808
2808
|
required(mask) {
|
|
2809
2809
|
const newShape = {};
|
|
2810
|
-
for (const
|
|
2811
|
-
if (mask && !mask[
|
|
2812
|
-
newShape[
|
|
2810
|
+
for (const key3 of util.objectKeys(this.shape)) {
|
|
2811
|
+
if (mask && !mask[key3]) {
|
|
2812
|
+
newShape[key3] = this.shape[key3];
|
|
2813
2813
|
} else {
|
|
2814
|
-
const fieldSchema = this.shape[
|
|
2814
|
+
const fieldSchema = this.shape[key3];
|
|
2815
2815
|
let newField = fieldSchema;
|
|
2816
2816
|
while (newField instanceof ZodOptional) {
|
|
2817
2817
|
newField = newField._def.innerType;
|
|
2818
2818
|
}
|
|
2819
|
-
newShape[
|
|
2819
|
+
newShape[key3] = newField;
|
|
2820
2820
|
}
|
|
2821
2821
|
}
|
|
2822
2822
|
return new _ZodObject({
|
|
@@ -2879,7 +2879,7 @@ var init_types = __esm({
|
|
|
2879
2879
|
return INVALID;
|
|
2880
2880
|
}
|
|
2881
2881
|
if (ctx.common.async) {
|
|
2882
|
-
return Promise.all(options.map(async (
|
|
2882
|
+
return Promise.all(options.map(async (option3) => {
|
|
2883
2883
|
const childCtx = {
|
|
2884
2884
|
...ctx,
|
|
2885
2885
|
common: {
|
|
@@ -2889,7 +2889,7 @@ var init_types = __esm({
|
|
|
2889
2889
|
parent: null
|
|
2890
2890
|
};
|
|
2891
2891
|
return {
|
|
2892
|
-
result: await
|
|
2892
|
+
result: await option3._parseAsync({
|
|
2893
2893
|
data: ctx.data,
|
|
2894
2894
|
path: ctx.path,
|
|
2895
2895
|
parent: childCtx
|
|
@@ -2900,7 +2900,7 @@ var init_types = __esm({
|
|
|
2900
2900
|
} else {
|
|
2901
2901
|
let dirty = void 0;
|
|
2902
2902
|
const issues = [];
|
|
2903
|
-
for (const
|
|
2903
|
+
for (const option3 of options) {
|
|
2904
2904
|
const childCtx = {
|
|
2905
2905
|
...ctx,
|
|
2906
2906
|
common: {
|
|
@@ -2909,7 +2909,7 @@ var init_types = __esm({
|
|
|
2909
2909
|
},
|
|
2910
2910
|
parent: null
|
|
2911
2911
|
};
|
|
2912
|
-
const result =
|
|
2912
|
+
const result = option3._parseSync({
|
|
2913
2913
|
data: ctx.data,
|
|
2914
2914
|
path: ctx.path,
|
|
2915
2915
|
parent: childCtx
|
|
@@ -2990,8 +2990,8 @@ var init_types = __esm({
|
|
|
2990
2990
|
}
|
|
2991
2991
|
const discriminator = this.discriminator;
|
|
2992
2992
|
const discriminatorValue = ctx.data[discriminator];
|
|
2993
|
-
const
|
|
2994
|
-
if (!
|
|
2993
|
+
const option3 = this.optionsMap.get(discriminatorValue);
|
|
2994
|
+
if (!option3) {
|
|
2995
2995
|
addIssueToContext(ctx, {
|
|
2996
2996
|
code: ZodIssueCode.invalid_union_discriminator,
|
|
2997
2997
|
options: Array.from(this.optionsMap.keys()),
|
|
@@ -3000,13 +3000,13 @@ var init_types = __esm({
|
|
|
3000
3000
|
return INVALID;
|
|
3001
3001
|
}
|
|
3002
3002
|
if (ctx.common.async) {
|
|
3003
|
-
return
|
|
3003
|
+
return option3._parseAsync({
|
|
3004
3004
|
data: ctx.data,
|
|
3005
3005
|
path: ctx.path,
|
|
3006
3006
|
parent: ctx
|
|
3007
3007
|
});
|
|
3008
3008
|
} else {
|
|
3009
|
-
return
|
|
3009
|
+
return option3._parseSync({
|
|
3010
3010
|
data: ctx.data,
|
|
3011
3011
|
path: ctx.path,
|
|
3012
3012
|
parent: ctx
|
|
@@ -3193,11 +3193,11 @@ var init_types = __esm({
|
|
|
3193
3193
|
const pairs = [];
|
|
3194
3194
|
const keyType = this._def.keyType;
|
|
3195
3195
|
const valueType = this._def.valueType;
|
|
3196
|
-
for (const
|
|
3196
|
+
for (const key3 in ctx.data) {
|
|
3197
3197
|
pairs.push({
|
|
3198
|
-
key: keyType._parse(new ParseInputLazyPath(ctx,
|
|
3199
|
-
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[
|
|
3200
|
-
alwaysSet:
|
|
3198
|
+
key: keyType._parse(new ParseInputLazyPath(ctx, key3, ctx.path, key3)),
|
|
3199
|
+
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key3], ctx.path, key3)),
|
|
3200
|
+
alwaysSet: key3 in ctx.data
|
|
3201
3201
|
});
|
|
3202
3202
|
}
|
|
3203
3203
|
if (ctx.common.async) {
|
|
@@ -3245,9 +3245,9 @@ var init_types = __esm({
|
|
|
3245
3245
|
}
|
|
3246
3246
|
const keyType = this._def.keyType;
|
|
3247
3247
|
const valueType = this._def.valueType;
|
|
3248
|
-
const pairs = [...ctx.data.entries()].map(([
|
|
3248
|
+
const pairs = [...ctx.data.entries()].map(([key3, value], index) => {
|
|
3249
3249
|
return {
|
|
3250
|
-
key: keyType._parse(new ParseInputLazyPath(ctx,
|
|
3250
|
+
key: keyType._parse(new ParseInputLazyPath(ctx, key3, ctx.path, [index, "key"])),
|
|
3251
3251
|
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
|
|
3252
3252
|
};
|
|
3253
3253
|
});
|
|
@@ -3255,30 +3255,30 @@ var init_types = __esm({
|
|
|
3255
3255
|
const finalMap = /* @__PURE__ */ new Map();
|
|
3256
3256
|
return Promise.resolve().then(async () => {
|
|
3257
3257
|
for (const pair of pairs) {
|
|
3258
|
-
const
|
|
3258
|
+
const key3 = await pair.key;
|
|
3259
3259
|
const value = await pair.value;
|
|
3260
|
-
if (
|
|
3260
|
+
if (key3.status === "aborted" || value.status === "aborted") {
|
|
3261
3261
|
return INVALID;
|
|
3262
3262
|
}
|
|
3263
|
-
if (
|
|
3263
|
+
if (key3.status === "dirty" || value.status === "dirty") {
|
|
3264
3264
|
status.dirty();
|
|
3265
3265
|
}
|
|
3266
|
-
finalMap.set(
|
|
3266
|
+
finalMap.set(key3.value, value.value);
|
|
3267
3267
|
}
|
|
3268
3268
|
return { status: status.value, value: finalMap };
|
|
3269
3269
|
});
|
|
3270
3270
|
} else {
|
|
3271
3271
|
const finalMap = /* @__PURE__ */ new Map();
|
|
3272
3272
|
for (const pair of pairs) {
|
|
3273
|
-
const
|
|
3273
|
+
const key3 = pair.key;
|
|
3274
3274
|
const value = pair.value;
|
|
3275
|
-
if (
|
|
3275
|
+
if (key3.status === "aborted" || value.status === "aborted") {
|
|
3276
3276
|
return INVALID;
|
|
3277
3277
|
}
|
|
3278
|
-
if (
|
|
3278
|
+
if (key3.status === "dirty" || value.status === "dirty") {
|
|
3279
3279
|
status.dirty();
|
|
3280
3280
|
}
|
|
3281
|
-
finalMap.set(
|
|
3281
|
+
finalMap.set(key3.value, value.value);
|
|
3282
3282
|
}
|
|
3283
3283
|
return { status: status.value, value: finalMap };
|
|
3284
3284
|
}
|
|
@@ -4794,9 +4794,9 @@ var require_constants = __commonJS({
|
|
|
4794
4794
|
"X-XSS-Protection"
|
|
4795
4795
|
];
|
|
4796
4796
|
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
|
|
4797
|
-
const
|
|
4798
|
-
const lowerCasedKey =
|
|
4799
|
-
headerNameLowerCasedRecord[
|
|
4797
|
+
const key3 = wellknownHeaderNames[i];
|
|
4798
|
+
const lowerCasedKey = key3.toLowerCase();
|
|
4799
|
+
headerNameLowerCasedRecord[key3] = headerNameLowerCasedRecord[lowerCasedKey] = lowerCasedKey;
|
|
4800
4800
|
}
|
|
4801
4801
|
Object.setPrototypeOf(headerNameLowerCasedRecord, null);
|
|
4802
4802
|
module.exports = {
|
|
@@ -4830,16 +4830,16 @@ var require_tree = __commonJS({
|
|
|
4830
4830
|
* @param {any} value
|
|
4831
4831
|
* @param {number} index
|
|
4832
4832
|
*/
|
|
4833
|
-
constructor(
|
|
4834
|
-
if (index === void 0 || index >=
|
|
4833
|
+
constructor(key3, value, index) {
|
|
4834
|
+
if (index === void 0 || index >= key3.length) {
|
|
4835
4835
|
throw new TypeError("Unreachable");
|
|
4836
4836
|
}
|
|
4837
|
-
const code = this.code =
|
|
4837
|
+
const code = this.code = key3.charCodeAt(index);
|
|
4838
4838
|
if (code > 127) {
|
|
4839
4839
|
throw new TypeError("key must be ascii string");
|
|
4840
4840
|
}
|
|
4841
|
-
if (
|
|
4842
|
-
this.middle = new _TstNode(
|
|
4841
|
+
if (key3.length !== ++index) {
|
|
4842
|
+
this.middle = new _TstNode(key3, value, index);
|
|
4843
4843
|
} else {
|
|
4844
4844
|
this.value = value;
|
|
4845
4845
|
}
|
|
@@ -4848,15 +4848,15 @@ var require_tree = __commonJS({
|
|
|
4848
4848
|
* @param {string} key
|
|
4849
4849
|
* @param {any} value
|
|
4850
4850
|
*/
|
|
4851
|
-
add(
|
|
4852
|
-
const length =
|
|
4851
|
+
add(key3, value) {
|
|
4852
|
+
const length = key3.length;
|
|
4853
4853
|
if (length === 0) {
|
|
4854
4854
|
throw new TypeError("Unreachable");
|
|
4855
4855
|
}
|
|
4856
4856
|
let index = 0;
|
|
4857
4857
|
let node = this;
|
|
4858
4858
|
while (true) {
|
|
4859
|
-
const code =
|
|
4859
|
+
const code = key3.charCodeAt(index);
|
|
4860
4860
|
if (code > 127) {
|
|
4861
4861
|
throw new TypeError("key must be ascii string");
|
|
4862
4862
|
}
|
|
@@ -4867,20 +4867,20 @@ var require_tree = __commonJS({
|
|
|
4867
4867
|
} else if (node.middle !== null) {
|
|
4868
4868
|
node = node.middle;
|
|
4869
4869
|
} else {
|
|
4870
|
-
node.middle = new _TstNode(
|
|
4870
|
+
node.middle = new _TstNode(key3, value, index);
|
|
4871
4871
|
break;
|
|
4872
4872
|
}
|
|
4873
4873
|
} else if (node.code < code) {
|
|
4874
4874
|
if (node.left !== null) {
|
|
4875
4875
|
node = node.left;
|
|
4876
4876
|
} else {
|
|
4877
|
-
node.left = new _TstNode(
|
|
4877
|
+
node.left = new _TstNode(key3, value, index);
|
|
4878
4878
|
break;
|
|
4879
4879
|
}
|
|
4880
4880
|
} else if (node.right !== null) {
|
|
4881
4881
|
node = node.right;
|
|
4882
4882
|
} else {
|
|
4883
|
-
node.right = new _TstNode(
|
|
4883
|
+
node.right = new _TstNode(key3, value, index);
|
|
4884
4884
|
break;
|
|
4885
4885
|
}
|
|
4886
4886
|
}
|
|
@@ -4889,12 +4889,12 @@ var require_tree = __commonJS({
|
|
|
4889
4889
|
* @param {Uint8Array} key
|
|
4890
4890
|
* @return {TstNode | null}
|
|
4891
4891
|
*/
|
|
4892
|
-
search(
|
|
4893
|
-
const keylength =
|
|
4892
|
+
search(key3) {
|
|
4893
|
+
const keylength = key3.length;
|
|
4894
4894
|
let index = 0;
|
|
4895
4895
|
let node = this;
|
|
4896
4896
|
while (node !== null && index < keylength) {
|
|
4897
|
-
let code =
|
|
4897
|
+
let code = key3[index];
|
|
4898
4898
|
if (code <= 90 && code >= 65) {
|
|
4899
4899
|
code |= 32;
|
|
4900
4900
|
}
|
|
@@ -4919,25 +4919,25 @@ var require_tree = __commonJS({
|
|
|
4919
4919
|
* @param {string} key
|
|
4920
4920
|
* @param {any} value
|
|
4921
4921
|
* */
|
|
4922
|
-
insert(
|
|
4922
|
+
insert(key3, value) {
|
|
4923
4923
|
if (this.node === null) {
|
|
4924
|
-
this.node = new TstNode(
|
|
4924
|
+
this.node = new TstNode(key3, value, 0);
|
|
4925
4925
|
} else {
|
|
4926
|
-
this.node.add(
|
|
4926
|
+
this.node.add(key3, value);
|
|
4927
4927
|
}
|
|
4928
4928
|
}
|
|
4929
4929
|
/**
|
|
4930
4930
|
* @param {Uint8Array} key
|
|
4931
4931
|
* @return {any}
|
|
4932
4932
|
*/
|
|
4933
|
-
lookup(
|
|
4934
|
-
return this.node?.search(
|
|
4933
|
+
lookup(key3) {
|
|
4934
|
+
return this.node?.search(key3)?.value ?? null;
|
|
4935
4935
|
}
|
|
4936
4936
|
};
|
|
4937
4937
|
var tree = new TernarySearchTree();
|
|
4938
4938
|
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
|
|
4939
|
-
const
|
|
4940
|
-
tree.insert(
|
|
4939
|
+
const key3 = headerNameLowerCasedRecord[wellknownHeaderNames[i]];
|
|
4940
|
+
tree.insert(key3, key3);
|
|
4941
4941
|
}
|
|
4942
4942
|
module.exports = {
|
|
4943
4943
|
TernarySearchTree,
|
|
@@ -5161,20 +5161,20 @@ var require_util = __commonJS({
|
|
|
5161
5161
|
function parseHeaders(headers, obj) {
|
|
5162
5162
|
if (obj === void 0) obj = {};
|
|
5163
5163
|
for (let i = 0; i < headers.length; i += 2) {
|
|
5164
|
-
const
|
|
5165
|
-
let val = obj[
|
|
5164
|
+
const key3 = headerNameToString(headers[i]);
|
|
5165
|
+
let val = obj[key3];
|
|
5166
5166
|
if (val) {
|
|
5167
5167
|
if (typeof val === "string") {
|
|
5168
5168
|
val = [val];
|
|
5169
|
-
obj[
|
|
5169
|
+
obj[key3] = val;
|
|
5170
5170
|
}
|
|
5171
5171
|
val.push(headers[i + 1].toString("utf8"));
|
|
5172
5172
|
} else {
|
|
5173
5173
|
const headersValue = headers[i + 1];
|
|
5174
5174
|
if (typeof headersValue === "string") {
|
|
5175
|
-
obj[
|
|
5175
|
+
obj[key3] = headersValue;
|
|
5176
5176
|
} else {
|
|
5177
|
-
obj[
|
|
5177
|
+
obj[key3] = Array.isArray(headersValue) ? headersValue.map((x) => x.toString("utf8")) : headersValue.toString("utf8");
|
|
5178
5178
|
}
|
|
5179
5179
|
}
|
|
5180
5180
|
}
|
|
@@ -5188,21 +5188,21 @@ var require_util = __commonJS({
|
|
|
5188
5188
|
const ret = new Array(len);
|
|
5189
5189
|
let hasContentLength = false;
|
|
5190
5190
|
let contentDispositionIdx = -1;
|
|
5191
|
-
let
|
|
5191
|
+
let key3;
|
|
5192
5192
|
let val;
|
|
5193
5193
|
let kLen = 0;
|
|
5194
5194
|
for (let n = 0; n < headers.length; n += 2) {
|
|
5195
|
-
|
|
5195
|
+
key3 = headers[n];
|
|
5196
5196
|
val = headers[n + 1];
|
|
5197
|
-
typeof
|
|
5197
|
+
typeof key3 !== "string" && (key3 = key3.toString());
|
|
5198
5198
|
typeof val !== "string" && (val = val.toString("utf8"));
|
|
5199
|
-
kLen =
|
|
5200
|
-
if (kLen === 14 &&
|
|
5199
|
+
kLen = key3.length;
|
|
5200
|
+
if (kLen === 14 && key3[7] === "-" && (key3 === "content-length" || key3.toLowerCase() === "content-length")) {
|
|
5201
5201
|
hasContentLength = true;
|
|
5202
|
-
} else if (kLen === 19 &&
|
|
5202
|
+
} else if (kLen === 19 && key3[7] === "-" && (key3 === "content-disposition" || key3.toLowerCase() === "content-disposition")) {
|
|
5203
5203
|
contentDispositionIdx = n + 1;
|
|
5204
5204
|
}
|
|
5205
|
-
ret[n] =
|
|
5205
|
+
ret[n] = key3;
|
|
5206
5206
|
ret[n + 1] = val;
|
|
5207
5207
|
}
|
|
5208
5208
|
if (hasContentLength && contentDispositionIdx !== -1) {
|
|
@@ -5887,20 +5887,20 @@ var require_request = __commonJS({
|
|
|
5887
5887
|
this.endHandler = null;
|
|
5888
5888
|
}
|
|
5889
5889
|
}
|
|
5890
|
-
addHeader(
|
|
5891
|
-
processHeader(this,
|
|
5890
|
+
addHeader(key3, value) {
|
|
5891
|
+
processHeader(this, key3, value);
|
|
5892
5892
|
return this;
|
|
5893
5893
|
}
|
|
5894
5894
|
};
|
|
5895
|
-
function processHeader(request,
|
|
5895
|
+
function processHeader(request, key3, val) {
|
|
5896
5896
|
if (val && (typeof val === "object" && !Array.isArray(val))) {
|
|
5897
|
-
throw new InvalidArgumentError(`invalid ${
|
|
5897
|
+
throw new InvalidArgumentError(`invalid ${key3} header`);
|
|
5898
5898
|
} else if (val === void 0) {
|
|
5899
5899
|
return;
|
|
5900
5900
|
}
|
|
5901
|
-
let headerName = headerNameLowerCasedRecord[
|
|
5901
|
+
let headerName = headerNameLowerCasedRecord[key3];
|
|
5902
5902
|
if (headerName === void 0) {
|
|
5903
|
-
headerName =
|
|
5903
|
+
headerName = key3.toLowerCase();
|
|
5904
5904
|
if (headerNameLowerCasedRecord[headerName] === void 0 && !isValidHTTPToken(headerName)) {
|
|
5905
5905
|
throw new InvalidArgumentError("invalid header key");
|
|
5906
5906
|
}
|
|
@@ -5910,13 +5910,13 @@ var require_request = __commonJS({
|
|
|
5910
5910
|
for (let i = 0; i < val.length; i++) {
|
|
5911
5911
|
if (typeof val[i] === "string") {
|
|
5912
5912
|
if (!isValidHeaderValue(val[i])) {
|
|
5913
|
-
throw new InvalidArgumentError(`invalid ${
|
|
5913
|
+
throw new InvalidArgumentError(`invalid ${key3} header`);
|
|
5914
5914
|
}
|
|
5915
5915
|
arr.push(val[i]);
|
|
5916
5916
|
} else if (val[i] === null) {
|
|
5917
5917
|
arr.push("");
|
|
5918
5918
|
} else if (typeof val[i] === "object") {
|
|
5919
|
-
throw new InvalidArgumentError(`invalid ${
|
|
5919
|
+
throw new InvalidArgumentError(`invalid ${key3} header`);
|
|
5920
5920
|
} else {
|
|
5921
5921
|
arr.push(`${val[i]}`);
|
|
5922
5922
|
}
|
|
@@ -5924,7 +5924,7 @@ var require_request = __commonJS({
|
|
|
5924
5924
|
val = arr;
|
|
5925
5925
|
} else if (typeof val === "string") {
|
|
5926
5926
|
if (!isValidHeaderValue(val)) {
|
|
5927
|
-
throw new InvalidArgumentError(`invalid ${
|
|
5927
|
+
throw new InvalidArgumentError(`invalid ${key3} header`);
|
|
5928
5928
|
}
|
|
5929
5929
|
} else if (val === null) {
|
|
5930
5930
|
val = "";
|
|
@@ -5949,7 +5949,7 @@ var require_request = __commonJS({
|
|
|
5949
5949
|
}
|
|
5950
5950
|
} else if (request.contentType === null && headerName === "content-type") {
|
|
5951
5951
|
request.contentType = val;
|
|
5952
|
-
request.headers.push(
|
|
5952
|
+
request.headers.push(key3, val);
|
|
5953
5953
|
} else if (headerName === "transfer-encoding" || headerName === "keep-alive" || headerName === "upgrade") {
|
|
5954
5954
|
throw new InvalidArgumentError(`invalid ${headerName} header`);
|
|
5955
5955
|
} else if (headerName === "connection") {
|
|
@@ -5963,7 +5963,7 @@ var require_request = __commonJS({
|
|
|
5963
5963
|
} else if (headerName === "expect") {
|
|
5964
5964
|
throw new NotSupportedError("expect header not supported");
|
|
5965
5965
|
} else {
|
|
5966
|
-
request.headers.push(
|
|
5966
|
+
request.headers.push(key3, val);
|
|
5967
5967
|
}
|
|
5968
5968
|
}
|
|
5969
5969
|
module.exports = Request;
|
|
@@ -6443,13 +6443,13 @@ var require_connect = __commonJS({
|
|
|
6443
6443
|
constructor(maxCachedSessions) {
|
|
6444
6444
|
this._maxCachedSessions = maxCachedSessions;
|
|
6445
6445
|
this._sessionCache = /* @__PURE__ */ new Map();
|
|
6446
|
-
this._sessionRegistry = new global.FinalizationRegistry((
|
|
6446
|
+
this._sessionRegistry = new global.FinalizationRegistry((key3) => {
|
|
6447
6447
|
if (this._sessionCache.size < this._maxCachedSessions) {
|
|
6448
6448
|
return;
|
|
6449
6449
|
}
|
|
6450
|
-
const ref = this._sessionCache.get(
|
|
6450
|
+
const ref = this._sessionCache.get(key3);
|
|
6451
6451
|
if (ref !== void 0 && ref.deref() === void 0) {
|
|
6452
|
-
this._sessionCache.delete(
|
|
6452
|
+
this._sessionCache.delete(key3);
|
|
6453
6453
|
}
|
|
6454
6454
|
});
|
|
6455
6455
|
}
|
|
@@ -6613,10 +6613,10 @@ var require_utils = __commonJS({
|
|
|
6613
6613
|
exports.enumToMap = void 0;
|
|
6614
6614
|
function enumToMap(obj) {
|
|
6615
6615
|
const res = {};
|
|
6616
|
-
Object.keys(obj).forEach((
|
|
6617
|
-
const value = obj[
|
|
6616
|
+
Object.keys(obj).forEach((key3) => {
|
|
6617
|
+
const value = obj[key3];
|
|
6618
6618
|
if (typeof value === "number") {
|
|
6619
|
-
res[
|
|
6619
|
+
res[key3] = value;
|
|
6620
6620
|
}
|
|
6621
6621
|
});
|
|
6622
6622
|
return res;
|
|
@@ -6793,9 +6793,9 @@ var require_constants2 = __commonJS({
|
|
|
6793
6793
|
];
|
|
6794
6794
|
exports.METHOD_MAP = utils_1.enumToMap(METHODS);
|
|
6795
6795
|
exports.H_METHOD_MAP = {};
|
|
6796
|
-
Object.keys(exports.METHOD_MAP).forEach((
|
|
6797
|
-
if (/^H/.test(
|
|
6798
|
-
exports.H_METHOD_MAP[
|
|
6796
|
+
Object.keys(exports.METHOD_MAP).forEach((key3) => {
|
|
6797
|
+
if (/^H/.test(key3)) {
|
|
6798
|
+
exports.H_METHOD_MAP[key3] = exports.METHOD_MAP[key3];
|
|
6799
6799
|
}
|
|
6800
6800
|
});
|
|
6801
6801
|
var FINISH;
|
|
@@ -7480,25 +7480,25 @@ var require_data_url = __commonJS({
|
|
|
7480
7480
|
function isHTTPWhiteSpace(char) {
|
|
7481
7481
|
return char === 13 || char === 10 || char === 9 || char === 32;
|
|
7482
7482
|
}
|
|
7483
|
-
function removeHTTPWhitespace(
|
|
7484
|
-
return removeChars(
|
|
7483
|
+
function removeHTTPWhitespace(str3, leading = true, trailing = true) {
|
|
7484
|
+
return removeChars(str3, leading, trailing, isHTTPWhiteSpace);
|
|
7485
7485
|
}
|
|
7486
7486
|
function isASCIIWhitespace(char) {
|
|
7487
7487
|
return char === 13 || char === 10 || char === 9 || char === 12 || char === 32;
|
|
7488
7488
|
}
|
|
7489
|
-
function removeASCIIWhitespace(
|
|
7490
|
-
return removeChars(
|
|
7489
|
+
function removeASCIIWhitespace(str3, leading = true, trailing = true) {
|
|
7490
|
+
return removeChars(str3, leading, trailing, isASCIIWhitespace);
|
|
7491
7491
|
}
|
|
7492
|
-
function removeChars(
|
|
7492
|
+
function removeChars(str3, leading, trailing, predicate) {
|
|
7493
7493
|
let lead = 0;
|
|
7494
|
-
let trail =
|
|
7494
|
+
let trail = str3.length - 1;
|
|
7495
7495
|
if (leading) {
|
|
7496
|
-
while (lead <
|
|
7496
|
+
while (lead < str3.length && predicate(str3.charCodeAt(lead))) lead++;
|
|
7497
7497
|
}
|
|
7498
7498
|
if (trailing) {
|
|
7499
|
-
while (trail > 0 && predicate(
|
|
7499
|
+
while (trail > 0 && predicate(str3.charCodeAt(trail))) trail--;
|
|
7500
7500
|
}
|
|
7501
|
-
return lead === 0 && trail ===
|
|
7501
|
+
return lead === 0 && trail === str3.length - 1 ? str3 : str3.slice(lead, trail + 1);
|
|
7502
7502
|
}
|
|
7503
7503
|
function isomorphicDecode(input) {
|
|
7504
7504
|
const length = input.length;
|
|
@@ -7766,19 +7766,19 @@ var require_webidl = __commonJS({
|
|
|
7766
7766
|
const result = {};
|
|
7767
7767
|
if (!types.isProxy(O)) {
|
|
7768
7768
|
const keys2 = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)];
|
|
7769
|
-
for (const
|
|
7770
|
-
const typedKey = keyConverter(
|
|
7771
|
-
const typedValue = valueConverter(O[
|
|
7769
|
+
for (const key3 of keys2) {
|
|
7770
|
+
const typedKey = keyConverter(key3, prefix, argument);
|
|
7771
|
+
const typedValue = valueConverter(O[key3], prefix, argument);
|
|
7772
7772
|
result[typedKey] = typedValue;
|
|
7773
7773
|
}
|
|
7774
7774
|
return result;
|
|
7775
7775
|
}
|
|
7776
7776
|
const keys = Reflect.ownKeys(O);
|
|
7777
|
-
for (const
|
|
7778
|
-
const desc = Reflect.getOwnPropertyDescriptor(O,
|
|
7777
|
+
for (const key3 of keys) {
|
|
7778
|
+
const desc = Reflect.getOwnPropertyDescriptor(O, key3);
|
|
7779
7779
|
if (desc?.enumerable) {
|
|
7780
|
-
const typedKey = keyConverter(
|
|
7781
|
-
const typedValue = valueConverter(O[
|
|
7780
|
+
const typedKey = keyConverter(key3, prefix, argument);
|
|
7781
|
+
const typedValue = valueConverter(O[key3], prefix, argument);
|
|
7782
7782
|
result[typedKey] = typedValue;
|
|
7783
7783
|
}
|
|
7784
7784
|
}
|
|
@@ -7809,29 +7809,29 @@ var require_webidl = __commonJS({
|
|
|
7809
7809
|
});
|
|
7810
7810
|
}
|
|
7811
7811
|
for (const options of converters) {
|
|
7812
|
-
const { key, defaultValue, required, converter } = options;
|
|
7812
|
+
const { key: key3, defaultValue, required, converter } = options;
|
|
7813
7813
|
if (required === true) {
|
|
7814
|
-
if (!Object.hasOwn(dictionary,
|
|
7814
|
+
if (!Object.hasOwn(dictionary, key3)) {
|
|
7815
7815
|
throw webidl.errors.exception({
|
|
7816
7816
|
header: prefix,
|
|
7817
|
-
message: `Missing required key "${
|
|
7817
|
+
message: `Missing required key "${key3}".`
|
|
7818
7818
|
});
|
|
7819
7819
|
}
|
|
7820
7820
|
}
|
|
7821
|
-
let value = dictionary[
|
|
7821
|
+
let value = dictionary[key3];
|
|
7822
7822
|
const hasDefault = Object.hasOwn(options, "defaultValue");
|
|
7823
7823
|
if (hasDefault && value !== null) {
|
|
7824
7824
|
value ??= defaultValue();
|
|
7825
7825
|
}
|
|
7826
7826
|
if (required || hasDefault || value !== void 0) {
|
|
7827
|
-
value = converter(value, prefix, `${argument}.${
|
|
7827
|
+
value = converter(value, prefix, `${argument}.${key3}`);
|
|
7828
7828
|
if (options.allowedValues && !options.allowedValues.includes(value)) {
|
|
7829
7829
|
throw webidl.errors.exception({
|
|
7830
7830
|
header: prefix,
|
|
7831
7831
|
message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(", ")}.`
|
|
7832
7832
|
});
|
|
7833
7833
|
}
|
|
7834
|
-
dict[
|
|
7834
|
+
dict[key3] = value;
|
|
7835
7835
|
}
|
|
7836
7836
|
}
|
|
7837
7837
|
return dict;
|
|
@@ -8446,18 +8446,18 @@ var require_util2 = __commonJS({
|
|
|
8446
8446
|
done: true
|
|
8447
8447
|
};
|
|
8448
8448
|
}
|
|
8449
|
-
const { [keyIndex]:
|
|
8449
|
+
const { [keyIndex]: key3, [valueIndex]: value } = values[index];
|
|
8450
8450
|
this.#index = index + 1;
|
|
8451
8451
|
let result;
|
|
8452
8452
|
switch (this.#kind) {
|
|
8453
8453
|
case "key":
|
|
8454
|
-
result =
|
|
8454
|
+
result = key3;
|
|
8455
8455
|
break;
|
|
8456
8456
|
case "value":
|
|
8457
8457
|
result = value;
|
|
8458
8458
|
break;
|
|
8459
8459
|
case "key+value":
|
|
8460
|
-
result = [
|
|
8460
|
+
result = [key3, value];
|
|
8461
8461
|
break;
|
|
8462
8462
|
}
|
|
8463
8463
|
return {
|
|
@@ -8523,8 +8523,8 @@ var require_util2 = __commonJS({
|
|
|
8523
8523
|
`Failed to execute 'forEach' on '${name}': parameter 1 is not of type 'Function'.`
|
|
8524
8524
|
);
|
|
8525
8525
|
}
|
|
8526
|
-
for (const { 0:
|
|
8527
|
-
callbackfn.call(thisArg, value,
|
|
8526
|
+
for (const { 0: key3, 1: value } of makeIterator(this, "key+value")) {
|
|
8527
|
+
callbackfn.call(thisArg, value, key3, this);
|
|
8528
8528
|
}
|
|
8529
8529
|
}
|
|
8530
8530
|
}
|
|
@@ -9417,7 +9417,7 @@ var require_body = __commonJS({
|
|
|
9417
9417
|
const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, "0")}`;
|
|
9418
9418
|
const prefix = `--${boundary}\r
|
|
9419
9419
|
Content-Disposition: form-data`;
|
|
9420
|
-
const escape = (
|
|
9420
|
+
const escape = (str3) => str3.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22");
|
|
9421
9421
|
const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, "\r\n");
|
|
9422
9422
|
const blobParts = [];
|
|
9423
9423
|
const rn = new Uint8Array([13, 10]);
|
|
@@ -9966,15 +9966,15 @@ var require_client_h1 = __commonJS({
|
|
|
9966
9966
|
} else {
|
|
9967
9967
|
this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]);
|
|
9968
9968
|
}
|
|
9969
|
-
const
|
|
9970
|
-
if (
|
|
9971
|
-
const headerName = util2.bufferToLowerCasedHeaderName(
|
|
9969
|
+
const key3 = this.headers[len - 2];
|
|
9970
|
+
if (key3.length === 10) {
|
|
9971
|
+
const headerName = util2.bufferToLowerCasedHeaderName(key3);
|
|
9972
9972
|
if (headerName === "keep-alive") {
|
|
9973
9973
|
this.keepAlive += buf.toString();
|
|
9974
9974
|
} else if (headerName === "connection") {
|
|
9975
9975
|
this.connection += buf.toString();
|
|
9976
9976
|
}
|
|
9977
|
-
} else if (
|
|
9977
|
+
} else if (key3.length === 14 && util2.bufferToLowerCasedHeaderName(key3) === "content-length") {
|
|
9978
9978
|
this.contentLength += buf.toString();
|
|
9979
9979
|
}
|
|
9980
9980
|
this.trackHeader(buf.length);
|
|
@@ -10459,15 +10459,15 @@ upgrade: ${upgrade}\r
|
|
|
10459
10459
|
}
|
|
10460
10460
|
if (Array.isArray(headers)) {
|
|
10461
10461
|
for (let n = 0; n < headers.length; n += 2) {
|
|
10462
|
-
const
|
|
10462
|
+
const key3 = headers[n + 0];
|
|
10463
10463
|
const val = headers[n + 1];
|
|
10464
10464
|
if (Array.isArray(val)) {
|
|
10465
10465
|
for (let i = 0; i < val.length; i++) {
|
|
10466
|
-
header += `${
|
|
10466
|
+
header += `${key3}: ${val[i]}\r
|
|
10467
10467
|
`;
|
|
10468
10468
|
}
|
|
10469
10469
|
} else {
|
|
10470
|
-
header += `${
|
|
10470
|
+
header += `${key3}: ${val}\r
|
|
10471
10471
|
`;
|
|
10472
10472
|
}
|
|
10473
10473
|
}
|
|
@@ -10929,8 +10929,8 @@ var require_client_h2 = __commonJS({
|
|
|
10929
10929
|
this[kSocket][kError] = err;
|
|
10930
10930
|
this[kClient][kOnError](err);
|
|
10931
10931
|
}
|
|
10932
|
-
function onHttp2FrameError(type, code,
|
|
10933
|
-
if (
|
|
10932
|
+
function onHttp2FrameError(type, code, id3) {
|
|
10933
|
+
if (id3 === 0) {
|
|
10934
10934
|
const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`);
|
|
10935
10935
|
this[kSocket][kError] = err;
|
|
10936
10936
|
this[kClient][kOnError](err);
|
|
@@ -10974,18 +10974,18 @@ var require_client_h2 = __commonJS({
|
|
|
10974
10974
|
}
|
|
10975
10975
|
const headers = {};
|
|
10976
10976
|
for (let n = 0; n < reqHeaders.length; n += 2) {
|
|
10977
|
-
const
|
|
10977
|
+
const key3 = reqHeaders[n + 0];
|
|
10978
10978
|
const val = reqHeaders[n + 1];
|
|
10979
10979
|
if (Array.isArray(val)) {
|
|
10980
10980
|
for (let i = 0; i < val.length; i++) {
|
|
10981
|
-
if (headers[
|
|
10982
|
-
headers[
|
|
10981
|
+
if (headers[key3]) {
|
|
10982
|
+
headers[key3] += `,${val[i]}`;
|
|
10983
10983
|
} else {
|
|
10984
|
-
headers[
|
|
10984
|
+
headers[key3] = val[i];
|
|
10985
10985
|
}
|
|
10986
10986
|
}
|
|
10987
10987
|
} else {
|
|
10988
|
-
headers[
|
|
10988
|
+
headers[key3] = val;
|
|
10989
10989
|
}
|
|
10990
10990
|
}
|
|
10991
10991
|
let stream;
|
|
@@ -11450,9 +11450,9 @@ var require_redirect_handler = __commonJS({
|
|
|
11450
11450
|
}
|
|
11451
11451
|
}
|
|
11452
11452
|
} else if (headers && typeof headers === "object") {
|
|
11453
|
-
for (const
|
|
11454
|
-
if (!shouldRemoveHeader(
|
|
11455
|
-
ret.push(
|
|
11453
|
+
for (const key3 of Object.keys(headers)) {
|
|
11454
|
+
if (!shouldRemoveHeader(key3, removeContent, unknownOrigin)) {
|
|
11455
|
+
ret.push(key3, headers[key3]);
|
|
11456
11456
|
}
|
|
11457
11457
|
}
|
|
11458
11458
|
} else {
|
|
@@ -12530,16 +12530,16 @@ var require_agent = __commonJS({
|
|
|
12530
12530
|
return ret;
|
|
12531
12531
|
}
|
|
12532
12532
|
[kDispatch](opts, handler) {
|
|
12533
|
-
let
|
|
12533
|
+
let key3;
|
|
12534
12534
|
if (opts.origin && (typeof opts.origin === "string" || opts.origin instanceof URL)) {
|
|
12535
|
-
|
|
12535
|
+
key3 = String(opts.origin);
|
|
12536
12536
|
} else {
|
|
12537
12537
|
throw new InvalidArgumentError("opts.origin must be a non-empty string or URL.");
|
|
12538
12538
|
}
|
|
12539
|
-
let dispatcher = this[kClients].get(
|
|
12539
|
+
let dispatcher = this[kClients].get(key3);
|
|
12540
12540
|
if (!dispatcher) {
|
|
12541
12541
|
dispatcher = this[kFactory](opts.origin, this[kOptions]).on("drain", this[kOnDrain]).on("connect", this[kOnConnect]).on("disconnect", this[kOnDisconnect]).on("connectionError", this[kOnConnectionError]);
|
|
12542
|
-
this[kClients].set(
|
|
12542
|
+
this[kClients].set(key3, dispatcher);
|
|
12543
12543
|
}
|
|
12544
12544
|
return dispatcher.dispatch(opts, handler);
|
|
12545
12545
|
}
|
|
@@ -12778,7 +12778,7 @@ var require_proxy_agent = __commonJS({
|
|
|
12778
12778
|
return headers;
|
|
12779
12779
|
}
|
|
12780
12780
|
function throwIfProxyAuthIsSent(headers) {
|
|
12781
|
-
const existProxyAuth = headers && Object.keys(headers).find((
|
|
12781
|
+
const existProxyAuth = headers && Object.keys(headers).find((key3) => key3.toLowerCase() === "proxy-authorization");
|
|
12782
12782
|
if (existProxyAuth) {
|
|
12783
12783
|
throw new InvalidArgumentError("Proxy-Authorization should be sent in ProxyAgent constructor");
|
|
12784
12784
|
}
|
|
@@ -14507,18 +14507,18 @@ var require_mock_utils = __commonJS({
|
|
|
14507
14507
|
})
|
|
14508
14508
|
);
|
|
14509
14509
|
}
|
|
14510
|
-
function getHeaderByName(headers,
|
|
14510
|
+
function getHeaderByName(headers, key3) {
|
|
14511
14511
|
if (Array.isArray(headers)) {
|
|
14512
14512
|
for (let i = 0; i < headers.length; i += 2) {
|
|
14513
|
-
if (headers[i].toLocaleLowerCase() ===
|
|
14513
|
+
if (headers[i].toLocaleLowerCase() === key3.toLocaleLowerCase()) {
|
|
14514
14514
|
return headers[i + 1];
|
|
14515
14515
|
}
|
|
14516
14516
|
}
|
|
14517
14517
|
return void 0;
|
|
14518
14518
|
} else if (typeof headers.get === "function") {
|
|
14519
|
-
return headers.get(
|
|
14519
|
+
return headers.get(key3);
|
|
14520
14520
|
} else {
|
|
14521
|
-
return lowerCaseEntries(headers)[
|
|
14521
|
+
return lowerCaseEntries(headers)[key3.toLocaleLowerCase()];
|
|
14522
14522
|
}
|
|
14523
14523
|
}
|
|
14524
14524
|
function buildHeadersFromArray(headers) {
|
|
@@ -14582,41 +14582,41 @@ var require_mock_utils = __commonJS({
|
|
|
14582
14582
|
return data.toString();
|
|
14583
14583
|
}
|
|
14584
14584
|
}
|
|
14585
|
-
function getMockDispatch(mockDispatches,
|
|
14586
|
-
const basePath =
|
|
14585
|
+
function getMockDispatch(mockDispatches, key3) {
|
|
14586
|
+
const basePath = key3.query ? buildURL(key3.path, key3.query) : key3.path;
|
|
14587
14587
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
14588
14588
|
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath));
|
|
14589
14589
|
if (matchedMockDispatches.length === 0) {
|
|
14590
14590
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
14591
14591
|
}
|
|
14592
|
-
matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method,
|
|
14592
|
+
matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key3.method));
|
|
14593
14593
|
if (matchedMockDispatches.length === 0) {
|
|
14594
|
-
throw new MockNotMatchedError(`Mock dispatch not matched for method '${
|
|
14594
|
+
throw new MockNotMatchedError(`Mock dispatch not matched for method '${key3.method}' on path '${resolvedPath}'`);
|
|
14595
14595
|
}
|
|
14596
|
-
matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== "undefined" ? matchValue(body,
|
|
14596
|
+
matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== "undefined" ? matchValue(body, key3.body) : true);
|
|
14597
14597
|
if (matchedMockDispatches.length === 0) {
|
|
14598
|
-
throw new MockNotMatchedError(`Mock dispatch not matched for body '${
|
|
14598
|
+
throw new MockNotMatchedError(`Mock dispatch not matched for body '${key3.body}' on path '${resolvedPath}'`);
|
|
14599
14599
|
}
|
|
14600
|
-
matchedMockDispatches = matchedMockDispatches.filter((mockDispatch2) => matchHeaders(mockDispatch2,
|
|
14600
|
+
matchedMockDispatches = matchedMockDispatches.filter((mockDispatch2) => matchHeaders(mockDispatch2, key3.headers));
|
|
14601
14601
|
if (matchedMockDispatches.length === 0) {
|
|
14602
|
-
const headers = typeof
|
|
14602
|
+
const headers = typeof key3.headers === "object" ? JSON.stringify(key3.headers) : key3.headers;
|
|
14603
14603
|
throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`);
|
|
14604
14604
|
}
|
|
14605
14605
|
return matchedMockDispatches[0];
|
|
14606
14606
|
}
|
|
14607
|
-
function addMockDispatch(mockDispatches,
|
|
14607
|
+
function addMockDispatch(mockDispatches, key3, data) {
|
|
14608
14608
|
const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false };
|
|
14609
14609
|
const replyData = typeof data === "function" ? { callback: data } : { ...data };
|
|
14610
|
-
const newMockDispatch = { ...baseData, ...
|
|
14610
|
+
const newMockDispatch = { ...baseData, ...key3, pending: true, data: { error: null, ...replyData } };
|
|
14611
14611
|
mockDispatches.push(newMockDispatch);
|
|
14612
14612
|
return newMockDispatch;
|
|
14613
14613
|
}
|
|
14614
|
-
function deleteMockDispatch(mockDispatches,
|
|
14614
|
+
function deleteMockDispatch(mockDispatches, key3) {
|
|
14615
14615
|
const index = mockDispatches.findIndex((dispatch) => {
|
|
14616
14616
|
if (!dispatch.consumed) {
|
|
14617
14617
|
return false;
|
|
14618
14618
|
}
|
|
14619
|
-
return matchKey(dispatch,
|
|
14619
|
+
return matchKey(dispatch, key3);
|
|
14620
14620
|
});
|
|
14621
14621
|
if (index !== -1) {
|
|
14622
14622
|
mockDispatches.splice(index, 1);
|
|
@@ -14636,9 +14636,9 @@ var require_mock_utils = __commonJS({
|
|
|
14636
14636
|
const keys = Object.keys(data);
|
|
14637
14637
|
const result = [];
|
|
14638
14638
|
for (let i = 0; i < keys.length; ++i) {
|
|
14639
|
-
const
|
|
14640
|
-
const value = data[
|
|
14641
|
-
const name = Buffer.from(`${
|
|
14639
|
+
const key3 = keys[i];
|
|
14640
|
+
const value = data[key3];
|
|
14641
|
+
const name = Buffer.from(`${key3}`);
|
|
14642
14642
|
if (Array.isArray(value)) {
|
|
14643
14643
|
for (let j = 0; j < value.length; ++j) {
|
|
14644
14644
|
result.push(name, Buffer.from(`${value[j]}`));
|
|
@@ -14660,8 +14660,8 @@ var require_mock_utils = __commonJS({
|
|
|
14660
14660
|
return Buffer.concat(buffers).toString("utf8");
|
|
14661
14661
|
}
|
|
14662
14662
|
function mockDispatch(opts, handler) {
|
|
14663
|
-
const
|
|
14664
|
-
const mockDispatch2 = getMockDispatch(this[kDispatches],
|
|
14663
|
+
const key3 = buildKey(opts);
|
|
14664
|
+
const mockDispatch2 = getMockDispatch(this[kDispatches], key3);
|
|
14665
14665
|
mockDispatch2.timesInvoked++;
|
|
14666
14666
|
if (mockDispatch2.data.callback) {
|
|
14667
14667
|
mockDispatch2.data = { ...mockDispatch2.data, ...mockDispatch2.data.callback(opts) };
|
|
@@ -14671,7 +14671,7 @@ var require_mock_utils = __commonJS({
|
|
|
14671
14671
|
mockDispatch2.consumed = !persist && timesInvoked >= times;
|
|
14672
14672
|
mockDispatch2.pending = timesInvoked < times;
|
|
14673
14673
|
if (error !== null) {
|
|
14674
|
-
deleteMockDispatch(this[kDispatches],
|
|
14674
|
+
deleteMockDispatch(this[kDispatches], key3);
|
|
14675
14675
|
handler.onError(error);
|
|
14676
14676
|
return true;
|
|
14677
14677
|
}
|
|
@@ -14696,7 +14696,7 @@ var require_mock_utils = __commonJS({
|
|
|
14696
14696
|
handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode));
|
|
14697
14697
|
handler.onData?.(Buffer.from(responseData));
|
|
14698
14698
|
handler.onComplete?.(responseTrailers);
|
|
14699
|
-
deleteMockDispatch(mockDispatches,
|
|
14699
|
+
deleteMockDispatch(mockDispatches, key3);
|
|
14700
14700
|
}
|
|
14701
14701
|
function resume() {
|
|
14702
14702
|
}
|
|
@@ -16603,16 +16603,16 @@ var require_dispatcher_weakref = __commonJS({
|
|
|
16603
16603
|
constructor(finalizer) {
|
|
16604
16604
|
this.finalizer = finalizer;
|
|
16605
16605
|
}
|
|
16606
|
-
register(dispatcher,
|
|
16606
|
+
register(dispatcher, key3) {
|
|
16607
16607
|
if (dispatcher.on) {
|
|
16608
16608
|
dispatcher.on("disconnect", () => {
|
|
16609
16609
|
if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) {
|
|
16610
|
-
this.finalizer(
|
|
16610
|
+
this.finalizer(key3);
|
|
16611
16611
|
}
|
|
16612
16612
|
});
|
|
16613
16613
|
}
|
|
16614
16614
|
}
|
|
16615
|
-
unregister(
|
|
16615
|
+
unregister(key3) {
|
|
16616
16616
|
}
|
|
16617
16617
|
};
|
|
16618
16618
|
module.exports = function() {
|
|
@@ -20065,8 +20065,8 @@ var require_util6 = __commonJS({
|
|
|
20065
20065
|
if (!part.includes("=")) {
|
|
20066
20066
|
throw new Error("Invalid unparsed");
|
|
20067
20067
|
}
|
|
20068
|
-
const [
|
|
20069
|
-
out.push(`${
|
|
20068
|
+
const [key3, ...value] = part.split("=");
|
|
20069
|
+
out.push(`${key3.trim()}=${value.join("=")}`);
|
|
20070
20070
|
}
|
|
20071
20071
|
return out.join("; ");
|
|
20072
20072
|
}
|
|
@@ -20265,9 +20265,9 @@ var require_cookies = __commonJS({
|
|
|
20265
20265
|
webidl.argumentLengthCheck(arguments, 2, "setCookie");
|
|
20266
20266
|
webidl.brandCheck(headers, Headers, { strict: false });
|
|
20267
20267
|
cookie = webidl.converters.Cookie(cookie);
|
|
20268
|
-
const
|
|
20269
|
-
if (
|
|
20270
|
-
headers.append("Set-Cookie",
|
|
20268
|
+
const str3 = stringify(cookie);
|
|
20269
|
+
if (str3) {
|
|
20270
|
+
headers.append("Set-Cookie", str3);
|
|
20271
20271
|
}
|
|
20272
20272
|
}
|
|
20273
20273
|
webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([
|
|
@@ -22793,34 +22793,38 @@ function sessionId() {
|
|
|
22793
22793
|
async function reach(url, init) {
|
|
22794
22794
|
return send(url, init, sessionId());
|
|
22795
22795
|
}
|
|
22796
|
-
function reachAs(session) {
|
|
22797
|
-
return (url, init) => send(url, init, session);
|
|
22796
|
+
function reachAs(session, instance) {
|
|
22797
|
+
return (url, init) => send(url, init, session, instance);
|
|
22798
22798
|
}
|
|
22799
|
-
|
|
22799
|
+
function setClient(name) {
|
|
22800
|
+
CLIENT = name;
|
|
22801
|
+
}
|
|
22802
|
+
async function send(url, init, session, instance = envSession("PAIGY_INSTANCE_ID") ?? INSTANCE_ID) {
|
|
22800
22803
|
try {
|
|
22801
22804
|
const headers = {
|
|
22802
22805
|
...init?.headers,
|
|
22803
|
-
"x-paigy-instance":
|
|
22804
|
-
"x-paigy-session": session
|
|
22806
|
+
"x-paigy-instance": instance,
|
|
22807
|
+
"x-paigy-session": session,
|
|
22808
|
+
...CLIENT ? { "x-paigy-client": CLIENT } : {}
|
|
22805
22809
|
};
|
|
22806
22810
|
return await fetch(url, { ...init, headers, dispatcher: await proxy() });
|
|
22807
22811
|
} catch (e) {
|
|
22808
22812
|
throw new Error(`${NETWORK_MSG} (${e?.message ?? String(e)})`);
|
|
22809
22813
|
}
|
|
22810
22814
|
}
|
|
22811
|
-
function addErrorMessage(res,
|
|
22815
|
+
function addErrorMessage(res, key22, errorMessage, refs) {
|
|
22812
22816
|
if (!refs?.errorMessages)
|
|
22813
22817
|
return;
|
|
22814
22818
|
if (errorMessage) {
|
|
22815
22819
|
res.errorMessage = {
|
|
22816
22820
|
...res.errorMessage,
|
|
22817
|
-
[
|
|
22821
|
+
[key22]: errorMessage
|
|
22818
22822
|
};
|
|
22819
22823
|
}
|
|
22820
22824
|
}
|
|
22821
|
-
function setResponseValueAndErrors(res,
|
|
22822
|
-
res[
|
|
22823
|
-
addErrorMessage(res,
|
|
22825
|
+
function setResponseValueAndErrors(res, key22, value, errorMessage, refs) {
|
|
22826
|
+
res[key22] = value;
|
|
22827
|
+
addErrorMessage(res, key22, errorMessage, refs);
|
|
22824
22828
|
}
|
|
22825
22829
|
function parseAnyDef(refs) {
|
|
22826
22830
|
if (refs.target !== "openAi") {
|
|
@@ -23283,11 +23287,11 @@ function parseRecordDef(def, refs) {
|
|
|
23283
23287
|
return {
|
|
23284
23288
|
type: "object",
|
|
23285
23289
|
required: def.keyType._def.values,
|
|
23286
|
-
properties: def.keyType._def.values.reduce((acc,
|
|
23290
|
+
properties: def.keyType._def.values.reduce((acc, key22) => ({
|
|
23287
23291
|
...acc,
|
|
23288
|
-
[
|
|
23292
|
+
[key22]: parseDef(def.valueType._def, {
|
|
23289
23293
|
...refs,
|
|
23290
|
-
currentPath: [...refs.currentPath, "properties",
|
|
23294
|
+
currentPath: [...refs.currentPath, "properties", key22]
|
|
23291
23295
|
}) ?? parseAnyDef(refs)
|
|
23292
23296
|
}), {}),
|
|
23293
23297
|
additionalProperties: refs.rejectedAdditionalProperties
|
|
@@ -23350,10 +23354,10 @@ function parseMapDef(def, refs) {
|
|
|
23350
23354
|
}
|
|
23351
23355
|
function parseNativeEnumDef(def) {
|
|
23352
23356
|
const object = def.values;
|
|
23353
|
-
const actualKeys = Object.keys(def.values).filter((
|
|
23354
|
-
return typeof object[object[
|
|
23357
|
+
const actualKeys = Object.keys(def.values).filter((key22) => {
|
|
23358
|
+
return typeof object[object[key22]] !== "number";
|
|
23355
23359
|
});
|
|
23356
|
-
const actualValues = actualKeys.map((
|
|
23360
|
+
const actualValues = actualKeys.map((key22) => object[key22]);
|
|
23357
23361
|
const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values)));
|
|
23358
23362
|
return {
|
|
23359
23363
|
type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : ["string", "number"],
|
|
@@ -23687,8 +23691,8 @@ function mcpInputSchema(s) {
|
|
|
23687
23691
|
return draft2020(schema);
|
|
23688
23692
|
}
|
|
23689
23693
|
function sessionSlot(sessionId2) {
|
|
23690
|
-
const
|
|
23691
|
-
return `session:${
|
|
23694
|
+
const id22 = sessionId2 ?? sessionId();
|
|
23695
|
+
return `session:${id22.slice(0, 8)}`;
|
|
23692
23696
|
}
|
|
23693
23697
|
function agentName() {
|
|
23694
23698
|
return process.env.PAIGY_AGENT || sessionSlot();
|
|
@@ -23743,12 +23747,15 @@ function updateSlot(agent2, patch) {
|
|
|
23743
23747
|
}
|
|
23744
23748
|
function slotIdentity(agent2) {
|
|
23745
23749
|
const t = readTokenFile()[agent2];
|
|
23746
|
-
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 };
|
|
23750
|
+
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 };
|
|
23747
23751
|
}
|
|
23748
23752
|
function readToken(agent2 = agentName()) {
|
|
23749
23753
|
if (process.env.PAIGY_TOKEN) return process.env.PAIGY_TOKEN;
|
|
23750
23754
|
return readTokenFile()[agent2]?.access_token ?? "";
|
|
23751
23755
|
}
|
|
23756
|
+
function readSlot(agent2) {
|
|
23757
|
+
return readTokenFile()[agent2]?.access_token ?? "";
|
|
23758
|
+
}
|
|
23752
23759
|
function listSlots() {
|
|
23753
23760
|
return Object.keys(readTokenFile());
|
|
23754
23761
|
}
|
|
@@ -23831,11 +23838,16 @@ async function updateGoal(goalId, input, opts = {}) {
|
|
|
23831
23838
|
if (!res.ok) await fail("update_goal", res);
|
|
23832
23839
|
return await res.json();
|
|
23833
23840
|
}
|
|
23834
|
-
async function hatch(name, voice = null) {
|
|
23835
|
-
const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/hatch`, {
|
|
23841
|
+
async function hatch(name, voice = null, opts = {}) {
|
|
23842
|
+
const res = await ensureAuthed(await (opts.reach ?? reach)(`${BACKEND_URL}/api/hatch`, {
|
|
23836
23843
|
method: "POST",
|
|
23837
23844
|
headers: { "content-type": "application/json", authorization: `Bearer ${authToken()}` },
|
|
23838
|
-
body: JSON.stringify({
|
|
23845
|
+
body: JSON.stringify({
|
|
23846
|
+
name,
|
|
23847
|
+
voice,
|
|
23848
|
+
...opts.brief ? { brief: opts.brief } : {},
|
|
23849
|
+
...opts.parentGoalId ? { parentGoalId: opts.parentGoalId } : {}
|
|
23850
|
+
})
|
|
23839
23851
|
}));
|
|
23840
23852
|
if (!res.ok) throw new Error(`hatch failed: ${res.status} ${await res.text()}`);
|
|
23841
23853
|
return await res.json();
|
|
@@ -23885,7 +23897,9 @@ async function recordDecision(decision, opts = {}) {
|
|
|
23885
23897
|
async function heartbeat(runtime, opts = {}) {
|
|
23886
23898
|
const body = {
|
|
23887
23899
|
...runtime !== void 0 ? { runtime } : {},
|
|
23888
|
-
...opts.activity !== void 0 ? { activity: opts.activity } : {}
|
|
23900
|
+
...opts.activity !== void 0 ? { activity: opts.activity } : {},
|
|
23901
|
+
// A listener's beat (`paigy-listen`): stamps when it last swept, and is not presence.
|
|
23902
|
+
...opts.listening ? { listening: true } : {}
|
|
23889
23903
|
};
|
|
23890
23904
|
const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/presence`, {
|
|
23891
23905
|
method: "POST",
|
|
@@ -23968,6 +23982,7 @@ async function contact(input, opts = {}) {
|
|
|
23968
23982
|
let deliveryId;
|
|
23969
23983
|
let deliveries = [];
|
|
23970
23984
|
let recorded = [];
|
|
23985
|
+
let demoted;
|
|
23971
23986
|
if ("deliveryId" in parsed) {
|
|
23972
23987
|
deliveryId = parsed.deliveryId;
|
|
23973
23988
|
} else {
|
|
@@ -23998,13 +24013,14 @@ async function contact(input, opts = {}) {
|
|
|
23998
24013
|
if (!res.ok) await fail("batch contact", res);
|
|
23999
24014
|
const receipt = await res.json();
|
|
24000
24015
|
deliveries = receipt.deliveries ?? [];
|
|
24016
|
+
if (parsed.channel === "call" && receipt.channel && receipt.channel !== "call") demoted = DEMOTED;
|
|
24001
24017
|
recorded = receipt.recorded ?? [];
|
|
24002
24018
|
if (deliveries.length === 0 && recorded.length) return { sent: false, recorded, message: NOT_SENT };
|
|
24003
24019
|
if (deliveries.length === 0) throw new Error("Goal contact returned no Delivery identities");
|
|
24004
24020
|
deliveryId = deliveries[0]?.deliveryId ?? "";
|
|
24005
24021
|
if (!deliveryId) throw new Error("Goal contact returned no valid Delivery identity");
|
|
24006
24022
|
}
|
|
24007
|
-
const all = deliveries.filter((d) => !!d.deliveryId && !!d.goalId).map(({ id, deliveryId: deliveryId2, goalId }) => ({ ...
|
|
24023
|
+
const all = deliveries.filter((d) => !!d.deliveryId && !!d.goalId).map(({ id: id22, deliveryId: deliveryId2, goalId }) => ({ ...id22 ? { id: id22 } : {}, deliveryId: deliveryId2, goalId }));
|
|
24008
24024
|
const joinedCard = deliveries[0]?.joinedCard === true;
|
|
24009
24025
|
const joinedCall = deliveries[0]?.joinedCall === true;
|
|
24010
24026
|
const read = async (signal2) => {
|
|
@@ -24016,7 +24032,8 @@ async function contact(input, opts = {}) {
|
|
|
24016
24032
|
...all.length > 1 ? { deliveries: all } : {},
|
|
24017
24033
|
...recorded.length ? { recorded, notSent: NOT_SENT } : {},
|
|
24018
24034
|
...joinedCard ? { joinedCard: true } : {},
|
|
24019
|
-
...joinedCall ? { joinedCall: true } : {}
|
|
24035
|
+
...joinedCall ? { joinedCall: true } : {},
|
|
24036
|
+
...demoted ? { demoted } : {}
|
|
24020
24037
|
};
|
|
24021
24038
|
};
|
|
24022
24039
|
const settled = (d) => d.kind === "notification" || d.state === "closed" || d.answers.length > 0 || d.entries.some((e) => e.kind === "contribution");
|
|
@@ -24148,9 +24165,9 @@ function connect(line) {
|
|
|
24148
24165
|
ws.addEventListener("error", again);
|
|
24149
24166
|
}
|
|
24150
24167
|
function subscribeRealtime(args) {
|
|
24151
|
-
const
|
|
24152
|
-
let line = lines.get(
|
|
24153
|
-
if (!line) lines.set(
|
|
24168
|
+
const key22 = `${args.url} ${args.anonKey}`;
|
|
24169
|
+
let line = lines.get(key22);
|
|
24170
|
+
if (!line) lines.set(key22, line = { url: args.url, anonKey: args.anonKey, open: false, attempt: 0, ref: 0, topics: /* @__PURE__ */ new Map() });
|
|
24154
24171
|
let t = line.topics.get(args.topic);
|
|
24155
24172
|
if (!t) {
|
|
24156
24173
|
line.topics.set(args.topic, t = { listeners: /* @__PURE__ */ new Set(), joined: false, attempt: 0 });
|
|
@@ -24172,7 +24189,7 @@ function subscribeRealtime(args) {
|
|
|
24172
24189
|
if (line.open) frame(line, `realtime:${args.topic}`, "phx_leave", {});
|
|
24173
24190
|
return;
|
|
24174
24191
|
}
|
|
24175
|
-
lines.delete(
|
|
24192
|
+
lines.delete(key22);
|
|
24176
24193
|
stop(line);
|
|
24177
24194
|
try {
|
|
24178
24195
|
line.ws?.close();
|
|
@@ -24204,7 +24221,29 @@ async function subscribeWake(onNudge, opts = {}) {
|
|
|
24204
24221
|
}
|
|
24205
24222
|
};
|
|
24206
24223
|
}
|
|
24207
|
-
|
|
24224
|
+
function withCodexEnv(text) {
|
|
24225
|
+
const head = /^\[mcp_servers\.paigy\][ \t]*(?:#[^\n]*)?\r?\n/m.exec(text);
|
|
24226
|
+
if (!head) return null;
|
|
24227
|
+
const start = head.index + head[0].length;
|
|
24228
|
+
const next = /^\[/m.exec(text.slice(start));
|
|
24229
|
+
const end = next ? start + next.index : text.length;
|
|
24230
|
+
const block2 = text.slice(start, end);
|
|
24231
|
+
const assignment = /^[ \t]*env_vars[ \t]*=/m.exec(block2);
|
|
24232
|
+
let updated;
|
|
24233
|
+
if (!assignment) updated = `env_vars = [${CODEX_ENV.map((v) => JSON.stringify(v)).join(", ")}]
|
|
24234
|
+
${block2}`;
|
|
24235
|
+
else {
|
|
24236
|
+
const array = /^[ \t]*env_vars[ \t]*=[ \t]*\[((?:#[^\n]*|[^\]"'#]|"[^"\n]*"|'[^'\n]*')*)\]/m.exec(block2);
|
|
24237
|
+
if (!array) return null;
|
|
24238
|
+
const existing = [...array[1].matchAll(/"([^"\n]*)"|'([^'\n]*)'|#[^\n]*/g)].flatMap((m) => m[0].startsWith("#") ? [] : [m[1] ?? m[2]]);
|
|
24239
|
+
const missing2 = CODEX_ENV.filter((v) => !existing.includes(v));
|
|
24240
|
+
if (!missing2.length) return text;
|
|
24241
|
+
const opening = array.index + array[0].indexOf("[") + 1;
|
|
24242
|
+
updated = block2.slice(0, opening) + missing2.map((v) => JSON.stringify(v)).join(", ") + (existing.length ? ", " : "") + block2.slice(opening);
|
|
24243
|
+
}
|
|
24244
|
+
return text.slice(0, start) + updated + text.slice(end);
|
|
24245
|
+
}
|
|
24246
|
+
var import_undici, require2, CODEX_ENV, BACKEND_URL, NETWORK_MSG, PROXY_ENV, agent, INSTANCE_ID, WORKSPACE_ID, envSession, lineage, CLIENT, ignoreOverride, defaultOptions, getDefaultOptions, getRefs, getRelativePath, parseCatchDef, integerDateParser, isJsonSchema7AllOfType, emojiRegex2, zodPatterns, ALPHA_NUMERIC, primitiveMappings, asAnyOf, parseOptionalDef, parsePipelineDef, parseReadonlyDef, selectParser, get$ref, addMeta, zodToJsonSchema, OPTIONS_MIN, OPTIONS_MAX, OptionSchema, OptionInputSchema, NIGHT, AskInputSchema, StartContactSchema, ContactSchema, CONTACT_SCHEMA, CONTACT_DESCRIPTION, CreateGoalSchema, CreateGoalToolSchema, CREATE_GOAL_DESCRIPTION, UpdateGoalSchema, UpdateGoalToolSchema, ClaimGoalSchema, GetGoalSchema, GET_GOAL_DESCRIPTION, UPDATE_GOAL_DESCRIPTION, CLAIM_GOAL_DESCRIPTION, CHECK_REPLIES_DESCRIPTION, CheckRepliesSchema, AGENT_TOOLS, AGENT_TOOL_NAMES, id, key, participant, SourceSchema, ResultRefSchema, NodeRefSchema, DependencySchema, goalState, existingGoalChanges, GoalChangeSchema, BrainGoalChangeSchema, option, QuestionChangeSchema, lessonScope, LessonChangeSchema, BrainNextSchema, messageBase, BrainMessageSchema, BrainSearchSchema, BrainResultSchema, str, strs, CompactResultSchema, COMPACT_RESULT_JSON_SCHEMA, LIVE_MS, WORKING_MS, ContextSchema, ParticipantSchema, TransformSchema, VisualSchema, NotifyLevelSchema, SelectShapeSchema, ReceiptEventSchema, AttentionSchema, NotifyRequestFields, NotifyRequestSchema, NotifyStatusSchema, AgentStateSchema, TurnSchema, UserAnswerSchema, IntentSchema, RideAlongSchema, AwaitItemSchema, VoiceKeySchema, AgendaTurnSchema, CLAIM_STALE_MS, InboxItemSchema, APNS_TOKEN_RE, PushTokenSchema, MissedCallSchema, clock, QUIET, BrokerTuningSchema, UserSettingsSchema, HistoryWorkSchema, HistoryEntrySchema, HistoryPageSchema, ACTIVITY_LINES, ACTIVITY_LINE_MAX, AgentActivitySchema, ConnectionSummarySchema, LedgerItemSchema, AgentLedgerSchema, ReassignResultSchema, MoveRingSchema, MoveSchema, QueueQuestionSchema, QueueReplySchema, QueueItemSchema, QueueDeltaSchema, COLD_AFTER_MS, NoteSourceSchema, NoteStatusSchema, NoteRepeatSchema, DecisionSchema, NoteSchema, TriageItemSchema, TriageAssignmentSchema, TriageStatusSchema, SubmitTriageSchema, TriageProposalSchema, AcceptTriageSchema, AcceptTriageResultSchema, DeliveryModeSchema, WAKE_EVENT, wakeChannel, RegisterDeliverySchema, OAuthStartSchema, DeliveryConfigSchema, HostDecisionSchema, WakeNudgeSchema, PairingStatusSchema, DeviceCodeSchema, DeviceInfoSchema, DeviceTokenSchema, SupportRequestSchema, NotificationFeedbackKindSchema, SlimOptionSchema, QuestionRowSchema, WorkStateSchema, WorkRowSchema, ComputerRowSchema, AgentRowSchema, SnapshotSchema, CallRecapSchema, TOKEN_PATH, KEY_PATH, sleep, UnpairedError, RevokedError, ApiError, tokenOverride, authToken, AWAIT_WINDOW_MS, asked, NOT_SENT, DEMOTED, HEARTBEAT_MS, RETRY_MS, JOIN, JOIN_TIMEOUT_MS, lines;
|
|
24208
24247
|
var init_dist = __esm({
|
|
24209
24248
|
"../../packages/sdk/dist/index.js"() {
|
|
24210
24249
|
"use strict";
|
|
@@ -24215,8 +24254,10 @@ var init_dist = __esm({
|
|
|
24215
24254
|
init_v3();
|
|
24216
24255
|
init_v3();
|
|
24217
24256
|
init_zod();
|
|
24257
|
+
init_zod();
|
|
24218
24258
|
import_undici = __toESM(require_undici(), 1);
|
|
24219
24259
|
require2 = __sdkCreateRequire(import.meta.url);
|
|
24260
|
+
CODEX_ENV = ["CODEX_THREAD_ID", "CODEX_SESSION_ID", "CODEX_HOME", "PAIGY_TOKEN", "PAIGY_SESSION_ID", "PAIGY_HARNESS", "PAIGY_INSTANCE_ID", "PAIGY_ON_WAKE"];
|
|
24220
24261
|
BACKEND_URL = process.env.PAIGY_BACKEND_URL ?? "https://paigy.ai";
|
|
24221
24262
|
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.`;
|
|
24222
24263
|
PROXY_ENV = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"];
|
|
@@ -24228,8 +24269,8 @@ var init_dist = __esm({
|
|
|
24228
24269
|
return INSTANCE_ID;
|
|
24229
24270
|
}
|
|
24230
24271
|
})();
|
|
24231
|
-
envSession = (
|
|
24232
|
-
const v = process.env[
|
|
24272
|
+
envSession = (key22) => {
|
|
24273
|
+
const v = process.env[key22];
|
|
24233
24274
|
return v && v.trim() ? v : void 0;
|
|
24234
24275
|
};
|
|
24235
24276
|
ignoreOverride = /* @__PURE__ */ Symbol("Let zodToJsonSchema decide on which parser to use");
|
|
@@ -24614,34 +24655,31 @@ var init_dist = __esm({
|
|
|
24614
24655
|
NIGHT = { from: 23, to: 7 };
|
|
24615
24656
|
AskInputSchema = external_exports.object({
|
|
24616
24657
|
id: external_exports.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
|
|
24617
|
-
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
|
|
24658
|
+
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."),
|
|
24618
24659
|
repo: external_exports.string().optional().describe("Optional repository context."),
|
|
24619
24660
|
ask: external_exports.string().trim().min(1).max(1e4).describe(
|
|
24620
|
-
"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
|
|
24661
|
+
"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."
|
|
24621
24662
|
),
|
|
24622
24663
|
options: external_exports.array(OptionInputSchema).min(1).max(6).optional(),
|
|
24623
|
-
//
|
|
24624
|
-
//
|
|
24625
|
-
//
|
|
24626
|
-
//
|
|
24627
|
-
// as "All three / 1 and 3 only / Just log it", which the person could not read without the text and
|
|
24628
|
-
// could not answer as the ticks he wanted. "many" is the one shape an agent knows and the read does
|
|
24629
|
-
// not: whether its own options exclude each other.
|
|
24664
|
+
// HOW THE OPTIONS ARE ANSWERED, SAID BY THE AGENT (owner, 2026-10-02: "one and many makes sense";
|
|
24665
|
+
// brain_prompts.md §1: structured agent questions need no model). Every card was pick-one while no
|
|
24666
|
+
// agent sent this; no read reshapes cards any more, so this is the card's shape, and the
|
|
24667
|
+
// description says so plainly.
|
|
24630
24668
|
select: external_exports.enum(["one", "many"]).optional().describe(
|
|
24631
|
-
'How the options are answered: "
|
|
24669
|
+
'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.'
|
|
24632
24670
|
),
|
|
24633
24671
|
answers: external_exports.string().trim().regex(/^[0-9a-fA-F-]{8,36}$/).optional().describe(
|
|
24634
24672
|
"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. Needs parentId: the Goal the question is on. The reply is sent to them as it is; to also ask something new, send that as its own ask."
|
|
24635
24673
|
)
|
|
24636
24674
|
}).strict();
|
|
24637
24675
|
StartContactSchema = external_exports.object({
|
|
24638
|
-
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;
|
|
24676
|
+
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."),
|
|
24639
24677
|
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."),
|
|
24640
24678
|
channel: external_exports.enum(["notification", "call"]).default("notification")
|
|
24641
24679
|
}).strict();
|
|
24642
24680
|
ContactSchema = external_exports.union([StartContactSchema, external_exports.object({ deliveryId: external_exports.string().uuid() }).strict()]);
|
|
24643
24681
|
CONTACT_SCHEMA = { type: "object", ...mcpInputSchema(ContactSchema) };
|
|
24644
|
-
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
|
|
24682
|
+
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.";
|
|
24645
24683
|
CreateGoalSchema = external_exports.object({
|
|
24646
24684
|
outcome: external_exports.string().trim().min(1).max(1e4),
|
|
24647
24685
|
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
|
|
@@ -24664,7 +24702,7 @@ var init_dist = __esm({
|
|
|
24664
24702
|
CreateGoalToolSchema = CreateGoalSchema.extend({
|
|
24665
24703
|
idempotencyKey: CreateGoalSchema.shape.idempotencyKey.optional().describe("Optional. One is minted per call; pass your own only so a retry lands on the same Goal.")
|
|
24666
24704
|
}).strict();
|
|
24667
|
-
CREATE_GOAL_DESCRIPTION = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only:
|
|
24705
|
+
CREATE_GOAL_DESCRIPTION = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
|
|
24668
24706
|
UpdateGoalSchema = external_exports.object({
|
|
24669
24707
|
revision: external_exports.number().int().positive(),
|
|
24670
24708
|
changes: external_exports.object({
|
|
@@ -24700,12 +24738,13 @@ var init_dist = __esm({
|
|
|
24700
24738
|
* between two of them named. Off by default; `docs/model/goal/diagnose-design.md`. */
|
|
24701
24739
|
diagnose: external_exports.boolean().optional()
|
|
24702
24740
|
}).strict();
|
|
24703
|
-
GET_GOAL_DESCRIPTION = "Read one Goal without claiming it: its outcome, state, revision, progress, blockers, the conversation on it (each question with its options and what was decided), `next`, the one step to take, and `more`, where to read further. A question in that conversation reads `open` (nothing yet), `answered` (a choice was made, and `answer` carries it), `replied` (they said something and the read settled the question on their words \u2014 NO option of yours was chosen, and the words are the reply line beside it, so read that before you act), or `closed`. The conversation carries everything the person said, every open question and your newest entry; your older entries are left out and counted \u2014 history: true reads every entry in full.
|
|
24704
|
-
UPDATE_GOAL_DESCRIPTION = `Update
|
|
24705
|
-
CLAIM_GOAL_DESCRIPTION = "Claim the oldest runnable or review-pending Goal you own
|
|
24741
|
+
GET_GOAL_DESCRIPTION = "Read one Goal without claiming it, including others (the ten most recent other contributors, with names, latest entry headlines and times): its outcome, state, revision, progress, blockers, the conversation on it (each question with its options and what was decided), `next`, the one step to take, and `more`, where to read further. A question in that conversation reads `open` (nothing yet), `answered` (a choice was made, and `answer` carries it), `replied` (they said something and the read settled the question on their words \u2014 NO option of yours was chosen, and the words are the reply line beside it, so read that before you act), or `closed`. The conversation carries everything the person said, every open question and your newest entry; your older entries are left out and counted \u2014 history: true reads every entry in full. Every Goal of your person is readable, whichever of their agents owns it; another account's Goals are not disclosed.\n\ndiagnose: true is for when a read has CONFUSED you \u2014 not for the working loop. It adds `diagnosis`, which asks every reader that already answers a question about your work and NAMES the reader behind every value, so you never guess which of two places to look: what state your work is really in (the stored `goals.state` beside the derived `goal_execution_state`, which can differ); whether anything is armed to ring and when (`ladder_candidates`, with the ladder's own last decision); whether a wake fired for you and what it did (durable `wake.*` events, beside when your process was last heard from); and what has reached you (`list_waiting` \u2014 review flags, unstarted work, open questions, the person's newest words). Read `diagnosis.disagreements` FIRST: each one is two readers giving different values for the same fact, with both values and both sources, and it never chooses between them \u2014 that is yours to do, from the Goal's own history. `diagnosis.looked` names every reader asked, including any that could not answer, so an empty answer is never confused with a broken one.";
|
|
24742
|
+
UPDATE_GOAL_DESCRIPTION = `Update a Goal you are on at an exact revision. You are on a Goal you own, or one you have written on (an update with progress, or a contact on it); any of your person's agents may write on any of their Goals, and one that never touched a Goal is refused (409 goal_not_joined). State, ownership, dependencies, children, progress, title, and review acknowledgement are explicit; stale revisions are rejected. A CONTACT ON THIS GOAL MOVES ITS REVISION: a question filed on a Goal is a change to it, so an update prepared before a contact and sent after it is refused as stale (409 goal_revision_conflict) \u2014 re-read the Goal, then write. title is the work's name in one to five words, as a person would refer to it out loud (it is spoken on a call and heads every list); null clears it. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. dueAt (an ISO instant, or null) makes the Goal wait until then; when it passes you are woken for it \u2014 use it for a promise to follow up later. withdraw: [questionId] takes back a question YOU asked on this Goal that is still open \u2014 because you acted on it yourself, it no longer matters, or you asked it wrongly (e.g. waiting: hard when nothing was blocked): it is cancelled, not answered, its card closes and it stops ringing; the id is the one the conversation shows. state: done means the work was accomplished, and it can be reopened: when the person says it is not done ("it's not working"), set state: active on that same Goal instead of starting a new one; its parent reopens with it. state: done while children are still open records your part as done: the Goal waits and closes by itself when its last open child closes. cancelled is final. Returns the Goal as get_goal reads it, at its new revision.`;
|
|
24743
|
+
CLAIM_GOAL_DESCRIPTION = "Claim a pending answer to your question or the oldest runnable or review-pending Goal you own. Pass goalId to join any Goal of your person; its assignment stays unchanged. Read others before overlapping another agent\u2019s work. Joining lets you contribute and change its state; use update_goal with ownerParticipant when the assignment itself should change. Returns the Goal as get_goal reads it, and marks you as on it, which never shuts another agent out: other agents of your person may write on it and change it too, and two changes at once are told apart by revision (409 goal_revision_conflict).";
|
|
24706
24744
|
CHECK_REPLIES_DESCRIPTION = "What is waiting for you: your open Deliveries (a request the user started toward you, a handoff), one row each with its Goals, how many decisions are still open, and the newest words in brief; `assigned`, your Goals nobody has started yet, however they became yours (claim_goal({goalId}) starts one); and `review`, your Goals with something new on them \u2014 the user's answers and notes are Entries on the Goal, not Deliveries. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread a Delivery in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true clears the Goal from `review` and closes the Deliveries addressed to you on it.";
|
|
24707
24745
|
CheckRepliesSchema = external_exports.object({}).strict();
|
|
24708
24746
|
AGENT_TOOLS = [
|
|
24747
|
+
{ name: "who_is_working", description: "Read your person's agents that contributed in the last 24 hours, newest first: at most 30 agents and their five most recently touched Goals, with their latest entry headline and time. Use get_goal to read a Goal and its other contributors before starting overlapping work. Read-only; no arguments.", inputSchema: mcpInputSchema(CheckRepliesSchema) },
|
|
24709
24748
|
{ name: "contact", description: CONTACT_DESCRIPTION, inputSchema: CONTACT_SCHEMA },
|
|
24710
24749
|
{ name: "check_replies", description: CHECK_REPLIES_DESCRIPTION, inputSchema: mcpInputSchema(CheckRepliesSchema) },
|
|
24711
24750
|
{ name: "create_goal", description: CREATE_GOAL_DESCRIPTION, inputSchema: mcpInputSchema(CreateGoalToolSchema) },
|
|
@@ -24714,8 +24753,158 @@ var init_dist = __esm({
|
|
|
24714
24753
|
{ name: "update_goal", description: UPDATE_GOAL_DESCRIPTION, inputSchema: mcpInputSchema(UpdateGoalToolSchema) }
|
|
24715
24754
|
];
|
|
24716
24755
|
AGENT_TOOL_NAMES = AGENT_TOOLS.map((t) => t.name);
|
|
24756
|
+
id = external_exports.string().uuid();
|
|
24757
|
+
key = external_exports.string().min(1).max(40);
|
|
24758
|
+
participant = external_exports.string().regex(/^(human|agent):.+$/, "a participant ID such as agent:<uuid>");
|
|
24759
|
+
SourceSchema = external_exports.object({
|
|
24760
|
+
entryId: id,
|
|
24761
|
+
span: external_exports.object({ start: external_exports.number().int().min(0), end: external_exports.number().int().min(1) }).strict().refine((s) => s.end > s.start, "a span ends after it starts").optional()
|
|
24762
|
+
}).strict();
|
|
24763
|
+
ResultRefSchema = external_exports.union([external_exports.object({ id }).strict(), external_exports.object({ local: key }).strict()]);
|
|
24764
|
+
NodeRefSchema = external_exports.object({ type: external_exports.enum(["goal", "question"]), id }).strict();
|
|
24765
|
+
DependencySchema = external_exports.object({
|
|
24766
|
+
blocker: NodeRefSchema,
|
|
24767
|
+
blocked: NodeRefSchema,
|
|
24768
|
+
action: external_exports.enum(["start", "complete", "answer"]),
|
|
24769
|
+
reason: external_exports.string().max(500).optional()
|
|
24770
|
+
}).strict();
|
|
24771
|
+
goalState = external_exports.enum(["open", "completed", "canceled"]);
|
|
24772
|
+
existingGoalChanges = [
|
|
24773
|
+
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"),
|
|
24774
|
+
external_exports.object({ kind: external_exports.literal("state"), goalId: id, state: goalState }).strict(),
|
|
24775
|
+
external_exports.object({ kind: external_exports.literal("assign"), goalId: id, ownerId: participant }).strict(),
|
|
24776
|
+
external_exports.object({ kind: external_exports.literal("defer"), goalId: id, until: external_exports.string().datetime().nullable() }).strict(),
|
|
24777
|
+
external_exports.object({ kind: external_exports.literal("move"), goalId: id, parentGoalId: id.nullable() }).strict(),
|
|
24778
|
+
external_exports.object({
|
|
24779
|
+
kind: external_exports.literal("dependency"),
|
|
24780
|
+
change: external_exports.enum(["add", "remove"]),
|
|
24781
|
+
goalId: id,
|
|
24782
|
+
dependsOnGoalId: id,
|
|
24783
|
+
action: external_exports.enum(["start", "complete"]),
|
|
24784
|
+
reason: external_exports.string().max(500).optional()
|
|
24785
|
+
}).strict()
|
|
24786
|
+
];
|
|
24787
|
+
GoalChangeSchema = external_exports.union([
|
|
24788
|
+
external_exports.object({
|
|
24789
|
+
kind: external_exports.literal("create"),
|
|
24790
|
+
title: external_exports.string().min(1).max(120),
|
|
24791
|
+
outcome: external_exports.string().min(1),
|
|
24792
|
+
ownerId: participant,
|
|
24793
|
+
parentGoalId: id.optional(),
|
|
24794
|
+
sourceEntryIds: external_exports.array(id)
|
|
24795
|
+
}).strict(),
|
|
24796
|
+
...existingGoalChanges
|
|
24797
|
+
]);
|
|
24798
|
+
BrainGoalChangeSchema = external_exports.union([
|
|
24799
|
+
// newSession: Paigy starts a session to own it (owner, 2026-10-06); until it has, the person owns it.
|
|
24800
|
+
external_exports.object({
|
|
24801
|
+
kind: external_exports.literal("create"),
|
|
24802
|
+
outcome: external_exports.string().min(1),
|
|
24803
|
+
title: external_exports.string().min(1).max(120),
|
|
24804
|
+
ownerId: participant,
|
|
24805
|
+
parentGoal: ResultRefSchema.nullable(),
|
|
24806
|
+
newSession: external_exports.literal(true).optional()
|
|
24807
|
+
}).strict(),
|
|
24808
|
+
...existingGoalChanges
|
|
24809
|
+
]);
|
|
24810
|
+
option = external_exports.object({ id: external_exports.string().min(1).max(40), label: external_exports.string().min(1), hint: external_exports.string().optional() }).strict();
|
|
24811
|
+
QuestionChangeSchema = external_exports.union([
|
|
24812
|
+
external_exports.object({
|
|
24813
|
+
kind: external_exports.literal("create"),
|
|
24814
|
+
text: external_exports.string().min(1),
|
|
24815
|
+
answererId: participant,
|
|
24816
|
+
goal: ResultRefSchema.optional(),
|
|
24817
|
+
blocks: external_exports.array(external_exports.object({ question: ResultRefSchema }).strict()),
|
|
24818
|
+
options: external_exports.array(option).min(2).optional(),
|
|
24819
|
+
pickMode: external_exports.enum(["one", "many", "rank"]).optional()
|
|
24820
|
+
}).strict().refine((c) => c.options === void 0 === (c.pickMode === void 0), "options and pickMode come together"),
|
|
24821
|
+
external_exports.object({ kind: external_exports.literal("edit"), questionId: id, text: external_exports.string().min(1) }).strict(),
|
|
24822
|
+
external_exports.object({ kind: external_exports.literal("assign"), questionId: id, answererId: participant }).strict(),
|
|
24823
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), questionId: id }).strict(),
|
|
24824
|
+
external_exports.object({ kind: external_exports.literal("dependency"), change: external_exports.enum(["add", "remove"]), edge: DependencySchema }).strict()
|
|
24825
|
+
]);
|
|
24826
|
+
lessonScope = external_exports.union([
|
|
24827
|
+
external_exports.object({ kind: external_exports.literal("user") }).strict(),
|
|
24828
|
+
external_exports.object({ kind: external_exports.literal("goal"), goal: ResultRefSchema }).strict()
|
|
24829
|
+
]);
|
|
24830
|
+
LessonChangeSchema = external_exports.union([
|
|
24831
|
+
external_exports.object({ kind: external_exports.literal("remember"), text: external_exports.string().min(1), scope: lessonScope }).strict(),
|
|
24832
|
+
external_exports.object({ kind: external_exports.literal("revise"), lessonId: id, text: external_exports.string().min(1), scope: lessonScope }).strict(),
|
|
24833
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), lessonId: id }).strict()
|
|
24834
|
+
]);
|
|
24835
|
+
BrainNextSchema = external_exports.object({
|
|
24836
|
+
instructions: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key).min(1) }).strict()),
|
|
24837
|
+
say: external_exports.array(key),
|
|
24838
|
+
then: external_exports.enum(["listen", "hold", "end", "none"]),
|
|
24839
|
+
waitFor: external_exports.array(ResultRefSchema),
|
|
24840
|
+
reason: external_exports.string()
|
|
24841
|
+
}).strict();
|
|
24842
|
+
messageBase = {
|
|
24843
|
+
key,
|
|
24844
|
+
text: external_exports.string().min(1),
|
|
24845
|
+
goals: external_exports.array(ResultRefSchema),
|
|
24846
|
+
questions: external_exports.array(ResultRefSchema),
|
|
24847
|
+
entryKeys: external_exports.array(key),
|
|
24848
|
+
obligationIds: external_exports.array(id)
|
|
24849
|
+
};
|
|
24850
|
+
BrainMessageSchema = external_exports.union([
|
|
24851
|
+
external_exports.object({ ...messageBase, to: external_exports.object({ kind: external_exports.literal("user") }).strict() }).strict(),
|
|
24852
|
+
external_exports.object({
|
|
24853
|
+
...messageBase,
|
|
24854
|
+
to: external_exports.object({ kind: external_exports.literal("session"), sessionId: id }).strict(),
|
|
24855
|
+
call: external_exports.object({ callId: id, listen: external_exports.literal(true) }).strict().optional()
|
|
24856
|
+
}).strict()
|
|
24857
|
+
]);
|
|
24858
|
+
BrainSearchSchema = external_exports.object({
|
|
24859
|
+
query: external_exports.string().min(1).max(500),
|
|
24860
|
+
within: external_exports.array(external_exports.enum(["entries", "goals", "answers"])).min(1),
|
|
24861
|
+
goalId: id.optional()
|
|
24862
|
+
}).strict();
|
|
24863
|
+
BrainResultSchema = external_exports.object({
|
|
24864
|
+
messages: external_exports.array(BrainMessageSchema),
|
|
24865
|
+
entries: external_exports.array(external_exports.object({ key, sources: external_exports.array(SourceSchema).min(1), goals: external_exports.array(ResultRefSchema) }).strict()),
|
|
24866
|
+
questions: external_exports.array(external_exports.object({ key, entryKeys: external_exports.array(key), change: QuestionChangeSchema }).strict()),
|
|
24867
|
+
answers: external_exports.array(external_exports.object({
|
|
24868
|
+
question: ResultRefSchema,
|
|
24869
|
+
entryKeys: external_exports.array(key).min(1),
|
|
24870
|
+
summary: external_exports.string().min(1),
|
|
24871
|
+
selectedOptionIds: external_exports.array(external_exports.string().min(1)).optional()
|
|
24872
|
+
}).strict()),
|
|
24873
|
+
goals: external_exports.array(external_exports.object({ key, entryKeys: external_exports.array(key), change: BrainGoalChangeSchema }).strict()),
|
|
24874
|
+
feedback: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key).min(1) }).strict()),
|
|
24875
|
+
lessons: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key).min(1), change: LessonChangeSchema }).strict()),
|
|
24876
|
+
next: BrainNextSchema,
|
|
24877
|
+
search: BrainSearchSchema.optional()
|
|
24878
|
+
}).strict();
|
|
24879
|
+
str = external_exports.string();
|
|
24880
|
+
strs = external_exports.array(external_exports.string());
|
|
24881
|
+
CompactResultSchema = external_exports.object({
|
|
24882
|
+
next: external_exports.object({ say: strs, then: external_exports.enum(["listen", "hold", "end", "none"]), waitFor: strs, reason: str, instructions: strs }).strict(),
|
|
24883
|
+
messages: external_exports.array(external_exports.object({ key: str, to: str, text: str, about: strs, entries: strs, owed: strs, inviteToCall: external_exports.boolean() }).strict()),
|
|
24884
|
+
entries: external_exports.array(external_exports.object({ key: str, from: str, start: external_exports.number().int(), end: external_exports.number().int(), on: strs }).strict()),
|
|
24885
|
+
answers: external_exports.array(external_exports.object({ question: str, entries: strs, summary: str, picked: strs }).strict()),
|
|
24886
|
+
changes: external_exports.array(external_exports.object({
|
|
24887
|
+
key: str,
|
|
24888
|
+
what: external_exports.enum(["goal", "question", "lesson"]),
|
|
24889
|
+
op: external_exports.enum(["create", "edit", "assign", "open", "complete", "cancel", "defer", "move", "block", "unblock", "withdraw", "remember", "revise"]),
|
|
24890
|
+
id: str,
|
|
24891
|
+
text: str,
|
|
24892
|
+
title: str,
|
|
24893
|
+
who: str,
|
|
24894
|
+
under: str,
|
|
24895
|
+
gate: external_exports.enum(["start", "complete", "answer", "none"]),
|
|
24896
|
+
options: external_exports.array(external_exports.object({ id: str, label: str }).strict()),
|
|
24897
|
+
pick: external_exports.enum(["one", "many", "rank", "words"]),
|
|
24898
|
+
entries: strs
|
|
24899
|
+
}).strict()),
|
|
24900
|
+
feedback: external_exports.array(strs),
|
|
24901
|
+
search: external_exports.object({ query: str, within: strs, goal: str }).strict()
|
|
24902
|
+
}).strict();
|
|
24903
|
+
COMPACT_RESULT_JSON_SCHEMA = (({ $schema: _, ...rest }) => rest)(
|
|
24904
|
+
zodToJsonSchema(CompactResultSchema, { $refStrategy: "none" })
|
|
24905
|
+
);
|
|
24717
24906
|
LIVE_MS = 3 * 6e4;
|
|
24718
|
-
WORKING_MS =
|
|
24907
|
+
WORKING_MS = 60 * 6e4;
|
|
24719
24908
|
ContextSchema = external_exports.object({
|
|
24720
24909
|
title: external_exports.string().min(1).describe("One-line headline of what you need (required, non-empty)."),
|
|
24721
24910
|
description: external_exports.array(external_exports.string().min(1)).describe(
|
|
@@ -24933,7 +25122,7 @@ var init_dist = __esm({
|
|
|
24933
25122
|
* (`parseDelay`, #1292), and a value here simply wins over that reading. */
|
|
24934
25123
|
dueInSeconds: external_exports.number().int().positive().optional(),
|
|
24935
25124
|
/** Feedback only (#812): WHICH failure the complaint names — typed by the mapper that
|
|
24936
|
-
* already read the utterance, so `
|
|
25125
|
+
* already read the utterance, so `signals.kind` stops defaulting to
|
|
24937
25126
|
* 'other' on every row. A table that records that something was wrong and nothing
|
|
24938
25127
|
* about what cannot answer "is the bot looping less this week?". */
|
|
24939
25128
|
fault: external_exports.enum(["loop", "unanswered", "overridden", "misheard", "slow", "other"]).optional()
|
|
@@ -25067,7 +25256,13 @@ var init_dist = __esm({
|
|
|
25067
25256
|
/** Whether the walk WAITS for an answer before moving on. Absent = derived as today
|
|
25068
25257
|
* (a question blocks, context flows). blocking:false on a question = ask and move
|
|
25069
25258
|
* on, the claim stays pending; blocking:true on context = hold for a reply. */
|
|
25070
|
-
blocking: external_exports.boolean().optional()
|
|
25259
|
+
blocking: external_exports.boolean().optional(),
|
|
25260
|
+
/** SPOKEN ONLY IF THEY SAY NOTHING (owner, 2026-10-01, call 812de935: "you're gonna re-ask, but it
|
|
25261
|
+
* shouldn't be the same words … more like, hey, are you still there, or are you able to answer, or
|
|
25262
|
+
* would you need more information"). The walk holds this turn out of its queue; at the queue's end it
|
|
25263
|
+
* listens for the last word, and only if that listen is silent is this turn said and asked. If they
|
|
25264
|
+
* speak, it is dropped and their words are taken like any reply. */
|
|
25265
|
+
ifSilent: external_exports.boolean().optional()
|
|
25071
25266
|
});
|
|
25072
25267
|
CLAIM_STALE_MS = 30 * 6e4;
|
|
25073
25268
|
InboxItemSchema = external_exports.object({
|
|
@@ -25211,7 +25406,18 @@ var init_dist = __esm({
|
|
|
25211
25406
|
/** THAT GOAL'S NAME (#2416) — what Activity's row is headed by, since a row there is one Goal
|
|
25212
25407
|
* and the cards it holds sit behind it. Stamped by the same read as `goalState`. */
|
|
25213
25408
|
goalTitle: external_exports.string().optional()
|
|
25214
|
-
}).optional()
|
|
25409
|
+
}).optional(),
|
|
25410
|
+
/** WHAT THIS CARD IS, IN TWELVE CHARACTERS (#3019) — the hash of every other field on it, stamped
|
|
25411
|
+
* by the one read that serves the open list (`apps/api/src/inbox/project.ts` `inboxFor`). It is
|
|
25412
|
+
* how the incremental read knows a card has not moved: the phone echoes back the revs it holds
|
|
25413
|
+
* (`POST /api/inbox/changes`) and is sent only the cards whose rev differs.
|
|
25414
|
+
*
|
|
25415
|
+
* THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK — the same mechanism as `QueueItem.rev`
|
|
25416
|
+
* (#2928) and an entry's (#3018), for the same reason: a card shows facts no `updated_at` of its
|
|
25417
|
+
* own moves (its Goal's state and name, how cold the work behind it has gone, whether a ring is
|
|
25418
|
+
* live). Optional, so a fixture, the demo and the archive lens need not spell one, and a card
|
|
25419
|
+
* with no rev is simply always re-sent. */
|
|
25420
|
+
rev: external_exports.string().optional()
|
|
25215
25421
|
});
|
|
25216
25422
|
APNS_TOKEN_RE = /^[0-9a-fA-F]{64}$/;
|
|
25217
25423
|
PushTokenSchema = external_exports.object({
|
|
@@ -25583,7 +25789,22 @@ var init_dist = __esm({
|
|
|
25583
25789
|
* minute after the person speaks erases their instant from it, and the durable traces the client
|
|
25584
25790
|
* can see (`replies`, `questions[].answeredAt`) miss a spontaneous note entirely — a `request`
|
|
25585
25791
|
* Entry with no `about_id` is in neither. */
|
|
25586
|
-
lastPersonAt: external_exports.string().nullable().optional()
|
|
25792
|
+
lastPersonAt: external_exports.string().nullable().optional(),
|
|
25793
|
+
/** WHAT THIS ROW IS, IN TWELVE CHARACTERS (#2928) — the hash of every other field on it, stamped
|
|
25794
|
+
* by the one projection that builds the row (`apps/api/src/goal/queue.ts`). It is how the
|
|
25795
|
+
* incremental read knows a row has not moved: the phone echoes back the revs it holds
|
|
25796
|
+
* (`POST /api/goals/changes`) and is sent only the rows whose rev differs.
|
|
25797
|
+
*
|
|
25798
|
+
* IT IS THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK. Nothing here reasons about which
|
|
25799
|
+
* writes change which field — the comparison is over the bytes the phone is holding, so a fact
|
|
25800
|
+
* the row shows that no `updated_at` moves for (a lease lapsing, a dependency's state, a
|
|
25801
|
+
* sibling appearing in `childGoalIds`) cannot go unnoticed. Optional because a hand-built
|
|
25802
|
+
* queue (a fixture, the demo) spells none, and a row with no rev is simply always re-sent. */
|
|
25803
|
+
rev: external_exports.string().optional()
|
|
25804
|
+
});
|
|
25805
|
+
QueueDeltaSchema = external_exports.object({
|
|
25806
|
+
ids: external_exports.array(external_exports.string()),
|
|
25807
|
+
items: external_exports.array(QueueItemSchema)
|
|
25587
25808
|
});
|
|
25588
25809
|
COLD_AFTER_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
25589
25810
|
NoteSourceSchema = external_exports.enum(["app", "call"]);
|
|
@@ -25756,6 +25977,11 @@ var init_dist = __esm({
|
|
|
25756
25977
|
/** Local host recovery must preserve the launch's runtime and Paigy identity. */
|
|
25757
25978
|
harness: external_exports.enum(["claude", "codex", "agy"]).optional(),
|
|
25758
25979
|
session_id: external_exports.string().uuid().optional(),
|
|
25980
|
+
/** A conversation the host must not resume: its context is full, so every turn fails
|
|
25981
|
+
* ("Prompt is too long"). Written when a run hits it (`run.ts` `onFull`); the host skips a slot
|
|
25982
|
+
* whose resumable session is this one, so its Goals reach the dead-agent handoff instead of a
|
|
25983
|
+
* copy that types the person's words into a turn that cannot run (Calls, 2026-10-06). */
|
|
25984
|
+
full_session: external_exports.string().optional(),
|
|
25759
25985
|
uik_pub: external_exports.string().nullable().optional()
|
|
25760
25986
|
});
|
|
25761
25987
|
SupportRequestSchema = external_exports.object({
|
|
@@ -25935,6 +26161,7 @@ var init_dist = __esm({
|
|
|
25935
26161
|
authToken = (explicit) => explicit ?? tokenOverride ?? readToken();
|
|
25936
26162
|
AWAIT_WINDOW_MS = 45e3;
|
|
25937
26163
|
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.";
|
|
26164
|
+
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.";
|
|
25938
26165
|
HEARTBEAT_MS = 25e3;
|
|
25939
26166
|
RETRY_MS = [1e3, 2e3, 5e3, 1e4, 3e4];
|
|
25940
26167
|
JOIN = { config: { broadcast: { self: false } } };
|
|
@@ -26837,14 +27064,14 @@ var require_regex = __commonJS({
|
|
|
26837
27064
|
var TEST_KANJI = new RegExp("^" + kanji + "$");
|
|
26838
27065
|
var TEST_NUMERIC = new RegExp("^" + numeric + "$");
|
|
26839
27066
|
var TEST_ALPHANUMERIC = new RegExp("^[A-Z0-9 $%*+\\-./:]+$");
|
|
26840
|
-
exports.testKanji = function testKanji(
|
|
26841
|
-
return TEST_KANJI.test(
|
|
27067
|
+
exports.testKanji = function testKanji(str3) {
|
|
27068
|
+
return TEST_KANJI.test(str3);
|
|
26842
27069
|
};
|
|
26843
|
-
exports.testNumeric = function testNumeric(
|
|
26844
|
-
return TEST_NUMERIC.test(
|
|
27070
|
+
exports.testNumeric = function testNumeric(str3) {
|
|
27071
|
+
return TEST_NUMERIC.test(str3);
|
|
26845
27072
|
};
|
|
26846
|
-
exports.testAlphanumeric = function testAlphanumeric(
|
|
26847
|
-
return TEST_ALPHANUMERIC.test(
|
|
27073
|
+
exports.testAlphanumeric = function testAlphanumeric(str3) {
|
|
27074
|
+
return TEST_ALPHANUMERIC.test(str3);
|
|
26848
27075
|
};
|
|
26849
27076
|
}
|
|
26850
27077
|
});
|
|
@@ -27294,11 +27521,11 @@ var require_dijkstra = __commonJS({
|
|
|
27294
27521
|
*/
|
|
27295
27522
|
PriorityQueue: {
|
|
27296
27523
|
make: function(opts) {
|
|
27297
|
-
var T = dijkstra.PriorityQueue, t = {},
|
|
27524
|
+
var T = dijkstra.PriorityQueue, t = {}, key3;
|
|
27298
27525
|
opts = opts || {};
|
|
27299
|
-
for (
|
|
27300
|
-
if (T.hasOwnProperty(
|
|
27301
|
-
t[
|
|
27526
|
+
for (key3 in T) {
|
|
27527
|
+
if (T.hasOwnProperty(key3)) {
|
|
27528
|
+
t[key3] = T[key3];
|
|
27302
27529
|
}
|
|
27303
27530
|
}
|
|
27304
27531
|
t.queue = [];
|
|
@@ -27346,13 +27573,13 @@ var require_segments = __commonJS({
|
|
|
27346
27573
|
var Regex = require_regex();
|
|
27347
27574
|
var Utils = require_utils2();
|
|
27348
27575
|
var dijkstra = require_dijkstra();
|
|
27349
|
-
function getStringByteLength(
|
|
27350
|
-
return unescape(encodeURIComponent(
|
|
27576
|
+
function getStringByteLength(str3) {
|
|
27577
|
+
return unescape(encodeURIComponent(str3)).length;
|
|
27351
27578
|
}
|
|
27352
|
-
function getSegments(regex, mode,
|
|
27579
|
+
function getSegments(regex, mode, str3) {
|
|
27353
27580
|
const segments = [];
|
|
27354
27581
|
let result;
|
|
27355
|
-
while ((result = regex.exec(
|
|
27582
|
+
while ((result = regex.exec(str3)) !== null) {
|
|
27356
27583
|
segments.push({
|
|
27357
27584
|
data: result[0],
|
|
27358
27585
|
index: result.index,
|
|
@@ -27449,18 +27676,18 @@ var require_segments = __commonJS({
|
|
|
27449
27676
|
const currentNodeIds = [];
|
|
27450
27677
|
for (let j = 0; j < nodeGroup.length; j++) {
|
|
27451
27678
|
const node = nodeGroup[j];
|
|
27452
|
-
const
|
|
27453
|
-
currentNodeIds.push(
|
|
27454
|
-
table[
|
|
27455
|
-
graph[
|
|
27679
|
+
const key3 = "" + i + j;
|
|
27680
|
+
currentNodeIds.push(key3);
|
|
27681
|
+
table[key3] = { node, lastCount: 0 };
|
|
27682
|
+
graph[key3] = {};
|
|
27456
27683
|
for (let n = 0; n < prevNodeIds.length; n++) {
|
|
27457
27684
|
const prevNodeId = prevNodeIds[n];
|
|
27458
27685
|
if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {
|
|
27459
|
-
graph[prevNodeId][
|
|
27686
|
+
graph[prevNodeId][key3] = getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) - getSegmentBitsLength(table[prevNodeId].lastCount, node.mode);
|
|
27460
27687
|
table[prevNodeId].lastCount += node.length;
|
|
27461
27688
|
} else {
|
|
27462
27689
|
if (table[prevNodeId]) table[prevNodeId].lastCount = node.length;
|
|
27463
|
-
graph[prevNodeId][
|
|
27690
|
+
graph[prevNodeId][key3] = getSegmentBitsLength(node.length, node.mode) + 4 + Mode.getCharCountIndicator(node.mode, version);
|
|
27464
27691
|
}
|
|
27465
27692
|
}
|
|
27466
27693
|
}
|
|
@@ -30186,13 +30413,13 @@ var require_svg_tag = __commonJS({
|
|
|
30186
30413
|
var Utils = require_utils3();
|
|
30187
30414
|
function getColorAttrib(color, attrib) {
|
|
30188
30415
|
const alpha = color.a / 255;
|
|
30189
|
-
const
|
|
30190
|
-
return alpha < 1 ?
|
|
30416
|
+
const str3 = attrib + '="' + color.hex + '"';
|
|
30417
|
+
return alpha < 1 ? str3 + " " + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"' : str3;
|
|
30191
30418
|
}
|
|
30192
30419
|
function svgCmd(cmd, x, y) {
|
|
30193
|
-
let
|
|
30194
|
-
if (typeof y !== "undefined")
|
|
30195
|
-
return
|
|
30420
|
+
let str3 = cmd + x;
|
|
30421
|
+
if (typeof y !== "undefined") str3 += " " + y;
|
|
30422
|
+
return str3;
|
|
30196
30423
|
}
|
|
30197
30424
|
function qrToPath(data, size, margin) {
|
|
30198
30425
|
let path = "";
|
|
@@ -30840,16 +31067,16 @@ function parseVerdicts(raw, knownIds, knownAgents) {
|
|
|
30840
31067
|
const seen = /* @__PURE__ */ new Set();
|
|
30841
31068
|
for (const row of rows) {
|
|
30842
31069
|
const r = row;
|
|
30843
|
-
const
|
|
30844
|
-
if (!
|
|
31070
|
+
const id3 = typeof r?.id === "string" ? r.id : "";
|
|
31071
|
+
if (!id3) {
|
|
30845
31072
|
dropped.push({ row, reason: "no id" });
|
|
30846
31073
|
continue;
|
|
30847
31074
|
}
|
|
30848
|
-
if (!knownIds.has(
|
|
31075
|
+
if (!knownIds.has(id3)) {
|
|
30849
31076
|
dropped.push({ row, reason: "id is not a note in this queue" });
|
|
30850
31077
|
continue;
|
|
30851
31078
|
}
|
|
30852
|
-
if (seen.has(
|
|
31079
|
+
if (seen.has(id3)) {
|
|
30853
31080
|
dropped.push({ row, reason: "duplicate verdict for this note" });
|
|
30854
31081
|
continue;
|
|
30855
31082
|
}
|
|
@@ -30864,12 +31091,12 @@ function parseVerdicts(raw, knownIds, knownAgents) {
|
|
|
30864
31091
|
continue;
|
|
30865
31092
|
}
|
|
30866
31093
|
verdicts.push({
|
|
30867
|
-
id,
|
|
31094
|
+
id: id3,
|
|
30868
31095
|
verdict,
|
|
30869
31096
|
agent: verdict === "assign" ? agent2 : null,
|
|
30870
31097
|
why: typeof r?.why === "string" ? r.why.trim().slice(0, 200) : null
|
|
30871
31098
|
});
|
|
30872
|
-
seen.add(
|
|
31099
|
+
seen.add(id3);
|
|
30873
31100
|
}
|
|
30874
31101
|
return { ok: true, verdicts, dropped };
|
|
30875
31102
|
}
|
|
@@ -31037,7 +31264,7 @@ async function runTriage(opts, deps = {}) {
|
|
|
31037
31264
|
const acted = suggested(run);
|
|
31038
31265
|
log(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")}).`);
|
|
31039
31266
|
if (!opts.apply) return 0;
|
|
31040
|
-
const accept = deps.accept ?? ((
|
|
31267
|
+
const accept = deps.accept ?? ((id3, body) => acceptTriage(id3, body));
|
|
31041
31268
|
const groups = [
|
|
31042
31269
|
{ body: { group: "close" }, label: `close ${plural(run.close.length, "note")}`, count: run.close.length, preapproved: opts.yes.close },
|
|
31043
31270
|
{ body: { group: "stale" }, label: `close ${plural(run.stale.length, "stale note")}`, count: run.stale.length, preapproved: opts.yes.stale },
|
|
@@ -31076,9 +31303,9 @@ init_catalog();
|
|
|
31076
31303
|
|
|
31077
31304
|
// src/cli-args.ts
|
|
31078
31305
|
var TRIAGE_VIA = ["ollama", "claude", "codex", "agy"];
|
|
31079
|
-
var USAGE = "usage: paigy-harness setup | pair | host [--grant DIR]\u2026 | service | enable-tools [--scope user|project] | hatch NAME [--voice KEY] [--slot SLOT] | handoff | triage [--via ollama|claude|codex|agy] [--json] [--apply [--yes-close] [--yes-stale] [--yes-assign]] | [--harness claude|codex|agy] [--mode bypass|ask] [--cwd DIR] [--
|
|
31306
|
+
var USAGE = "usage: paigy-harness setup | pair | host [--grant DIR]\u2026 | service | enable-tools [--scope user|project] | hatch NAME [--voice KEY] [--slot SLOT] | launch NAME [--under GOAL] [--voice KEY] [--harness \u2026] [--mode \u2026] [--cwd DIR] BRIEF\u2026 | handoff | triage [--via ollama|claude|codex|agy] [--json] [--apply [--yes-close] [--yes-stale] [--yes-assign]] | [--harness claude|codex|agy] [--mode bypass|ask] [--cwd DIR] [--grace SECONDS] [--doctor] PROMPT\u2026";
|
|
31080
31307
|
function parseArgs(argv) {
|
|
31081
|
-
const args = { harness: "claude", mode: "bypass", cwd: process.cwd(), doctor: false, help: false, host: false, pair: false, service: false, setup: false, enableTools: false, scope: "user", grant: [], hatch: null, voice: null, slot: null,
|
|
31308
|
+
const args = { harness: "claude", mode: "bypass", cwd: process.cwd(), doctor: false, help: false, host: false, pair: false, service: false, setup: false, enableTools: false, scope: "user", grant: [], hatch: null, voice: null, slot: null, launch: null, under: null, graceSeconds: 90, prompt: "", handoff: false, triage: false, via: null, json: false, apply: false, yesClose: false, yesStale: false, yesAssign: false };
|
|
31082
31309
|
const words2 = [];
|
|
31083
31310
|
for (let i = 0; i < argv.length; i++) {
|
|
31084
31311
|
const arg = argv[i];
|
|
@@ -31149,9 +31376,13 @@ function parseArgs(argv) {
|
|
|
31149
31376
|
} else if (arg === "--slot") {
|
|
31150
31377
|
args.slot = next() ?? null;
|
|
31151
31378
|
} else if (arg === "--identity") {
|
|
31379
|
+
return { error: '--identity is gone: start a helper with `paigy-harness launch NAME "brief"`, which gives it its own session' };
|
|
31380
|
+
} else if (arg === "launch") {
|
|
31152
31381
|
const v = next();
|
|
31153
|
-
if (!v) return { error:
|
|
31154
|
-
args.
|
|
31382
|
+
if (!v) return { error: 'launch needs a name: paigy-harness launch "Deploy check" "brief"' };
|
|
31383
|
+
args.launch = v;
|
|
31384
|
+
} else if (arg === "--under") {
|
|
31385
|
+
args.under = next() ?? null;
|
|
31155
31386
|
} else if (arg?.startsWith("--")) {
|
|
31156
31387
|
return { error: `unknown flag ${arg}` };
|
|
31157
31388
|
} else if (arg) {
|
|
@@ -31160,6 +31391,7 @@ function parseArgs(argv) {
|
|
|
31160
31391
|
}
|
|
31161
31392
|
args.prompt = words2.join(" ");
|
|
31162
31393
|
if (args.help) return args;
|
|
31394
|
+
if (args.launch && !args.prompt) return { error: 'launch needs a brief: paigy-harness launch "Deploy check" "brief"' };
|
|
31163
31395
|
if (!args.doctor && !args.handoff && !args.hatch && !args.host && !args.pair && !args.service && !args.setup && !args.enableTools && !args.triage && !args.prompt) return { error: "a prompt is required (or setup / --doctor / pair / host / service / enable-tools / hatch NAME / handoff / triage)" };
|
|
31164
31396
|
if ((args.yesClose || args.yesStale || args.yesAssign) && !args.apply)
|
|
31165
31397
|
return { error: "--yes-close/--yes-stale/--yes-assign only apply with --apply" };
|
|
@@ -31192,20 +31424,23 @@ function onEnter(input, onLine) {
|
|
|
31192
31424
|
// src/cli.ts
|
|
31193
31425
|
init_dist();
|
|
31194
31426
|
var import_qrcode = __toESM(require_lib(), 1);
|
|
31427
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
31195
31428
|
import { hostname } from "os";
|
|
31196
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as
|
|
31429
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
31197
31430
|
import { execFile as execFile2, execSync } from "child_process";
|
|
31198
31431
|
import { homedir as homedir10 } from "os";
|
|
31199
|
-
import { join as
|
|
31432
|
+
import { join as join11 } from "path";
|
|
31200
31433
|
|
|
31201
31434
|
// src/run.ts
|
|
31202
31435
|
init_dist();
|
|
31436
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
31203
31437
|
|
|
31204
31438
|
// src/harness/session.ts
|
|
31439
|
+
init_dist();
|
|
31205
31440
|
import { spawn } from "child_process";
|
|
31206
|
-
import { existsSync as existsSync3 } from "fs";
|
|
31441
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
31207
31442
|
import { homedir as homedir4 } from "os";
|
|
31208
|
-
import { resolve, delimiter as delimiter2 } from "path";
|
|
31443
|
+
import { resolve, delimiter as delimiter2, join as join5 } from "path";
|
|
31209
31444
|
|
|
31210
31445
|
// src/harness/acp.ts
|
|
31211
31446
|
var none = { events: [], writes: [] };
|
|
@@ -31278,10 +31513,10 @@ var AcpDriver = class {
|
|
|
31278
31513
|
return this.flush();
|
|
31279
31514
|
}
|
|
31280
31515
|
/** Answer a PermissionEvent (ask mode). The id is the request's JSON-RPC id as a string. */
|
|
31281
|
-
respond(
|
|
31282
|
-
const request = this.pending.get(
|
|
31516
|
+
respond(id3, decision) {
|
|
31517
|
+
const request = this.pending.get(id3);
|
|
31283
31518
|
if (!request) return [];
|
|
31284
|
-
this.pending.delete(
|
|
31519
|
+
this.pending.delete(id3);
|
|
31285
31520
|
const optionId = optionFor(request.options, decision);
|
|
31286
31521
|
return [
|
|
31287
31522
|
optionId ? frame2({ id: request.id, result: { outcome: { outcome: "selected", optionId } } }) : frame2({ id: request.id, result: { outcome: { outcome: "cancelled" } } })
|
|
@@ -31435,7 +31670,7 @@ var AcpDriver = class {
|
|
|
31435
31670
|
writes: [frame2({ id: msg.id, error: { code: -32601, message: `Method not found: ${msg.method}` } })]
|
|
31436
31671
|
};
|
|
31437
31672
|
}
|
|
31438
|
-
const
|
|
31673
|
+
const id3 = msg.id;
|
|
31439
31674
|
const options = msg.params?.options ?? [];
|
|
31440
31675
|
const title = msg.params?.toolCall?.title?.trim() || "a tool call";
|
|
31441
31676
|
const tool = msg.params?.toolCall?.kind ?? "tool";
|
|
@@ -31446,21 +31681,21 @@ var AcpDriver = class {
|
|
|
31446
31681
|
// means "don't stall the agent", never "don't tell the user".
|
|
31447
31682
|
events: [{ kind: "turn", role: "agent", text: `auto-approved: ${title}`, tools: [tool] }],
|
|
31448
31683
|
writes: [
|
|
31449
|
-
optionId ? frame2({ id, result: { outcome: { outcome: "selected", optionId } } }) : frame2({ id, result: { outcome: { outcome: "cancelled" } } })
|
|
31684
|
+
optionId ? frame2({ id: id3, result: { outcome: { outcome: "selected", optionId } } }) : frame2({ id: id3, result: { outcome: { outcome: "cancelled" } } })
|
|
31450
31685
|
]
|
|
31451
31686
|
};
|
|
31452
31687
|
}
|
|
31453
|
-
this.pending.set(String(
|
|
31688
|
+
this.pending.set(String(id3), { id: id3, options });
|
|
31454
31689
|
return {
|
|
31455
|
-
events: [{ kind: "permission", id: String(
|
|
31690
|
+
events: [{ kind: "permission", id: String(id3), tool, summary: title }],
|
|
31456
31691
|
writes: []
|
|
31457
31692
|
};
|
|
31458
31693
|
}
|
|
31459
31694
|
/** The frame that opens the conversation: a resume of `resume` while there is one to try,
|
|
31460
31695
|
* else a new session. */
|
|
31461
|
-
opening(
|
|
31696
|
+
opening(id3) {
|
|
31462
31697
|
const params = { cwd: this.cwd, mcpServers: [], ...this.meta ? { _meta: this.meta } : {} };
|
|
31463
|
-
return this.resume ? { id, method: "session/resume", params: { sessionId: this.resume, ...params } } : { id, method: "session/new", params };
|
|
31698
|
+
return this.resume ? { id: id3, method: "session/resume", params: { sessionId: this.resume, ...params } } : { id: id3, method: "session/new", params };
|
|
31464
31699
|
}
|
|
31465
31700
|
/** Send the queued prompts as one turn, if the agent can take one right now. */
|
|
31466
31701
|
flush() {
|
|
@@ -31579,6 +31814,21 @@ function startSession(opts) {
|
|
|
31579
31814
|
if (!existsSync3(cwd)) {
|
|
31580
31815
|
queueMicrotask(() => opts.onEvent({ kind: "error", message: `workspace does not exist: ${cwd}` }));
|
|
31581
31816
|
}
|
|
31817
|
+
const codexConfig = opts.harness === "codex" ? JSON.parse(process.env.CODEX_CONFIG || "{}") : null;
|
|
31818
|
+
if (codexConfig) {
|
|
31819
|
+
const key3 = "mcp_servers.paigy.env_vars";
|
|
31820
|
+
const configPath = join5(process.env.CODEX_HOME || join5(homedir4(), ".codex"), "config.toml");
|
|
31821
|
+
const saved = existsSync3(configPath) ? readFileSync3(configPath, "utf8") : "";
|
|
31822
|
+
const registered = /\[mcp_servers\.paigy\][\s\S]*?(?=\n\[|$)/.exec(saved)?.[0];
|
|
31823
|
+
const configured = codexConfig["mcp_servers.paigy.command"] || codexConfig["mcp_servers.paigy.url"] || codexConfig.mcp_servers?.paigy?.command || codexConfig.mcp_servers?.paigy?.url;
|
|
31824
|
+
if (!configured && !registered) {
|
|
31825
|
+
codexConfig["mcp_servers.paigy.command"] = "npx";
|
|
31826
|
+
codexConfig["mcp_servers.paigy.args"] = ["-y", "@paigy/mcp@latest"];
|
|
31827
|
+
}
|
|
31828
|
+
const savedVars = registered?.match(/env_vars\s*=\s*\[([\s\S]*?)\]/)?.[1] ?? "";
|
|
31829
|
+
const inherited = [...savedVars.matchAll(/["']([A-Za-z_][A-Za-z0-9_]*)["']/g)].map((match) => match[1]);
|
|
31830
|
+
codexConfig[key3] = [.../* @__PURE__ */ new Set([...inherited, ...codexConfig[key3] ?? codexConfig.mcp_servers?.paigy?.env_vars ?? [], ...CODEX_ENV])];
|
|
31831
|
+
}
|
|
31582
31832
|
const child = (opts.spawnFn ?? spawn)(opts.bin ?? ADAPTER_BIN[opts.harness], [], {
|
|
31583
31833
|
cwd,
|
|
31584
31834
|
// The adapter shells out to its vendor CLI (`claude`, `codex`), and a GUI- or
|
|
@@ -31589,7 +31839,9 @@ function startSession(opts) {
|
|
|
31589
31839
|
...process.env,
|
|
31590
31840
|
PATH: [process.env.PATH, ...probeDirs()].filter(Boolean).join(delimiter2),
|
|
31591
31841
|
...opts.token ? { PAIGY_TOKEN: opts.token } : {},
|
|
31592
|
-
...opts.
|
|
31842
|
+
...opts.instance ? { PAIGY_INSTANCE_ID: opts.instance } : {},
|
|
31843
|
+
...codexConfig ? { CODEX_CONFIG: JSON.stringify(codexConfig) } : {},
|
|
31844
|
+
...opts.session ?? opts.resume ? { PAIGY_SESSION_ID: opts.session ?? opts.resume } : {},
|
|
31593
31845
|
// A PUMP DRIVES THIS PROCESS (2026-09-22, #2265): every run `runHarness` starts has the
|
|
31594
31846
|
// bridge's pump typing answers in, so nothing inside it may start a second delivery path.
|
|
31595
31847
|
// Exported on EVERY spawn — `PAIGY_SESSION_ID` above is the conversation to resume, and a
|
|
@@ -31651,8 +31903,8 @@ function startSession(opts) {
|
|
|
31651
31903
|
send(text) {
|
|
31652
31904
|
write(driver.send(text));
|
|
31653
31905
|
},
|
|
31654
|
-
respond(
|
|
31655
|
-
write(driver.respond(
|
|
31906
|
+
respond(id3, decision) {
|
|
31907
|
+
write(driver.respond(id3, decision));
|
|
31656
31908
|
},
|
|
31657
31909
|
stop() {
|
|
31658
31910
|
write(driver.close());
|
|
@@ -31724,19 +31976,19 @@ var getRefs2 = (options) => {
|
|
|
31724
31976
|
};
|
|
31725
31977
|
|
|
31726
31978
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/errorMessages.js
|
|
31727
|
-
function addErrorMessage2(res,
|
|
31979
|
+
function addErrorMessage2(res, key3, errorMessage, refs) {
|
|
31728
31980
|
if (!refs?.errorMessages)
|
|
31729
31981
|
return;
|
|
31730
31982
|
if (errorMessage) {
|
|
31731
31983
|
res.errorMessage = {
|
|
31732
31984
|
...res.errorMessage,
|
|
31733
|
-
[
|
|
31985
|
+
[key3]: errorMessage
|
|
31734
31986
|
};
|
|
31735
31987
|
}
|
|
31736
31988
|
}
|
|
31737
|
-
function setResponseValueAndErrors2(res,
|
|
31738
|
-
res[
|
|
31739
|
-
addErrorMessage2(res,
|
|
31989
|
+
function setResponseValueAndErrors2(res, key3, value, errorMessage, refs) {
|
|
31990
|
+
res[key3] = value;
|
|
31991
|
+
addErrorMessage2(res, key3, errorMessage, refs);
|
|
31740
31992
|
}
|
|
31741
31993
|
|
|
31742
31994
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js
|
|
@@ -32335,11 +32587,11 @@ function parseRecordDef2(def, refs) {
|
|
|
32335
32587
|
return {
|
|
32336
32588
|
type: "object",
|
|
32337
32589
|
required: def.keyType._def.values,
|
|
32338
|
-
properties: def.keyType._def.values.reduce((acc,
|
|
32590
|
+
properties: def.keyType._def.values.reduce((acc, key3) => ({
|
|
32339
32591
|
...acc,
|
|
32340
|
-
[
|
|
32592
|
+
[key3]: parseDef2(def.valueType._def, {
|
|
32341
32593
|
...refs,
|
|
32342
|
-
currentPath: [...refs.currentPath, "properties",
|
|
32594
|
+
currentPath: [...refs.currentPath, "properties", key3]
|
|
32343
32595
|
}) ?? parseAnyDef2(refs)
|
|
32344
32596
|
}), {}),
|
|
32345
32597
|
additionalProperties: refs.rejectedAdditionalProperties
|
|
@@ -32406,10 +32658,10 @@ function parseMapDef2(def, refs) {
|
|
|
32406
32658
|
// ../../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
|
|
32407
32659
|
function parseNativeEnumDef2(def) {
|
|
32408
32660
|
const object = def.values;
|
|
32409
|
-
const actualKeys = Object.keys(def.values).filter((
|
|
32410
|
-
return typeof object[object[
|
|
32661
|
+
const actualKeys = Object.keys(def.values).filter((key3) => {
|
|
32662
|
+
return typeof object[object[key3]] !== "number";
|
|
32411
32663
|
});
|
|
32412
|
-
const actualValues = actualKeys.map((
|
|
32664
|
+
const actualValues = actualKeys.map((key3) => object[key3]);
|
|
32413
32665
|
const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values)));
|
|
32414
32666
|
return {
|
|
32415
32667
|
type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : ["string", "number"],
|
|
@@ -32961,6 +33213,7 @@ var zodToJsonSchema2 = (schema, options) => {
|
|
|
32961
33213
|
|
|
32962
33214
|
// ../../packages/schema/dist/index.js
|
|
32963
33215
|
init_zod();
|
|
33216
|
+
init_zod();
|
|
32964
33217
|
var OPTIONS_MIN2 = 2;
|
|
32965
33218
|
var OPTIONS_MAX2 = 6;
|
|
32966
33219
|
var OptionSchema2 = external_exports.object({
|
|
@@ -33011,34 +33264,31 @@ function mcpInputSchema2(s) {
|
|
|
33011
33264
|
}
|
|
33012
33265
|
var AskInputSchema2 = external_exports.object({
|
|
33013
33266
|
id: external_exports.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
|
|
33014
|
-
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
|
|
33267
|
+
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."),
|
|
33015
33268
|
repo: external_exports.string().optional().describe("Optional repository context."),
|
|
33016
33269
|
ask: external_exports.string().trim().min(1).max(1e4).describe(
|
|
33017
|
-
"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
|
|
33270
|
+
"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."
|
|
33018
33271
|
),
|
|
33019
33272
|
options: external_exports.array(OptionInputSchema2).min(1).max(6).optional(),
|
|
33020
|
-
//
|
|
33021
|
-
//
|
|
33022
|
-
//
|
|
33023
|
-
//
|
|
33024
|
-
// as "All three / 1 and 3 only / Just log it", which the person could not read without the text and
|
|
33025
|
-
// could not answer as the ticks he wanted. "many" is the one shape an agent knows and the read does
|
|
33026
|
-
// not: whether its own options exclude each other.
|
|
33273
|
+
// HOW THE OPTIONS ARE ANSWERED, SAID BY THE AGENT (owner, 2026-10-02: "one and many makes sense";
|
|
33274
|
+
// brain_prompts.md §1: structured agent questions need no model). Every card was pick-one while no
|
|
33275
|
+
// agent sent this; no read reshapes cards any more, so this is the card's shape, and the
|
|
33276
|
+
// description says so plainly.
|
|
33027
33277
|
select: external_exports.enum(["one", "many"]).optional().describe(
|
|
33028
|
-
'How the options are answered: "
|
|
33278
|
+
'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.'
|
|
33029
33279
|
),
|
|
33030
33280
|
answers: external_exports.string().trim().regex(/^[0-9a-fA-F-]{8,36}$/).optional().describe(
|
|
33031
33281
|
"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. Needs parentId: the Goal the question is on. The reply is sent to them as it is; to also ask something new, send that as its own ask."
|
|
33032
33282
|
)
|
|
33033
33283
|
}).strict();
|
|
33034
33284
|
var StartContactSchema2 = external_exports.object({
|
|
33035
|
-
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;
|
|
33285
|
+
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."),
|
|
33036
33286
|
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."),
|
|
33037
33287
|
channel: external_exports.enum(["notification", "call"]).default("notification")
|
|
33038
33288
|
}).strict();
|
|
33039
33289
|
var ContactSchema2 = external_exports.union([StartContactSchema2, external_exports.object({ deliveryId: external_exports.string().uuid() }).strict()]);
|
|
33040
33290
|
var CONTACT_SCHEMA2 = { type: "object", ...mcpInputSchema2(ContactSchema2) };
|
|
33041
|
-
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
|
|
33291
|
+
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.";
|
|
33042
33292
|
var CreateGoalSchema2 = external_exports.object({
|
|
33043
33293
|
outcome: external_exports.string().trim().min(1).max(1e4),
|
|
33044
33294
|
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
|
|
@@ -33061,7 +33311,7 @@ var CreateGoalSchema2 = external_exports.object({
|
|
|
33061
33311
|
var CreateGoalToolSchema2 = CreateGoalSchema2.extend({
|
|
33062
33312
|
idempotencyKey: CreateGoalSchema2.shape.idempotencyKey.optional().describe("Optional. One is minted per call; pass your own only so a retry lands on the same Goal.")
|
|
33063
33313
|
}).strict();
|
|
33064
|
-
var CREATE_GOAL_DESCRIPTION2 = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only:
|
|
33314
|
+
var CREATE_GOAL_DESCRIPTION2 = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
|
|
33065
33315
|
var UpdateGoalSchema2 = external_exports.object({
|
|
33066
33316
|
revision: external_exports.number().int().positive(),
|
|
33067
33317
|
changes: external_exports.object({
|
|
@@ -33097,12 +33347,13 @@ var GetGoalSchema2 = external_exports.object({
|
|
|
33097
33347
|
* between two of them named. Off by default; `docs/model/goal/diagnose-design.md`. */
|
|
33098
33348
|
diagnose: external_exports.boolean().optional()
|
|
33099
33349
|
}).strict();
|
|
33100
|
-
var GET_GOAL_DESCRIPTION2 = "Read one Goal without claiming it: its outcome, state, revision, progress, blockers, the conversation on it (each question with its options and what was decided), `next`, the one step to take, and `more`, where to read further. A question in that conversation reads `open` (nothing yet), `answered` (a choice was made, and `answer` carries it), `replied` (they said something and the read settled the question on their words \u2014 NO option of yours was chosen, and the words are the reply line beside it, so read that before you act), or `closed`. The conversation carries everything the person said, every open question and your newest entry; your older entries are left out and counted \u2014 history: true reads every entry in full.
|
|
33101
|
-
var UPDATE_GOAL_DESCRIPTION2 = `Update
|
|
33102
|
-
var CLAIM_GOAL_DESCRIPTION2 = "Claim the oldest runnable or review-pending Goal you own
|
|
33350
|
+
var GET_GOAL_DESCRIPTION2 = "Read one Goal without claiming it, including others (the ten most recent other contributors, with names, latest entry headlines and times): its outcome, state, revision, progress, blockers, the conversation on it (each question with its options and what was decided), `next`, the one step to take, and `more`, where to read further. A question in that conversation reads `open` (nothing yet), `answered` (a choice was made, and `answer` carries it), `replied` (they said something and the read settled the question on their words \u2014 NO option of yours was chosen, and the words are the reply line beside it, so read that before you act), or `closed`. The conversation carries everything the person said, every open question and your newest entry; your older entries are left out and counted \u2014 history: true reads every entry in full. Every Goal of your person is readable, whichever of their agents owns it; another account's Goals are not disclosed.\n\ndiagnose: true is for when a read has CONFUSED you \u2014 not for the working loop. It adds `diagnosis`, which asks every reader that already answers a question about your work and NAMES the reader behind every value, so you never guess which of two places to look: what state your work is really in (the stored `goals.state` beside the derived `goal_execution_state`, which can differ); whether anything is armed to ring and when (`ladder_candidates`, with the ladder's own last decision); whether a wake fired for you and what it did (durable `wake.*` events, beside when your process was last heard from); and what has reached you (`list_waiting` \u2014 review flags, unstarted work, open questions, the person's newest words). Read `diagnosis.disagreements` FIRST: each one is two readers giving different values for the same fact, with both values and both sources, and it never chooses between them \u2014 that is yours to do, from the Goal's own history. `diagnosis.looked` names every reader asked, including any that could not answer, so an empty answer is never confused with a broken one.";
|
|
33351
|
+
var UPDATE_GOAL_DESCRIPTION2 = `Update a Goal you are on at an exact revision. You are on a Goal you own, or one you have written on (an update with progress, or a contact on it); any of your person's agents may write on any of their Goals, and one that never touched a Goal is refused (409 goal_not_joined). State, ownership, dependencies, children, progress, title, and review acknowledgement are explicit; stale revisions are rejected. A CONTACT ON THIS GOAL MOVES ITS REVISION: a question filed on a Goal is a change to it, so an update prepared before a contact and sent after it is refused as stale (409 goal_revision_conflict) \u2014 re-read the Goal, then write. title is the work's name in one to five words, as a person would refer to it out loud (it is spoken on a call and heads every list); null clears it. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. dueAt (an ISO instant, or null) makes the Goal wait until then; when it passes you are woken for it \u2014 use it for a promise to follow up later. withdraw: [questionId] takes back a question YOU asked on this Goal that is still open \u2014 because you acted on it yourself, it no longer matters, or you asked it wrongly (e.g. waiting: hard when nothing was blocked): it is cancelled, not answered, its card closes and it stops ringing; the id is the one the conversation shows. state: done means the work was accomplished, and it can be reopened: when the person says it is not done ("it's not working"), set state: active on that same Goal instead of starting a new one; its parent reopens with it. state: done while children are still open records your part as done: the Goal waits and closes by itself when its last open child closes. cancelled is final. Returns the Goal as get_goal reads it, at its new revision.`;
|
|
33352
|
+
var CLAIM_GOAL_DESCRIPTION2 = "Claim a pending answer to your question or the oldest runnable or review-pending Goal you own. Pass goalId to join any Goal of your person; its assignment stays unchanged. Read others before overlapping another agent\u2019s work. Joining lets you contribute and change its state; use update_goal with ownerParticipant when the assignment itself should change. Returns the Goal as get_goal reads it, and marks you as on it, which never shuts another agent out: other agents of your person may write on it and change it too, and two changes at once are told apart by revision (409 goal_revision_conflict).";
|
|
33103
33353
|
var CHECK_REPLIES_DESCRIPTION2 = "What is waiting for you: your open Deliveries (a request the user started toward you, a handoff), one row each with its Goals, how many decisions are still open, and the newest words in brief; `assigned`, your Goals nobody has started yet, however they became yours (claim_goal({goalId}) starts one); and `review`, your Goals with something new on them \u2014 the user's answers and notes are Entries on the Goal, not Deliveries. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread a Delivery in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true clears the Goal from `review` and closes the Deliveries addressed to you on it.";
|
|
33104
33354
|
var CheckRepliesSchema2 = external_exports.object({}).strict();
|
|
33105
33355
|
var AGENT_TOOLS2 = [
|
|
33356
|
+
{ name: "who_is_working", description: "Read your person's agents that contributed in the last 24 hours, newest first: at most 30 agents and their five most recently touched Goals, with their latest entry headline and time. Use get_goal to read a Goal and its other contributors before starting overlapping work. Read-only; no arguments.", inputSchema: mcpInputSchema2(CheckRepliesSchema2) },
|
|
33106
33357
|
{ name: "contact", description: CONTACT_DESCRIPTION2, inputSchema: CONTACT_SCHEMA2 },
|
|
33107
33358
|
{ name: "check_replies", description: CHECK_REPLIES_DESCRIPTION2, inputSchema: mcpInputSchema2(CheckRepliesSchema2) },
|
|
33108
33359
|
{ name: "create_goal", description: CREATE_GOAL_DESCRIPTION2, inputSchema: mcpInputSchema2(CreateGoalToolSchema2) },
|
|
@@ -33111,6 +33362,156 @@ var AGENT_TOOLS2 = [
|
|
|
33111
33362
|
{ name: "update_goal", description: UPDATE_GOAL_DESCRIPTION2, inputSchema: mcpInputSchema2(UpdateGoalToolSchema2) }
|
|
33112
33363
|
];
|
|
33113
33364
|
var AGENT_TOOL_NAMES2 = AGENT_TOOLS2.map((t) => t.name);
|
|
33365
|
+
var id2 = external_exports.string().uuid();
|
|
33366
|
+
var key2 = external_exports.string().min(1).max(40);
|
|
33367
|
+
var participant2 = external_exports.string().regex(/^(human|agent):.+$/, "a participant ID such as agent:<uuid>");
|
|
33368
|
+
var SourceSchema2 = external_exports.object({
|
|
33369
|
+
entryId: id2,
|
|
33370
|
+
span: external_exports.object({ start: external_exports.number().int().min(0), end: external_exports.number().int().min(1) }).strict().refine((s) => s.end > s.start, "a span ends after it starts").optional()
|
|
33371
|
+
}).strict();
|
|
33372
|
+
var ResultRefSchema2 = external_exports.union([external_exports.object({ id: id2 }).strict(), external_exports.object({ local: key2 }).strict()]);
|
|
33373
|
+
var NodeRefSchema2 = external_exports.object({ type: external_exports.enum(["goal", "question"]), id: id2 }).strict();
|
|
33374
|
+
var DependencySchema2 = external_exports.object({
|
|
33375
|
+
blocker: NodeRefSchema2,
|
|
33376
|
+
blocked: NodeRefSchema2,
|
|
33377
|
+
action: external_exports.enum(["start", "complete", "answer"]),
|
|
33378
|
+
reason: external_exports.string().max(500).optional()
|
|
33379
|
+
}).strict();
|
|
33380
|
+
var goalState2 = external_exports.enum(["open", "completed", "canceled"]);
|
|
33381
|
+
var existingGoalChanges2 = [
|
|
33382
|
+
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"),
|
|
33383
|
+
external_exports.object({ kind: external_exports.literal("state"), goalId: id2, state: goalState2 }).strict(),
|
|
33384
|
+
external_exports.object({ kind: external_exports.literal("assign"), goalId: id2, ownerId: participant2 }).strict(),
|
|
33385
|
+
external_exports.object({ kind: external_exports.literal("defer"), goalId: id2, until: external_exports.string().datetime().nullable() }).strict(),
|
|
33386
|
+
external_exports.object({ kind: external_exports.literal("move"), goalId: id2, parentGoalId: id2.nullable() }).strict(),
|
|
33387
|
+
external_exports.object({
|
|
33388
|
+
kind: external_exports.literal("dependency"),
|
|
33389
|
+
change: external_exports.enum(["add", "remove"]),
|
|
33390
|
+
goalId: id2,
|
|
33391
|
+
dependsOnGoalId: id2,
|
|
33392
|
+
action: external_exports.enum(["start", "complete"]),
|
|
33393
|
+
reason: external_exports.string().max(500).optional()
|
|
33394
|
+
}).strict()
|
|
33395
|
+
];
|
|
33396
|
+
var GoalChangeSchema2 = external_exports.union([
|
|
33397
|
+
external_exports.object({
|
|
33398
|
+
kind: external_exports.literal("create"),
|
|
33399
|
+
title: external_exports.string().min(1).max(120),
|
|
33400
|
+
outcome: external_exports.string().min(1),
|
|
33401
|
+
ownerId: participant2,
|
|
33402
|
+
parentGoalId: id2.optional(),
|
|
33403
|
+
sourceEntryIds: external_exports.array(id2)
|
|
33404
|
+
}).strict(),
|
|
33405
|
+
...existingGoalChanges2
|
|
33406
|
+
]);
|
|
33407
|
+
var BrainGoalChangeSchema2 = external_exports.union([
|
|
33408
|
+
// newSession: Paigy starts a session to own it (owner, 2026-10-06); until it has, the person owns it.
|
|
33409
|
+
external_exports.object({
|
|
33410
|
+
kind: external_exports.literal("create"),
|
|
33411
|
+
outcome: external_exports.string().min(1),
|
|
33412
|
+
title: external_exports.string().min(1).max(120),
|
|
33413
|
+
ownerId: participant2,
|
|
33414
|
+
parentGoal: ResultRefSchema2.nullable(),
|
|
33415
|
+
newSession: external_exports.literal(true).optional()
|
|
33416
|
+
}).strict(),
|
|
33417
|
+
...existingGoalChanges2
|
|
33418
|
+
]);
|
|
33419
|
+
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();
|
|
33420
|
+
var QuestionChangeSchema2 = external_exports.union([
|
|
33421
|
+
external_exports.object({
|
|
33422
|
+
kind: external_exports.literal("create"),
|
|
33423
|
+
text: external_exports.string().min(1),
|
|
33424
|
+
answererId: participant2,
|
|
33425
|
+
goal: ResultRefSchema2.optional(),
|
|
33426
|
+
blocks: external_exports.array(external_exports.object({ question: ResultRefSchema2 }).strict()),
|
|
33427
|
+
options: external_exports.array(option2).min(2).optional(),
|
|
33428
|
+
pickMode: external_exports.enum(["one", "many", "rank"]).optional()
|
|
33429
|
+
}).strict().refine((c) => c.options === void 0 === (c.pickMode === void 0), "options and pickMode come together"),
|
|
33430
|
+
external_exports.object({ kind: external_exports.literal("edit"), questionId: id2, text: external_exports.string().min(1) }).strict(),
|
|
33431
|
+
external_exports.object({ kind: external_exports.literal("assign"), questionId: id2, answererId: participant2 }).strict(),
|
|
33432
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), questionId: id2 }).strict(),
|
|
33433
|
+
external_exports.object({ kind: external_exports.literal("dependency"), change: external_exports.enum(["add", "remove"]), edge: DependencySchema2 }).strict()
|
|
33434
|
+
]);
|
|
33435
|
+
var lessonScope2 = external_exports.union([
|
|
33436
|
+
external_exports.object({ kind: external_exports.literal("user") }).strict(),
|
|
33437
|
+
external_exports.object({ kind: external_exports.literal("goal"), goal: ResultRefSchema2 }).strict()
|
|
33438
|
+
]);
|
|
33439
|
+
var LessonChangeSchema2 = external_exports.union([
|
|
33440
|
+
external_exports.object({ kind: external_exports.literal("remember"), text: external_exports.string().min(1), scope: lessonScope2 }).strict(),
|
|
33441
|
+
external_exports.object({ kind: external_exports.literal("revise"), lessonId: id2, text: external_exports.string().min(1), scope: lessonScope2 }).strict(),
|
|
33442
|
+
external_exports.object({ kind: external_exports.literal("withdraw"), lessonId: id2 }).strict()
|
|
33443
|
+
]);
|
|
33444
|
+
var BrainNextSchema2 = external_exports.object({
|
|
33445
|
+
instructions: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key2).min(1) }).strict()),
|
|
33446
|
+
say: external_exports.array(key2),
|
|
33447
|
+
then: external_exports.enum(["listen", "hold", "end", "none"]),
|
|
33448
|
+
waitFor: external_exports.array(ResultRefSchema2),
|
|
33449
|
+
reason: external_exports.string()
|
|
33450
|
+
}).strict();
|
|
33451
|
+
var messageBase2 = {
|
|
33452
|
+
key: key2,
|
|
33453
|
+
text: external_exports.string().min(1),
|
|
33454
|
+
goals: external_exports.array(ResultRefSchema2),
|
|
33455
|
+
questions: external_exports.array(ResultRefSchema2),
|
|
33456
|
+
entryKeys: external_exports.array(key2),
|
|
33457
|
+
obligationIds: external_exports.array(id2)
|
|
33458
|
+
};
|
|
33459
|
+
var BrainMessageSchema2 = external_exports.union([
|
|
33460
|
+
external_exports.object({ ...messageBase2, to: external_exports.object({ kind: external_exports.literal("user") }).strict() }).strict(),
|
|
33461
|
+
external_exports.object({
|
|
33462
|
+
...messageBase2,
|
|
33463
|
+
to: external_exports.object({ kind: external_exports.literal("session"), sessionId: id2 }).strict(),
|
|
33464
|
+
call: external_exports.object({ callId: id2, listen: external_exports.literal(true) }).strict().optional()
|
|
33465
|
+
}).strict()
|
|
33466
|
+
]);
|
|
33467
|
+
var BrainSearchSchema2 = external_exports.object({
|
|
33468
|
+
query: external_exports.string().min(1).max(500),
|
|
33469
|
+
within: external_exports.array(external_exports.enum(["entries", "goals", "answers"])).min(1),
|
|
33470
|
+
goalId: id2.optional()
|
|
33471
|
+
}).strict();
|
|
33472
|
+
var BrainResultSchema2 = external_exports.object({
|
|
33473
|
+
messages: external_exports.array(BrainMessageSchema2),
|
|
33474
|
+
entries: external_exports.array(external_exports.object({ key: key2, sources: external_exports.array(SourceSchema2).min(1), goals: external_exports.array(ResultRefSchema2) }).strict()),
|
|
33475
|
+
questions: external_exports.array(external_exports.object({ key: key2, entryKeys: external_exports.array(key2), change: QuestionChangeSchema2 }).strict()),
|
|
33476
|
+
answers: external_exports.array(external_exports.object({
|
|
33477
|
+
question: ResultRefSchema2,
|
|
33478
|
+
entryKeys: external_exports.array(key2).min(1),
|
|
33479
|
+
summary: external_exports.string().min(1),
|
|
33480
|
+
selectedOptionIds: external_exports.array(external_exports.string().min(1)).optional()
|
|
33481
|
+
}).strict()),
|
|
33482
|
+
goals: external_exports.array(external_exports.object({ key: key2, entryKeys: external_exports.array(key2), change: BrainGoalChangeSchema2 }).strict()),
|
|
33483
|
+
feedback: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key2).min(1) }).strict()),
|
|
33484
|
+
lessons: external_exports.array(external_exports.object({ entryKeys: external_exports.array(key2).min(1), change: LessonChangeSchema2 }).strict()),
|
|
33485
|
+
next: BrainNextSchema2,
|
|
33486
|
+
search: BrainSearchSchema2.optional()
|
|
33487
|
+
}).strict();
|
|
33488
|
+
var str2 = external_exports.string();
|
|
33489
|
+
var strs2 = external_exports.array(external_exports.string());
|
|
33490
|
+
var CompactResultSchema2 = external_exports.object({
|
|
33491
|
+
next: external_exports.object({ say: strs2, then: external_exports.enum(["listen", "hold", "end", "none"]), waitFor: strs2, reason: str2, instructions: strs2 }).strict(),
|
|
33492
|
+
messages: external_exports.array(external_exports.object({ key: str2, to: str2, text: str2, about: strs2, entries: strs2, owed: strs2, inviteToCall: external_exports.boolean() }).strict()),
|
|
33493
|
+
entries: external_exports.array(external_exports.object({ key: str2, from: str2, start: external_exports.number().int(), end: external_exports.number().int(), on: strs2 }).strict()),
|
|
33494
|
+
answers: external_exports.array(external_exports.object({ question: str2, entries: strs2, summary: str2, picked: strs2 }).strict()),
|
|
33495
|
+
changes: external_exports.array(external_exports.object({
|
|
33496
|
+
key: str2,
|
|
33497
|
+
what: external_exports.enum(["goal", "question", "lesson"]),
|
|
33498
|
+
op: external_exports.enum(["create", "edit", "assign", "open", "complete", "cancel", "defer", "move", "block", "unblock", "withdraw", "remember", "revise"]),
|
|
33499
|
+
id: str2,
|
|
33500
|
+
text: str2,
|
|
33501
|
+
title: str2,
|
|
33502
|
+
who: str2,
|
|
33503
|
+
under: str2,
|
|
33504
|
+
gate: external_exports.enum(["start", "complete", "answer", "none"]),
|
|
33505
|
+
options: external_exports.array(external_exports.object({ id: str2, label: str2 }).strict()),
|
|
33506
|
+
pick: external_exports.enum(["one", "many", "rank", "words"]),
|
|
33507
|
+
entries: strs2
|
|
33508
|
+
}).strict()),
|
|
33509
|
+
feedback: external_exports.array(strs2),
|
|
33510
|
+
search: external_exports.object({ query: str2, within: strs2, goal: str2 }).strict()
|
|
33511
|
+
}).strict();
|
|
33512
|
+
var COMPACT_RESULT_JSON_SCHEMA2 = (({ $schema: _, ...rest }) => rest)(
|
|
33513
|
+
zodToJsonSchema2(CompactResultSchema2, { $refStrategy: "none" })
|
|
33514
|
+
);
|
|
33114
33515
|
function entryWords(entry) {
|
|
33115
33516
|
const content = entry.content;
|
|
33116
33517
|
if (content && "sealed" in content) return "";
|
|
@@ -33123,11 +33524,13 @@ function entryWords(entry) {
|
|
|
33123
33524
|
const description = plain.description;
|
|
33124
33525
|
const parts = [title, ...Array.isArray(description) ? description : []].filter((v) => typeof v === "string");
|
|
33125
33526
|
if (parts.length) return parts.join("\n\n");
|
|
33527
|
+
const line = plain.line;
|
|
33528
|
+
if (typeof line === "string" && line.trim()) return line;
|
|
33126
33529
|
}
|
|
33127
33530
|
return entry.sources.map((source) => source.text).join("\n");
|
|
33128
33531
|
}
|
|
33129
33532
|
var LIVE_MS2 = 3 * 6e4;
|
|
33130
|
-
var WORKING_MS2 =
|
|
33533
|
+
var WORKING_MS2 = 60 * 6e4;
|
|
33131
33534
|
var ContextSchema2 = external_exports.object({
|
|
33132
33535
|
title: external_exports.string().min(1).describe("One-line headline of what you need (required, non-empty)."),
|
|
33133
33536
|
description: external_exports.array(external_exports.string().min(1)).describe(
|
|
@@ -33345,7 +33748,7 @@ var IntentSchema2 = external_exports.object({
|
|
|
33345
33748
|
* (`parseDelay`, #1292), and a value here simply wins over that reading. */
|
|
33346
33749
|
dueInSeconds: external_exports.number().int().positive().optional(),
|
|
33347
33750
|
/** Feedback only (#812): WHICH failure the complaint names — typed by the mapper that
|
|
33348
|
-
* already read the utterance, so `
|
|
33751
|
+
* already read the utterance, so `signals.kind` stops defaulting to
|
|
33349
33752
|
* 'other' on every row. A table that records that something was wrong and nothing
|
|
33350
33753
|
* about what cannot answer "is the bot looping less this week?". */
|
|
33351
33754
|
fault: external_exports.enum(["loop", "unanswered", "overridden", "misheard", "slow", "other"]).optional()
|
|
@@ -33479,7 +33882,13 @@ var AgendaTurnSchema2 = external_exports.object({
|
|
|
33479
33882
|
/** Whether the walk WAITS for an answer before moving on. Absent = derived as today
|
|
33480
33883
|
* (a question blocks, context flows). blocking:false on a question = ask and move
|
|
33481
33884
|
* on, the claim stays pending; blocking:true on context = hold for a reply. */
|
|
33482
|
-
blocking: external_exports.boolean().optional()
|
|
33885
|
+
blocking: external_exports.boolean().optional(),
|
|
33886
|
+
/** SPOKEN ONLY IF THEY SAY NOTHING (owner, 2026-10-01, call 812de935: "you're gonna re-ask, but it
|
|
33887
|
+
* shouldn't be the same words … more like, hey, are you still there, or are you able to answer, or
|
|
33888
|
+
* would you need more information"). The walk holds this turn out of its queue; at the queue's end it
|
|
33889
|
+
* listens for the last word, and only if that listen is silent is this turn said and asked. If they
|
|
33890
|
+
* speak, it is dropped and their words are taken like any reply. */
|
|
33891
|
+
ifSilent: external_exports.boolean().optional()
|
|
33483
33892
|
});
|
|
33484
33893
|
var CLAIM_STALE_MS2 = 30 * 6e4;
|
|
33485
33894
|
var InboxItemSchema2 = external_exports.object({
|
|
@@ -33623,7 +34032,18 @@ var InboxItemSchema2 = external_exports.object({
|
|
|
33623
34032
|
/** THAT GOAL'S NAME (#2416) — what Activity's row is headed by, since a row there is one Goal
|
|
33624
34033
|
* and the cards it holds sit behind it. Stamped by the same read as `goalState`. */
|
|
33625
34034
|
goalTitle: external_exports.string().optional()
|
|
33626
|
-
}).optional()
|
|
34035
|
+
}).optional(),
|
|
34036
|
+
/** WHAT THIS CARD IS, IN TWELVE CHARACTERS (#3019) — the hash of every other field on it, stamped
|
|
34037
|
+
* by the one read that serves the open list (`apps/api/src/inbox/project.ts` `inboxFor`). It is
|
|
34038
|
+
* how the incremental read knows a card has not moved: the phone echoes back the revs it holds
|
|
34039
|
+
* (`POST /api/inbox/changes`) and is sent only the cards whose rev differs.
|
|
34040
|
+
*
|
|
34041
|
+
* THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK — the same mechanism as `QueueItem.rev`
|
|
34042
|
+
* (#2928) and an entry's (#3018), for the same reason: a card shows facts no `updated_at` of its
|
|
34043
|
+
* own moves (its Goal's state and name, how cold the work behind it has gone, whether a ring is
|
|
34044
|
+
* live). Optional, so a fixture, the demo and the archive lens need not spell one, and a card
|
|
34045
|
+
* with no rev is simply always re-sent. */
|
|
34046
|
+
rev: external_exports.string().optional()
|
|
33627
34047
|
});
|
|
33628
34048
|
var APNS_TOKEN_RE2 = /^[0-9a-fA-F]{64}$/;
|
|
33629
34049
|
var PushTokenSchema2 = external_exports.object({
|
|
@@ -33995,7 +34415,22 @@ var QueueItemSchema2 = external_exports.object({
|
|
|
33995
34415
|
* minute after the person speaks erases their instant from it, and the durable traces the client
|
|
33996
34416
|
* can see (`replies`, `questions[].answeredAt`) miss a spontaneous note entirely — a `request`
|
|
33997
34417
|
* Entry with no `about_id` is in neither. */
|
|
33998
|
-
lastPersonAt: external_exports.string().nullable().optional()
|
|
34418
|
+
lastPersonAt: external_exports.string().nullable().optional(),
|
|
34419
|
+
/** WHAT THIS ROW IS, IN TWELVE CHARACTERS (#2928) — the hash of every other field on it, stamped
|
|
34420
|
+
* by the one projection that builds the row (`apps/api/src/goal/queue.ts`). It is how the
|
|
34421
|
+
* incremental read knows a row has not moved: the phone echoes back the revs it holds
|
|
34422
|
+
* (`POST /api/goals/changes`) and is sent only the rows whose rev differs.
|
|
34423
|
+
*
|
|
34424
|
+
* IT IS THE PAYLOAD'S OWN HASH, NEVER A STAMP ON THE WORK. Nothing here reasons about which
|
|
34425
|
+
* writes change which field — the comparison is over the bytes the phone is holding, so a fact
|
|
34426
|
+
* the row shows that no `updated_at` moves for (a lease lapsing, a dependency's state, a
|
|
34427
|
+
* sibling appearing in `childGoalIds`) cannot go unnoticed. Optional because a hand-built
|
|
34428
|
+
* queue (a fixture, the demo) spells none, and a row with no rev is simply always re-sent. */
|
|
34429
|
+
rev: external_exports.string().optional()
|
|
34430
|
+
});
|
|
34431
|
+
var QueueDeltaSchema2 = external_exports.object({
|
|
34432
|
+
ids: external_exports.array(external_exports.string()),
|
|
34433
|
+
items: external_exports.array(QueueItemSchema2)
|
|
33999
34434
|
});
|
|
34000
34435
|
var COLD_AFTER_MS2 = 3 * 24 * 60 * 60 * 1e3;
|
|
34001
34436
|
var NoteSourceSchema2 = external_exports.enum(["app", "call"]);
|
|
@@ -34166,6 +34601,11 @@ var DeviceTokenSchema2 = external_exports.object({
|
|
|
34166
34601
|
/** Local host recovery must preserve the launch's runtime and Paigy identity. */
|
|
34167
34602
|
harness: external_exports.enum(["claude", "codex", "agy"]).optional(),
|
|
34168
34603
|
session_id: external_exports.string().uuid().optional(),
|
|
34604
|
+
/** A conversation the host must not resume: its context is full, so every turn fails
|
|
34605
|
+
* ("Prompt is too long"). Written when a run hits it (`run.ts` `onFull`); the host skips a slot
|
|
34606
|
+
* whose resumable session is this one, so its Goals reach the dead-agent handoff instead of a
|
|
34607
|
+
* copy that types the person's words into a turn that cannot run (Calls, 2026-10-06). */
|
|
34608
|
+
full_session: external_exports.string().optional(),
|
|
34169
34609
|
uik_pub: external_exports.string().nullable().optional()
|
|
34170
34610
|
});
|
|
34171
34611
|
var SupportRequestSchema2 = external_exports.object({
|
|
@@ -34519,9 +34959,13 @@ async function finish(result, state, rail, opts) {
|
|
|
34519
34959
|
const progress = result?.trim().slice(0, 1e4) || void 0;
|
|
34520
34960
|
let revision = goal.revision;
|
|
34521
34961
|
try {
|
|
34522
|
-
const held = await rail.
|
|
34962
|
+
const held = await rail.read(goal.id);
|
|
34523
34963
|
revision = held.revision ?? revision;
|
|
34524
34964
|
const owed = state.noted?.some((b) => b.goals.includes(goal.id));
|
|
34965
|
+
if (held.state === "done" || held.state === "cancelled") {
|
|
34966
|
+
if (!owed) state.goal = void 0;
|
|
34967
|
+
return;
|
|
34968
|
+
}
|
|
34525
34969
|
if (!held.openDecisionNeedIds?.length && !owed) {
|
|
34526
34970
|
await rail.update(goal.id, { revision, changes: { state: "done", ...progress ? { progress } : {} }, reason: "The agent finished its turn." });
|
|
34527
34971
|
state.goal = void 0;
|
|
@@ -34539,17 +34983,31 @@ async function finish(result, state, rail, opts) {
|
|
|
34539
34983
|
}
|
|
34540
34984
|
async function cannotWork(report, state, rail, opts) {
|
|
34541
34985
|
state.resting = true;
|
|
34986
|
+
const say = (parentId) => rail.contact({ asks: [{ ask: report, ...parentId ? { parentId } : {} }], waiting: "none", channel: "notification" });
|
|
34542
34987
|
try {
|
|
34543
34988
|
if (!state.goal) {
|
|
34544
|
-
const claimed = await rail.claim();
|
|
34545
|
-
if (
|
|
34546
|
-
|
|
34989
|
+
const claimed = await rail.claim().catch(() => void 0);
|
|
34990
|
+
if (claimed?.goalId && claimed.revision !== void 0) state.goal = { id: claimed.goalId, revision: claimed.revision };
|
|
34991
|
+
}
|
|
34992
|
+
if (!state.goal) {
|
|
34993
|
+
await say();
|
|
34994
|
+
return;
|
|
34995
|
+
}
|
|
34996
|
+
try {
|
|
34997
|
+
await say(state.goal.id);
|
|
34998
|
+
} catch (error) {
|
|
34999
|
+
if (!/goal_parent_invalid/.test(error.message)) throw error;
|
|
35000
|
+
opts?.log?.(`\u26A0 the held Goal ${state.goal.id.slice(0, 8)} refused the notice (goal_parent_invalid) \u2014 saying it unplaced`);
|
|
35001
|
+
await say();
|
|
34547
35002
|
}
|
|
34548
|
-
await rail.contact({ asks: [{ ask: report, parentId: state.goal.id }], waiting: "none", channel: "notification" });
|
|
34549
35003
|
} catch (error) {
|
|
34550
35004
|
opts?.log?.(`\u26A0 could not say the agent cannot work: ${error.message}`);
|
|
34551
35005
|
}
|
|
34552
35006
|
}
|
|
35007
|
+
function conversationFull(result) {
|
|
35008
|
+
return /prompt is too long/i.test(result ?? "");
|
|
35009
|
+
}
|
|
35010
|
+
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.";
|
|
34553
35011
|
async function afterTurn(event, state, rail, opts) {
|
|
34554
35012
|
if (event.failed) {
|
|
34555
35013
|
const limit = limitIn(event.result, (opts?.now ?? Date.now)());
|
|
@@ -34562,6 +35020,11 @@ async function afterTurn(event, state, rail, opts) {
|
|
|
34562
35020
|
opts?.log?.(`\u23F8 paused by the usage limit until ${limit.resets}: nothing is typed in until then, and it carries on by itself`);
|
|
34563
35021
|
return limit;
|
|
34564
35022
|
}
|
|
35023
|
+
if (conversationFull(event.result)) {
|
|
35024
|
+
if (!state.full) await cannotWork(FULL_NOTICE, state, rail, opts);
|
|
35025
|
+
state.full = true;
|
|
35026
|
+
return void 0;
|
|
35027
|
+
}
|
|
34565
35028
|
await cannotWork(`The agent stopped without finishing.
|
|
34566
35029
|
|
|
34567
35030
|
${event.result?.trim() || "No result reported."}`, state, rail, opts);
|
|
@@ -34610,11 +35073,16 @@ function beat() {
|
|
|
34610
35073
|
}
|
|
34611
35074
|
var BEAT_REPORT_MS = 10 * 6e4;
|
|
34612
35075
|
var ended = (state) => state === "done" || state === "cancelled";
|
|
34613
|
-
function unheard(brief, state, since = null, after = -1) {
|
|
35076
|
+
function unheard(brief, state, since = null, after = -1, reviewSince) {
|
|
34614
35077
|
const seen = state.seen ??= /* @__PURE__ */ new Set();
|
|
34615
35078
|
const words2 = [];
|
|
35079
|
+
const pendingAt = reviewSince ? Date.parse(reviewSince) : null;
|
|
34616
35080
|
for (const [i, e] of (brief.entries ?? []).entries()) {
|
|
34617
35081
|
if (seen.has(e.entryId) || !e.authorParticipant.startsWith("human:")) continue;
|
|
35082
|
+
if (pendingAt !== null && Date.parse(e.createdAt) < pendingAt) {
|
|
35083
|
+
seen.add(e.entryId);
|
|
35084
|
+
continue;
|
|
35085
|
+
}
|
|
34618
35086
|
if (i <= after) {
|
|
34619
35087
|
seen.add(e.entryId);
|
|
34620
35088
|
continue;
|
|
@@ -34625,6 +35093,12 @@ function unheard(brief, state, since = null, after = -1) {
|
|
|
34625
35093
|
const text = entryWords(e).trim();
|
|
34626
35094
|
if (text) words2.push(text);
|
|
34627
35095
|
}
|
|
35096
|
+
if (pendingAt !== null) for (const answer of brief.answers ?? []) {
|
|
35097
|
+
const key3 = `answer:${answer.decisionNeedId}`;
|
|
35098
|
+
if (seen.has(key3) || Date.parse(answer.acceptedAt) < pendingAt) continue;
|
|
35099
|
+
seen.add(key3);
|
|
35100
|
+
words2.push(`Answer to question ${answer.decisionNeedId}: ${JSON.stringify(answer.result)}`);
|
|
35101
|
+
}
|
|
34628
35102
|
return words2;
|
|
34629
35103
|
}
|
|
34630
35104
|
function sinceTheWork(brief) {
|
|
@@ -34667,16 +35141,16 @@ async function gather(state, rail, held) {
|
|
|
34667
35141
|
const listed = /* @__PURE__ */ new Set();
|
|
34668
35142
|
const announced = state.announced ??= /* @__PURE__ */ new Set();
|
|
34669
35143
|
if (waiting) {
|
|
34670
|
-
for (const
|
|
35144
|
+
for (const id3 of announced) if (!(waiting.assigned ?? []).some((g) => g.goalId === id3)) announced.delete(id3);
|
|
34671
35145
|
}
|
|
34672
35146
|
for (const g of waiting?.assigned ?? []) if (g.goalId !== state.goal.id && !announced.has(g.goalId)) look2(g.goalId, "assigned", g.title);
|
|
34673
35147
|
for (const g of waiting?.review ?? []) {
|
|
34674
35148
|
listed.add(g.goalId);
|
|
34675
35149
|
look2(g.goalId, "waiting work", g.title);
|
|
34676
35150
|
}
|
|
34677
|
-
for (const d of waiting?.deliveries ?? []) for (const
|
|
34678
|
-
listed.add(
|
|
34679
|
-
look2(
|
|
35151
|
+
for (const d of waiting?.deliveries ?? []) for (const id3 of d.goalIds) {
|
|
35152
|
+
listed.add(id3);
|
|
35153
|
+
look2(id3, "waiting work");
|
|
34680
35154
|
}
|
|
34681
35155
|
const moved = movedBelow(held, state);
|
|
34682
35156
|
for (const { goal, since } of moved) look2(goal.goalId, "subtree", goal.title, since);
|
|
@@ -34693,9 +35167,9 @@ async function gather(state, rail, held) {
|
|
|
34693
35167
|
}
|
|
34694
35168
|
}
|
|
34695
35169
|
read.add(goalId);
|
|
34696
|
-
const fresh = found.via === "waiting work" || found.via === "assigned" ? sinceTheWork(brief) : { after: -1 };
|
|
35170
|
+
const fresh = !brief.reviewSince && (found.via === "waiting work" || found.via === "assigned") ? sinceTheWork(brief) : { after: -1 };
|
|
34697
35171
|
if (found.via === "assigned") announced.add(goalId);
|
|
34698
|
-
heard.push({ goalId, ...found, brief, words: unheard(brief, state, since ?? null, fresh.after), ...fresh.note ? { note: fresh.note } : {} });
|
|
35172
|
+
heard.push({ goalId, ...found, brief, words: unheard(brief, state, brief.reviewSince ? null : since ?? null, fresh.after, brief.reviewSince), ...fresh.note ? { note: fresh.note } : {} });
|
|
34699
35173
|
}
|
|
34700
35174
|
for (const { goal, since } of moved) if (read.has(goal.goalId)) state.below.goals.set(goal.goalId, { since, at: goal.updatedAt ?? null });
|
|
34701
35175
|
return { heard, listed };
|
|
@@ -34714,7 +35188,7 @@ var block = (h) => [
|
|
|
34714
35188
|
...h.note ? [`The last note on it, from the agent before you: ${h.note}`] : [],
|
|
34715
35189
|
...h.words
|
|
34716
35190
|
].join("\n\n");
|
|
34717
|
-
var short = (ids) => ids.map((
|
|
35191
|
+
var short = (ids) => ids.map((id3) => id3.slice(0, 8)).join(", ");
|
|
34718
35192
|
var given = (heard) => heard.filter((h) => h.via === "assigned").map((h) => h.goalId);
|
|
34719
35193
|
async function hear(session, state, rail, held, opts) {
|
|
34720
35194
|
const log = opts?.log;
|
|
@@ -34781,8 +35255,8 @@ async function acknowledge(goalId, brief, state, rail, log) {
|
|
|
34781
35255
|
if (acked.has(goalId) && acked.get(goalId) === brief.revision) return;
|
|
34782
35256
|
acked.set(goalId, brief.revision);
|
|
34783
35257
|
try {
|
|
34784
|
-
|
|
34785
|
-
const done = await rail.update(goalId, { revision:
|
|
35258
|
+
if (brief.revision === void 0) throw new Error("review_revision_missing");
|
|
35259
|
+
const done = await rail.update(goalId, { revision: brief.revision, changes: { reviewed: true }, reason: "Read by the harness session; the person's words on it are typed in." });
|
|
34786
35260
|
acked.set(goalId, done.revision);
|
|
34787
35261
|
if (state.goal?.id === goalId && done.revision !== void 0) state.goal.revision = done.revision;
|
|
34788
35262
|
} catch (error) {
|
|
@@ -34819,25 +35293,26 @@ async function look(session, state, rail, opts) {
|
|
|
34819
35293
|
brief2 = await rail.claim();
|
|
34820
35294
|
if (!brief2.goalId || brief2.revision === void 0) {
|
|
34821
35295
|
state.goal = { id: admitted.goalId, revision: admitted.revision };
|
|
34822
|
-
send2(session, state, [HARNESS_INSTRUCTION, prompt].join("\n\n"));
|
|
35296
|
+
send2(session, state, [HARNESS_INSTRUCTION, named(admitted.goalId, void 0, { outcome: prompt }), prompt].join("\n\n"));
|
|
34823
35297
|
return;
|
|
34824
35298
|
}
|
|
34825
35299
|
} else {
|
|
34826
35300
|
return;
|
|
34827
35301
|
}
|
|
34828
35302
|
}
|
|
34829
|
-
unheard(brief2, state);
|
|
34830
|
-
if (
|
|
34831
|
-
|
|
35303
|
+
const pendingWords = brief2.reviewSince ? unheard(brief2, state, null, -1, brief2.reviewSince) : null;
|
|
35304
|
+
if (!pendingWords) unheard(brief2, state);
|
|
35305
|
+
if (!ended(brief2.state)) {
|
|
34832
35306
|
state.goal = { id: brief2.goalId, revision: brief2.revision };
|
|
34833
35307
|
state.below = baseline(brief2.goalId, brief2.subtree);
|
|
34834
35308
|
}
|
|
34835
35309
|
const outcome2 = brief2.outcome?.trim() ?? "";
|
|
34836
|
-
const said = (brief2.entries ?? []).map((e) => entryWords(e).trim()).filter((w) => w && w.toLowerCase() !== outcome2.toLowerCase());
|
|
35310
|
+
const said = (pendingWords ?? (brief2.entries ?? []).map((e) => entryWords(e).trim())).filter((w) => w && w.toLowerCase() !== outcome2.toLowerCase());
|
|
34837
35311
|
const left = brief2.earlier ? brief2.earlier.omitted + brief2.earlier.shortened : 0;
|
|
34838
35312
|
const earlier = left ? `(${left} earlier entries on this Goal are left out or shortened; get_goal with history: true reads them in full.)` : "";
|
|
34839
35313
|
const fullText = [outcome2, earlier, ...said].filter(Boolean).join("\n\n");
|
|
34840
|
-
send2(session, state, [HARNESS_INSTRUCTION, fullText].filter(Boolean).join("\n\n"));
|
|
35314
|
+
send2(session, state, [HARNESS_INSTRUCTION, named(brief2.goalId, void 0, brief2), fullText].filter(Boolean).join("\n\n"));
|
|
35315
|
+
if (ended(brief2.state)) await acknowledge(brief2.goalId, brief2, state, rail, opts?.log);
|
|
34841
35316
|
return;
|
|
34842
35317
|
}
|
|
34843
35318
|
const brief = await rail.read(state.goal.id);
|
|
@@ -34846,6 +35321,7 @@ async function look(session, state, rail, opts) {
|
|
|
34846
35321
|
const resolve3 = state.asks?.get(answer.requestEntryId);
|
|
34847
35322
|
if (!resolve3) continue;
|
|
34848
35323
|
state.asks.delete(answer.requestEntryId);
|
|
35324
|
+
(state.seen ??= /* @__PURE__ */ new Set()).add(`answer:${answer.decisionNeedId}`);
|
|
34849
35325
|
resolve3(answer.result);
|
|
34850
35326
|
}
|
|
34851
35327
|
if (ended(brief.state)) {
|
|
@@ -34923,8 +35399,9 @@ function runHarness(opts) {
|
|
|
34923
35399
|
const state = { resting: true };
|
|
34924
35400
|
const clock4 = beat();
|
|
34925
35401
|
let session = null;
|
|
34926
|
-
const speaksAs = opts.
|
|
34927
|
-
const
|
|
35402
|
+
const speaksAs = opts.session ?? opts.resume ?? sessionId();
|
|
35403
|
+
const instance = randomUUID6();
|
|
35404
|
+
const rail = railFor({ token: opts.token, reach: reachAs(speaksAs, instance) });
|
|
34928
35405
|
let inbox;
|
|
34929
35406
|
if (opts.harness === "claude") {
|
|
34930
35407
|
try {
|
|
@@ -34975,11 +35452,17 @@ ${event.message}`, state, rail, { log: opts.log });
|
|
|
34975
35452
|
tail = [];
|
|
34976
35453
|
const carried = state.carriedOn && !event.failed;
|
|
34977
35454
|
if (await afterTurn(event, state, rail, { log: opts.log })) LIMITS.paused(name, Date.now());
|
|
34978
|
-
else if (
|
|
35455
|
+
else if (state.full) {
|
|
35456
|
+
opts.log(`\u25A0 ${name}'s conversation is full \u2014 ending this run; it will not be resumed`);
|
|
35457
|
+
opts.onFull?.(speaksAs);
|
|
35458
|
+
stop2();
|
|
35459
|
+
return;
|
|
35460
|
+
} else if (carried) runningAgain();
|
|
34979
35461
|
clock4.nudge("rest");
|
|
34980
35462
|
}
|
|
34981
35463
|
}
|
|
34982
35464
|
session = startSession({
|
|
35465
|
+
instance,
|
|
34983
35466
|
harness: opts.harness,
|
|
34984
35467
|
cwd: opts.cwd,
|
|
34985
35468
|
mode: opts.mode,
|
|
@@ -35022,9 +35505,9 @@ ${event.message}`, state, rail, { log: opts.log });
|
|
|
35022
35505
|
|
|
35023
35506
|
// src/host.ts
|
|
35024
35507
|
init_dist();
|
|
35025
|
-
import { readFileSync as
|
|
35508
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
35026
35509
|
import { homedir as homedir9 } from "os";
|
|
35027
|
-
import { join as
|
|
35510
|
+
import { join as join10 } from "path";
|
|
35028
35511
|
|
|
35029
35512
|
// src/broker.ts
|
|
35030
35513
|
init_evidence();
|
|
@@ -35044,15 +35527,15 @@ function ago(iso, now) {
|
|
|
35044
35527
|
init_catalog();
|
|
35045
35528
|
|
|
35046
35529
|
// src/workspaces.ts
|
|
35047
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as
|
|
35048
|
-
import { dirname as dirname2, join as
|
|
35530
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
35531
|
+
import { dirname as dirname2, join as join6, resolve as resolve2 } from "path";
|
|
35049
35532
|
import { homedir as homedir6 } from "os";
|
|
35050
35533
|
function workspacesFile() {
|
|
35051
|
-
return
|
|
35534
|
+
return join6(homedir6(), ".paigy", "workspaces.json");
|
|
35052
35535
|
}
|
|
35053
35536
|
function listWorkspaces(deps) {
|
|
35054
35537
|
try {
|
|
35055
|
-
const parsed = JSON.parse(
|
|
35538
|
+
const parsed = JSON.parse(readFileSync4(deps.file, "utf8"));
|
|
35056
35539
|
return Array.isArray(parsed) ? parsed.filter((w) => typeof w === "string") : [];
|
|
35057
35540
|
} catch {
|
|
35058
35541
|
return [];
|
|
@@ -35081,8 +35564,8 @@ function resolveWakeDir(pinned, deps) {
|
|
|
35081
35564
|
}
|
|
35082
35565
|
function originOf(dir) {
|
|
35083
35566
|
try {
|
|
35084
|
-
if (!statSync3(
|
|
35085
|
-
const config =
|
|
35567
|
+
if (!statSync3(join6(dir, ".git")).isDirectory()) return null;
|
|
35568
|
+
const config = readFileSync4(join6(dir, ".git", "config"), "utf8");
|
|
35086
35569
|
const section = config.split(/^\[/m).find((s) => /^remote\s+"origin"\]/.test(s));
|
|
35087
35570
|
return section?.match(/^\s*url\s*=\s*(.+)$/m)?.[1]?.trim() ?? null;
|
|
35088
35571
|
} catch {
|
|
@@ -35103,7 +35586,7 @@ function listRepos(deps) {
|
|
|
35103
35586
|
}
|
|
35104
35587
|
for (const name of children) {
|
|
35105
35588
|
if (repos.length >= MAX_REPOS) return repos;
|
|
35106
|
-
const path =
|
|
35589
|
+
const path = join6(root, name);
|
|
35107
35590
|
const remote = originOf(path);
|
|
35108
35591
|
if (remote) repos.push({ path, remote });
|
|
35109
35592
|
}
|
|
@@ -35114,9 +35597,9 @@ function listRepos(deps) {
|
|
|
35114
35597
|
// src/holder.ts
|
|
35115
35598
|
init_dist();
|
|
35116
35599
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
35117
|
-
import { readFileSync as
|
|
35600
|
+
import { readFileSync as readFileSync5, readdirSync as readdirSync3 } from "fs";
|
|
35118
35601
|
import { homedir as homedir7 } from "os";
|
|
35119
|
-
import { join as
|
|
35602
|
+
import { join as join7 } from "path";
|
|
35120
35603
|
function isAlive(pid) {
|
|
35121
35604
|
try {
|
|
35122
35605
|
process.kill(pid, 0);
|
|
@@ -35154,9 +35637,9 @@ function proven(pid, procStart, deps) {
|
|
|
35154
35637
|
});
|
|
35155
35638
|
}
|
|
35156
35639
|
function localHolderPids(deps = {}) {
|
|
35157
|
-
const dir = deps.dir ??
|
|
35640
|
+
const dir = deps.dir ?? join7(process.env.CLAUDE_CONFIG_DIR?.trim() || join7(homedir7(), ".claude"), "sessions");
|
|
35158
35641
|
const list = deps.list ?? ((d) => readdirSync3(d));
|
|
35159
|
-
const read = deps.read ?? ((f) =>
|
|
35642
|
+
const read = deps.read ?? ((f) => readFileSync5(f, "utf8"));
|
|
35160
35643
|
const check = { alive: deps.alive ?? isAlive, started: deps.started ?? psStart };
|
|
35161
35644
|
const held = /* @__PURE__ */ new Map();
|
|
35162
35645
|
let files;
|
|
@@ -35169,7 +35652,7 @@ function localHolderPids(deps = {}) {
|
|
|
35169
35652
|
if (!/^\d+\.json$/.test(file)) continue;
|
|
35170
35653
|
let row;
|
|
35171
35654
|
try {
|
|
35172
|
-
row = JSON.parse(read(
|
|
35655
|
+
row = JSON.parse(read(join7(dir, file)));
|
|
35173
35656
|
} catch {
|
|
35174
35657
|
continue;
|
|
35175
35658
|
}
|
|
@@ -35199,9 +35682,9 @@ function descendsFrom(pid, ancestor, parent = psParent) {
|
|
|
35199
35682
|
return false;
|
|
35200
35683
|
}
|
|
35201
35684
|
function localHolders(deps = {}) {
|
|
35202
|
-
const dir = deps.dir ??
|
|
35685
|
+
const dir = deps.dir ?? join7(process.env.CLAUDE_CONFIG_DIR?.trim() || join7(homedir7(), ".claude"), "sessions");
|
|
35203
35686
|
const list = deps.list ?? ((d) => readdirSync3(d));
|
|
35204
|
-
const read = deps.read ?? ((f) =>
|
|
35687
|
+
const read = deps.read ?? ((f) => readFileSync5(f, "utf8"));
|
|
35205
35688
|
const check = { alive: deps.alive ?? isAlive, started: deps.started ?? psStart };
|
|
35206
35689
|
const held = /* @__PURE__ */ new Map();
|
|
35207
35690
|
let files;
|
|
@@ -35214,7 +35697,7 @@ function localHolders(deps = {}) {
|
|
|
35214
35697
|
if (!/^\d+\.json$/.test(file)) continue;
|
|
35215
35698
|
let row;
|
|
35216
35699
|
try {
|
|
35217
|
-
row = JSON.parse(read(
|
|
35700
|
+
row = JSON.parse(read(join7(dir, file)));
|
|
35218
35701
|
} catch {
|
|
35219
35702
|
continue;
|
|
35220
35703
|
}
|
|
@@ -35289,7 +35772,7 @@ async function endSession(end, deps) {
|
|
|
35289
35772
|
// src/owner.ts
|
|
35290
35773
|
import { closeSync as closeSync2, openSync as openSync2, readSync, readdirSync as readdirSync4 } from "fs";
|
|
35291
35774
|
import { homedir as homedir8 } from "os";
|
|
35292
|
-
import { join as
|
|
35775
|
+
import { join as join8 } from "path";
|
|
35293
35776
|
var HEAD_BYTES = 64e3;
|
|
35294
35777
|
function readHead(file) {
|
|
35295
35778
|
const fd = openSync2(file, "r");
|
|
@@ -35305,7 +35788,7 @@ function ownerSession(slot, deps = {}) {
|
|
|
35305
35788
|
const m = /^session:([0-9a-f]{8})$/.exec(slot);
|
|
35306
35789
|
if (!m) return null;
|
|
35307
35790
|
const prefix = m[1];
|
|
35308
|
-
const root = deps.projectsDir ??
|
|
35791
|
+
const root = deps.projectsDir ?? join8(homedir8(), ".claude", "projects");
|
|
35309
35792
|
const list = deps.list ?? ((dir) => readdirSync4(dir));
|
|
35310
35793
|
const head = deps.head ?? readHead;
|
|
35311
35794
|
let folders;
|
|
@@ -35317,7 +35800,7 @@ function ownerSession(slot, deps = {}) {
|
|
|
35317
35800
|
for (const folder of folders) {
|
|
35318
35801
|
let files;
|
|
35319
35802
|
try {
|
|
35320
|
-
files = list(
|
|
35803
|
+
files = list(join8(root, folder));
|
|
35321
35804
|
} catch {
|
|
35322
35805
|
continue;
|
|
35323
35806
|
}
|
|
@@ -35325,7 +35808,7 @@ function ownerSession(slot, deps = {}) {
|
|
|
35325
35808
|
if (!file) continue;
|
|
35326
35809
|
let text;
|
|
35327
35810
|
try {
|
|
35328
|
-
text = head(
|
|
35811
|
+
text = head(join8(root, folder, file));
|
|
35329
35812
|
} catch {
|
|
35330
35813
|
continue;
|
|
35331
35814
|
}
|
|
@@ -35345,7 +35828,7 @@ function ownerSession(slot, deps = {}) {
|
|
|
35345
35828
|
// src/update.ts
|
|
35346
35829
|
import { execFile } from "child_process";
|
|
35347
35830
|
import { createRequire } from "module";
|
|
35348
|
-
import { dirname as dirname3, join as
|
|
35831
|
+
import { dirname as dirname3, join as join9 } from "path";
|
|
35349
35832
|
import { promisify } from "util";
|
|
35350
35833
|
var SERVICE_LABEL = "ai.paigy.harness";
|
|
35351
35834
|
var VERSION = createRequire(import.meta.url)("../package.json").version;
|
|
@@ -35372,7 +35855,7 @@ async function latestVersion() {
|
|
|
35372
35855
|
}
|
|
35373
35856
|
async function install(version) {
|
|
35374
35857
|
const bin = dirname3(process.execPath);
|
|
35375
|
-
await promisify(execFile)(
|
|
35858
|
+
await promisify(execFile)(join9(bin, "npm"), ["install", "-g", `@paigy/harness@${version}`], {
|
|
35376
35859
|
env: { ...process.env, PATH: `${bin}:${process.env.PATH ?? ""}`, npm_config_update_notifier: "false" },
|
|
35377
35860
|
timeout: 5 * 6e4
|
|
35378
35861
|
});
|
|
@@ -35423,7 +35906,7 @@ function selfUpdater(deps) {
|
|
|
35423
35906
|
}
|
|
35424
35907
|
|
|
35425
35908
|
// src/host.ts
|
|
35426
|
-
var HOST_FILE =
|
|
35909
|
+
var HOST_FILE = join10(homedir9(), ".paigy", "host.json");
|
|
35427
35910
|
function wakeHarness(slot, saved, claudeTranscript) {
|
|
35428
35911
|
if (slot === "Desktop") return void 0;
|
|
35429
35912
|
if (saved !== null) return saved === "agy" || saved === "codex" || saved === "claude" ? saved : void 0;
|
|
@@ -35439,26 +35922,33 @@ var claimedRun = (sessionId2) => {
|
|
|
35439
35922
|
return { slot, key: runKey(slot) };
|
|
35440
35923
|
};
|
|
35441
35924
|
var launchRun = (spec) => ({ session: spec.sessionId });
|
|
35925
|
+
var BOUND_ELSEWHERE_MS = 10 * 6e4;
|
|
35926
|
+
var boundElsewhere = /* @__PURE__ */ new Map();
|
|
35927
|
+
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";
|
|
35442
35928
|
var NOTHING_WAITING = "has nothing waiting";
|
|
35443
35929
|
async function waitingWork(token, session) {
|
|
35930
|
+
const quiet = boundElsewhere.get(token);
|
|
35931
|
+
if (quiet !== void 0 && Date.now() < quiet) return { skip: BOUND_SKIP };
|
|
35444
35932
|
let found;
|
|
35445
35933
|
try {
|
|
35446
35934
|
found = await checkReplies({ token, ...session ? { reach: reachAs(session) } : {} });
|
|
35447
35935
|
} catch (error) {
|
|
35448
35936
|
if (error instanceof RevokedError) return { skip: "was revoked: its credential is gone for good", revoked: true };
|
|
35449
35937
|
if (error instanceof ApiError && error.body?.error === "identity_session_mismatch") {
|
|
35450
|
-
|
|
35938
|
+
boundElsewhere.set(token, Date.now() + BOUND_ELSEWHERE_MS);
|
|
35939
|
+
return { skip: BOUND_SKIP };
|
|
35451
35940
|
}
|
|
35452
35941
|
return { skip: `could not read what is waiting (${error.message})` };
|
|
35453
35942
|
}
|
|
35943
|
+
boundElsewhere.delete(token);
|
|
35454
35944
|
const next = found.claimable;
|
|
35455
35945
|
const about = next ? { goalId: next.goalId, ...next.since ? { since: next.since } : {} } : {};
|
|
35456
35946
|
const n = found.deliveries.length;
|
|
35457
35947
|
if (n) return { waiting: n === 1 ? "a message" : `${n} messages`, ...about };
|
|
35458
35948
|
return next ? { waiting: `Goal ${next.goalId.slice(0, 8)}${next.title ? ` "${next.title}"` : ""}`, ...about } : { skip: NOTHING_WAITING };
|
|
35459
35949
|
}
|
|
35460
|
-
function evict(runs,
|
|
35461
|
-
if (runs.get(
|
|
35950
|
+
function evict(runs, key3, run) {
|
|
35951
|
+
if (runs.get(key3)?.run === run) runs.delete(key3);
|
|
35462
35952
|
}
|
|
35463
35953
|
var PRESENCE_FRESH_MS = 3 * 6e4;
|
|
35464
35954
|
var IDLE_HOLDER_MS = 30 * 6e4;
|
|
@@ -35501,9 +35991,9 @@ function startHost(opts) {
|
|
|
35501
35991
|
const agent2 = slotIdentity(slot).tokenId;
|
|
35502
35992
|
if (!agent2) return;
|
|
35503
35993
|
const goalId = found?.goalId;
|
|
35504
|
-
const
|
|
35505
|
-
if (recorded.get(slot) ===
|
|
35506
|
-
recorded.set(slot,
|
|
35994
|
+
const key3 = `${decision}:${goalId ?? ""}`;
|
|
35995
|
+
if (recorded.get(slot) === key3) return;
|
|
35996
|
+
recorded.set(slot, key3);
|
|
35507
35997
|
void recordDecision({
|
|
35508
35998
|
agent: agent2,
|
|
35509
35999
|
decision,
|
|
@@ -35553,7 +36043,7 @@ function startHost(opts) {
|
|
|
35553
36043
|
const specs = await claimSessions(asHost).catch(() => []);
|
|
35554
36044
|
for (const spec of specs) {
|
|
35555
36045
|
const label = spec.name ?? spec.harness;
|
|
35556
|
-
const { slot, key } = claimedRun(spec.sessionId);
|
|
36046
|
+
const { slot, key: key3 } = claimedRun(spec.sessionId);
|
|
35557
36047
|
const log = (line) => opts.log(`[${label}] ${line}`);
|
|
35558
36048
|
try {
|
|
35559
36049
|
saveToken({
|
|
@@ -35576,14 +36066,17 @@ function startHost(opts) {
|
|
|
35576
36066
|
token: spec.token,
|
|
35577
36067
|
...launchRun(spec),
|
|
35578
36068
|
onExit: () => {
|
|
35579
|
-
evict(runs,
|
|
36069
|
+
evict(runs, key3, run);
|
|
35580
36070
|
goneAt.set(slot, Date.now());
|
|
35581
36071
|
opts.log(`\u2716 ${label} ended`);
|
|
35582
36072
|
},
|
|
36073
|
+
onFull: (session) => {
|
|
36074
|
+
updateSlot(slot, { full_session: session });
|
|
36075
|
+
},
|
|
35583
36076
|
name: label,
|
|
35584
36077
|
log
|
|
35585
36078
|
});
|
|
35586
|
-
runs.set(
|
|
36079
|
+
runs.set(key3, { run, label, token: spec.token });
|
|
35587
36080
|
void heartbeat(void 0, { token: spec.token }).catch(() => {
|
|
35588
36081
|
});
|
|
35589
36082
|
void refreshIdentities();
|
|
@@ -35635,9 +36128,9 @@ function startHost(opts) {
|
|
|
35635
36128
|
let lastHolders = /* @__PURE__ */ new Map();
|
|
35636
36129
|
async function wakeSlot(slot, { presence, holders }, cause = "sweep") {
|
|
35637
36130
|
{
|
|
35638
|
-
const
|
|
36131
|
+
const key3 = runKey(slot);
|
|
35639
36132
|
if (slot === "Desktop" || isRevoked(slot)) return;
|
|
35640
|
-
const live = runs.get(
|
|
36133
|
+
const live = runs.get(key3);
|
|
35641
36134
|
if (live) {
|
|
35642
36135
|
const theirs = (localHolderPids().get(slot) ?? []).map((p) => p.pid).filter((pid) => !descendsFrom(pid, process.pid));
|
|
35643
36136
|
if (theirs.length) {
|
|
@@ -35672,6 +36165,11 @@ function startHost(opts) {
|
|
|
35672
36165
|
}
|
|
35673
36166
|
const identity = slotIdentity(slot);
|
|
35674
36167
|
const owner = !identity.harness || identity.harness === "claude" ? ownerSession(slot) : null;
|
|
36168
|
+
const resumes = owner?.sessionId ?? identity.sessionId;
|
|
36169
|
+
if (resumes && identity.fullSession === resumes) {
|
|
36170
|
+
skip(`has a full conversation (${resumes.slice(0, 8)}) \u2014 not resuming it; its Goals go to the dead-agent handoff`);
|
|
36171
|
+
return;
|
|
36172
|
+
}
|
|
35675
36173
|
const read = async () => {
|
|
35676
36174
|
const got = await waitingWork(token, identity.sessionId ?? owner?.sessionId);
|
|
35677
36175
|
if (!("skip" in got)) return got;
|
|
@@ -35712,7 +36210,7 @@ function startHost(opts) {
|
|
|
35712
36210
|
}
|
|
35713
36211
|
found ??= await read() ?? void 0;
|
|
35714
36212
|
if (!found) return;
|
|
35715
|
-
if (runs.has(
|
|
36213
|
+
if (runs.has(key3)) {
|
|
35716
36214
|
skip("was started by the wake that read it first");
|
|
35717
36215
|
return;
|
|
35718
36216
|
}
|
|
@@ -35728,14 +36226,17 @@ function startHost(opts) {
|
|
|
35728
36226
|
// A dead run must not squat the slot — evict so the next wake can respawn. Only ITS entry:
|
|
35729
36227
|
// a run that is no longer the slot's must not take the live one's place away with it.
|
|
35730
36228
|
onExit: () => {
|
|
35731
|
-
evict(runs,
|
|
36229
|
+
evict(runs, key3, run);
|
|
35732
36230
|
goneAt.set(slot, Date.now());
|
|
35733
36231
|
opts.log(`\u2716 ${label} ended`);
|
|
35734
36232
|
},
|
|
36233
|
+
onFull: (session) => {
|
|
36234
|
+
updateSlot(slot, { full_session: session });
|
|
36235
|
+
},
|
|
35735
36236
|
name: label,
|
|
35736
36237
|
log
|
|
35737
36238
|
});
|
|
35738
|
-
runs.set(
|
|
36239
|
+
runs.set(key3, { run, label, token });
|
|
35739
36240
|
void heartbeat(void 0, { token }).catch(() => {
|
|
35740
36241
|
});
|
|
35741
36242
|
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}`;
|
|
@@ -35788,17 +36289,17 @@ function startHost(opts) {
|
|
|
35788
36289
|
void heartbeat(void 0, { token, activity: { lines: lines2, at: (/* @__PURE__ */ new Date()).toISOString() } }).catch(() => {
|
|
35789
36290
|
});
|
|
35790
36291
|
};
|
|
35791
|
-
for (const [
|
|
36292
|
+
for (const [key3, r] of runs) {
|
|
35792
36293
|
if (!r.token) continue;
|
|
35793
36294
|
const lines2 = r.run.tail();
|
|
35794
|
-
const was = published.get(
|
|
36295
|
+
const was = published.get(key3);
|
|
35795
36296
|
if (was && sameTail(was.lines, lines2)) continue;
|
|
35796
|
-
published.set(
|
|
36297
|
+
published.set(key3, { token: r.token, lines: lines2 });
|
|
35797
36298
|
publishTail(r.token, lines2);
|
|
35798
36299
|
}
|
|
35799
|
-
for (const [
|
|
35800
|
-
if (runs.has(
|
|
35801
|
-
published.delete(
|
|
36300
|
+
for (const [key3, was] of published) {
|
|
36301
|
+
if (runs.has(key3)) continue;
|
|
36302
|
+
published.delete(key3);
|
|
35802
36303
|
if (was.lines.length > 0) publishTail(was.token, []);
|
|
35803
36304
|
}
|
|
35804
36305
|
};
|
|
@@ -35829,25 +36330,25 @@ function startHost(opts) {
|
|
|
35829
36330
|
})));
|
|
35830
36331
|
};
|
|
35831
36332
|
const api = {
|
|
35832
|
-
sessions: () => [...runs.entries()].map(([
|
|
36333
|
+
sessions: () => [...runs.entries()].map(([id3, r]) => [id3, r.label]),
|
|
35833
36334
|
// Every identity this machine holds, plus what it's doing right now. Slots are the
|
|
35834
36335
|
// roster (hatched agents, the terminal tools, claimed sessions); a run makes one of
|
|
35835
36336
|
// them live, and a run mid-turn makes it working.
|
|
35836
36337
|
roster: () => {
|
|
35837
36338
|
const live = new Map([...runs.values()].map((r) => [r.label, r.run]));
|
|
35838
36339
|
const names2 = /* @__PURE__ */ new Map();
|
|
35839
|
-
for (const
|
|
36340
|
+
for (const key3 of listSlots()) if (key3 !== "Desktop" && !isRevoked(key3)) names2.set(slotName(key3) ?? key3, key3);
|
|
35840
36341
|
for (const label of live.keys()) if (!names2.has(label)) names2.set(label, null);
|
|
35841
36342
|
return [...names2.entries()].map(([name, slot]) => {
|
|
35842
|
-
const
|
|
36343
|
+
const id3 = slot ? slotIdentity(slot) : { voice: null, tokenId: null };
|
|
35843
36344
|
return {
|
|
35844
36345
|
name,
|
|
35845
36346
|
// The slot key rides along so the window's agent page can speak AS this agent —
|
|
35846
36347
|
// its pending reads (`checkReplies`, the same pure read the sweep does) need the
|
|
35847
36348
|
// slot's own token, and the display name is not a key.
|
|
35848
36349
|
slot,
|
|
35849
|
-
tokenId:
|
|
35850
|
-
voice:
|
|
36350
|
+
tokenId: id3.tokenId,
|
|
36351
|
+
voice: id3.voice,
|
|
35851
36352
|
// RUNNING IS ABOUT THE IDENTITY, NOT ABOUT US (owner, 2026-09-14). This was
|
|
35852
36353
|
// `live.has(name)` — "this host spawned it and it has not exited" — which is a fact
|
|
35853
36354
|
// about our own process table, not about the agent. An ordinary terminal session
|
|
@@ -35855,7 +36356,7 @@ function startHost(opts) {
|
|
|
35855
36356
|
// sessions we started ourselves. The server already knows: `last_seen_at` on the
|
|
35856
36357
|
// agent's own token, the same evidence `wakeAction` stands back for. So: a run we
|
|
35857
36358
|
// hold, OR a process the server heard from inside `PRESENCE_FRESH_MS`.
|
|
35858
|
-
running: live.has(name) || !!slot && lastHolders.has(slot) || !!
|
|
36359
|
+
running: live.has(name) || !!slot && lastHolders.has(slot) || !!id3.tokenId && Date.now() - (lastPresence.get(id3.tokenId) ?? 0) < PRESENCE_FRESH_MS,
|
|
35859
36360
|
// `working` stays ours alone — it means a run WE hold is mid-turn, which is the only
|
|
35860
36361
|
// thing a tail can tell us. A process we did not spawn has no tail here to read.
|
|
35861
36362
|
working: live.get(name)?.working() ?? false
|
|
@@ -35976,20 +36477,14 @@ async function pairThisMachine() {
|
|
|
35976
36477
|
}
|
|
35977
36478
|
}
|
|
35978
36479
|
function forwardCodexThreadId() {
|
|
35979
|
-
const cfg =
|
|
36480
|
+
const cfg = join11(process.env.CODEX_HOME || join11(homedir10(), ".codex"), "config.toml");
|
|
35980
36481
|
if (!existsSync5(cfg)) return;
|
|
35981
|
-
const text =
|
|
35982
|
-
const
|
|
35983
|
-
|
|
35984
|
-
if (at < 0) return;
|
|
35985
|
-
const block2 = text.slice(at + head.length, (() => {
|
|
35986
|
-
const n = text.indexOf("\n[", at + head.length);
|
|
35987
|
-
return n < 0 ? text.length : n;
|
|
35988
|
-
})());
|
|
35989
|
-
if (/^\s*env_vars\s*=/m.test(block2)) return;
|
|
35990
|
-
writeFileSync5(cfg, text.slice(0, at + head.length) + 'env_vars = ["CODEX_THREAD_ID", "CODEX_SESSION_ID"]\n' + text.slice(at + head.length));
|
|
36482
|
+
const text = readFileSync7(cfg, "utf8");
|
|
36483
|
+
const updated = withCodexEnv(text);
|
|
36484
|
+
if (updated !== null && updated !== text) writeFileSync5(cfg, updated);
|
|
35991
36485
|
}
|
|
35992
36486
|
async function main() {
|
|
36487
|
+
setClient(`harness@${VERSION}`);
|
|
35993
36488
|
const parsed = parseArgs(process.argv.slice(2));
|
|
35994
36489
|
if ("error" in parsed) {
|
|
35995
36490
|
console.error(`paigy-harness: ${parsed.error}`);
|
|
@@ -36005,6 +36500,7 @@ async function main() {
|
|
|
36005
36500
|
console.log(" service install the host as a login service (macOS)");
|
|
36006
36501
|
console.log(" enable-tools allowlist Paigy's tools in Claude Code so they don't prompt each time");
|
|
36007
36502
|
console.log(" hatch NAME mint a sibling identity from this machine's credential");
|
|
36503
|
+
console.log(' launch NAME "brief" start a helper session with its own identity and its brief as its first Goal [--under GOAL]');
|
|
36008
36504
|
console.log(" handoff pin this terminal's identity here so your phone can resume it");
|
|
36009
36505
|
console.log(" triage sweep your whole note queue with a model on THIS machine and");
|
|
36010
36506
|
console.log(" send grouped suggestions to your phone (close / stale / assign)");
|
|
@@ -36078,7 +36574,7 @@ async function main() {
|
|
|
36078
36574
|
const wsDeps = { file: workspacesFile() };
|
|
36079
36575
|
for (const dir of parsed.grant) addWorkspace(dir, wsDeps);
|
|
36080
36576
|
if (!listWorkspaces(wsDeps).length) {
|
|
36081
|
-
const guess =
|
|
36577
|
+
const guess = join11(homedir10(), "projects");
|
|
36082
36578
|
if (existsSync5(guess)) {
|
|
36083
36579
|
addWorkspace(guess, wsDeps);
|
|
36084
36580
|
console.log(`\u2713 workspace granted: ${guess} (change with --grant DIR)`);
|
|
@@ -36110,9 +36606,9 @@ async function main() {
|
|
|
36110
36606
|
}
|
|
36111
36607
|
}
|
|
36112
36608
|
try {
|
|
36113
|
-
const settings =
|
|
36609
|
+
const settings = join11(homedir10(), ".claude", "settings.json");
|
|
36114
36610
|
if (which("claude") && existsSync5(settings)) {
|
|
36115
|
-
const cfg = JSON.parse(
|
|
36611
|
+
const cfg = JSON.parse(readFileSync7(settings, "utf8"));
|
|
36116
36612
|
if (!cfg["statusLine"]) {
|
|
36117
36613
|
cfg["statusLine"] = { type: "command", command: "npx -y -p @paigy/mcp@latest paigy-statusline" };
|
|
36118
36614
|
writeFileSync5(settings, JSON.stringify(cfg, null, 2));
|
|
@@ -36168,13 +36664,13 @@ async function main() {
|
|
|
36168
36664
|
<key>SoftResourceLimits</key><dict>
|
|
36169
36665
|
<key>NumberOfFiles</key><integer>65536</integer>
|
|
36170
36666
|
</dict>
|
|
36171
|
-
<key>StandardOutPath</key><string>${
|
|
36172
|
-
<key>StandardErrorPath</key><string>${
|
|
36667
|
+
<key>StandardOutPath</key><string>${join11(homedir10(), ".paigy", "host.log")}</string>
|
|
36668
|
+
<key>StandardErrorPath</key><string>${join11(homedir10(), ".paigy", "host.log")}</string>
|
|
36173
36669
|
</dict></plist>
|
|
36174
36670
|
`;
|
|
36175
|
-
const dir =
|
|
36671
|
+
const dir = join11(homedir10(), "Library", "LaunchAgents");
|
|
36176
36672
|
mkdirSync4(dir, { recursive: true });
|
|
36177
|
-
const path =
|
|
36673
|
+
const path = join11(dir, `${SERVICE_LABEL}.plist`);
|
|
36178
36674
|
writeFileSync5(path, plist);
|
|
36179
36675
|
execSync(`launchctl unload ${path} 2>/dev/null; launchctl load ${path}`, { shell: "/bin/sh" });
|
|
36180
36676
|
console.log(`\u2713 host installed as a login service (${path}) \u2014 logs at ~/.paigy/host.log`);
|
|
@@ -36219,7 +36715,7 @@ async function main() {
|
|
|
36219
36715
|
return;
|
|
36220
36716
|
}
|
|
36221
36717
|
if (parsed.hatch) {
|
|
36222
|
-
overrideToken(
|
|
36718
|
+
overrideToken(readSlot("Desktop") || null);
|
|
36223
36719
|
const minted = await hatch(parsed.hatch, parsed.voice ?? null);
|
|
36224
36720
|
saveToken({ access_token: minted.token, name: minted.name ?? parsed.hatch, device: null }, parsed.slot ?? minted.name ?? parsed.hatch);
|
|
36225
36721
|
if (!minted.name) {
|
|
@@ -36227,8 +36723,7 @@ async function main() {
|
|
|
36227
36723
|
return;
|
|
36228
36724
|
}
|
|
36229
36725
|
console.log(`\u2713 hatched "${minted.name}" \u2014 it's on your phone's Agents screen now.`);
|
|
36230
|
-
console.log(`
|
|
36231
|
-
console.log(` run with it: paigy-harness --identity "${minted.name}" --harness codex "\u2026"`);
|
|
36726
|
+
console.log(` start a helper with its own session instead: paigy-harness launch "<name>" "<brief>"`);
|
|
36232
36727
|
return;
|
|
36233
36728
|
}
|
|
36234
36729
|
if (parsed.host) {
|
|
@@ -36246,21 +36741,27 @@ async function main() {
|
|
|
36246
36741
|
});
|
|
36247
36742
|
return;
|
|
36248
36743
|
}
|
|
36249
|
-
let identityToken;
|
|
36250
|
-
if (parsed.identity) {
|
|
36251
|
-
const slot = readToken(parsed.identity);
|
|
36252
|
-
if (!slot) {
|
|
36253
|
-
console.error(`No slot for "${parsed.identity}" \u2014 hatch it first: paigy-harness hatch "${parsed.identity}"`);
|
|
36254
|
-
process.exit(1);
|
|
36255
|
-
}
|
|
36256
|
-
identityToken = slot;
|
|
36257
|
-
}
|
|
36258
36744
|
const state = detectAll().find((a) => a.name === parsed.harness);
|
|
36259
36745
|
if (state && state.status !== "ready") {
|
|
36260
36746
|
const hint = state.hint ?? "setup incomplete";
|
|
36261
36747
|
console.error(`\u270B ${state.label}: ${hint}`);
|
|
36262
36748
|
process.exit(1);
|
|
36263
36749
|
}
|
|
36750
|
+
let launched;
|
|
36751
|
+
if (parsed.launch) {
|
|
36752
|
+
overrideToken(readSlot("Desktop") || null);
|
|
36753
|
+
const session = randomUUID7();
|
|
36754
|
+
const minted = await hatch(parsed.launch, parsed.voice ?? null, {
|
|
36755
|
+
reach: reachAs(session),
|
|
36756
|
+
brief: parsed.prompt,
|
|
36757
|
+
...parsed.under ? { parentGoalId: parsed.under } : {}
|
|
36758
|
+
}).catch((e) => {
|
|
36759
|
+
console.error(`\u270B the helper was not launched: ${e.message}`);
|
|
36760
|
+
process.exit(1);
|
|
36761
|
+
}).finally(() => overrideToken(null));
|
|
36762
|
+
launched = { token: minted.token, session, ...minted.goalId ? { goalId: minted.goalId } : {} };
|
|
36763
|
+
console.log(`\u2713 launched "${minted.name ?? parsed.launch}"${minted.name ? "" : " (unnamed: you already have an agent with that name)"}, on its own session; its Goal is ${minted.goalId ?? "missing"}`);
|
|
36764
|
+
}
|
|
36264
36765
|
const askTerminal = async (promptText) => {
|
|
36265
36766
|
if (parsed.graceSeconds <= 0 || !process.stdin.isTTY) return null;
|
|
36266
36767
|
const readline = await import("readline/promises");
|
|
@@ -36281,9 +36782,10 @@ async function main() {
|
|
|
36281
36782
|
harness: parsed.harness,
|
|
36282
36783
|
cwd: parsed.cwd,
|
|
36283
36784
|
mode: parsed.mode,
|
|
36284
|
-
|
|
36785
|
+
// hatch already admitted this brief; the pump must not admit it again after completion.
|
|
36786
|
+
prompt: launched ? "" : parsed.prompt,
|
|
36285
36787
|
...state?.bin ? { bin: state.bin } : {},
|
|
36286
|
-
...
|
|
36788
|
+
...launched ? { token: launched.token, session: launched.session } : {},
|
|
36287
36789
|
localAsk: {
|
|
36288
36790
|
permission: async (summary) => {
|
|
36289
36791
|
const said = await askTerminal(`\u23F8 blocked: ${summary} \u2014 allow? [y/n]`);
|
|
@@ -36295,7 +36797,7 @@ async function main() {
|
|
|
36295
36797
|
});
|
|
36296
36798
|
const beat2 = async () => {
|
|
36297
36799
|
try {
|
|
36298
|
-
await heartbeat();
|
|
36800
|
+
await heartbeat(void 0, launched ? { token: launched.token } : {});
|
|
36299
36801
|
signedOut = false;
|
|
36300
36802
|
} catch (e) {
|
|
36301
36803
|
if (!isUnauthorized(e) || signedOut) return;
|