halfcycle 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/bin/bin.bundle.mjs +1474 -869
- package/commands/agent-teams-orchestration.md +1 -1
- package/commands/consistency-check.md +1 -1
- package/commands/context-update.md +1 -1
- package/commands/halfcycle-design.md +1 -1
- package/commands/halfcycle-setup.md +1 -1
- package/commands/stack-assembly-worker.md +1 -1
- package/commands/task-execution.md +1 -1
- package/commands/task-graph.md +1 -1
- package/commands/write-spec.md +1 -1
- package/dist/bin.js +0 -0
- package/dist/build-record/render-v2.d.ts.map +1 -1
- package/dist/check-tasks.d.ts +28 -5
- package/dist/check-tasks.d.ts.map +1 -1
- package/dist/cli-contract.d.ts +1 -1
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/cli.js +2510 -1352
- package/dist/cli.js.map +3 -3
- package/dist/close-phase.d.ts +13 -10
- package/dist/close-phase.d.ts.map +1 -1
- package/dist/index.js +149 -69
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/local-allow.d.ts +108 -0
- package/dist/local-allow.d.ts.map +1 -0
- package/dist/open-phase.d.ts +8 -2
- package/dist/open-phase.d.ts.map +1 -1
- package/dist/pace.d.ts +11 -6
- package/dist/pace.d.ts.map +1 -1
- package/dist/review.d.ts +3 -2
- package/dist/review.d.ts.map +1 -1
- package/dist/size.d.ts +72 -0
- package/dist/size.d.ts.map +1 -0
- package/dist/uninstall.d.ts.map +1 -1
- package/package.json +11 -11
package/bin/bin.bundle.mjs
CHANGED
|
@@ -16748,6 +16748,15 @@ var BUILD_TASK_BUDGET_MAX_MINUTES = 10080;
|
|
|
16748
16748
|
var BUILD_TASK_NOTE_MAX = 240;
|
|
16749
16749
|
var BUILD_TASK_CLEAR_COMMAND_MAX = 240;
|
|
16750
16750
|
var buildTaskKindSchema = external_exports.enum(["build", "review", "spec", "walk", "check"]);
|
|
16751
|
+
var BUILD_TASK_KIND_LABEL = Object.freeze({
|
|
16752
|
+
build: "Build",
|
|
16753
|
+
review: "Review",
|
|
16754
|
+
spec: "Spec",
|
|
16755
|
+
walk: "Walk",
|
|
16756
|
+
check: "Check"
|
|
16757
|
+
});
|
|
16758
|
+
var buildTaskShipsSchema = external_exports.enum(["deploy", "release"]);
|
|
16759
|
+
var BUILD_TASK_SHIPPED_MAX = 64;
|
|
16751
16760
|
var buildTaskIdSchema = external_exports.string().min(1).max(64);
|
|
16752
16761
|
var buildTaskSchema = external_exports.object({
|
|
16753
16762
|
// The task's own id, as the coordinator's graph names it.
|
|
@@ -16800,7 +16809,19 @@ var buildTaskSchema = external_exports.object({
|
|
|
16800
16809
|
clearCommand: descriptionText(BUILD_TASK_CLEAR_COMMAND_MAX).optional(),
|
|
16801
16810
|
// On a task held for a person, the crew member ready to take it on once it is
|
|
16802
16811
|
// cleared, by callsign. Absent when nobody is standing by.
|
|
16803
|
-
standingBy: agentNameSchema.optional()
|
|
16812
|
+
standingBy: agentNameSchema.optional(),
|
|
16813
|
+
// The batch this task was started in, counted from 0. A record of when it ran,
|
|
16814
|
+
// sent only once it has run; absent on a task not started yet.
|
|
16815
|
+
wave: external_exports.number().int().min(0).max(BUILD_SNAPSHOT_TASK_LIMIT).optional(),
|
|
16816
|
+
// True when the task is a check of the whole project rather than of one piece of
|
|
16817
|
+
// work. Absent otherwise; never false.
|
|
16818
|
+
wholeProject: external_exports.literal(true).optional(),
|
|
16819
|
+
// How the task ships what was built: deployed, or released. Absent on a task that
|
|
16820
|
+
// ships nothing.
|
|
16821
|
+
ships: buildTaskShipsSchema.optional(),
|
|
16822
|
+
// The commit or version the task reported when it shipped, exactly as reported, as
|
|
16823
|
+
// one word with no spaces. Absent until it has shipped, or when it reported none.
|
|
16824
|
+
shipped: external_exports.string().min(1).max(BUILD_TASK_SHIPPED_MAX).regex(/^[^\s\x00-\x1f\x7f-\x9f]*$/, { message: "must be one word, with no spaces or control characters" }).optional()
|
|
16804
16825
|
}).strict().superRefine((task, ctx) => {
|
|
16805
16826
|
if (task.reviews !== void 0 && task.reviews === task.id) {
|
|
16806
16827
|
ctx.addIssue({
|
|
@@ -17216,7 +17237,26 @@ var timeRunNotSentSchema = external_exports.object({
|
|
|
17216
17237
|
reason: external_exports.enum(TIME_NOT_SENT_REASONS)
|
|
17217
17238
|
}).strict();
|
|
17218
17239
|
var timeRunResultSchema = external_exports.discriminatedUnion("outcome", [timeRunRecordedSchema, timeRunNotSentSchema]);
|
|
17219
|
-
var
|
|
17240
|
+
var TIME_ROW_KEYS = [
|
|
17241
|
+
"building",
|
|
17242
|
+
"reviewing",
|
|
17243
|
+
"lateFixes",
|
|
17244
|
+
"checks",
|
|
17245
|
+
"walks",
|
|
17246
|
+
"untied",
|
|
17247
|
+
"waitingOnPerson",
|
|
17248
|
+
"waitingOnMachine"
|
|
17249
|
+
];
|
|
17250
|
+
var timeRowsSchema = external_exports.object({
|
|
17251
|
+
building: timeCountSchema,
|
|
17252
|
+
reviewing: timeCountSchema,
|
|
17253
|
+
lateFixes: timeCountSchema,
|
|
17254
|
+
checks: timeCountSchema,
|
|
17255
|
+
walks: timeCountSchema,
|
|
17256
|
+
untied: timeCountSchema,
|
|
17257
|
+
waitingOnPerson: timeCountSchema,
|
|
17258
|
+
waitingOnMachine: timeCountSchema
|
|
17259
|
+
}).strict();
|
|
17220
17260
|
var timeTotalsSchema = external_exports.object({
|
|
17221
17261
|
building: timeCountSchema,
|
|
17222
17262
|
reviewing: timeCountSchema,
|
|
@@ -17239,25 +17279,70 @@ var timeUsageTotalsSchema = external_exports.object({
|
|
|
17239
17279
|
ctx.addIssue({ code: "custom", path: [key], message: "must be 0 when no usage could be read" });
|
|
17240
17280
|
}
|
|
17241
17281
|
});
|
|
17282
|
+
var timeReviewCountsSchema = external_exports.object({
|
|
17283
|
+
attempts: timeCountSchema,
|
|
17284
|
+
reviews: timeCountSchema,
|
|
17285
|
+
failed: timeCountSchema
|
|
17286
|
+
}).strict().superRefine((v, ctx) => {
|
|
17287
|
+
if (v.failed > v.reviews)
|
|
17288
|
+
ctx.addIssue({ code: "custom", path: ["failed"], message: "must not be more than the reviews" });
|
|
17289
|
+
});
|
|
17290
|
+
var timeKindSchema = external_exports.object({
|
|
17291
|
+
kind: buildTaskKindSchema.nullable(),
|
|
17292
|
+
workingSeconds: timeCountSchema,
|
|
17293
|
+
budgetMinutes: timeCountSchema.nullable()
|
|
17294
|
+
}).strict();
|
|
17242
17295
|
var timeTaskSummarySchema = external_exports.object({
|
|
17243
17296
|
task: buildTaskIdSchema,
|
|
17244
17297
|
title: buildTaskSchema.shape.title.optional(),
|
|
17298
|
+
clock: timeRowsSchema,
|
|
17299
|
+
agent: timeRowsSchema,
|
|
17300
|
+
permissionPromptSeconds: timeCountSchema,
|
|
17245
17301
|
totals: timeTotalsSchema,
|
|
17246
17302
|
usage: timeUsageTotalsSchema
|
|
17247
17303
|
}).strict();
|
|
17304
|
+
var TIME_KINDS_MAX = buildTaskKindSchema.options.length + 1;
|
|
17305
|
+
var timeSharePercentSchema = external_exports.number().nonnegative().finite();
|
|
17306
|
+
var timeShareKindSchema = external_exports.object({
|
|
17307
|
+
kind: external_exports.enum(TIME_ROW_KEYS),
|
|
17308
|
+
percent: timeSharePercentSchema
|
|
17309
|
+
}).strict();
|
|
17310
|
+
var timeShareKindsSchema = external_exports.array(timeShareKindSchema).max(TIME_ROW_KEYS.length).superRefine((kinds, ctx) => {
|
|
17311
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17312
|
+
kinds.forEach((entry, i) => {
|
|
17313
|
+
if (seen.has(entry.kind))
|
|
17314
|
+
ctx.addIssue({ code: "custom", path: [i, "kind"], message: "lists one kind twice" });
|
|
17315
|
+
seen.add(entry.kind);
|
|
17316
|
+
});
|
|
17317
|
+
});
|
|
17318
|
+
var timeSummaryShareSchema = external_exports.discriminatedUnion("state", [
|
|
17319
|
+
external_exports.object({ state: external_exports.literal("unknown") }).strict(),
|
|
17320
|
+
external_exports.object({
|
|
17321
|
+
state: external_exports.literal("known"),
|
|
17322
|
+
weekCeilingTokens: external_exports.number().int().positive(),
|
|
17323
|
+
spentPercent: timeSharePercentSchema,
|
|
17324
|
+
kinds: timeShareKindsSchema
|
|
17325
|
+
}).strict()
|
|
17326
|
+
]);
|
|
17248
17327
|
var timeSummarySchema = external_exports.object({
|
|
17249
17328
|
phase: phaseNameSchema,
|
|
17250
17329
|
closed: external_exports.boolean(),
|
|
17251
17330
|
openedAt: utcIso8601,
|
|
17252
17331
|
closedAt: utcIso8601.nullable(),
|
|
17253
17332
|
elapsedSeconds: timeCountSchema,
|
|
17333
|
+
clock: timeRowsSchema,
|
|
17334
|
+
agent: timeRowsSchema,
|
|
17335
|
+
permissionPromptSeconds: timeCountSchema,
|
|
17254
17336
|
totals: timeTotalsSchema,
|
|
17255
17337
|
usage: timeUsageTotalsSchema,
|
|
17338
|
+
reviews: timeReviewCountsSchema,
|
|
17339
|
+
kinds: external_exports.array(timeKindSchema).max(TIME_KINDS_MAX, { message: `can list at most ${TIME_KINDS_MAX} kinds` }),
|
|
17256
17340
|
tasks: external_exports.array(timeTaskSummarySchema).max(BUILD_SNAPSHOT_TASK_LIMIT, { message: `can list at most ${BUILD_SNAPSHOT_TASK_LIMIT} tasks` }),
|
|
17257
17341
|
notTiedToATask: external_exports.object({
|
|
17258
17342
|
totals: timeTotalsSchema,
|
|
17259
17343
|
usage: timeUsageTotalsSchema
|
|
17260
|
-
}).strict()
|
|
17344
|
+
}).strict(),
|
|
17345
|
+
share: timeSummaryShareSchema.optional()
|
|
17261
17346
|
}).strict().superRefine((v, ctx) => {
|
|
17262
17347
|
if (v.closed !== (v.closedAt !== null)) {
|
|
17263
17348
|
ctx.addIssue({ code: "custom", path: ["closedAt"], message: "must be set exactly when the phase is closed" });
|
|
@@ -17268,18 +17353,30 @@ var timeSummarySchema = external_exports.object({
|
|
|
17268
17353
|
ctx.addIssue({ code: "custom", path: ["tasks", i, "task"], message: "lists one task twice" });
|
|
17269
17354
|
seen.add(row.task);
|
|
17270
17355
|
});
|
|
17356
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
17357
|
+
v.kinds.forEach((entry, i) => {
|
|
17358
|
+
if (kinds.has(entry.kind))
|
|
17359
|
+
ctx.addIssue({ code: "custom", path: ["kinds", i, "kind"], message: "lists one kind twice" });
|
|
17360
|
+
kinds.add(entry.kind);
|
|
17361
|
+
});
|
|
17271
17362
|
});
|
|
17272
17363
|
var timeTraceIntervalSchema = external_exports.object({
|
|
17273
17364
|
...timeIntervalSchema.shape,
|
|
17274
|
-
counted: external_exports.enum(
|
|
17365
|
+
counted: external_exports.enum(TIME_ROW_KEYS).nullable(),
|
|
17275
17366
|
countedSeconds: timeCountSchema
|
|
17276
17367
|
}).strict().superRefine((v, ctx) => {
|
|
17277
|
-
const { counted
|
|
17368
|
+
const { counted, countedSeconds, ...stored } = v;
|
|
17278
17369
|
const result = timeIntervalSchema.safeParse(stored);
|
|
17279
|
-
if (result.success)
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
|
|
17370
|
+
if (!result.success) {
|
|
17371
|
+
for (const issue2 of result.error.issues)
|
|
17372
|
+
ctx.addIssue({ code: "custom", path: issue2.path, message: issue2.message });
|
|
17373
|
+
}
|
|
17374
|
+
if (counted === null !== (v.state === "waiting-person")) {
|
|
17375
|
+
ctx.addIssue({ code: "custom", path: ["counted"], message: "is empty exactly for a permission prompt" });
|
|
17376
|
+
}
|
|
17377
|
+
if (counted === null && countedSeconds !== 0) {
|
|
17378
|
+
ctx.addIssue({ code: "custom", path: ["countedSeconds"], message: "must be 0 for a permission prompt" });
|
|
17379
|
+
}
|
|
17283
17380
|
});
|
|
17284
17381
|
var timeTraceApprovalWaitSchema = external_exports.object({
|
|
17285
17382
|
planVersion: planVersionSchema,
|
|
@@ -17287,10 +17384,17 @@ var timeTraceApprovalWaitSchema = external_exports.object({
|
|
|
17287
17384
|
to: utcIso8601.nullable(),
|
|
17288
17385
|
countedSeconds: timeCountSchema
|
|
17289
17386
|
}).strict();
|
|
17387
|
+
var timeTraceDeclaredWaitSchema = external_exports.object({
|
|
17388
|
+
declaration: external_exports.uuid(),
|
|
17389
|
+
from: utcIso8601,
|
|
17390
|
+
to: utcIso8601.nullable(),
|
|
17391
|
+
countedSeconds: timeCountSchema
|
|
17392
|
+
}).strict();
|
|
17290
17393
|
var timeTraceSchema = external_exports.object({
|
|
17291
17394
|
summary: timeSummarySchema,
|
|
17292
17395
|
intervals: external_exports.array(timeTraceIntervalSchema),
|
|
17293
17396
|
approvalWaits: external_exports.array(timeTraceApprovalWaitSchema),
|
|
17397
|
+
declaredWaits: external_exports.array(timeTraceDeclaredWaitSchema),
|
|
17294
17398
|
usage: external_exports.array(timeUsageSchema)
|
|
17295
17399
|
}).strict();
|
|
17296
17400
|
function timeDurationLabelOf(seconds) {
|
|
@@ -17303,6 +17407,16 @@ function timeDurationLabelOf(seconds) {
|
|
|
17303
17407
|
return `${String(hours)} h ${String(minutes).padStart(2, "0")} min`;
|
|
17304
17408
|
}
|
|
17305
17409
|
|
|
17410
|
+
// ../events/dist/repository-facts.js
|
|
17411
|
+
var REPOSITORY_FACTS = Object.freeze(["database", "browser-app", "inbound-webhooks"]);
|
|
17412
|
+
var repositoryFactSchema = external_exports.enum(REPOSITORY_FACTS);
|
|
17413
|
+
var repositoryFactsSchema = external_exports.array(repositoryFactSchema).max(REPOSITORY_FACTS.length).refine((facts) => new Set(facts).size === facts.length, { message: "must name each fact once" });
|
|
17414
|
+
var REPOSITORY_FACT_WORDS = Object.freeze({
|
|
17415
|
+
database: "database",
|
|
17416
|
+
"browser-app": "web front end",
|
|
17417
|
+
"inbound-webhooks": "incoming webhooks"
|
|
17418
|
+
});
|
|
17419
|
+
|
|
17306
17420
|
// ../events/dist/code-link.js
|
|
17307
17421
|
var codeLinkAddressSchema = external_exports.string().regex(GITHUB_REPOSITORY_ADDRESS, { message: "must be a GitHub repository address: https://github.com/<owner>/<repo>" }).refine((v) => !looksLikeSecret(v), { message: "looks like a password or key, so it is not sent" });
|
|
17308
17422
|
var codeLinkFactsSchema = external_exports.object({
|
|
@@ -18032,7 +18146,7 @@ var phaseWorkSchema = external_exports.object({
|
|
|
18032
18146
|
var STANDING_RULE_FILE = "docs/invariants.md";
|
|
18033
18147
|
var CHANGE_MOVED_BY = Object.freeze(["sort", "person", "self"]);
|
|
18034
18148
|
var changeMovedBySchema = external_exports.enum(CHANGE_MOVED_BY);
|
|
18035
|
-
var PHASE_PATH_SET_BY = Object.freeze(["open", "person", "self"]);
|
|
18149
|
+
var PHASE_PATH_SET_BY = Object.freeze(["open", "person", "self", "size"]);
|
|
18036
18150
|
var phasePathSetBySchema = external_exports.enum(PHASE_PATH_SET_BY);
|
|
18037
18151
|
var SMALL_CHANGE_OUTCOMES = Object.freeze(["done", "moved-up", "stopped"]);
|
|
18038
18152
|
var smallChangeOutcomeSchema = external_exports.enum(SMALL_CHANGE_OUTCOMES);
|
|
@@ -18603,789 +18717,963 @@ function shownReviewEntryOf(view, shownAt) {
|
|
|
18603
18717
|
};
|
|
18604
18718
|
}
|
|
18605
18719
|
|
|
18606
|
-
// ../events/dist/
|
|
18607
|
-
var
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
var TYPED_REVIEW_OFF_SENTENCE = "Reviewing by typing is switched off for now.";
|
|
18611
|
-
var CLIENT_UPDATE_SENTENCE = `To approve by typing in a session, Halfcycle needs updating: run \`${HALFCYCLE_COMMAND}\` in this project's folder, then reopen your session and ask again.`;
|
|
18612
|
-
|
|
18613
|
-
// ../events/dist/device-auth.js
|
|
18614
|
-
var utcIso86012 = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/, "must be a UTC ISO-8601 timestamp ending in Z");
|
|
18615
|
-
var DEVICE_AUTH_STATUS = {
|
|
18616
|
-
/** The poll: minted, nobody has acted yet. Keep polling. 200. */
|
|
18617
|
-
PENDING: "pending",
|
|
18618
|
-
/** The poll: approved, and the credential is in this body. Once only. 200. */
|
|
18619
|
-
APPROVED: "approved",
|
|
18620
|
-
/** Confirm: the decision was recorded (approve or decline). 200. */
|
|
18621
|
-
RECORDED: "recorded",
|
|
18622
|
-
/** The human refused at the confirmation page. 400 on the poll. */
|
|
18623
|
-
DECLINED: "declined",
|
|
18624
|
-
/** The code's absolute expiry has passed. 400. */
|
|
18625
|
-
EXPIRED: "expired",
|
|
18626
|
-
/** Never minted, or already spent. 400. */
|
|
18627
|
-
UNKNOWN: "unknown",
|
|
18628
|
-
/** Confirm: neither `approve` nor `decline` was named. Nothing was bound. 400. */
|
|
18629
|
-
INVALID_DECISION: "invalid-decision",
|
|
18630
|
-
/** Confirm: an approval arrived with no signed-in identity. 400. */
|
|
18631
|
-
IDENTITY_REQUIRED: "identity-required",
|
|
18632
|
-
/** This deployment has no `SIGNIN_BASE_URL` / `DEVICE_AUTH_CONFIRM_SECRET`. 503. */
|
|
18633
|
-
NOT_CONFIGURED: "not-configured",
|
|
18634
|
-
/** Confirm: the shared confirmation secret was missing or wrong. 401. */
|
|
18635
|
-
UNAUTHORIZED: "unauthorized",
|
|
18636
|
-
/** Confirm: the code was already approved, declined or claimed. 409. */
|
|
18637
|
-
ALREADY_DECIDED: "already-decided",
|
|
18638
|
-
/**
|
|
18639
|
-
* Confirm: an approval named a signed-in identity whose account has not accepted
|
|
18640
|
-
* the terms of service and privacy policy currently in force. 400.
|
|
18641
|
-
*
|
|
18642
|
-
* NOT BOUND TO THE DEVICE CODE. Unlike every other refusal in this const, this one
|
|
18643
|
-
* says nothing about the code itself — the code is still `pending` after this
|
|
18644
|
-
* response, exactly as it was before the request, so the SAME userCode can be
|
|
18645
|
-
* confirmed again once the caller has recorded acceptance. `deviceConfirmRequestSchema`'s
|
|
18646
|
-
* `acceptTerms` is how a second confirm says it did.
|
|
18647
|
-
*/
|
|
18648
|
-
TERMS_REQUIRED: "terms-required"
|
|
18649
|
-
};
|
|
18650
|
-
var DEVICE_POLL_REFUSALS = [
|
|
18651
|
-
DEVICE_AUTH_STATUS.DECLINED,
|
|
18652
|
-
DEVICE_AUTH_STATUS.EXPIRED,
|
|
18653
|
-
DEVICE_AUTH_STATUS.UNKNOWN
|
|
18654
|
-
];
|
|
18655
|
-
var deviceAuthStartResponseSchema = external_exports.object({
|
|
18656
|
-
deviceCode: external_exports.string().min(1),
|
|
18657
|
-
userCode: external_exports.string().min(1),
|
|
18658
|
-
verificationUrl: external_exports.string().min(1),
|
|
18659
|
-
expiresAt: utcIso86012,
|
|
18660
|
-
pollIntervalMs: external_exports.number().int().positive()
|
|
18661
|
-
}).strict();
|
|
18662
|
-
var devicePollPendingSchema = external_exports.object({
|
|
18663
|
-
status: external_exports.literal(DEVICE_AUTH_STATUS.PENDING),
|
|
18664
|
-
pollIntervalMs: external_exports.number().int().positive()
|
|
18665
|
-
}).strict();
|
|
18666
|
-
var devicePollApprovedSchema = external_exports.object({
|
|
18667
|
-
status: external_exports.literal(DEVICE_AUTH_STATUS.APPROVED),
|
|
18668
|
-
accountId: external_exports.string().min(1),
|
|
18669
|
-
credential: external_exports.string().min(1),
|
|
18670
|
-
expiresAt: utcIso86012
|
|
18671
|
-
}).strict();
|
|
18672
|
-
var deviceAuthRefusalSchema = external_exports.object({
|
|
18673
|
-
status: external_exports.enum([
|
|
18674
|
-
DEVICE_AUTH_STATUS.DECLINED,
|
|
18675
|
-
DEVICE_AUTH_STATUS.EXPIRED,
|
|
18676
|
-
DEVICE_AUTH_STATUS.UNKNOWN,
|
|
18677
|
-
DEVICE_AUTH_STATUS.INVALID_DECISION,
|
|
18678
|
-
DEVICE_AUTH_STATUS.IDENTITY_REQUIRED,
|
|
18679
|
-
DEVICE_AUTH_STATUS.NOT_CONFIGURED,
|
|
18680
|
-
DEVICE_AUTH_STATUS.UNAUTHORIZED,
|
|
18681
|
-
DEVICE_AUTH_STATUS.ALREADY_DECIDED,
|
|
18682
|
-
DEVICE_AUTH_STATUS.TERMS_REQUIRED
|
|
18683
|
-
]),
|
|
18684
|
-
message: external_exports.string().min(1)
|
|
18685
|
-
}).strict();
|
|
18686
|
-
var devicePollResponseSchema = external_exports.union([
|
|
18687
|
-
devicePollPendingSchema,
|
|
18688
|
-
devicePollApprovedSchema,
|
|
18689
|
-
deviceAuthRefusalSchema
|
|
18690
|
-
]);
|
|
18691
|
-
var deviceConfirmRequestSchema = external_exports.object({
|
|
18692
|
-
userCode: external_exports.string().min(1),
|
|
18693
|
-
decision: external_exports.enum(["approve", "decline"]),
|
|
18694
|
-
externalAuthId: external_exports.string().min(1).optional(),
|
|
18695
|
-
email: external_exports.string().optional(),
|
|
18696
|
-
acceptTerms: external_exports.boolean().optional()
|
|
18697
|
-
}).strict();
|
|
18698
|
-
var deviceConfirmRecordedSchema = external_exports.object({
|
|
18699
|
-
status: external_exports.literal(DEVICE_AUTH_STATUS.RECORDED),
|
|
18700
|
-
accountId: external_exports.string().min(1).optional()
|
|
18701
|
-
}).strict();
|
|
18702
|
-
var deviceConfirmResponseSchema = external_exports.union([
|
|
18703
|
-
deviceConfirmRecordedSchema,
|
|
18704
|
-
deviceAuthRefusalSchema
|
|
18705
|
-
]);
|
|
18706
|
-
var DASHBOARD_URL = "https://app.halfcycle.ai";
|
|
18707
|
-
|
|
18708
|
-
// ../events/dist/project-page.js
|
|
18709
|
-
function projectPageUrl(engagementId) {
|
|
18710
|
-
return isEngagementId(engagementId) ? `${DASHBOARD_URL}/${encodeURIComponent(engagementId)}` : void 0;
|
|
18720
|
+
// ../events/dist/stop-words.js
|
|
18721
|
+
var NOTHING_NEEDED = "Nothing is needed from you.";
|
|
18722
|
+
function isOneLine(v) {
|
|
18723
|
+
return !/[\r\n]/.test(v);
|
|
18711
18724
|
}
|
|
18712
|
-
function
|
|
18713
|
-
|
|
18714
|
-
if (page === void 0)
|
|
18715
|
-
return void 0;
|
|
18716
|
-
return `${page}/console/system-view?${new URLSearchParams({ phase }).toString()}`;
|
|
18725
|
+
function asksSomething(v) {
|
|
18726
|
+
return v.includes("?");
|
|
18717
18727
|
}
|
|
18718
|
-
function
|
|
18719
|
-
|
|
18720
|
-
return `To ask for access, open ${page} signed in as this account and choose "Request access". Then let the project's owner know, so they can approve it.`;
|
|
18728
|
+
function saysNothingIsNeeded(yourPart) {
|
|
18729
|
+
return yourPart === null || typeof yourPart === "string" && yourPart.trim() === NOTHING_NEEDED;
|
|
18721
18730
|
}
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
18725
|
-
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
phase: scopePhaseSchema,
|
|
18731
|
-
number: external_exports.number().int().min(1),
|
|
18732
|
-
notes: external_exports.array(scopeNoteEntrySchema).min(1).max(PHASE_PLAN_CHANGES_MAX + 1)
|
|
18733
|
-
}).strict().superRefine((entry, ctx) => {
|
|
18734
|
-
entry.notes.forEach((n, i) => {
|
|
18735
|
-
if (n.part === void 0 && i !== entry.notes.length - 1) {
|
|
18736
|
-
ctx.addIssue({
|
|
18737
|
-
code: external_exports.ZodIssueCode.custom,
|
|
18738
|
-
path: ["notes", i],
|
|
18739
|
-
message: "the note on the whole phase comes after every note on a part"
|
|
18740
|
-
});
|
|
18741
|
-
}
|
|
18742
|
-
});
|
|
18743
|
-
});
|
|
18744
|
-
var scopeWaitingSchema = external_exports.object({
|
|
18745
|
-
phase: scopePhaseSchema,
|
|
18746
|
-
number: external_exports.number().int().min(1),
|
|
18747
|
-
changedParts: external_exports.array(scopePartNameSchema).max(PHASE_PLAN_CHANGES_MAX)
|
|
18748
|
-
}).strict();
|
|
18749
|
-
var scopeNoticesSchema = external_exports.object({
|
|
18750
|
-
sentBack: external_exports.array(scopeSentBackSchema),
|
|
18751
|
-
waiting: external_exports.array(scopeWaitingSchema),
|
|
18752
|
-
typedApprovalOffered: external_exports.boolean()
|
|
18753
|
-
}).strict().refine((v) => v.sentBack.length > 0 || v.waiting.length > 0, {
|
|
18754
|
-
message: "carried only when a phase was sent back or waits for the owner"
|
|
18731
|
+
var stopPartSchema = external_exports.string().refine((v) => v.trim().length > 0, { message: "must say something" }).refine(isOneLine, { message: "must be one line" });
|
|
18732
|
+
var stopWordsSchema = external_exports.object({
|
|
18733
|
+
happened: stopPartSchema,
|
|
18734
|
+
yourPart: stopPartSchema.nullable(),
|
|
18735
|
+
next: stopPartSchema
|
|
18736
|
+
}).strict().refine((w) => !(saysNothingIsNeeded(w.yourPart) && (asksSomething(w.happened) || asksSomething(w.next))), {
|
|
18737
|
+
message: "asks the person something, so it cannot say nothing is needed from them",
|
|
18738
|
+
path: ["yourPart"]
|
|
18755
18739
|
});
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
function approvedInConsoleSentence(phase) {
|
|
18759
|
-
return `Scope for ${phaseWords(phase)} was approved in the console; continuing. Say so to the person, then carry on with the next step; they do not need to tell you.`;
|
|
18740
|
+
function stopTextOf(words) {
|
|
18741
|
+
return `${words.happened} ${words.yourPart ?? NOTHING_NEEDED} ${words.next}`;
|
|
18760
18742
|
}
|
|
18761
|
-
|
|
18762
|
-
|
|
18743
|
+
|
|
18744
|
+
// ../events/dist/pacing.js
|
|
18745
|
+
var CAREFUL_START_AGENTS = 3;
|
|
18746
|
+
var KEEP_FREE_MAX = 90;
|
|
18747
|
+
var keepFreePercentSchema = external_exports.number().int().min(0).max(KEEP_FREE_MAX);
|
|
18748
|
+
var KEEP_FREE_DEFAULT = 20;
|
|
18749
|
+
var PACE_AGENTS_MAX = 20;
|
|
18750
|
+
var FIVE_HOUR_WINDOW_MINUTES = 300;
|
|
18751
|
+
var SEVEN_DAY_WINDOW_MINUTES = 10080;
|
|
18752
|
+
var PACE_WINDOW_MINUTES_MAX = 525600;
|
|
18753
|
+
var MINUTE_KEY = /^([1-9][0-9]{0,6})-minute$/;
|
|
18754
|
+
function isPaceWindowKind(value) {
|
|
18755
|
+
if (value === "five-hour" || value === "seven-day")
|
|
18756
|
+
return true;
|
|
18757
|
+
if (typeof value !== "string")
|
|
18758
|
+
return false;
|
|
18759
|
+
const match = MINUTE_KEY.exec(value);
|
|
18760
|
+
if (match === null)
|
|
18761
|
+
return false;
|
|
18762
|
+
const minutes = Number(match[1]);
|
|
18763
|
+
return minutes <= PACE_WINDOW_MINUTES_MAX && minutes !== FIVE_HOUR_WINDOW_MINUTES && minutes !== SEVEN_DAY_WINDOW_MINUTES;
|
|
18763
18764
|
}
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18765
|
+
var paceWindowKindSchema = external_exports.custom((value) => isPaceWindowKind(value), {
|
|
18766
|
+
message: "not a usage window key"
|
|
18767
|
+
});
|
|
18768
|
+
function paceWindowMinutesOf(kind) {
|
|
18769
|
+
if (kind === "five-hour")
|
|
18770
|
+
return FIVE_HOUR_WINDOW_MINUTES;
|
|
18771
|
+
if (kind === "seven-day")
|
|
18772
|
+
return SEVEN_DAY_WINDOW_MINUTES;
|
|
18773
|
+
return Number(MINUTE_KEY.exec(kind)?.[1] ?? 0);
|
|
18770
18774
|
}
|
|
18771
|
-
function
|
|
18772
|
-
|
|
18775
|
+
function paceWindowKindOf(minutes) {
|
|
18776
|
+
if (!Number.isInteger(minutes) || minutes < 1 || minutes > PACE_WINDOW_MINUTES_MAX)
|
|
18777
|
+
return null;
|
|
18778
|
+
if (minutes === FIVE_HOUR_WINDOW_MINUTES)
|
|
18779
|
+
return "five-hour";
|
|
18780
|
+
if (minutes === SEVEN_DAY_WINDOW_MINUTES)
|
|
18781
|
+
return "seven-day";
|
|
18782
|
+
return `${String(minutes)}-minute`;
|
|
18773
18783
|
}
|
|
18774
|
-
function
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18784
|
+
function paceWindowWordsOf(kind) {
|
|
18785
|
+
const minutes = paceWindowMinutesOf(kind);
|
|
18786
|
+
if (minutes === FIVE_HOUR_WINDOW_MINUTES)
|
|
18787
|
+
return "5-hour window";
|
|
18788
|
+
if (minutes === SEVEN_DAY_WINDOW_MINUTES)
|
|
18789
|
+
return "weekly window";
|
|
18790
|
+
if (minutes % 1440 === 0)
|
|
18791
|
+
return `${String(minutes / 1440)}-day window`;
|
|
18792
|
+
if (minutes % 60 === 0)
|
|
18793
|
+
return `${String(minutes / 60)}-hour window`;
|
|
18794
|
+
return `${String(minutes)}-minute window`;
|
|
18780
18795
|
}
|
|
18781
|
-
function
|
|
18782
|
-
|
|
18783
|
-
return [];
|
|
18784
|
-
return [offerTyping === "yes" ? `Or they approve it in the System view: ${address}` : `They approve it in the System view: ${address}`];
|
|
18796
|
+
function paceShareWordsOf(keepFreePercent) {
|
|
18797
|
+
return keepFreePercent === 20 ? "a fifth" : `${String(keepFreePercent)}%`;
|
|
18785
18798
|
}
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
}
|
|
18800
|
-
}
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
|
|
18807
|
-
|
|
18808
|
-
question: reviewNoteSchema
|
|
18809
|
-
}).strict();
|
|
18810
|
-
var reviewNoticeSentBackSchema = external_exports.object({
|
|
18811
|
-
phase: scopePhaseSchema,
|
|
18812
|
-
number: reviewPhaseNumberSchema,
|
|
18813
|
-
part: systemPartIdSchema,
|
|
18814
|
-
partName: systemPartSchema.shape.name,
|
|
18815
|
-
note: reviewNoteSchema
|
|
18799
|
+
var PACE_STATES = ["full", "slowing", "holding"];
|
|
18800
|
+
var paceStateSchema = external_exports.enum(PACE_STATES);
|
|
18801
|
+
var PACE_SHARE_GIVEN_IN = ["chat", "agent", "relayed"];
|
|
18802
|
+
var paceShareGivenInSchema = external_exports.enum(PACE_SHARE_GIVEN_IN);
|
|
18803
|
+
var paceShareRequestSchema = external_exports.object({ keepFreePercent: keepFreePercentSchema, givenIn: paceShareGivenInSchema }).strict();
|
|
18804
|
+
var paceShareResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
18805
|
+
external_exports.object({
|
|
18806
|
+
outcome: external_exports.literal("recorded"),
|
|
18807
|
+
keepFreePercent: keepFreePercentSchema,
|
|
18808
|
+
moreAllowance: external_exports.boolean().optional()
|
|
18809
|
+
}).strict(),
|
|
18810
|
+
external_exports.object({ outcome: external_exports.literal("needs-the-person"), keepFreePercent: keepFreePercentSchema }).strict(),
|
|
18811
|
+
external_exports.object({ outcome: external_exports.literal("not-owner") }).strict(),
|
|
18812
|
+
external_exports.object({ outcome: external_exports.literal("no-owner") }).strict(),
|
|
18813
|
+
external_exports.object({ outcome: external_exports.literal("unavailable") }).strict()
|
|
18814
|
+
]);
|
|
18815
|
+
var pacingBasisTaskSchema = external_exports.object({
|
|
18816
|
+
id: buildTaskIdSchema,
|
|
18817
|
+
dependsOn: external_exports.array(buildTaskIdSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
18818
|
+
budgetMinutes: external_exports.number().int().min(1).max(BUILD_TASK_BUDGET_MAX_MINUTES).optional(),
|
|
18819
|
+
human: external_exports.boolean(),
|
|
18820
|
+
kind: buildTaskKindSchema.optional()
|
|
18816
18821
|
}).strict();
|
|
18817
|
-
var
|
|
18818
|
-
|
|
18819
|
-
|
|
18820
|
-
|
|
18821
|
-
|
|
18822
|
-
|
|
18823
|
-
|
|
18824
|
-
|
|
18825
|
-
|
|
18826
|
-
|
|
18827
|
-
const answer = `${HALFCYCLE_COMMAND} review ${quoteForShell(entry.phase)} --answer ${quoteForShell(entry.part)} "<your answer>"`;
|
|
18828
|
-
return `Before anything else: the project's owner asked about "${entry.partName}" in the review of ${phaseCalled(entry.phase)}: ${entry.question} Answer it with ${answer}.`;
|
|
18829
|
-
}
|
|
18830
|
-
function sentBackNotice2(entry) {
|
|
18831
|
-
return `Before anything else: the project's owner sent "${entry.partName}" in ${phaseCalled(entry.phase)} back to building: ${entry.note} Rebuild it: add or reopen the tasks that build it. For each task that rebuilds it, add a task that reviews the rebuild, held by a different agent from the one that built it. When each review has passed, report the build with the time each task finished, then run the close step again.`;
|
|
18822
|
+
var PACE_DEFAULT_TASK_MINUTES = 30;
|
|
18823
|
+
var PACE_DURATION_ROUND_MINUTES = 10;
|
|
18824
|
+
function taskMinutesOf(task, medianTaskMinutes) {
|
|
18825
|
+
if (task.human)
|
|
18826
|
+
return 0;
|
|
18827
|
+
if (task.budgetMinutes !== void 0)
|
|
18828
|
+
return task.budgetMinutes;
|
|
18829
|
+
if (medianTaskMinutes !== null && medianTaskMinutes > 0)
|
|
18830
|
+
return medianTaskMinutes;
|
|
18831
|
+
return PACE_DEFAULT_TASK_MINUTES;
|
|
18832
18832
|
}
|
|
18833
|
-
function
|
|
18834
|
-
return
|
|
18833
|
+
function paceDurationRoundedOf(minutes) {
|
|
18834
|
+
return Math.ceil(minutes / PACE_DURATION_ROUND_MINUTES) * PACE_DURATION_ROUND_MINUTES;
|
|
18835
18835
|
}
|
|
18836
|
-
|
|
18837
|
-
|
|
18838
|
-
|
|
18839
|
-
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
|
|
18845
|
-
consoleUrl: external_exports.string().optional()
|
|
18836
|
+
var pacingBasisSchema = external_exports.object({
|
|
18837
|
+
outcome: external_exports.literal("basis"),
|
|
18838
|
+
claudePlan: external_exports.string().nullable().optional(),
|
|
18839
|
+
keepFreePercent: keepFreePercentSchema,
|
|
18840
|
+
settingsUrl: external_exports.string().optional(),
|
|
18841
|
+
phase: phaseNameSchema.nullable(),
|
|
18842
|
+
tasks: external_exports.array(pacingBasisTaskSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
18843
|
+
medianTaskMinutes: external_exports.number().nonnegative().nullable(),
|
|
18844
|
+
medianTaskTokens: external_exports.number().nonnegative().nullable()
|
|
18846
18845
|
}).strict();
|
|
18847
|
-
var
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18846
|
+
var paceSuggestionSchema = external_exports.object({
|
|
18847
|
+
number: external_exports.number().int().min(1).max(PACE_AGENTS_MAX),
|
|
18848
|
+
minutes: external_exports.number().int().nonnegative().nullable(),
|
|
18849
|
+
pauses: external_exports.number().int().nonnegative(),
|
|
18850
|
+
keepFreePercent: keepFreePercentSchema,
|
|
18851
|
+
knownWindow: paceWindowKindSchema.nullable(),
|
|
18852
|
+
expectedTokens: external_exports.number().int().nonnegative().optional(),
|
|
18853
|
+
limitTokens: external_exports.number().int().positive().optional(),
|
|
18854
|
+
multiple: external_exports.number().positive().nullable().optional(),
|
|
18855
|
+
firstGuess: external_exports.boolean().optional(),
|
|
18856
|
+
limitSetBy: external_exports.enum(["default", "person", "other"]).optional(),
|
|
18857
|
+
weekCeilingTokens: external_exports.number().int().positive().optional(),
|
|
18858
|
+
workMinutes: external_exports.number().int().nonnegative().nullable().optional()
|
|
18851
18859
|
}).strict();
|
|
18852
|
-
var
|
|
18853
|
-
var
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
];
|
|
18860
|
-
var SWITCH_ACCOUNT_ANSWER = 'answer "s" when asked';
|
|
18861
|
-
var NO_CREDENTIAL_SENTENCE = 'Halfcycle is not connected: this machine has no working Halfcycle credential for this project. Run "npx halfcycle" in the project folder to sign in again.';
|
|
18862
|
-
var NOT_THIS_ACCOUNT_SENTENCE = `Halfcycle is not connected: this project belongs to another Halfcycle account. To switch, run "npx halfcycle" in this project and ${SWITCH_ACCOUNT_ANSWER}.`;
|
|
18863
|
-
var UPDATE_CLAUDE_CODE_SENTENCE = "Halfcycle is not connected: this Claude Code version does not name the server it connects to, so no credential was sent. Update Claude Code, then reopen.";
|
|
18864
|
-
var CANNOT_REACH_SENTENCE = "Halfcycle is not connected: its server could not be reached, so its tools are unavailable in this session. Check your network, then reopen the project.";
|
|
18865
|
-
var SERVICE_PROBLEM_SENTENCE = "Halfcycle is not connected: its service had a problem just now, so nothing in this session is being checked. Reopen the project to try again.";
|
|
18866
|
-
var FOLDER_NOT_TRUSTED_SENTENCE = "Folder not yet trusted. Open this folder once in interactive Claude Code and trust it; then headless runs work.";
|
|
18867
|
-
var SCOPE_UNCHECKED_SENTENCE = "If this project needs approval before building, that cannot be checked either, so work done now shows as built without approval unless already approved.";
|
|
18868
|
-
var PLACEHOLDER_SENTENCES = Object.freeze({
|
|
18869
|
-
[NO_CREDENTIAL_PLACEHOLDER]: NO_CREDENTIAL_SENTENCE,
|
|
18870
|
-
[NOT_THIS_ACCOUNT_PLACEHOLDER]: NOT_THIS_ACCOUNT_SENTENCE,
|
|
18871
|
-
[UPDATE_CLAUDE_CODE_PLACEHOLDER]: UPDATE_CLAUDE_CODE_SENTENCE
|
|
18872
|
-
});
|
|
18873
|
-
|
|
18874
|
-
// ../events/dist/scope-chat.js
|
|
18875
|
-
var chatScopeApproveRequestSchema = external_exports.object({
|
|
18876
|
-
act: external_exports.literal("approve"),
|
|
18877
|
-
reference: phaseIdentitySchema,
|
|
18878
|
-
planVersion: planVersionSchema
|
|
18860
|
+
var PACE_NOT_PACED_REASONS = ["not-configured", "unreadable"];
|
|
18861
|
+
var limitHeldSchema = external_exports.object({
|
|
18862
|
+
used: external_exports.number().int().nonnegative(),
|
|
18863
|
+
limit: external_exports.number().int().positive(),
|
|
18864
|
+
raiseBy: external_exports.number().int().nonnegative(),
|
|
18865
|
+
working: external_exports.number().int().nonnegative(),
|
|
18866
|
+
weekCeilingTokens: external_exports.number().int().positive().optional()
|
|
18879
18867
|
}).strict();
|
|
18880
|
-
var
|
|
18881
|
-
|
|
18882
|
-
|
|
18883
|
-
|
|
18884
|
-
note: scopeNoteWireSchema.optional()
|
|
18868
|
+
var paceUsageSchema = external_exports.object({
|
|
18869
|
+
used: external_exports.number().int().nonnegative(),
|
|
18870
|
+
limit: external_exports.number().int().positive(),
|
|
18871
|
+
weekCeilingTokens: external_exports.number().int().positive().optional()
|
|
18885
18872
|
}).strict();
|
|
18886
|
-
var
|
|
18887
|
-
|
|
18888
|
-
|
|
18873
|
+
var paceRunResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
18874
|
+
external_exports.object({
|
|
18875
|
+
outcome: external_exports.literal("paced"),
|
|
18876
|
+
pace: paceStateSchema,
|
|
18877
|
+
number: external_exports.number().int().min(1).max(PACE_AGENTS_MAX),
|
|
18878
|
+
allowedNow: external_exports.number().int().nonnegative(),
|
|
18879
|
+
windowKind: paceWindowKindSchema.optional(),
|
|
18880
|
+
until: utcIso8601.optional(),
|
|
18881
|
+
keepFreePercent: keepFreePercentSchema.optional(),
|
|
18882
|
+
suggestion: paceSuggestionSchema.optional(),
|
|
18883
|
+
limit: external_exports.literal("reached").optional(),
|
|
18884
|
+
limitHeld: limitHeldSchema.optional(),
|
|
18885
|
+
usage: paceUsageSchema.optional()
|
|
18886
|
+
}).strict(),
|
|
18887
|
+
external_exports.object({ outcome: external_exports.literal("not-paced"), reason: external_exports.enum(PACE_NOT_PACED_REASONS) }).strict()
|
|
18889
18888
|
]);
|
|
18890
|
-
|
|
18891
|
-
|
|
18892
|
-
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
}).strict();
|
|
18897
|
-
var chatScopeAlreadyApprovedSchema = external_exports.object({
|
|
18898
|
-
outcome: external_exports.literal("already-approved"),
|
|
18899
|
-
replanNeeded: external_exports.boolean()
|
|
18900
|
-
}).strict();
|
|
18901
|
-
var chatScopeRefusedSchema = external_exports.object({
|
|
18902
|
-
outcome: external_exports.literal("refused"),
|
|
18903
|
-
problems: external_exports.array(systemDescriptionProblemSchema).min(1)
|
|
18904
|
-
}).strict();
|
|
18905
|
-
var chatAmbiguousSchema = external_exports.object({
|
|
18906
|
-
outcome: external_exports.literal("ambiguous"),
|
|
18907
|
-
phases: external_exports.array(scopePhaseSchema).min(2)
|
|
18908
|
-
}).strict();
|
|
18909
|
-
function bareOutcome(outcome) {
|
|
18910
|
-
return external_exports.object({ outcome: external_exports.literal(outcome) }).strict();
|
|
18889
|
+
function tokenCountWordsOf(n) {
|
|
18890
|
+
if (n < 1e3)
|
|
18891
|
+
return String(Math.max(0, Math.round(n)));
|
|
18892
|
+
const rounded = Number(n.toPrecision(2));
|
|
18893
|
+
const [unit, word] = rounded >= 1e9 ? [1e9, "billion"] : rounded >= 1e6 ? [1e6, "million"] : [1e3, "thousand"];
|
|
18894
|
+
return `${String(Number((rounded / unit).toPrecision(2)))} ${word}`;
|
|
18911
18895
|
}
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
chatScopeAlreadyApprovedSchema,
|
|
18915
|
-
chatScopeRefusedSchema,
|
|
18916
|
-
chatAmbiguousSchema,
|
|
18917
|
-
bareOutcome("show-first"),
|
|
18918
|
-
bareOutcome("plan-changed"),
|
|
18919
|
-
bareOutcome("build-started"),
|
|
18920
|
-
bareOutcome("not-owner"),
|
|
18921
|
-
bareOutcome("no-owner"),
|
|
18922
|
-
bareOutcome("not-offered"),
|
|
18923
|
-
bareOutcome("unavailable")
|
|
18924
|
-
]);
|
|
18925
|
-
|
|
18926
|
-
// ../events/dist/review-chat.js
|
|
18927
|
-
var chatReviewAcceptRequestSchema = external_exports.object({
|
|
18928
|
-
act: external_exports.literal("accept"),
|
|
18929
|
-
reference: phaseIdentitySchema,
|
|
18930
|
-
reviewVersion: external_exports.number().int().min(0),
|
|
18931
|
-
parts: external_exports.array(systemPartIdSchema).max(REVIEW_PARTS_MAX),
|
|
18932
|
-
waitingClaims: external_exports.literal(true).optional()
|
|
18933
|
-
}).strict();
|
|
18934
|
-
function notedRequest(act) {
|
|
18935
|
-
return external_exports.object({
|
|
18936
|
-
act: external_exports.literal(act),
|
|
18937
|
-
reference: phaseIdentitySchema,
|
|
18938
|
-
reviewVersion: external_exports.number().int().min(0),
|
|
18939
|
-
part: systemPartIdSchema,
|
|
18940
|
-
note: reviewNoteWireSchema
|
|
18941
|
-
}).strict();
|
|
18896
|
+
function paceAgentsOf(n) {
|
|
18897
|
+
return n === 1 ? "1 agent" : `${String(n)} agents`;
|
|
18942
18898
|
}
|
|
18943
|
-
var
|
|
18944
|
-
var
|
|
18945
|
-
|
|
18946
|
-
|
|
18947
|
-
|
|
18948
|
-
|
|
18949
|
-
|
|
18950
|
-
|
|
18951
|
-
|
|
18952
|
-
|
|
18899
|
+
var DAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
18900
|
+
var MONTH_NAMES = [
|
|
18901
|
+
"January",
|
|
18902
|
+
"February",
|
|
18903
|
+
"March",
|
|
18904
|
+
"April",
|
|
18905
|
+
"May",
|
|
18906
|
+
"June",
|
|
18907
|
+
"July",
|
|
18908
|
+
"August",
|
|
18909
|
+
"September",
|
|
18910
|
+
"October",
|
|
18911
|
+
"November",
|
|
18912
|
+
"December"
|
|
18913
|
+
];
|
|
18914
|
+
var SIX_DAYS_MS = 6 * 24 * 60 * 60 * 1e3;
|
|
18915
|
+
function paceClockOf(at, now) {
|
|
18916
|
+
const hours = at.getHours();
|
|
18917
|
+
const clock = `${String(hours % 12 === 0 ? 12 : hours % 12)}:${String(at.getMinutes()).padStart(2, "0")} ${hours < 12 ? "am" : "pm"}`;
|
|
18918
|
+
const sameDay = at.getFullYear() === now.getFullYear() && at.getMonth() === now.getMonth() && at.getDate() === now.getDate();
|
|
18919
|
+
if (sameDay)
|
|
18920
|
+
return clock;
|
|
18921
|
+
const day = DAY_NAMES[at.getDay()] ?? "";
|
|
18922
|
+
if (at.getTime() - now.getTime() > SIX_DAYS_MS) {
|
|
18923
|
+
return `${day} ${String(at.getDate())} ${MONTH_NAMES[at.getMonth()] ?? ""} ${clock}`;
|
|
18924
|
+
}
|
|
18925
|
+
return `${day} ${clock}`;
|
|
18926
|
+
}
|
|
18927
|
+
var PACE_P5 = "This build may use all of your allowance. It will not slow down to leave room for you.";
|
|
18928
|
+
function paceS1Of(window, k, until, now, keepFreePercent) {
|
|
18929
|
+
return `Halfcycle is slowing this build so you keep about ${paceShareWordsOf(keepFreePercent)} of this ${paceWindowWordsOf(window)} for your own work. It will run at most ${paceAgentsOf(k)} at once until ${paceClockOf(until, now)}.`;
|
|
18930
|
+
}
|
|
18931
|
+
function paceS2Of(window, k, until, now, keepFreePercent) {
|
|
18932
|
+
const head = `Halfcycle has paused new work in this build until ${paceClockOf(until, now)}, when your ${paceWindowWordsOf(window)} resets, so you keep about ${paceShareWordsOf(keepFreePercent)} of it for your own work.`;
|
|
18933
|
+
if (k === 0)
|
|
18934
|
+
return head;
|
|
18935
|
+
return k === 1 ? `${head} The 1 agent already working will finish its task.` : `${head} The ${String(k)} agents already working will finish their tasks.`;
|
|
18936
|
+
}
|
|
18937
|
+
function paceS3Of(window, n) {
|
|
18938
|
+
return `Your ${paceWindowWordsOf(window)} has reset. Halfcycle is starting new work again, up to ${paceAgentsOf(n)} at once.`;
|
|
18939
|
+
}
|
|
18940
|
+
function paceOfferTextOf(input) {
|
|
18941
|
+
const canFaster = input.number < PACE_AGENTS_MAX;
|
|
18942
|
+
const canUseMore = input.keepFreePercent > 0;
|
|
18943
|
+
if (!canFaster && !canUseMore)
|
|
18944
|
+
return null;
|
|
18945
|
+
const head = `You have used only ${String(Math.floor(input.percentUsed))}% of this ${paceWindowWordsOf(input.window)}, and more than half of it has passed.`;
|
|
18946
|
+
const useUpTo = `"use up to ${String(Math.min(100, 100 - input.keepFreePercent + 10))}%" to let this build use more of it`;
|
|
18947
|
+
if (canFaster && canUseMore)
|
|
18948
|
+
return `${head} Say "faster" for one more agent, or ${useUpTo}.`;
|
|
18949
|
+
if (canFaster)
|
|
18950
|
+
return `${head} Say "faster" for one more agent.`;
|
|
18951
|
+
return `${head} Say ${useUpTo}.`;
|
|
18952
|
+
}
|
|
18953
|
+
function paceF1Of(k) {
|
|
18954
|
+
return `This build runs at most ${paceAgentsOf(k)} at once.`;
|
|
18955
|
+
}
|
|
18956
|
+
function paceAgentLineOf(pace, allowance, until, now) {
|
|
18957
|
+
const fewer = `once fewer than ${paceAgentsOf(allowance)} are working.`;
|
|
18958
|
+
if (until === null)
|
|
18959
|
+
return `Start it ${fewer}`;
|
|
18960
|
+
if (pace === "holding")
|
|
18961
|
+
return `Start it after ${paceClockOf(until, now)}.`;
|
|
18962
|
+
return `Start it after ${paceClockOf(until, now)}, or ${fewer}`;
|
|
18963
|
+
}
|
|
18964
|
+
var PACE_NOTHING_CHANGED = "Nothing was changed.";
|
|
18965
|
+
function paceHeldStartTextOf(input) {
|
|
18966
|
+
const { pace, allowance, working, window, until, now, keepFreePercent } = input;
|
|
18967
|
+
if (pace === "full" || window === null || until === null) {
|
|
18968
|
+
return `${paceF1Of(allowance)} ${paceAgentLineOf("full", allowance, null, now)} ${PACE_NOTHING_CHANGED}`;
|
|
18969
|
+
}
|
|
18970
|
+
const head = pace === "slowing" ? paceS1Of(window, allowance, until, now, keepFreePercent) : paceS2Of(window, working, until, now, keepFreePercent);
|
|
18971
|
+
return `${head} ${paceAgentLineOf(pace, allowance, until, now)} ${PACE_NOTHING_CHANGED}`;
|
|
18972
|
+
}
|
|
18973
|
+
var PACE_FIRST_READ = "Reading this computer's usage records for the first time. This can take a minute.";
|
|
18974
|
+
var PACE_AGENTS_TOO_MANY = `Run at most ${String(PACE_AGENTS_MAX)} agents at once.`;
|
|
18975
|
+
var PACE_ONLY_PERSON_RAISES = 'Only the person can raise the number of agents, by typing "faster" or "run 5 agents" in the chat. Nothing was changed.';
|
|
18976
|
+
function paceStatusLineOf(percent, window) {
|
|
18977
|
+
return `Halfcycle \xB7 ${String(Math.round(percent))}% of this ${paceWindowWordsOf(window)} used`;
|
|
18978
|
+
}
|
|
18979
|
+
var STARTING_TOKENS_PER_TASK = 9e6;
|
|
18980
|
+
var LIMIT_MULTIPLE_DEFAULT = 2;
|
|
18981
|
+
var LIMIT_MULTIPLE_RANGE = { min: 1, max: 20 };
|
|
18982
|
+
var LIMIT_FIGURE_RANGE = { min: 1e6, max: 1e11 };
|
|
18983
|
+
var LIMIT_HISTORY_MAX = 20;
|
|
18984
|
+
var LIMIT_ROUND_TOKENS = 1e3;
|
|
18985
|
+
var LIMIT_COUNTED_KINDS = ["build", "review", "check"];
|
|
18986
|
+
var LIMIT_PARTS = ["half", "three-quarters", "nine-tenths", "limit"];
|
|
18987
|
+
var limitPartSchema = external_exports.enum(LIMIT_PARTS);
|
|
18988
|
+
var LIMIT_PART_SHARE = {
|
|
18989
|
+
half: 0.5,
|
|
18990
|
+
"three-quarters": 0.75,
|
|
18991
|
+
"nine-tenths": 0.9,
|
|
18992
|
+
limit: 1
|
|
18993
|
+
};
|
|
18994
|
+
var LIMIT_SET_BY = ["default", "person", "other"];
|
|
18995
|
+
var limitSetBySchema = external_exports.enum(LIMIT_SET_BY);
|
|
18996
|
+
var LIMIT_TYPED_BY = ["person", "not-attended", "cannot-tell"];
|
|
18997
|
+
var limitTypedBySchema = external_exports.enum(LIMIT_TYPED_BY);
|
|
18998
|
+
var limitHistoryEntrySchema = external_exports.object({
|
|
18999
|
+
at: utcIso8601,
|
|
19000
|
+
kind: external_exports.enum(["raised", "set", "stopped"]),
|
|
19001
|
+
limit: external_exports.number().int().positive(),
|
|
19002
|
+
by: limitTypedBySchema,
|
|
19003
|
+
relayed: external_exports.literal(true).optional()
|
|
18953
19004
|
}).strict();
|
|
18954
|
-
var
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
19005
|
+
var PHASE_LIMIT_FILENAME = "limit.json";
|
|
19006
|
+
var phaseLimitFileSchema = external_exports.object({
|
|
19007
|
+
phase: phaseNameSchema,
|
|
19008
|
+
expected: external_exports.number().int().nonnegative(),
|
|
19009
|
+
expectedMinutes: external_exports.number().nonnegative().nullable(),
|
|
19010
|
+
limit: external_exports.number().int().positive(),
|
|
19011
|
+
multiple: external_exports.number().positive().nullable(),
|
|
19012
|
+
setBy: limitSetBySchema,
|
|
19013
|
+
firstGuess: external_exports.boolean(),
|
|
19014
|
+
shown: external_exports.array(limitPartSchema).max(LIMIT_PARTS.length),
|
|
19015
|
+
awaiting: external_exports.boolean(),
|
|
19016
|
+
history: external_exports.array(limitHistoryEntrySchema).max(LIMIT_HISTORY_MAX)
|
|
19017
|
+
}).strict();
|
|
19018
|
+
function phaseLimitFileOf(raw, phase) {
|
|
19019
|
+
const parsed = phaseLimitFileSchema.safeParse(raw);
|
|
19020
|
+
if (!parsed.success)
|
|
19021
|
+
return null;
|
|
19022
|
+
return phase === null || parsed.data.phase === phase ? parsed.data : null;
|
|
19023
|
+
}
|
|
19024
|
+
var phaseUsageFileSchema = external_exports.object({
|
|
19025
|
+
phase: phaseNameSchema,
|
|
19026
|
+
openedAt: utcIso8601,
|
|
19027
|
+
tokens: external_exports.number().int().nonnegative(),
|
|
19028
|
+
at: utcIso8601
|
|
19029
|
+
}).strict();
|
|
19030
|
+
function limitPartLineOf(part, used, weekCeilingTokens = null) {
|
|
19031
|
+
return limitPartShareTextOf(part, used, weekCeilingTokens);
|
|
18964
19032
|
}
|
|
18965
|
-
function
|
|
18966
|
-
|
|
19033
|
+
function limitReachedPartsOf(input) {
|
|
19034
|
+
const { figure, caveat } = limitReachedFigureOf(input.limit, input.weekCeilingTokens);
|
|
19035
|
+
const finish = input.working === 0 ? "" : input.working === 1 ? " The 1 agent already working will finish its task." : ` The ${String(input.working)} agents already working will finish their tasks.`;
|
|
19036
|
+
return {
|
|
19037
|
+
happened: `This phase has reached its usage limit${figure}. No new work will start.${finish}`,
|
|
19038
|
+
yourPart: 'Say "keep going" to raise the limit and carry on, or "stop" to leave the phase paused here.',
|
|
19039
|
+
next: `Nothing is lost either way; the work waits for your answer.${caveat}`
|
|
19040
|
+
};
|
|
18967
19041
|
}
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
var
|
|
18977
|
-
|
|
18978
|
-
|
|
19042
|
+
function limitReachedLineOf(input) {
|
|
19043
|
+
return stopTextOf(limitReachedPartsOf(input));
|
|
19044
|
+
}
|
|
19045
|
+
function limitHeldStartTextOf(limit, weekCeilingTokens = null) {
|
|
19046
|
+
return `${limitHeldShareTextOf(limit, weekCeilingTokens)} Ask the person to say "keep going" or "stop", and start nothing until they have. ${PACE_NOTHING_CHANGED}`;
|
|
19047
|
+
}
|
|
19048
|
+
|
|
19049
|
+
// ../events/dist/plan-usage.js
|
|
19050
|
+
var windowPercentSchema = external_exports.number().min(0).max(100);
|
|
19051
|
+
var planUsageWindowSchema = external_exports.object({
|
|
19052
|
+
usedPercent: windowPercentSchema,
|
|
19053
|
+
resetsAt: utcIso8601
|
|
18979
19054
|
}).strict();
|
|
18980
|
-
var
|
|
18981
|
-
|
|
18982
|
-
name: systemPartSchema.shape.name
|
|
19055
|
+
var planUsageWeekSchema = planUsageWindowSchema.extend({
|
|
19056
|
+
ceilingTokens: external_exports.number().int().positive().nullable()
|
|
18983
19057
|
}).strict();
|
|
18984
|
-
var
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
bareOutcome2("unavailable")
|
|
18989
|
-
]);
|
|
18990
|
-
|
|
18991
|
-
// ../events/dist/owner-waits.js
|
|
18992
|
-
var OWNER_WAIT_ITEMS = Object.freeze([
|
|
18993
|
-
Object.freeze({ id: "delete-users-data", words: "Deleting or replacing data people already have." }),
|
|
18994
|
-
Object.freeze({
|
|
18995
|
-
id: "change-promises",
|
|
18996
|
-
words: "Changing what the product promises its users, such as pricing, terms or privacy."
|
|
18997
|
-
}),
|
|
18998
|
-
Object.freeze({ id: "spend-or-sign-up", words: "Anything that costs money or signs up for a service." }),
|
|
18999
|
-
Object.freeze({ id: "publish-or-release", words: "Publishing or releasing to users." }),
|
|
19000
|
-
Object.freeze({ id: "reshape-shared-data", words: "Dropping or reshaping stored data that other parts read." }),
|
|
19001
|
-
Object.freeze({ id: "change-standing-rule", words: "Changing a standing rule." })
|
|
19002
|
-
]);
|
|
19003
|
-
var OWNER_WAIT_ITEM_IDS = Object.freeze(OWNER_WAIT_ITEMS.map((item) => item.id));
|
|
19004
|
-
var ownerWaitItemIdSchema = external_exports.enum(OWNER_WAIT_ITEM_IDS);
|
|
19005
|
-
var OWNER_WAIT_FIXED_COUNT = OWNER_WAIT_ITEMS.length;
|
|
19006
|
-
var OWNER_WAIT_ADDITIONS_MAX = 20;
|
|
19007
|
-
var OWNER_WAIT_TEXT_MAX = 240;
|
|
19008
|
-
var ownerWaitItemRefSchema = external_exports.union([
|
|
19009
|
-
external_exports.number().int().min(1),
|
|
19010
|
-
external_exports.string().uuid({ message: "must be a number from 1 to 6, or the id shown beside an added item" })
|
|
19011
|
-
]);
|
|
19012
|
-
var ownerWaitText = descriptionText(OWNER_WAIT_TEXT_MAX);
|
|
19013
|
-
var ownerWaitAddRequestSchema = external_exports.object({
|
|
19014
|
-
engagementId: external_exports.string().min(1),
|
|
19015
|
-
text: ownerWaitText,
|
|
19016
|
-
reason: ownerWaitText
|
|
19058
|
+
var planUsageReportSchema = external_exports.object({
|
|
19059
|
+
fiveHour: planUsageWindowSchema.nullable(),
|
|
19060
|
+
week: planUsageWeekSchema.nullable(),
|
|
19061
|
+
readAt: utcIso8601
|
|
19017
19062
|
}).strict();
|
|
19018
|
-
var
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
|
|
19022
|
-
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
item: ownerWaitItemRefSchema,
|
|
19026
|
-
question: ownerWaitText,
|
|
19027
|
-
recommendation: ownerWaitText,
|
|
19028
|
-
task: buildTaskIdSchema.optional(),
|
|
19029
|
-
by: agentNameSchema.optional(),
|
|
19030
|
-
undoable: ownerWaitUndoableSchema.optional(),
|
|
19031
|
-
how: statementText(STATEMENT_MAX).optional()
|
|
19032
|
-
}).strict().refine((r) => r.undoable === "yes" === (r.how !== void 0), {
|
|
19033
|
-
message: "says how to undo it exactly when it can be undone",
|
|
19034
|
-
path: ["how"]
|
|
19035
|
-
});
|
|
19036
|
-
var OWNER_WAIT_DECLARE_REFUSALS = ["no-open-phase", "unknown-item", "say-if-undoable"];
|
|
19037
|
-
var ownerWaitDeclareResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19038
|
-
external_exports.object({ outcome: external_exports.literal("recorded"), id: external_exports.string().uuid(), say: external_exports.string().min(1) }).strict(),
|
|
19039
|
-
external_exports.object({
|
|
19040
|
-
outcome: external_exports.literal("go-ahead"),
|
|
19041
|
-
id: external_exports.string().uuid(),
|
|
19042
|
-
callId: external_exports.number().int().positive(),
|
|
19043
|
-
say: external_exports.string().min(1)
|
|
19044
|
-
}).strict(),
|
|
19045
|
-
external_exports.object({ outcome: external_exports.literal("refused"), reason: external_exports.enum(OWNER_WAIT_DECLARE_REFUSALS) }).strict()
|
|
19046
|
-
]);
|
|
19047
|
-
var ownerWaitAddedItemSchema = external_exports.object({
|
|
19048
|
-
id: external_exports.string().uuid(),
|
|
19049
|
-
words: external_exports.string().min(1),
|
|
19050
|
-
reason: external_exports.string().min(1),
|
|
19051
|
-
addedAt: utcIso8601
|
|
19063
|
+
var planKeepFreePercentSchema = external_exports.number().int().min(0).max(90);
|
|
19064
|
+
var workMinutesSchema = external_exports.number().int().nonnegative().nullable();
|
|
19065
|
+
var planUsagePhaseSchema = external_exports.object({
|
|
19066
|
+
phase: phaseNameSchema,
|
|
19067
|
+
spentPercent: timeSharePercentSchema,
|
|
19068
|
+
expectedPercent: timeSharePercentSchema.optional(),
|
|
19069
|
+
kinds: timeShareKindsSchema
|
|
19052
19070
|
}).strict();
|
|
19053
|
-
var
|
|
19054
|
-
|
|
19055
|
-
|
|
19071
|
+
var PLAN_USAGE_PHASES_MAX = 100;
|
|
19072
|
+
var planUsageUnknownSchema = external_exports.object({
|
|
19073
|
+
state: external_exports.literal("unknown"),
|
|
19074
|
+
windowsRead: external_exports.boolean(),
|
|
19075
|
+
workMinutes: workMinutesSchema,
|
|
19076
|
+
keepFreePercent: planKeepFreePercentSchema
|
|
19056
19077
|
}).strict();
|
|
19057
|
-
var
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
|
|
19078
|
+
var planUsageKnownSchema = external_exports.object({
|
|
19079
|
+
state: external_exports.literal("known"),
|
|
19080
|
+
workMinutes: workMinutesSchema,
|
|
19081
|
+
keepFreePercent: planKeepFreePercentSchema,
|
|
19082
|
+
weekCeilingTokens: external_exports.number().int().positive(),
|
|
19083
|
+
fiveHourPercent: windowPercentSchema.nullable(),
|
|
19084
|
+
weekPercent: windowPercentSchema.nullable(),
|
|
19085
|
+
readAt: utcIso8601,
|
|
19086
|
+
phases: external_exports.array(planUsagePhaseSchema).max(PLAN_USAGE_PHASES_MAX)
|
|
19087
|
+
}).strict().superRefine((v, ctx) => {
|
|
19088
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19089
|
+
v.phases.forEach((entry, i) => {
|
|
19090
|
+
if (seen.has(entry.phase))
|
|
19091
|
+
ctx.addIssue({ code: "custom", path: ["phases", i, "phase"], message: "lists one phase twice" });
|
|
19092
|
+
seen.add(entry.phase);
|
|
19093
|
+
});
|
|
19068
19094
|
});
|
|
19069
|
-
var
|
|
19070
|
-
|
|
19071
|
-
|
|
19072
|
-
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
function ownerWaitShortIdOf(declarationId) {
|
|
19076
|
-
return declarationId.slice(0, OWNER_WAIT_SHORT_ID_LENGTH).toLowerCase();
|
|
19095
|
+
var planUsageSchema = external_exports.discriminatedUnion("state", [planUsageUnknownSchema, planUsageKnownSchema]);
|
|
19096
|
+
function agentWorkMinutesOf(tasks, medianTaskMinutes) {
|
|
19097
|
+
if (tasks === null || tasks.length === 0)
|
|
19098
|
+
return null;
|
|
19099
|
+
const sum2 = tasks.reduce((total, task) => total + taskMinutesOf(task, medianTaskMinutes), 0);
|
|
19100
|
+
return paceDurationRoundedOf(sum2);
|
|
19077
19101
|
}
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
function ownerWaitApproveLineOf(declarationId) {
|
|
19081
|
-
return `approve wait ${ownerWaitShortIdOf(declarationId)}`;
|
|
19102
|
+
function weekPercentOf(tokens, weekCeilingTokens) {
|
|
19103
|
+
return weekCeilingTokens > 0 ? tokens / weekCeilingTokens * 100 : 0;
|
|
19082
19104
|
}
|
|
19083
|
-
function
|
|
19084
|
-
return
|
|
19105
|
+
function planSharePercentWordsOf(percent) {
|
|
19106
|
+
return percent < 0.5 ? "under 1%" : `${String(Math.round(percent))}%`;
|
|
19085
19107
|
}
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
external_exports.object({ act: external_exports.literal("decline"), wait: ownerWaitShortIdSchema, note: scopeNoteWireSchema }).strict()
|
|
19089
|
-
]);
|
|
19090
|
-
function bareOutcome3(outcome) {
|
|
19091
|
-
return external_exports.object({ outcome: external_exports.literal(outcome) }).strict();
|
|
19108
|
+
function aboutShareOf(percent) {
|
|
19109
|
+
return percent < 0.5 ? planSharePercentWordsOf(percent) : `about ${planSharePercentWordsOf(percent)}`;
|
|
19092
19110
|
}
|
|
19093
|
-
var
|
|
19094
|
-
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
|
|
19099
|
-
|
|
19100
|
-
|
|
19101
|
-
|
|
19102
|
-
|
|
19103
|
-
|
|
19104
|
-
|
|
19105
|
-
|
|
19111
|
+
var PLAN_USAGE_CAVEAT = "These figures are estimates. Many things affect usage, and some of them are outside Halfcycle's control.";
|
|
19112
|
+
function ofYourWeek(tokens, weekCeilingTokens) {
|
|
19113
|
+
return `${aboutShareOf(weekPercentOf(tokens, weekCeilingTokens))} of your week`;
|
|
19114
|
+
}
|
|
19115
|
+
function ceilingKnown(weekCeilingTokens) {
|
|
19116
|
+
return typeof weekCeilingTokens === "number" && weekCeilingTokens > 0;
|
|
19117
|
+
}
|
|
19118
|
+
function figureThenCaveat(sentence) {
|
|
19119
|
+
return `${sentence} ${PLAN_USAGE_CAVEAT}`;
|
|
19120
|
+
}
|
|
19121
|
+
function limitPartShareTextOf(part, used, weekCeilingTokens) {
|
|
19122
|
+
const words = part === "half" ? "half" : part === "three-quarters" ? "three quarters" : "nine tenths";
|
|
19123
|
+
const head = ceilingKnown(weekCeilingTokens) ? figureThenCaveat(`This phase has used ${words} of its usage limit: ${ofYourWeek(used, weekCeilingTokens)}.`) : `This phase has used ${words} of its usage limit.`;
|
|
19124
|
+
return part === "nine-tenths" ? `${head} New work stops at the limit.` : head;
|
|
19125
|
+
}
|
|
19126
|
+
function limitReachedFigureOf(limit, weekCeilingTokens) {
|
|
19127
|
+
if (!ceilingKnown(weekCeilingTokens))
|
|
19128
|
+
return { figure: "", caveat: "" };
|
|
19129
|
+
return { figure: `: ${ofYourWeek(limit, weekCeilingTokens)}`, caveat: ` ${PLAN_USAGE_CAVEAT}` };
|
|
19130
|
+
}
|
|
19131
|
+
function limitKeepGoingShareText(limit, used, weekCeilingTokens) {
|
|
19132
|
+
if (!ceilingKnown(weekCeilingTokens))
|
|
19133
|
+
return "Done. The limit is raised. New work can start again.";
|
|
19134
|
+
return `${figureThenCaveat(`Done. The limit is now ${ofYourWeek(limit, weekCeilingTokens)}.`)} This phase has used ${aboutShareOf(weekPercentOf(used, weekCeilingTokens))}. New work can start again.`;
|
|
19135
|
+
}
|
|
19136
|
+
function limitAlreadyUsedShareSuffix(limit, used, weekCeilingTokens) {
|
|
19137
|
+
if (limit > used)
|
|
19138
|
+
return "";
|
|
19139
|
+
return ceilingKnown(weekCeilingTokens) ? ` This phase has already used ${ofYourWeek(used, weekCeilingTokens)}, so no new work will start until you raise it.` : " This phase has already used that much, so no new work will start until you raise it.";
|
|
19140
|
+
}
|
|
19141
|
+
function limitTimesShareText(limit, typed, used, weekCeilingTokens) {
|
|
19142
|
+
const suffix = limitAlreadyUsedShareSuffix(limit, used, weekCeilingTokens);
|
|
19143
|
+
if (!ceilingKnown(weekCeilingTokens)) {
|
|
19144
|
+
return `Done. The limit for this phase is now ${typed} times what it is expected to use.${suffix}`;
|
|
19145
|
+
}
|
|
19146
|
+
return `${figureThenCaveat(`Done. The limit for this phase is now ${ofYourWeek(limit, weekCeilingTokens)}.`)} That is ${typed} times what it is expected to use.${suffix}`;
|
|
19147
|
+
}
|
|
19148
|
+
function limitFigureShareText(limit, used, weekCeilingTokens) {
|
|
19149
|
+
const suffix = limitAlreadyUsedShareSuffix(limit, used, weekCeilingTokens);
|
|
19150
|
+
if (!ceilingKnown(weekCeilingTokens))
|
|
19151
|
+
return `Done. The limit for this phase is set.${suffix}`;
|
|
19152
|
+
return `${figureThenCaveat(`Done. The limit for this phase is now ${ofYourWeek(limit, weekCeilingTokens)}.`)}${suffix}`;
|
|
19153
|
+
}
|
|
19154
|
+
function limitHeldShareTextOf(limit, weekCeilingTokens) {
|
|
19155
|
+
if (!ceilingKnown(weekCeilingTokens))
|
|
19156
|
+
return "This phase has reached its usage limit, so no new agent starts.";
|
|
19157
|
+
return figureThenCaveat(`This phase has reached its usage limit of ${ofYourWeek(limit, weekCeilingTokens)}, so no new agent starts.`);
|
|
19158
|
+
}
|
|
19159
|
+
function limitNoExpectedShareText(weekCeilingTokens) {
|
|
19160
|
+
return ceilingKnown(weekCeilingTokens) ? 'Nothing changed: there is no expected usage yet, so say a share of the week, like "limit it to 10% of the week".' : "Nothing changed: there is no expected usage for this phase yet.";
|
|
19161
|
+
}
|
|
19162
|
+
function limitTimesRangeShareText(range, weekCeilingTokens) {
|
|
19163
|
+
const head = `Nothing changed: a limit is between ${String(range.min)} and ${String(range.max)} times what is expected.`;
|
|
19164
|
+
return ceilingKnown(weekCeilingTokens) ? `${head} Say a share of the week instead, like "limit it to 10% of the week".` : head;
|
|
19165
|
+
}
|
|
19166
|
+
var LIMIT_SHARE_NOT_SET_TEXT = 'Nothing changed. To set a limit now, say "limit it to 2 times".';
|
|
19167
|
+
|
|
19168
|
+
// ../events/dist/client-version.js
|
|
19169
|
+
var CLIENT_VERSION_HEADER = "x-halfcycle-client";
|
|
19170
|
+
var TYPED_APPROVAL_OFF_SENTENCE = "Approving by typing is switched off for now.";
|
|
19171
|
+
var HEADLESS_CANNOT_APPROVE = "(a headless session cannot approve, by design)";
|
|
19172
|
+
var TYPED_REVIEW_OFF_SENTENCE = "Reviewing by typing is switched off for now.";
|
|
19173
|
+
var CLIENT_UPDATE_SENTENCE = `To approve by typing in a session, Halfcycle needs updating: run \`${HALFCYCLE_COMMAND}\` in this project's folder, then reopen your session and ask again.`;
|
|
19174
|
+
|
|
19175
|
+
// ../events/dist/device-auth.js
|
|
19176
|
+
var utcIso86012 = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/, "must be a UTC ISO-8601 timestamp ending in Z");
|
|
19177
|
+
var DEVICE_AUTH_STATUS = {
|
|
19178
|
+
/** The poll: minted, nobody has acted yet. Keep polling. 200. */
|
|
19179
|
+
PENDING: "pending",
|
|
19180
|
+
/** The poll: approved, and the credential is in this body. Once only. 200. */
|
|
19181
|
+
APPROVED: "approved",
|
|
19182
|
+
/** Confirm: the decision was recorded (approve or decline). 200. */
|
|
19183
|
+
RECORDED: "recorded",
|
|
19184
|
+
/** The human refused at the confirmation page. 400 on the poll. */
|
|
19185
|
+
DECLINED: "declined",
|
|
19186
|
+
/** The code's absolute expiry has passed. 400. */
|
|
19187
|
+
EXPIRED: "expired",
|
|
19188
|
+
/** Never minted, or already spent. 400. */
|
|
19189
|
+
UNKNOWN: "unknown",
|
|
19190
|
+
/** Confirm: neither `approve` nor `decline` was named. Nothing was bound. 400. */
|
|
19191
|
+
INVALID_DECISION: "invalid-decision",
|
|
19192
|
+
/** Confirm: an approval arrived with no signed-in identity. 400. */
|
|
19193
|
+
IDENTITY_REQUIRED: "identity-required",
|
|
19194
|
+
/** This deployment has no `SIGNIN_BASE_URL` / `DEVICE_AUTH_CONFIRM_SECRET`. 503. */
|
|
19195
|
+
NOT_CONFIGURED: "not-configured",
|
|
19196
|
+
/** Confirm: the shared confirmation secret was missing or wrong. 401. */
|
|
19197
|
+
UNAUTHORIZED: "unauthorized",
|
|
19198
|
+
/** Confirm: the code was already approved, declined or claimed. 409. */
|
|
19199
|
+
ALREADY_DECIDED: "already-decided",
|
|
19200
|
+
/**
|
|
19201
|
+
* Confirm: an approval named a signed-in identity whose account has not accepted
|
|
19202
|
+
* the terms of service and privacy policy currently in force. 400.
|
|
19203
|
+
*
|
|
19204
|
+
* NOT BOUND TO THE DEVICE CODE. Unlike every other refusal in this const, this one
|
|
19205
|
+
* says nothing about the code itself — the code is still `pending` after this
|
|
19206
|
+
* response, exactly as it was before the request, so the SAME userCode can be
|
|
19207
|
+
* confirmed again once the caller has recorded acceptance. `deviceConfirmRequestSchema`'s
|
|
19208
|
+
* `acceptTerms` is how a second confirm says it did.
|
|
19209
|
+
*/
|
|
19210
|
+
TERMS_REQUIRED: "terms-required"
|
|
19211
|
+
};
|
|
19212
|
+
var DEVICE_POLL_REFUSALS = [
|
|
19213
|
+
DEVICE_AUTH_STATUS.DECLINED,
|
|
19214
|
+
DEVICE_AUTH_STATUS.EXPIRED,
|
|
19215
|
+
DEVICE_AUTH_STATUS.UNKNOWN
|
|
19216
|
+
];
|
|
19217
|
+
var deviceAuthStartResponseSchema = external_exports.object({
|
|
19218
|
+
deviceCode: external_exports.string().min(1),
|
|
19219
|
+
userCode: external_exports.string().min(1),
|
|
19220
|
+
verificationUrl: external_exports.string().min(1),
|
|
19221
|
+
expiresAt: utcIso86012,
|
|
19222
|
+
pollIntervalMs: external_exports.number().int().positive()
|
|
19223
|
+
}).strict();
|
|
19224
|
+
var devicePollPendingSchema = external_exports.object({
|
|
19225
|
+
status: external_exports.literal(DEVICE_AUTH_STATUS.PENDING),
|
|
19226
|
+
pollIntervalMs: external_exports.number().int().positive()
|
|
19227
|
+
}).strict();
|
|
19228
|
+
var devicePollApprovedSchema = external_exports.object({
|
|
19229
|
+
status: external_exports.literal(DEVICE_AUTH_STATUS.APPROVED),
|
|
19230
|
+
accountId: external_exports.string().min(1),
|
|
19231
|
+
credential: external_exports.string().min(1),
|
|
19232
|
+
expiresAt: utcIso86012
|
|
19233
|
+
}).strict();
|
|
19234
|
+
var deviceAuthRefusalSchema = external_exports.object({
|
|
19235
|
+
status: external_exports.enum([
|
|
19236
|
+
DEVICE_AUTH_STATUS.DECLINED,
|
|
19237
|
+
DEVICE_AUTH_STATUS.EXPIRED,
|
|
19238
|
+
DEVICE_AUTH_STATUS.UNKNOWN,
|
|
19239
|
+
DEVICE_AUTH_STATUS.INVALID_DECISION,
|
|
19240
|
+
DEVICE_AUTH_STATUS.IDENTITY_REQUIRED,
|
|
19241
|
+
DEVICE_AUTH_STATUS.NOT_CONFIGURED,
|
|
19242
|
+
DEVICE_AUTH_STATUS.UNAUTHORIZED,
|
|
19243
|
+
DEVICE_AUTH_STATUS.ALREADY_DECIDED,
|
|
19244
|
+
DEVICE_AUTH_STATUS.TERMS_REQUIRED
|
|
19245
|
+
]),
|
|
19246
|
+
message: external_exports.string().min(1)
|
|
19247
|
+
}).strict();
|
|
19248
|
+
var devicePollResponseSchema = external_exports.union([
|
|
19249
|
+
devicePollPendingSchema,
|
|
19250
|
+
devicePollApprovedSchema,
|
|
19251
|
+
deviceAuthRefusalSchema
|
|
19252
|
+
]);
|
|
19253
|
+
var deviceConfirmRequestSchema = external_exports.object({
|
|
19254
|
+
userCode: external_exports.string().min(1),
|
|
19255
|
+
decision: external_exports.enum(["approve", "decline"]),
|
|
19256
|
+
externalAuthId: external_exports.string().min(1).optional(),
|
|
19257
|
+
email: external_exports.string().optional(),
|
|
19258
|
+
acceptTerms: external_exports.boolean().optional()
|
|
19259
|
+
}).strict();
|
|
19260
|
+
var deviceConfirmRecordedSchema = external_exports.object({
|
|
19261
|
+
status: external_exports.literal(DEVICE_AUTH_STATUS.RECORDED),
|
|
19262
|
+
accountId: external_exports.string().min(1).optional()
|
|
19263
|
+
}).strict();
|
|
19264
|
+
var deviceConfirmResponseSchema = external_exports.union([
|
|
19265
|
+
deviceConfirmRecordedSchema,
|
|
19266
|
+
deviceAuthRefusalSchema
|
|
19106
19267
|
]);
|
|
19268
|
+
var DASHBOARD_URL = "https://app.halfcycle.ai";
|
|
19107
19269
|
|
|
19108
|
-
// ../events/dist/
|
|
19109
|
-
|
|
19110
|
-
|
|
19111
|
-
var keepFreePercentSchema = external_exports.number().int().min(0).max(KEEP_FREE_MAX);
|
|
19112
|
-
var KEEP_FREE_DEFAULT = 20;
|
|
19113
|
-
var PACE_AGENTS_MAX = 20;
|
|
19114
|
-
var FIVE_HOUR_WINDOW_MINUTES = 300;
|
|
19115
|
-
var SEVEN_DAY_WINDOW_MINUTES = 10080;
|
|
19116
|
-
var PACE_WINDOW_MINUTES_MAX = 525600;
|
|
19117
|
-
var MINUTE_KEY = /^([1-9][0-9]{0,6})-minute$/;
|
|
19118
|
-
function isPaceWindowKind(value) {
|
|
19119
|
-
if (value === "five-hour" || value === "seven-day")
|
|
19120
|
-
return true;
|
|
19121
|
-
if (typeof value !== "string")
|
|
19122
|
-
return false;
|
|
19123
|
-
const match = MINUTE_KEY.exec(value);
|
|
19124
|
-
if (match === null)
|
|
19125
|
-
return false;
|
|
19126
|
-
const minutes = Number(match[1]);
|
|
19127
|
-
return minutes <= PACE_WINDOW_MINUTES_MAX && minutes !== FIVE_HOUR_WINDOW_MINUTES && minutes !== SEVEN_DAY_WINDOW_MINUTES;
|
|
19270
|
+
// ../events/dist/project-page.js
|
|
19271
|
+
function projectPageUrl(engagementId) {
|
|
19272
|
+
return isEngagementId(engagementId) ? `${DASHBOARD_URL}/${encodeURIComponent(engagementId)}` : void 0;
|
|
19128
19273
|
}
|
|
19129
|
-
|
|
19130
|
-
|
|
19274
|
+
function systemViewUrl(engagementId, phase) {
|
|
19275
|
+
const page = projectPageUrl(engagementId);
|
|
19276
|
+
if (page === void 0)
|
|
19277
|
+
return void 0;
|
|
19278
|
+
return `${page}/console/system-view?${new URLSearchParams({ phase }).toString()}`;
|
|
19279
|
+
}
|
|
19280
|
+
function requestAccessSentence(engagementId) {
|
|
19281
|
+
const page = projectPageUrl(engagementId) ?? "this project's page on Halfcycle";
|
|
19282
|
+
return `To ask for access, open ${page} signed in as this account and choose "Request access". Then let the project's owner know, so they can approve it.`;
|
|
19283
|
+
}
|
|
19284
|
+
|
|
19285
|
+
// ../events/dist/scope-notices.js
|
|
19286
|
+
var scopePartNameSchema = external_exports.string().min(1).max(SYSTEM_PART_NAME_MAX);
|
|
19287
|
+
var scopeNoteEntrySchema = external_exports.object({
|
|
19288
|
+
part: scopePartNameSchema.optional(),
|
|
19289
|
+
note: external_exports.string().min(1).max(SCOPE_NOTE_MAX)
|
|
19290
|
+
}).strict();
|
|
19291
|
+
var scopeSentBackSchema = external_exports.object({
|
|
19292
|
+
phase: scopePhaseSchema,
|
|
19293
|
+
number: external_exports.number().int().min(1),
|
|
19294
|
+
notes: external_exports.array(scopeNoteEntrySchema).min(1).max(PHASE_PLAN_CHANGES_MAX + 1)
|
|
19295
|
+
}).strict().superRefine((entry, ctx) => {
|
|
19296
|
+
entry.notes.forEach((n, i) => {
|
|
19297
|
+
if (n.part === void 0 && i !== entry.notes.length - 1) {
|
|
19298
|
+
ctx.addIssue({
|
|
19299
|
+
code: external_exports.ZodIssueCode.custom,
|
|
19300
|
+
path: ["notes", i],
|
|
19301
|
+
message: "the note on the whole phase comes after every note on a part"
|
|
19302
|
+
});
|
|
19303
|
+
}
|
|
19304
|
+
});
|
|
19131
19305
|
});
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
|
|
19306
|
+
var scopeWaitingSchema = external_exports.object({
|
|
19307
|
+
phase: scopePhaseSchema,
|
|
19308
|
+
number: external_exports.number().int().min(1),
|
|
19309
|
+
changedParts: external_exports.array(scopePartNameSchema).max(PHASE_PLAN_CHANGES_MAX)
|
|
19310
|
+
}).strict();
|
|
19311
|
+
var scopeNoticesSchema = external_exports.object({
|
|
19312
|
+
sentBack: external_exports.array(scopeSentBackSchema),
|
|
19313
|
+
waiting: external_exports.array(scopeWaitingSchema),
|
|
19314
|
+
typedApprovalOffered: external_exports.boolean()
|
|
19315
|
+
}).strict().refine((v) => v.sentBack.length > 0 || v.waiting.length > 0, {
|
|
19316
|
+
message: "carried only when a phase was sent back or waits for the owner"
|
|
19317
|
+
});
|
|
19318
|
+
var scopeApprovedNoticeSchema = external_exports.object({ phase: scopePhaseSchema }).strict();
|
|
19319
|
+
var scopeApprovedNoticesSchema = external_exports.array(scopeApprovedNoticeSchema);
|
|
19320
|
+
function approvedInConsoleSentence(phase) {
|
|
19321
|
+
return `Scope for ${phaseWords(phase)} was approved in the console; continuing. Say so to the person, then carry on with the next step; they do not need to tell you.`;
|
|
19138
19322
|
}
|
|
19139
|
-
function
|
|
19140
|
-
|
|
19141
|
-
return null;
|
|
19142
|
-
if (minutes === FIVE_HOUR_WINDOW_MINUTES)
|
|
19143
|
-
return "five-hour";
|
|
19144
|
-
if (minutes === SEVEN_DAY_WINDOW_MINUTES)
|
|
19145
|
-
return "seven-day";
|
|
19146
|
-
return `${String(minutes)}-minute`;
|
|
19323
|
+
function quotedParts(parts) {
|
|
19324
|
+
return parts.map((p) => `"${p}"`).join(", ");
|
|
19147
19325
|
}
|
|
19148
|
-
function
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
19152
|
-
|
|
19153
|
-
|
|
19154
|
-
if (minutes % 1440 === 0)
|
|
19155
|
-
return `${String(minutes / 1440)}-day window`;
|
|
19156
|
-
if (minutes % 60 === 0)
|
|
19157
|
-
return `${String(minutes / 60)}-hour window`;
|
|
19158
|
-
return `${String(minutes)}-minute window`;
|
|
19326
|
+
function approvalSentence(phase, offerTyping) {
|
|
19327
|
+
if (offerTyping === "off")
|
|
19328
|
+
return TYPED_APPROVAL_OFF_SENTENCE;
|
|
19329
|
+
if (offerTyping === "update")
|
|
19330
|
+
return CLIENT_UPDATE_SENTENCE;
|
|
19331
|
+
return `In their own interactive session ${HEADLESS_CANNOT_APPROVE}, they ask to see the plan, check each part, and then type: approve ${phase}.`;
|
|
19159
19332
|
}
|
|
19160
|
-
function
|
|
19161
|
-
return
|
|
19333
|
+
function phaseWords(phase) {
|
|
19334
|
+
return `phase "${phase}"`;
|
|
19162
19335
|
}
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
|
|
19169
|
-
external_exports.object({
|
|
19170
|
-
outcome: external_exports.literal("recorded"),
|
|
19171
|
-
keepFreePercent: keepFreePercentSchema,
|
|
19172
|
-
moreAllowance: external_exports.boolean().optional()
|
|
19173
|
-
}).strict(),
|
|
19174
|
-
external_exports.object({ outcome: external_exports.literal("needs-the-person"), keepFreePercent: keepFreePercentSchema }).strict(),
|
|
19175
|
-
external_exports.object({ outcome: external_exports.literal("not-owner") }).strict(),
|
|
19176
|
-
external_exports.object({ outcome: external_exports.literal("no-owner") }).strict(),
|
|
19177
|
-
external_exports.object({ outcome: external_exports.literal("unavailable") }).strict()
|
|
19178
|
-
]);
|
|
19179
|
-
var pacingBasisTaskSchema = external_exports.object({
|
|
19180
|
-
id: buildTaskIdSchema,
|
|
19181
|
-
dependsOn: external_exports.array(buildTaskIdSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
19182
|
-
budgetMinutes: external_exports.number().int().min(1).max(BUILD_TASK_BUDGET_MAX_MINUTES).optional(),
|
|
19183
|
-
human: external_exports.boolean(),
|
|
19184
|
-
kind: buildTaskKindSchema.optional()
|
|
19185
|
-
}).strict();
|
|
19186
|
-
var pacingBasisSchema = external_exports.object({
|
|
19187
|
-
outcome: external_exports.literal("basis"),
|
|
19188
|
-
claudePlan: external_exports.string().nullable().optional(),
|
|
19189
|
-
keepFreePercent: keepFreePercentSchema,
|
|
19190
|
-
settingsUrl: external_exports.string().optional(),
|
|
19191
|
-
phase: phaseNameSchema.nullable(),
|
|
19192
|
-
tasks: external_exports.array(pacingBasisTaskSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
19193
|
-
medianTaskMinutes: external_exports.number().nonnegative().nullable(),
|
|
19194
|
-
medianTaskTokens: external_exports.number().nonnegative().nullable()
|
|
19195
|
-
}).strict();
|
|
19196
|
-
var paceSuggestionSchema = external_exports.object({
|
|
19197
|
-
number: external_exports.number().int().min(1).max(PACE_AGENTS_MAX),
|
|
19198
|
-
minutes: external_exports.number().int().nonnegative().nullable(),
|
|
19199
|
-
pauses: external_exports.number().int().nonnegative(),
|
|
19200
|
-
keepFreePercent: keepFreePercentSchema,
|
|
19201
|
-
knownWindow: paceWindowKindSchema.nullable(),
|
|
19202
|
-
expectedTokens: external_exports.number().int().nonnegative().optional(),
|
|
19203
|
-
limitTokens: external_exports.number().int().positive().optional(),
|
|
19204
|
-
multiple: external_exports.number().positive().nullable().optional(),
|
|
19205
|
-
firstGuess: external_exports.boolean().optional(),
|
|
19206
|
-
limitSetBy: external_exports.enum(["default", "person", "other"]).optional()
|
|
19207
|
-
}).strict();
|
|
19208
|
-
var PACE_NOT_PACED_REASONS = ["not-configured", "unreadable"];
|
|
19209
|
-
var limitHeldSchema = external_exports.object({
|
|
19210
|
-
used: external_exports.number().int().nonnegative(),
|
|
19211
|
-
limit: external_exports.number().int().positive(),
|
|
19212
|
-
raiseBy: external_exports.number().int().nonnegative(),
|
|
19213
|
-
working: external_exports.number().int().nonnegative()
|
|
19214
|
-
}).strict();
|
|
19215
|
-
var paceUsageSchema = external_exports.object({
|
|
19216
|
-
used: external_exports.number().int().nonnegative(),
|
|
19217
|
-
limit: external_exports.number().int().positive()
|
|
19218
|
-
}).strict();
|
|
19219
|
-
var paceRunResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19220
|
-
external_exports.object({
|
|
19221
|
-
outcome: external_exports.literal("paced"),
|
|
19222
|
-
pace: paceStateSchema,
|
|
19223
|
-
number: external_exports.number().int().min(1).max(PACE_AGENTS_MAX),
|
|
19224
|
-
allowedNow: external_exports.number().int().nonnegative(),
|
|
19225
|
-
windowKind: paceWindowKindSchema.optional(),
|
|
19226
|
-
until: utcIso8601.optional(),
|
|
19227
|
-
keepFreePercent: keepFreePercentSchema.optional(),
|
|
19228
|
-
suggestion: paceSuggestionSchema.optional(),
|
|
19229
|
-
limit: external_exports.literal("reached").optional(),
|
|
19230
|
-
limitHeld: limitHeldSchema.optional(),
|
|
19231
|
-
usage: paceUsageSchema.optional()
|
|
19232
|
-
}).strict(),
|
|
19233
|
-
external_exports.object({ outcome: external_exports.literal("not-paced"), reason: external_exports.enum(PACE_NOT_PACED_REASONS) }).strict()
|
|
19234
|
-
]);
|
|
19235
|
-
function tokenCountWordsOf(n) {
|
|
19236
|
-
if (n < 1e3)
|
|
19237
|
-
return String(Math.max(0, Math.round(n)));
|
|
19238
|
-
const rounded = Number(n.toPrecision(2));
|
|
19239
|
-
const [unit, word] = rounded >= 1e9 ? [1e9, "billion"] : rounded >= 1e6 ? [1e6, "million"] : [1e3, "thousand"];
|
|
19240
|
-
return `${String(Number((rounded / unit).toPrecision(2)))} ${word}`;
|
|
19336
|
+
function sentBackNotice(entry) {
|
|
19337
|
+
return [
|
|
19338
|
+
`Before anything else: the project's owner sent the scope of ${phaseWords(entry.phase)} back with these notes.`,
|
|
19339
|
+
...entry.notes.map((n) => n.part === void 0 ? `- ${n.note}` : `- "${n.part}": ${n.note}`),
|
|
19340
|
+
`Change the plan to answer every note, then send it again: say "plan the next phase" to start. It then waits for the owner's approval again.`
|
|
19341
|
+
].join("\n");
|
|
19241
19342
|
}
|
|
19242
|
-
function
|
|
19243
|
-
|
|
19343
|
+
function systemViewSentence(offerTyping, address) {
|
|
19344
|
+
if (address === void 0)
|
|
19345
|
+
return [];
|
|
19346
|
+
return [offerTyping === "yes" ? `Or they approve it in the System view: ${address}` : `They approve it in the System view: ${address}`];
|
|
19244
19347
|
}
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
"
|
|
19252
|
-
"June",
|
|
19253
|
-
"July",
|
|
19254
|
-
"August",
|
|
19255
|
-
"September",
|
|
19256
|
-
"October",
|
|
19257
|
-
"November",
|
|
19258
|
-
"December"
|
|
19259
|
-
];
|
|
19260
|
-
var SIX_DAYS_MS = 6 * 24 * 60 * 60 * 1e3;
|
|
19261
|
-
function paceClockOf(at, now) {
|
|
19262
|
-
const hours = at.getHours();
|
|
19263
|
-
const clock = `${String(hours % 12 === 0 ? 12 : hours % 12)}:${String(at.getMinutes()).padStart(2, "0")} ${hours < 12 ? "am" : "pm"}`;
|
|
19264
|
-
const sameDay = at.getFullYear() === now.getFullYear() && at.getMonth() === now.getMonth() && at.getDate() === now.getDate();
|
|
19265
|
-
if (sameDay)
|
|
19266
|
-
return clock;
|
|
19267
|
-
const day = DAY_NAMES[at.getDay()] ?? "";
|
|
19268
|
-
if (at.getTime() - now.getTime() > SIX_DAYS_MS) {
|
|
19269
|
-
return `${day} ${String(at.getDate())} ${MONTH_NAMES[at.getMonth()] ?? ""} ${clock}`;
|
|
19270
|
-
}
|
|
19271
|
-
return `${day} ${clock}`;
|
|
19348
|
+
function waitingNotice(entry, offerTyping, engagementId) {
|
|
19349
|
+
return [
|
|
19350
|
+
...entry.changedParts.length > 0 ? [`These parts changed since the owner last decided on this phase, and wait for their approval: ${quotedParts(entry.changedParts)}.`] : [],
|
|
19351
|
+
`The scope of ${phaseWords(entry.phase)} is waiting for the project's owner to approve it.`,
|
|
19352
|
+
approvalSentence(entry.phase, offerTyping),
|
|
19353
|
+
...systemViewSentence(offerTyping, systemViewUrl(engagementId, entry.phase))
|
|
19354
|
+
].join(" ");
|
|
19272
19355
|
}
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
return
|
|
19356
|
+
function scopeNoticeText(scope, options) {
|
|
19357
|
+
const omit2 = options.omitActivePhase === true ? options.activePhase : void 0;
|
|
19358
|
+
return {
|
|
19359
|
+
sentBack: scope.sentBack.map(sentBackNotice),
|
|
19360
|
+
waiting: scope.waiting.filter((w) => omit2 === void 0 || w.phase !== omit2).map((w) => waitingNotice(w, options.offerTyping, options.engagementId))
|
|
19361
|
+
};
|
|
19362
|
+
}
|
|
19363
|
+
|
|
19364
|
+
// ../events/dist/review-notices.js
|
|
19365
|
+
var reviewNoticeQuestionSchema = external_exports.object({
|
|
19366
|
+
phase: scopePhaseSchema,
|
|
19367
|
+
number: reviewPhaseNumberSchema,
|
|
19368
|
+
part: systemPartIdSchema,
|
|
19369
|
+
partName: systemPartSchema.shape.name,
|
|
19370
|
+
question: reviewNoteSchema
|
|
19371
|
+
}).strict();
|
|
19372
|
+
var reviewNoticeSentBackSchema = external_exports.object({
|
|
19373
|
+
phase: scopePhaseSchema,
|
|
19374
|
+
number: reviewPhaseNumberSchema,
|
|
19375
|
+
part: systemPartIdSchema,
|
|
19376
|
+
partName: systemPartSchema.shape.name,
|
|
19377
|
+
note: reviewNoteSchema
|
|
19378
|
+
}).strict();
|
|
19379
|
+
var reviewNoticesSchema = external_exports.object({
|
|
19380
|
+
questions: external_exports.array(reviewNoticeQuestionSchema).max(REVIEW_PARTS_MAX),
|
|
19381
|
+
sentBack: external_exports.array(reviewNoticeSentBackSchema).max(REVIEW_PARTS_MAX)
|
|
19382
|
+
}).strict().refine((v) => v.questions.length > 0 || v.sentBack.length > 0, {
|
|
19383
|
+
message: "carried only when a question waits or a part was sent back"
|
|
19384
|
+
});
|
|
19385
|
+
function phaseCalled(phase) {
|
|
19386
|
+
return `phase "${phase}"`;
|
|
19276
19387
|
}
|
|
19277
|
-
function
|
|
19278
|
-
const
|
|
19279
|
-
|
|
19280
|
-
return head;
|
|
19281
|
-
return k === 1 ? `${head} The 1 agent already working will finish its task.` : `${head} The ${String(k)} agents already working will finish their tasks.`;
|
|
19388
|
+
function questionNotice(entry) {
|
|
19389
|
+
const answer = `${HALFCYCLE_COMMAND} review ${quoteForShell(entry.phase)} --answer ${quoteForShell(entry.part)} "<your answer>"`;
|
|
19390
|
+
return `Before anything else: the project's owner asked about "${entry.partName}" in the review of ${phaseCalled(entry.phase)}: ${entry.question} Answer it with ${answer}.`;
|
|
19282
19391
|
}
|
|
19283
|
-
function
|
|
19284
|
-
return `
|
|
19392
|
+
function sentBackNotice2(entry) {
|
|
19393
|
+
return `Before anything else: the project's owner sent "${entry.partName}" in ${phaseCalled(entry.phase)} back to building: ${entry.note} Rebuild it: add or reopen the tasks that build it. For each task that rebuilds it, add a task that reviews the rebuild, held by a different agent from the one that built it. When each review has passed, report the build with the time each task finished, then run the close step again.`;
|
|
19285
19394
|
}
|
|
19286
|
-
function
|
|
19287
|
-
|
|
19288
|
-
const canUseMore = input.keepFreePercent > 0;
|
|
19289
|
-
if (!canFaster && !canUseMore)
|
|
19290
|
-
return null;
|
|
19291
|
-
const head = `You have used only ${String(Math.floor(input.percentUsed))}% of this ${paceWindowWordsOf(input.window)}, and more than half of it has passed.`;
|
|
19292
|
-
const useUpTo = `"use up to ${String(Math.min(100, 100 - input.keepFreePercent + 10))}%" to let this build use more of it`;
|
|
19293
|
-
if (canFaster && canUseMore)
|
|
19294
|
-
return `${head} Say "faster" for one more agent, or ${useUpTo}.`;
|
|
19295
|
-
if (canFaster)
|
|
19296
|
-
return `${head} Say "faster" for one more agent.`;
|
|
19297
|
-
return `${head} Say ${useUpTo}.`;
|
|
19395
|
+
function reviewNoticeText(review) {
|
|
19396
|
+
return [...review.questions.map(questionNotice), ...review.sentBack.map(sentBackNotice2)];
|
|
19298
19397
|
}
|
|
19299
|
-
|
|
19300
|
-
|
|
19398
|
+
|
|
19399
|
+
// ../events/dist/credential-wire.js
|
|
19400
|
+
var engagementCredentialResponseSchema = external_exports.object({
|
|
19401
|
+
engagementId: external_exports.string(),
|
|
19402
|
+
sessionToken: external_exports.string(),
|
|
19403
|
+
mcpUrl: external_exports.string(),
|
|
19404
|
+
guardUrl: external_exports.string(),
|
|
19405
|
+
controlTelemetryUrl: external_exports.string(),
|
|
19406
|
+
methodVersion: external_exports.string().optional(),
|
|
19407
|
+
consoleUrl: external_exports.string().optional()
|
|
19408
|
+
}).strict();
|
|
19409
|
+
var ciTokenExchangeResponseSchema = external_exports.object({
|
|
19410
|
+
token: external_exports.string(),
|
|
19411
|
+
expiresAt: utcIso8601,
|
|
19412
|
+
engagementId: external_exports.string()
|
|
19413
|
+
}).strict();
|
|
19414
|
+
var NO_CREDENTIAL_PLACEHOLDER = "halfcycle:no-credential";
|
|
19415
|
+
var NOT_THIS_ACCOUNT_PLACEHOLDER = "halfcycle:not-this-account";
|
|
19416
|
+
var UPDATE_CLAUDE_CODE_PLACEHOLDER = "halfcycle:update-claude-code";
|
|
19417
|
+
var CREDENTIAL_PLACEHOLDERS = [
|
|
19418
|
+
NO_CREDENTIAL_PLACEHOLDER,
|
|
19419
|
+
NOT_THIS_ACCOUNT_PLACEHOLDER,
|
|
19420
|
+
UPDATE_CLAUDE_CODE_PLACEHOLDER
|
|
19421
|
+
];
|
|
19422
|
+
var SWITCH_ACCOUNT_ANSWER = 'answer "s" when asked';
|
|
19423
|
+
var NO_CREDENTIAL_SENTENCE = 'Halfcycle is not connected: this machine has no working Halfcycle credential for this project. Run "npx halfcycle" in the project folder to sign in again.';
|
|
19424
|
+
var NOT_THIS_ACCOUNT_SENTENCE = `Halfcycle is not connected: this project belongs to another Halfcycle account. To switch, run "npx halfcycle" in this project and ${SWITCH_ACCOUNT_ANSWER}.`;
|
|
19425
|
+
var UPDATE_CLAUDE_CODE_SENTENCE = "Halfcycle is not connected: this Claude Code version does not name the server it connects to, so no credential was sent. Update Claude Code, then reopen.";
|
|
19426
|
+
var CANNOT_REACH_SENTENCE = "Halfcycle is not connected: its server could not be reached, so its tools are unavailable in this session. Check your network, then reopen the project.";
|
|
19427
|
+
var SERVICE_PROBLEM_SENTENCE = "Halfcycle is not connected: its service had a problem just now, so nothing in this session is being checked. Reopen the project to try again.";
|
|
19428
|
+
var FOLDER_NOT_TRUSTED_SENTENCE = "Folder not yet trusted. Open this folder once in interactive Claude Code and trust it; then headless runs work.";
|
|
19429
|
+
var SCOPE_UNCHECKED_SENTENCE = "If this project needs approval before building, that cannot be checked either, so work done now shows as built without approval unless already approved.";
|
|
19430
|
+
var PLACEHOLDER_SENTENCES = Object.freeze({
|
|
19431
|
+
[NO_CREDENTIAL_PLACEHOLDER]: NO_CREDENTIAL_SENTENCE,
|
|
19432
|
+
[NOT_THIS_ACCOUNT_PLACEHOLDER]: NOT_THIS_ACCOUNT_SENTENCE,
|
|
19433
|
+
[UPDATE_CLAUDE_CODE_PLACEHOLDER]: UPDATE_CLAUDE_CODE_SENTENCE
|
|
19434
|
+
});
|
|
19435
|
+
|
|
19436
|
+
// ../events/dist/scope-chat.js
|
|
19437
|
+
var chatScopeApproveRequestSchema = external_exports.object({
|
|
19438
|
+
act: external_exports.literal("approve"),
|
|
19439
|
+
reference: phaseIdentitySchema,
|
|
19440
|
+
planVersion: planVersionSchema
|
|
19441
|
+
}).strict();
|
|
19442
|
+
var chatScopeSendBackRequestSchema = external_exports.object({
|
|
19443
|
+
act: external_exports.literal("send-back"),
|
|
19444
|
+
reference: phaseIdentitySchema,
|
|
19445
|
+
planVersion: planVersionSchema,
|
|
19446
|
+
note: scopeNoteWireSchema.optional()
|
|
19447
|
+
}).strict();
|
|
19448
|
+
var chatScopeRequestSchema = external_exports.discriminatedUnion("act", [
|
|
19449
|
+
chatScopeApproveRequestSchema,
|
|
19450
|
+
chatScopeSendBackRequestSchema
|
|
19451
|
+
]);
|
|
19452
|
+
var CHAT_SCOPE_ACTS = SCOPE_ACTS;
|
|
19453
|
+
var chatScopeRecordedSchema = external_exports.object({
|
|
19454
|
+
outcome: external_exports.literal("recorded"),
|
|
19455
|
+
act: external_exports.enum(CHAT_SCOPE_ACTS),
|
|
19456
|
+
phase: scopePhaseSchema,
|
|
19457
|
+
planVersion: planVersionSchema
|
|
19458
|
+
}).strict();
|
|
19459
|
+
var chatScopeAlreadyApprovedSchema = external_exports.object({
|
|
19460
|
+
outcome: external_exports.literal("already-approved"),
|
|
19461
|
+
replanNeeded: external_exports.boolean()
|
|
19462
|
+
}).strict();
|
|
19463
|
+
var chatScopeRefusedSchema = external_exports.object({
|
|
19464
|
+
outcome: external_exports.literal("refused"),
|
|
19465
|
+
problems: external_exports.array(systemDescriptionProblemSchema).min(1)
|
|
19466
|
+
}).strict();
|
|
19467
|
+
var chatAmbiguousSchema = external_exports.object({
|
|
19468
|
+
outcome: external_exports.literal("ambiguous"),
|
|
19469
|
+
phases: external_exports.array(scopePhaseSchema).min(2)
|
|
19470
|
+
}).strict();
|
|
19471
|
+
function bareOutcome(outcome) {
|
|
19472
|
+
return external_exports.object({ outcome: external_exports.literal(outcome) }).strict();
|
|
19301
19473
|
}
|
|
19302
|
-
|
|
19303
|
-
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19474
|
+
var chatScopeResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19475
|
+
chatScopeRecordedSchema,
|
|
19476
|
+
chatScopeAlreadyApprovedSchema,
|
|
19477
|
+
chatScopeRefusedSchema,
|
|
19478
|
+
chatAmbiguousSchema,
|
|
19479
|
+
bareOutcome("show-first"),
|
|
19480
|
+
bareOutcome("plan-changed"),
|
|
19481
|
+
bareOutcome("build-started"),
|
|
19482
|
+
bareOutcome("not-owner"),
|
|
19483
|
+
bareOutcome("no-owner"),
|
|
19484
|
+
bareOutcome("not-offered"),
|
|
19485
|
+
bareOutcome("unavailable")
|
|
19486
|
+
]);
|
|
19487
|
+
|
|
19488
|
+
// ../events/dist/review-chat.js
|
|
19489
|
+
var chatReviewAcceptRequestSchema = external_exports.object({
|
|
19490
|
+
act: external_exports.literal("accept"),
|
|
19491
|
+
reference: phaseIdentitySchema,
|
|
19492
|
+
reviewVersion: external_exports.number().int().min(0),
|
|
19493
|
+
parts: external_exports.array(systemPartIdSchema).max(REVIEW_PARTS_MAX),
|
|
19494
|
+
waitingClaims: external_exports.literal(true).optional()
|
|
19495
|
+
}).strict();
|
|
19496
|
+
function notedRequest(act) {
|
|
19497
|
+
return external_exports.object({
|
|
19498
|
+
act: external_exports.literal(act),
|
|
19499
|
+
reference: phaseIdentitySchema,
|
|
19500
|
+
reviewVersion: external_exports.number().int().min(0),
|
|
19501
|
+
part: systemPartIdSchema,
|
|
19502
|
+
note: reviewNoteWireSchema
|
|
19503
|
+
}).strict();
|
|
19309
19504
|
}
|
|
19310
|
-
var
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19505
|
+
var chatReviewQuestionRequestSchema = notedRequest("question");
|
|
19506
|
+
var chatReviewSendBackRequestSchema = notedRequest("send-back");
|
|
19507
|
+
var chatReviewCarryRequestSchema = notedRequest("carry");
|
|
19508
|
+
var chatReviewDropRequestSchema = notedRequest("drop");
|
|
19509
|
+
var chatReviewRejectRequestSchema = external_exports.object({
|
|
19510
|
+
act: external_exports.literal("reject"),
|
|
19511
|
+
reference: phaseIdentitySchema,
|
|
19512
|
+
reviewVersion: external_exports.number().int().min(0),
|
|
19513
|
+
task: buildTaskIdSchema,
|
|
19514
|
+
note: reviewNoteWireSchema
|
|
19515
|
+
}).strict();
|
|
19516
|
+
var chatReviewRequestSchema = external_exports.discriminatedUnion("act", [
|
|
19517
|
+
chatReviewAcceptRequestSchema,
|
|
19518
|
+
chatReviewQuestionRequestSchema,
|
|
19519
|
+
chatReviewSendBackRequestSchema,
|
|
19520
|
+
chatReviewCarryRequestSchema,
|
|
19521
|
+
chatReviewDropRequestSchema,
|
|
19522
|
+
chatReviewRejectRequestSchema
|
|
19523
|
+
]);
|
|
19524
|
+
function bareOutcome2(outcome) {
|
|
19525
|
+
return external_exports.object({ outcome: external_exports.literal(outcome) }).strict();
|
|
19318
19526
|
}
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
var PACE_ONLY_PERSON_RAISES = 'Only the person can raise the number of agents, by typing "faster" or "run 5 agents" in the chat. Nothing was changed.';
|
|
19322
|
-
function paceStatusLineOf(percent, window) {
|
|
19323
|
-
return `Halfcycle \xB7 ${String(Math.round(percent))}% of this ${paceWindowWordsOf(window)} used`;
|
|
19527
|
+
function notTheConsoleNotDecidable(option) {
|
|
19528
|
+
return option !== reviewNotDecidableSchema;
|
|
19324
19529
|
}
|
|
19325
|
-
var
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
var
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
"three-quarters": 0.75,
|
|
19337
|
-
"nine-tenths": 0.9,
|
|
19338
|
-
limit: 1
|
|
19339
|
-
};
|
|
19340
|
-
var LIMIT_SET_BY = ["default", "person", "other"];
|
|
19341
|
-
var limitSetBySchema = external_exports.enum(LIMIT_SET_BY);
|
|
19342
|
-
var LIMIT_TYPED_BY = ["person", "not-attended", "cannot-tell"];
|
|
19343
|
-
var limitTypedBySchema = external_exports.enum(LIMIT_TYPED_BY);
|
|
19344
|
-
var limitHistoryEntrySchema = external_exports.object({
|
|
19345
|
-
at: utcIso8601,
|
|
19346
|
-
kind: external_exports.enum(["raised", "set", "stopped"]),
|
|
19347
|
-
limit: external_exports.number().int().positive(),
|
|
19348
|
-
by: limitTypedBySchema,
|
|
19349
|
-
relayed: external_exports.literal(true).optional()
|
|
19530
|
+
var chatReviewResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19531
|
+
reviewPartsNotDecidableSchema,
|
|
19532
|
+
...reviewDecisionResultSchema.options.filter(notTheConsoleNotDecidable),
|
|
19533
|
+
bareOutcome2("show-first"),
|
|
19534
|
+
bareOutcome2("not-offered"),
|
|
19535
|
+
chatAmbiguousSchema,
|
|
19536
|
+
bareOutcome2("nothing-waiting")
|
|
19537
|
+
]);
|
|
19538
|
+
var reviewAnswerRequestSchema = external_exports.object({
|
|
19539
|
+
part: systemPartIdSchema,
|
|
19540
|
+
answer: statementText(REVIEW_ANSWER_MAX)
|
|
19350
19541
|
}).strict();
|
|
19351
|
-
var
|
|
19352
|
-
|
|
19353
|
-
|
|
19354
|
-
expected: external_exports.number().int().nonnegative(),
|
|
19355
|
-
expectedMinutes: external_exports.number().nonnegative().nullable(),
|
|
19356
|
-
limit: external_exports.number().int().positive(),
|
|
19357
|
-
multiple: external_exports.number().positive().nullable(),
|
|
19358
|
-
setBy: limitSetBySchema,
|
|
19359
|
-
firstGuess: external_exports.boolean(),
|
|
19360
|
-
shown: external_exports.array(limitPartSchema).max(LIMIT_PARTS.length),
|
|
19361
|
-
awaiting: external_exports.boolean(),
|
|
19362
|
-
history: external_exports.array(limitHistoryEntrySchema).max(LIMIT_HISTORY_MAX)
|
|
19542
|
+
var reviewAnswerRecordedSchema = external_exports.object({
|
|
19543
|
+
outcome: external_exports.literal("recorded"),
|
|
19544
|
+
name: systemPartSchema.shape.name
|
|
19363
19545
|
}).strict();
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
19546
|
+
var reviewAnswerResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19547
|
+
reviewAnswerRecordedSchema,
|
|
19548
|
+
bareOutcome2("no-question"),
|
|
19549
|
+
reviewRefusedSchema,
|
|
19550
|
+
bareOutcome2("unavailable")
|
|
19551
|
+
]);
|
|
19552
|
+
|
|
19553
|
+
// ../events/dist/owner-wait-answer.js
|
|
19554
|
+
var OWNER_WAIT_SHORT_ID_LENGTH = 8;
|
|
19555
|
+
var ownerWaitShortIdSchema = external_exports.string().regex(/^[0-9a-f]{8}$/);
|
|
19556
|
+
function ownerWaitShortIdOf(declarationId) {
|
|
19557
|
+
return declarationId.slice(0, OWNER_WAIT_SHORT_ID_LENGTH).toLowerCase();
|
|
19369
19558
|
}
|
|
19370
|
-
var
|
|
19371
|
-
|
|
19372
|
-
|
|
19373
|
-
|
|
19374
|
-
at: utcIso8601
|
|
19375
|
-
}).strict();
|
|
19376
|
-
function limitPartLineOf(part, used, limit) {
|
|
19377
|
-
const words = part === "half" ? "half" : part === "three-quarters" ? "three quarters" : "nine tenths";
|
|
19378
|
-
const line2 = `This phase has used ${words} of its usage limit: ${tokenCountWordsOf(used)} of ${tokenCountWordsOf(limit)} tokens.`;
|
|
19379
|
-
return part === "nine-tenths" ? `${line2} New work stops at the limit.` : line2;
|
|
19559
|
+
var OWNER_WAIT_ANSWER_ACTS = ["approve", "decline"];
|
|
19560
|
+
var ownerWaitAnswerActSchema = external_exports.enum(OWNER_WAIT_ANSWER_ACTS);
|
|
19561
|
+
function ownerWaitApproveLineOf(declarationId) {
|
|
19562
|
+
return `approve wait ${ownerWaitShortIdOf(declarationId)}`;
|
|
19380
19563
|
}
|
|
19381
|
-
function
|
|
19382
|
-
|
|
19383
|
-
const finish = working === 0 ? "" : working === 1 ? " The 1 agent already working will finish its task." : ` The ${String(working)} agents already working will finish their tasks.`;
|
|
19384
|
-
return `${head}${finish} Say "keep going" to raise the limit by about ${tokenCountWordsOf(raiseBy)} tokens and carry on, or "stop" to leave the phase paused here. Nothing is lost either way.`;
|
|
19564
|
+
function ownerWaitDeclineLineOf(declarationId) {
|
|
19565
|
+
return `decline wait ${ownerWaitShortIdOf(declarationId)}: <why>`;
|
|
19385
19566
|
}
|
|
19386
|
-
|
|
19387
|
-
|
|
19567
|
+
var ownerWaitChatRequestSchema = external_exports.discriminatedUnion("act", [
|
|
19568
|
+
external_exports.object({ act: external_exports.literal("approve"), wait: ownerWaitShortIdSchema }).strict(),
|
|
19569
|
+
external_exports.object({ act: external_exports.literal("decline"), wait: ownerWaitShortIdSchema, note: scopeNoteWireSchema }).strict()
|
|
19570
|
+
]);
|
|
19571
|
+
function bareOutcome3(outcome) {
|
|
19572
|
+
return external_exports.object({ outcome: external_exports.literal(outcome) }).strict();
|
|
19388
19573
|
}
|
|
19574
|
+
var ownerWaitChatResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19575
|
+
external_exports.object({
|
|
19576
|
+
outcome: external_exports.literal("recorded"),
|
|
19577
|
+
act: ownerWaitAnswerActSchema,
|
|
19578
|
+
question: external_exports.string().min(1)
|
|
19579
|
+
}).strict(),
|
|
19580
|
+
external_exports.object({ outcome: external_exports.literal("refused"), problems: external_exports.array(systemDescriptionProblemSchema).min(1) }).strict(),
|
|
19581
|
+
bareOutcome3("not-owner"),
|
|
19582
|
+
bareOutcome3("no-owner"),
|
|
19583
|
+
bareOutcome3("not-found"),
|
|
19584
|
+
bareOutcome3("ambiguous"),
|
|
19585
|
+
bareOutcome3("not-offered"),
|
|
19586
|
+
bareOutcome3("unavailable")
|
|
19587
|
+
]);
|
|
19588
|
+
|
|
19589
|
+
// ../events/dist/owner-waits.js
|
|
19590
|
+
var OWNER_WAIT_ITEMS = Object.freeze([
|
|
19591
|
+
Object.freeze({ id: "delete-users-data", words: "Deleting or replacing data people already have." }),
|
|
19592
|
+
Object.freeze({
|
|
19593
|
+
id: "change-promises",
|
|
19594
|
+
words: "Changing what the product promises its users, such as pricing, terms or privacy."
|
|
19595
|
+
}),
|
|
19596
|
+
Object.freeze({ id: "spend-or-sign-up", words: "Anything that costs money or signs up for a service." }),
|
|
19597
|
+
Object.freeze({ id: "publish-or-release", words: "Publishing or releasing to users." }),
|
|
19598
|
+
Object.freeze({ id: "reshape-shared-data", words: "Dropping or reshaping stored data that other parts read." }),
|
|
19599
|
+
Object.freeze({ id: "change-standing-rule", words: "Changing a standing rule." })
|
|
19600
|
+
]);
|
|
19601
|
+
var OWNER_WAIT_ITEM_IDS = Object.freeze(OWNER_WAIT_ITEMS.map((item) => item.id));
|
|
19602
|
+
var ownerWaitItemIdSchema = external_exports.enum(OWNER_WAIT_ITEM_IDS);
|
|
19603
|
+
var OWNER_WAIT_FIXED_COUNT = OWNER_WAIT_ITEMS.length;
|
|
19604
|
+
var OWNER_WAIT_ADDITIONS_MAX = 20;
|
|
19605
|
+
var OWNER_WAIT_TEXT_MAX = 240;
|
|
19606
|
+
var ownerWaitItemRefSchema = external_exports.union([
|
|
19607
|
+
external_exports.number().int().min(1),
|
|
19608
|
+
external_exports.string().uuid({ message: "must be a number from 1 to 6, or the id shown beside an added item" })
|
|
19609
|
+
]);
|
|
19610
|
+
var ownerWaitText = descriptionText(OWNER_WAIT_TEXT_MAX);
|
|
19611
|
+
var ownerWaitAddRequestSchema = external_exports.object({
|
|
19612
|
+
engagementId: external_exports.string().min(1),
|
|
19613
|
+
text: ownerWaitText,
|
|
19614
|
+
reason: ownerWaitText
|
|
19615
|
+
}).strict();
|
|
19616
|
+
var ownerWaitAddResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19617
|
+
external_exports.object({ outcome: external_exports.literal("added"), id: external_exports.string().uuid(), addedAt: utcIso8601 }).strict(),
|
|
19618
|
+
external_exports.object({ outcome: external_exports.literal("refused"), reason: external_exports.literal("too-many") }).strict()
|
|
19619
|
+
]);
|
|
19620
|
+
var ownerWaitUndoableSchema = external_exports.enum(["yes", "no"]);
|
|
19621
|
+
var ownerWaitDeclareRequestSchema = external_exports.object({
|
|
19622
|
+
engagementId: external_exports.string().min(1),
|
|
19623
|
+
item: ownerWaitItemRefSchema,
|
|
19624
|
+
question: ownerWaitText,
|
|
19625
|
+
recommendation: ownerWaitText,
|
|
19626
|
+
task: buildTaskIdSchema.optional(),
|
|
19627
|
+
by: agentNameSchema.optional(),
|
|
19628
|
+
undoable: ownerWaitUndoableSchema.optional(),
|
|
19629
|
+
how: statementText(STATEMENT_MAX).optional()
|
|
19630
|
+
}).strict().refine((r) => r.undoable === "yes" === (r.how !== void 0), {
|
|
19631
|
+
message: "says how to undo it exactly when it can be undone",
|
|
19632
|
+
path: ["how"]
|
|
19633
|
+
});
|
|
19634
|
+
var OWNER_WAIT_DECLARE_REFUSALS = ["no-open-phase", "unknown-item", "say-if-undoable"];
|
|
19635
|
+
var ownerWaitDeclareResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
19636
|
+
external_exports.object({ outcome: external_exports.literal("recorded"), id: external_exports.string().uuid(), say: external_exports.string().min(1) }).strict(),
|
|
19637
|
+
external_exports.object({
|
|
19638
|
+
outcome: external_exports.literal("go-ahead"),
|
|
19639
|
+
id: external_exports.string().uuid(),
|
|
19640
|
+
callId: external_exports.number().int().positive(),
|
|
19641
|
+
say: external_exports.string().min(1)
|
|
19642
|
+
}).strict(),
|
|
19643
|
+
external_exports.object({ outcome: external_exports.literal("refused"), reason: external_exports.enum(OWNER_WAIT_DECLARE_REFUSALS) }).strict()
|
|
19644
|
+
]);
|
|
19645
|
+
var ownerWaitAddedItemSchema = external_exports.object({
|
|
19646
|
+
id: external_exports.string().uuid(),
|
|
19647
|
+
words: external_exports.string().min(1),
|
|
19648
|
+
reason: external_exports.string().min(1),
|
|
19649
|
+
addedAt: utcIso8601
|
|
19650
|
+
}).strict();
|
|
19651
|
+
var ownerWaitListSchema = external_exports.object({
|
|
19652
|
+
fixed: external_exports.array(external_exports.object({ id: ownerWaitItemIdSchema, words: external_exports.string().min(1) }).strict()).length(OWNER_WAIT_FIXED_COUNT),
|
|
19653
|
+
added: external_exports.array(ownerWaitAddedItemSchema).max(OWNER_WAIT_ADDITIONS_MAX)
|
|
19654
|
+
}).strict();
|
|
19655
|
+
var ownerWaitDeclarationSchema = external_exports.object({
|
|
19656
|
+
id: external_exports.string().uuid(),
|
|
19657
|
+
fixedItem: ownerWaitItemIdSchema.nullable(),
|
|
19658
|
+
addition: external_exports.object({ id: external_exports.string().uuid(), words: external_exports.string().min(1) }).strict().nullable(),
|
|
19659
|
+
question: external_exports.string().min(1),
|
|
19660
|
+
recommendation: external_exports.string().min(1),
|
|
19661
|
+
task: buildTaskIdSchema.nullable(),
|
|
19662
|
+
declaredAt: utcIso8601
|
|
19663
|
+
}).strict().refine((d) => d.fixedItem === null !== (d.addition === null), {
|
|
19664
|
+
message: "names exactly one item: a fixed one or an added one",
|
|
19665
|
+
path: ["fixedItem"]
|
|
19666
|
+
});
|
|
19667
|
+
var ownerWaitDeclarationsSchema = external_exports.object({ declarations: external_exports.array(ownerWaitDeclarationSchema) }).strict();
|
|
19668
|
+
var ownerWaitOpenSchema = external_exports.object({
|
|
19669
|
+
wait: ownerWaitShortIdSchema,
|
|
19670
|
+
task: buildTaskIdSchema.nullable(),
|
|
19671
|
+
question: external_exports.string().min(1),
|
|
19672
|
+
recommendation: external_exports.string().min(1),
|
|
19673
|
+
declaredAt: utcIso8601
|
|
19674
|
+
}).strict();
|
|
19675
|
+
var ownerWaitsOpenSchema = external_exports.object({ waits: external_exports.array(ownerWaitOpenSchema) }).strict();
|
|
19676
|
+
var OWNER_WAIT_TOO_MANY = `This project already has ${String(OWNER_WAIT_ADDITIONS_MAX)} things added to what waits for the owner. Ask the owner to take one off on their settings page in the console first; it cannot be done by typing in chat.`;
|
|
19389
19677
|
|
|
19390
19678
|
// ../events/dist/autonomy.js
|
|
19391
19679
|
var AUTONOMY_CHANGED_IN = ["console", "chat"];
|
|
@@ -21569,6 +21857,110 @@ function toAstShapes(markers) {
|
|
|
21569
21857
|
// dist/extract/context.js
|
|
21570
21858
|
import { readFileSync as readFileSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
21571
21859
|
import { join as join4, relative as relative2, sep } from "node:path";
|
|
21860
|
+
|
|
21861
|
+
// dist/extract/repo-facts.js
|
|
21862
|
+
var DATABASE_FILE = /\.sql$|^schema\.prisma$|^drizzle\.config\.|^alembic\.ini$|^knexfile\./i;
|
|
21863
|
+
var BROWSER_FILE = /\.(tsx|jsx|vue|svelte|astro)$|^index\.html$|^(next|vite|nuxt|svelte|astro)\.config\.|^angular\.json$/i;
|
|
21864
|
+
var WEBHOOK_NAME = /webhook/i;
|
|
21865
|
+
var DATABASE_DEPS = /* @__PURE__ */ new Set([
|
|
21866
|
+
"pg",
|
|
21867
|
+
"mysql",
|
|
21868
|
+
"mysql2",
|
|
21869
|
+
"mongodb",
|
|
21870
|
+
"mongoose",
|
|
21871
|
+
"sqlite3",
|
|
21872
|
+
"better-sqlite3",
|
|
21873
|
+
"prisma",
|
|
21874
|
+
"@prisma/client",
|
|
21875
|
+
"drizzle-orm",
|
|
21876
|
+
"typeorm",
|
|
21877
|
+
"sequelize",
|
|
21878
|
+
"knex",
|
|
21879
|
+
"postgres",
|
|
21880
|
+
"psycopg",
|
|
21881
|
+
"psycopg2",
|
|
21882
|
+
"sqlalchemy",
|
|
21883
|
+
"pymysql",
|
|
21884
|
+
"asyncpg",
|
|
21885
|
+
"pymongo",
|
|
21886
|
+
"github.com/lib/pq",
|
|
21887
|
+
"github.com/jackc/pgx",
|
|
21888
|
+
"github.com/go-sql-driver/mysql",
|
|
21889
|
+
"gorm.io/gorm",
|
|
21890
|
+
"diesel",
|
|
21891
|
+
"sqlx",
|
|
21892
|
+
"activerecord"
|
|
21893
|
+
]);
|
|
21894
|
+
var BROWSER_DEPS = /* @__PURE__ */ new Set([
|
|
21895
|
+
"react",
|
|
21896
|
+
"react-dom",
|
|
21897
|
+
"next",
|
|
21898
|
+
"vue",
|
|
21899
|
+
"nuxt",
|
|
21900
|
+
"svelte",
|
|
21901
|
+
"@sveltejs/kit",
|
|
21902
|
+
"@angular/core",
|
|
21903
|
+
"solid-js",
|
|
21904
|
+
"preact",
|
|
21905
|
+
"astro",
|
|
21906
|
+
"vite"
|
|
21907
|
+
]);
|
|
21908
|
+
var MANIFEST_NAMES = /* @__PURE__ */ new Set(["package.json", "go.mod", "requirements.txt", "pyproject.toml", "Gemfile", "Cargo.toml"]);
|
|
21909
|
+
function isFactManifest(fileName) {
|
|
21910
|
+
return MANIFEST_NAMES.has(fileName);
|
|
21911
|
+
}
|
|
21912
|
+
function newFactCollector() {
|
|
21913
|
+
return { found: /* @__PURE__ */ new Set() };
|
|
21914
|
+
}
|
|
21915
|
+
function noteFileName(c, fileName, underDocs) {
|
|
21916
|
+
if (underDocs)
|
|
21917
|
+
return;
|
|
21918
|
+
if (DATABASE_FILE.test(fileName))
|
|
21919
|
+
c.found.add("database");
|
|
21920
|
+
if (BROWSER_FILE.test(fileName))
|
|
21921
|
+
c.found.add("browser-app");
|
|
21922
|
+
if (WEBHOOK_NAME.test(fileName))
|
|
21923
|
+
c.found.add("inbound-webhooks");
|
|
21924
|
+
}
|
|
21925
|
+
function noteDirName(c, dirName, underDocs) {
|
|
21926
|
+
if (underDocs)
|
|
21927
|
+
return;
|
|
21928
|
+
if (WEBHOOK_NAME.test(dirName))
|
|
21929
|
+
c.found.add("inbound-webhooks");
|
|
21930
|
+
if (dirName === "migrations")
|
|
21931
|
+
c.found.add("database");
|
|
21932
|
+
}
|
|
21933
|
+
function dependencyNames(fileName, content) {
|
|
21934
|
+
if (fileName === "package.json") {
|
|
21935
|
+
try {
|
|
21936
|
+
const parsed = JSON.parse(content);
|
|
21937
|
+
const names = [];
|
|
21938
|
+
for (const key of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
21939
|
+
const block = parsed[key];
|
|
21940
|
+
if (block !== null && typeof block === "object")
|
|
21941
|
+
names.push(...Object.keys(block));
|
|
21942
|
+
}
|
|
21943
|
+
return names;
|
|
21944
|
+
} catch {
|
|
21945
|
+
return [];
|
|
21946
|
+
}
|
|
21947
|
+
}
|
|
21948
|
+
return content.split(/[\s"'=<>~^,;:\[\]()]+/).filter((t) => t.length > 0);
|
|
21949
|
+
}
|
|
21950
|
+
function noteManifest(c, fileName, content) {
|
|
21951
|
+
for (const name of dependencyNames(fileName, content)) {
|
|
21952
|
+
const lower = name.toLowerCase();
|
|
21953
|
+
if (DATABASE_DEPS.has(lower))
|
|
21954
|
+
c.found.add("database");
|
|
21955
|
+
if (BROWSER_DEPS.has(lower))
|
|
21956
|
+
c.found.add("browser-app");
|
|
21957
|
+
}
|
|
21958
|
+
}
|
|
21959
|
+
function factsOf(c) {
|
|
21960
|
+
return REPOSITORY_FACTS.filter((f) => c.found.has(f));
|
|
21961
|
+
}
|
|
21962
|
+
|
|
21963
|
+
// dist/extract/context.js
|
|
21572
21964
|
var EXCLUDED_DIRS2 = /* @__PURE__ */ new Set([
|
|
21573
21965
|
"node_modules",
|
|
21574
21966
|
".git",
|
|
@@ -21582,6 +21974,7 @@ var EXCLUDED_DIRS2 = /* @__PURE__ */ new Set([
|
|
|
21582
21974
|
"coverage",
|
|
21583
21975
|
".cache"
|
|
21584
21976
|
]);
|
|
21977
|
+
var PROSE_DIRS = /* @__PURE__ */ new Set(["docs", "skills", "runbooks", "method"]);
|
|
21585
21978
|
function classifyFile(fileName) {
|
|
21586
21979
|
if (fileName === "Dockerfile" || fileName.startsWith("Dockerfile."))
|
|
21587
21980
|
return "dockerfile";
|
|
@@ -21591,7 +21984,7 @@ function classifyFile(fileName) {
|
|
|
21591
21984
|
return "env-example";
|
|
21592
21985
|
return null;
|
|
21593
21986
|
}
|
|
21594
|
-
function walk(dir, repoRoot, acc) {
|
|
21987
|
+
function walk(dir, repoRoot, acc, facts, underDocs = false) {
|
|
21595
21988
|
let entries;
|
|
21596
21989
|
try {
|
|
21597
21990
|
entries = readdirSync2(dir, { withFileTypes: true });
|
|
@@ -21602,11 +21995,21 @@ function walk(dir, repoRoot, acc) {
|
|
|
21602
21995
|
if (entry.isDirectory()) {
|
|
21603
21996
|
if (EXCLUDED_DIRS2.has(entry.name))
|
|
21604
21997
|
continue;
|
|
21605
|
-
|
|
21998
|
+
const lower = entry.name.toLowerCase();
|
|
21999
|
+
noteDirName(facts, lower, underDocs);
|
|
22000
|
+
walk(join4(dir, entry.name), repoRoot, acc, facts, underDocs || PROSE_DIRS.has(lower));
|
|
21606
22001
|
continue;
|
|
21607
22002
|
}
|
|
21608
22003
|
if (!entry.isFile())
|
|
21609
22004
|
continue;
|
|
22005
|
+
noteFileName(facts, entry.name, underDocs);
|
|
22006
|
+
if (!underDocs && isFactManifest(entry.name)) {
|
|
22007
|
+
try {
|
|
22008
|
+
noteManifest(facts, entry.name, readFileSync4(join4(dir, entry.name), "utf-8"));
|
|
22009
|
+
} catch {
|
|
22010
|
+
continue;
|
|
22011
|
+
}
|
|
22012
|
+
}
|
|
21610
22013
|
const kind = classifyFile(entry.name);
|
|
21611
22014
|
if (!kind)
|
|
21612
22015
|
continue;
|
|
@@ -21626,8 +22029,9 @@ function loadChangeSetContext(repoRoot) {
|
|
|
21626
22029
|
if (cached2)
|
|
21627
22030
|
return cached2;
|
|
21628
22031
|
const declarationFiles = [];
|
|
21629
|
-
|
|
21630
|
-
|
|
22032
|
+
const facts = newFactCollector();
|
|
22033
|
+
walk(repoRoot, repoRoot, declarationFiles, facts);
|
|
22034
|
+
const context = { declarationFiles, repoRoot, repoFacts: factsOf(facts) };
|
|
21631
22035
|
cache.set(repoRoot, context);
|
|
21632
22036
|
return context;
|
|
21633
22037
|
}
|
|
@@ -21722,6 +22126,7 @@ function buildGuardEvalRun(opts) {
|
|
|
21722
22126
|
...opts.failureReason !== void 0 ? { failureReason: opts.failureReason } : {},
|
|
21723
22127
|
phase: opts.phase,
|
|
21724
22128
|
scope,
|
|
22129
|
+
...opts.repoFacts !== void 0 ? { repoFacts: [...opts.repoFacts] } : {},
|
|
21725
22130
|
// cost is optional (D6: live cost signal lands later; ingest works without it)
|
|
21726
22131
|
// result present IFF the run was evaluated (schema-enforced refinement).
|
|
21727
22132
|
...opts.outcome === "evaluated" && opts.result !== void 0 ? { result: opts.result } : {}
|
|
@@ -21741,7 +22146,8 @@ async function emitRunRecord(opts) {
|
|
|
21741
22146
|
outcome: opts.outcome,
|
|
21742
22147
|
failureReason: opts.failureReason,
|
|
21743
22148
|
changeSet: opts.changeSet,
|
|
21744
|
-
diffBase: opts.diffBase
|
|
22149
|
+
diffBase: opts.diffBase,
|
|
22150
|
+
repoFacts: opts.repoFacts
|
|
21745
22151
|
});
|
|
21746
22152
|
await emitTelemetry(run, {
|
|
21747
22153
|
controlTelemetryUrl: telemetryConfig.controlTelemetryUrl,
|
|
@@ -21807,7 +22213,8 @@ async function runCi() {
|
|
|
21807
22213
|
runType: "ci",
|
|
21808
22214
|
outcome: acquired.kind === "contract" ? "contract-error" : "infra-error",
|
|
21809
22215
|
failureReason: `ci credential: ${acquired.kind}: ${acquired.message}`,
|
|
21810
|
-
changeSet
|
|
22216
|
+
changeSet,
|
|
22217
|
+
repoFacts: context.repoFacts
|
|
21811
22218
|
});
|
|
21812
22219
|
process.stderr.write(credentialExchangeFailureMessage(acquired));
|
|
21813
22220
|
return 1;
|
|
@@ -21822,7 +22229,7 @@ async function runCi() {
|
|
|
21822
22229
|
}
|
|
21823
22230
|
}
|
|
21824
22231
|
if (!configResult.config) {
|
|
21825
|
-
await emitRunRecord({ runType: "ci", outcome: "unconfigured", changeSet });
|
|
22232
|
+
await emitRunRecord({ runType: "ci", outcome: "unconfigured", changeSet, repoFacts: context.repoFacts });
|
|
21826
22233
|
process.stderr.write(isHalfcycleOwnCi() ? ciNeverConfiguredMessage() : CI_NOT_SUPPORTED_MESSAGE);
|
|
21827
22234
|
return 1;
|
|
21828
22235
|
}
|
|
@@ -21839,6 +22246,7 @@ async function evaluateAndAct(args2) {
|
|
|
21839
22246
|
outcome: outcomeForClientFailure(clientResult.kind),
|
|
21840
22247
|
failureReason: failure.reason,
|
|
21841
22248
|
changeSet,
|
|
22249
|
+
repoFacts: context.repoFacts,
|
|
21842
22250
|
credentialRefused: failure.kind === "credential"
|
|
21843
22251
|
});
|
|
21844
22252
|
if (failure.kind === "credential") {
|
|
@@ -21865,6 +22273,7 @@ async function evaluateAndAct(args2) {
|
|
|
21865
22273
|
phase: telemetryConfig.phase,
|
|
21866
22274
|
outcome: "evaluated",
|
|
21867
22275
|
changeSet,
|
|
22276
|
+
repoFacts: context.repoFacts,
|
|
21868
22277
|
result: clientResult.envelope
|
|
21869
22278
|
});
|
|
21870
22279
|
await emitTelemetry(run, {
|
|
@@ -24230,19 +24639,19 @@ function settled(dir, file2, tokens) {
|
|
|
24230
24639
|
writePhaseLimit(dir, next);
|
|
24231
24640
|
return next;
|
|
24232
24641
|
}
|
|
24233
|
-
function turnEndLimitLine(file2, tokens, working) {
|
|
24642
|
+
function turnEndLimitLine(file2, tokens, working, weekCeilingTokens = null) {
|
|
24234
24643
|
if (file2.awaiting) {
|
|
24235
24644
|
if (file2.shown.includes("limit"))
|
|
24236
24645
|
return { text: null, file: file2 };
|
|
24237
24646
|
return {
|
|
24238
|
-
text: limitReachedLineOf(
|
|
24647
|
+
text: limitReachedLineOf({ limit: file2.limit, working, weekCeilingTokens }),
|
|
24239
24648
|
file: { ...file2, shown: [...LIMIT_PARTS] }
|
|
24240
24649
|
};
|
|
24241
24650
|
}
|
|
24242
24651
|
const r = partsReached(tokens, file2.limit, file2.shown);
|
|
24243
24652
|
if (r.show === null)
|
|
24244
24653
|
return { text: null, file: file2 };
|
|
24245
|
-
return { text: limitPartLineOf(r.show, tokens,
|
|
24654
|
+
return { text: limitPartLineOf(r.show, tokens, weekCeilingTokens), file: { ...file2, shown: r.shown } };
|
|
24246
24655
|
}
|
|
24247
24656
|
function openPhaseLimit(dir, remembered) {
|
|
24248
24657
|
if (remembered !== null && remembered.phase === null)
|
|
@@ -26481,7 +26890,7 @@ async function evaluateEdit(reply, readSeat, at, profile) {
|
|
|
26481
26890
|
});
|
|
26482
26891
|
const configResult = readConfig();
|
|
26483
26892
|
if (!configResult.config) {
|
|
26484
|
-
await emitRunRecord({ runType: "hook", outcome: "unconfigured", changeSet });
|
|
26893
|
+
await emitRunRecord({ runType: "hook", outcome: "unconfigured", changeSet, repoFacts: context.repoFacts });
|
|
26485
26894
|
if (!firstNoticeThisSession("credential-missing", repoRoot, input.session_id))
|
|
26486
26895
|
return;
|
|
26487
26896
|
emitNeverConfigured(UNCONFIGURED_EXIT_TOOL_USE, readNeverConfiguredReason(), pinnedEngagementId(projectFolder()), reply);
|
|
@@ -26505,6 +26914,7 @@ async function evaluateEdit(reply, readSeat, at, profile) {
|
|
|
26505
26914
|
outcome: outcomeForClientFailure(clientResult.kind),
|
|
26506
26915
|
failureReason: failure.reason,
|
|
26507
26916
|
changeSet,
|
|
26917
|
+
repoFacts: context.repoFacts,
|
|
26508
26918
|
credential: evaluation.token,
|
|
26509
26919
|
credentialRefused: failure.kind === "credential"
|
|
26510
26920
|
});
|
|
@@ -26539,6 +26949,7 @@ async function evaluateEdit(reply, readSeat, at, profile) {
|
|
|
26539
26949
|
phase: telemetryConfig.phase,
|
|
26540
26950
|
outcome: "evaluated",
|
|
26541
26951
|
changeSet,
|
|
26952
|
+
repoFacts: context.repoFacts,
|
|
26542
26953
|
result: clientResult.envelope
|
|
26543
26954
|
});
|
|
26544
26955
|
await emitTelemetry(run, {
|
|
@@ -26786,29 +27197,171 @@ function runsBesideOtherWork(toolInput, record2) {
|
|
|
26786
27197
|
}
|
|
26787
27198
|
|
|
26788
27199
|
// dist/pace-hook.js
|
|
26789
|
-
import { mkdirSync as
|
|
26790
|
-
import
|
|
27200
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync21, renameSync as renameSync11, unlinkSync as unlinkSync8, writeFileSync as writeFileSync13 } from "node:fs";
|
|
27201
|
+
import nodePath6 from "node:path";
|
|
26791
27202
|
|
|
26792
27203
|
// dist/pace-verb.js
|
|
26793
|
-
import { mkdirSync as
|
|
27204
|
+
import { mkdirSync as mkdirSync8, readdirSync as readdirSync8, readFileSync as readFileSync20, renameSync as renameSync10, statSync as statSync6, writeFileSync as writeFileSync12 } from "node:fs";
|
|
26794
27205
|
import { homedir as homedir9 } from "node:os";
|
|
27206
|
+
import nodePath5 from "node:path";
|
|
27207
|
+
|
|
27208
|
+
// dist/plan-report.js
|
|
27209
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync19, renameSync as renameSync9, writeFileSync as writeFileSync11 } from "node:fs";
|
|
26795
27210
|
import nodePath4 from "node:path";
|
|
26796
|
-
var
|
|
26797
|
-
var
|
|
27211
|
+
var PLAN_REPORT_MIN_INTERVAL_MS = 10 * 60 * 1e3;
|
|
27212
|
+
var PLAN_MIN_GAIN_POINTS = 2;
|
|
27213
|
+
var PLAN_FIRST_READ_FILENAME = "plan-first-read.json";
|
|
27214
|
+
var PLAN_DERIVED_FILENAME = "plan-derived-ceiling.json";
|
|
27215
|
+
var PLAN_REPORT_THROTTLE_FILENAME = "plan-report.json";
|
|
27216
|
+
function isNum2(v) {
|
|
27217
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
27218
|
+
}
|
|
27219
|
+
function isTime(v) {
|
|
27220
|
+
return typeof v === "string" && !Number.isNaN(Date.parse(v));
|
|
27221
|
+
}
|
|
27222
|
+
function readAccounts(path) {
|
|
27223
|
+
try {
|
|
27224
|
+
const v = JSON.parse(readFileSync19(path, "utf-8"));
|
|
27225
|
+
const accounts = typeof v === "object" && v !== null ? v["accounts"] : void 0;
|
|
27226
|
+
return typeof accounts === "object" && accounts !== null && !Array.isArray(accounts) ? { ...accounts } : {};
|
|
27227
|
+
} catch {
|
|
27228
|
+
return {};
|
|
27229
|
+
}
|
|
27230
|
+
}
|
|
27231
|
+
function writeAccount(path, key, entry) {
|
|
27232
|
+
const accounts = readAccounts(path);
|
|
27233
|
+
accounts[key] = entry;
|
|
27234
|
+
mkdirSync7(nodePath4.dirname(path), { recursive: true, mode: 448 });
|
|
27235
|
+
const tmp = `${path}.${String(process.pid)}.${Math.random().toString(36).slice(2, 10)}.tmp`;
|
|
27236
|
+
writeFileSync11(tmp, JSON.stringify({ accounts }), { mode: 384 });
|
|
27237
|
+
renameSync9(tmp, path);
|
|
27238
|
+
}
|
|
27239
|
+
function firstReadOf(key, home) {
|
|
27240
|
+
const v = readAccounts(nodePath4.join(pacingDir(home), PLAN_FIRST_READ_FILENAME))[key];
|
|
27241
|
+
if (typeof v !== "object" || v === null)
|
|
27242
|
+
return null;
|
|
27243
|
+
const o = v;
|
|
27244
|
+
return isNum2(o["usedPercent"]) && isTime(o["resetsAt"]) && isTime(o["at"]) ? { usedPercent: o["usedPercent"], resetsAt: o["resetsAt"], at: o["at"] } : null;
|
|
27245
|
+
}
|
|
27246
|
+
function derivedOf(key, home) {
|
|
27247
|
+
const v = readAccounts(nodePath4.join(pacingDir(home), PLAN_DERIVED_FILENAME))[key];
|
|
27248
|
+
if (typeof v !== "object" || v === null)
|
|
27249
|
+
return null;
|
|
27250
|
+
const o = v;
|
|
27251
|
+
return isNum2(o["tokens"]) && Number.isInteger(o["tokens"]) && o["tokens"] > 0 && isTime(o["resetsAt"]) ? { tokens: o["tokens"], resetsAt: o["resetsAt"] } : null;
|
|
27252
|
+
}
|
|
27253
|
+
function weeklyCeilingOf(key, deps = {}) {
|
|
27254
|
+
const learned = readLearnedAccount(key, deps)?.ceilings["seven-day"];
|
|
27255
|
+
if (learned !== void 0)
|
|
27256
|
+
return learned.tokens;
|
|
27257
|
+
const week = readReportedAccount(key, deps)["seven-day"];
|
|
27258
|
+
const derived = derivedOf(key, deps.home);
|
|
27259
|
+
if (week === void 0 || derived === null)
|
|
27260
|
+
return null;
|
|
27261
|
+
return Date.parse(derived.resetsAt) === Date.parse(week.resetsAt) ? derived.tokens : null;
|
|
27262
|
+
}
|
|
27263
|
+
function derivedBetweenReads(key, week, deps, nowMs) {
|
|
27264
|
+
const first = firstReadOf(key, deps.home);
|
|
27265
|
+
if (first === null || Date.parse(first.resetsAt) !== Date.parse(week.resetsAt)) {
|
|
27266
|
+
const thisRead = { usedPercent: week.usedPercentage, resetsAt: week.resetsAt, at: week.savedAt };
|
|
27267
|
+
writeAccount(nodePath4.join(pacingDir(deps.home), PLAN_FIRST_READ_FILENAME), key, thisRead);
|
|
27268
|
+
return null;
|
|
27269
|
+
}
|
|
27270
|
+
if (deps.configFolder === "codex-home")
|
|
27271
|
+
return null;
|
|
27272
|
+
const gain = week.usedPercentage - first.usedPercent;
|
|
27273
|
+
if (gain < PLAN_MIN_GAIN_POINTS)
|
|
27274
|
+
return null;
|
|
27275
|
+
if (readLearnedAccount(key, { home: deps.home }) === null)
|
|
27276
|
+
return null;
|
|
27277
|
+
const scanned = scanUnderLock(key, { ...deps.home === void 0 ? {} : { home: deps.home }, now: () => new Date(nowMs) }, 0);
|
|
27278
|
+
if (scanned === null)
|
|
27279
|
+
return null;
|
|
27280
|
+
const fromSec = Math.floor(Date.parse(first.at) / 1e3);
|
|
27281
|
+
const toSec = Math.floor(Date.parse(week.savedAt) / 1e3);
|
|
27282
|
+
if (!(toSec > fromSec) || scanned.coveredFrom > fromSec)
|
|
27283
|
+
return null;
|
|
27284
|
+
const tokens = tokensBetween(scanned.minutes, fromSec, toSec);
|
|
27285
|
+
if (!(tokens > 0))
|
|
27286
|
+
return null;
|
|
27287
|
+
const ceiling = Math.round(tokens * 100 / gain);
|
|
27288
|
+
return ceiling > 0 ? ceiling : null;
|
|
27289
|
+
}
|
|
27290
|
+
async function planUsageReport(input, deps = {}) {
|
|
27291
|
+
try {
|
|
27292
|
+
const code = process.exitCode;
|
|
27293
|
+
if (code !== void 0 && code !== null && Number(code) !== 0)
|
|
27294
|
+
return;
|
|
27295
|
+
const env = deps.env ?? process.env;
|
|
27296
|
+
const configured = readConfig(env);
|
|
27297
|
+
if (configured.config === null)
|
|
27298
|
+
return;
|
|
27299
|
+
const { guardEngagementId: engagementId, guardServiceToken: token } = configured.config;
|
|
27300
|
+
const dir = enginePacingDir(engagementId, deps.home);
|
|
27301
|
+
if (dir === null)
|
|
27302
|
+
return;
|
|
27303
|
+
const nowMs = (deps.now ?? Date.now)();
|
|
27304
|
+
const said = typeof input === "object" && input !== null ? input["transcript_path"] : void 0;
|
|
27305
|
+
const key = configFolderKey({
|
|
27306
|
+
env,
|
|
27307
|
+
transcriptPath: typeof said === "string" && said !== "" ? said : null,
|
|
27308
|
+
home: deps.home,
|
|
27309
|
+
rule: deps.configFolder
|
|
27310
|
+
});
|
|
27311
|
+
const throttlePath = nodePath4.join(dir, PLAN_REPORT_THROTTLE_FILENAME);
|
|
27312
|
+
const last = readAccounts(throttlePath)[key];
|
|
27313
|
+
if (isNum2(last) && nowMs >= last && nowMs - last < PLAN_REPORT_MIN_INTERVAL_MS)
|
|
27314
|
+
return;
|
|
27315
|
+
writeAccount(throttlePath, key, nowMs);
|
|
27316
|
+
const now = new Date(nowMs);
|
|
27317
|
+
if (deps.configFolder === "codex-home")
|
|
27318
|
+
refreshCodexWindows(key, { home: deps.home, now: () => now });
|
|
27319
|
+
const reported = readReportedAccount(key, { home: deps.home });
|
|
27320
|
+
const five = reported["five-hour"];
|
|
27321
|
+
const week = reported["seven-day"];
|
|
27322
|
+
const freshWeek = reportedFresh(week, now) ? week : void 0;
|
|
27323
|
+
let ceiling = null;
|
|
27324
|
+
if (freshWeek !== void 0) {
|
|
27325
|
+
const learned = readLearnedAccount(key, { home: deps.home })?.ceilings["seven-day"];
|
|
27326
|
+
ceiling = weeklyCeilingOf(key, { home: deps.home });
|
|
27327
|
+
let derived = null;
|
|
27328
|
+
if (learned === void 0) {
|
|
27329
|
+
try {
|
|
27330
|
+
derived = derivedBetweenReads(key, freshWeek, deps, nowMs);
|
|
27331
|
+
} catch {
|
|
27332
|
+
derived = null;
|
|
27333
|
+
}
|
|
27334
|
+
}
|
|
27335
|
+
if (derived !== null) {
|
|
27336
|
+
try {
|
|
27337
|
+
writeAccount(nodePath4.join(pacingDir(deps.home), PLAN_DERIVED_FILENAME), key, { tokens: derived, resetsAt: freshWeek.resetsAt });
|
|
27338
|
+
} catch {
|
|
27339
|
+
}
|
|
27340
|
+
ceiling = derived;
|
|
27341
|
+
}
|
|
27342
|
+
}
|
|
27343
|
+
const report = {
|
|
27344
|
+
fiveHour: reportedFresh(five, now) ? { usedPercent: five.usedPercentage, resetsAt: five.resetsAt } : null,
|
|
27345
|
+
week: freshWeek === void 0 ? null : { usedPercent: freshWeek.usedPercentage, resetsAt: freshWeek.resetsAt, ceilingTokens: ceiling },
|
|
27346
|
+
readAt: now.toISOString()
|
|
27347
|
+
};
|
|
27348
|
+
if (!planUsageReportSchema.safeParse(report).success)
|
|
27349
|
+
return;
|
|
27350
|
+
await requestJson(deps.fetchFn ?? globalThis.fetch, `${readControlOrigin(env).origin}/engagements/${encodeURIComponent(engagementId)}/plan-usage`, {
|
|
27351
|
+
method: "PUT",
|
|
27352
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
27353
|
+
body: JSON.stringify(report)
|
|
27354
|
+
}, OBSERVE_REQUEST_DEADLINE_MS);
|
|
27355
|
+
} catch {
|
|
27356
|
+
}
|
|
27357
|
+
}
|
|
27358
|
+
|
|
27359
|
+
// dist/pace-verb.js
|
|
26798
27360
|
var PACE_WINDOW_MINUTES = 300;
|
|
26799
27361
|
var PACE_BASIS_DEADLINE_MS = 5e3;
|
|
26800
27362
|
var PACE_FIRST_READ_WAIT_MS = 10 * 60 * 1e3;
|
|
26801
27363
|
var PACE_LATER_READ_WAIT_MS = 5e3;
|
|
26802
27364
|
var BUILD_NUMBER_FILENAME = "build.json";
|
|
26803
|
-
function taskMinutesOf(task, medianTaskMinutes) {
|
|
26804
|
-
if (task.human)
|
|
26805
|
-
return 0;
|
|
26806
|
-
if (task.budgetMinutes !== void 0)
|
|
26807
|
-
return task.budgetMinutes;
|
|
26808
|
-
if (medianTaskMinutes !== null && medianTaskMinutes > 0)
|
|
26809
|
-
return medianTaskMinutes;
|
|
26810
|
-
return PACE_DEFAULT_TASK_MINUTES;
|
|
26811
|
-
}
|
|
26812
27365
|
function layoutGraph(tasks, agents, medianTaskMinutes) {
|
|
26813
27366
|
const index = /* @__PURE__ */ new Map();
|
|
26814
27367
|
tasks.forEach((t2, i) => {
|
|
@@ -26892,7 +27445,7 @@ function suggestedNumberOf(input) {
|
|
|
26892
27445
|
function suggestPace(input) {
|
|
26893
27446
|
const tasks = input.tasks !== null && input.tasks.length > 0 ? input.tasks : null;
|
|
26894
27447
|
const number4 = input.named !== null ? clampAgents(input.named, PACE_AGENTS_MAX) : suggestedNumberOf(input);
|
|
26895
|
-
const minutes = tasks === null ? null :
|
|
27448
|
+
const minutes = tasks === null ? null : paceDurationRoundedOf(layoutGraph(tasks, number4, input.medianTaskMinutes).minutes);
|
|
26896
27449
|
let pauses = 0;
|
|
26897
27450
|
const ceiling = input.learned?.ceilings["five-hour"];
|
|
26898
27451
|
if (tasks !== null && ceiling !== void 0 && input.medianTaskTokens !== null) {
|
|
@@ -26908,20 +27461,32 @@ function suggestPace(input) {
|
|
|
26908
27461
|
minutes,
|
|
26909
27462
|
pauses,
|
|
26910
27463
|
keepFreePercent: input.keepFreePercent,
|
|
26911
|
-
knownWindow
|
|
27464
|
+
knownWindow,
|
|
27465
|
+
workMinutes: agentWorkMinutesOf(tasks, input.medianTaskMinutes)
|
|
26912
27466
|
};
|
|
26913
27467
|
}
|
|
27468
|
+
function weekCeilingFor(key, home) {
|
|
27469
|
+
try {
|
|
27470
|
+
const tokens = weeklyCeilingOf(key, home === void 0 ? {} : { home });
|
|
27471
|
+
if (tokens === null || !Number.isFinite(tokens))
|
|
27472
|
+
return null;
|
|
27473
|
+
const whole = Math.round(tokens);
|
|
27474
|
+
return whole > 0 ? whole : null;
|
|
27475
|
+
} catch {
|
|
27476
|
+
return null;
|
|
27477
|
+
}
|
|
27478
|
+
}
|
|
26914
27479
|
function enginePacingDir(engagementId, home) {
|
|
26915
27480
|
if (!isEngagementId(engagementId))
|
|
26916
27481
|
return null;
|
|
26917
|
-
return
|
|
27482
|
+
return nodePath5.join(home ?? homedir9(), HALFCYCLE_DIR_NAME, ENGAGEMENTS_DIR_NAME, engagementId, PACING_DIR_NAME);
|
|
26918
27483
|
}
|
|
26919
27484
|
function readBuildNumber(engagementId, home) {
|
|
26920
27485
|
const dir = enginePacingDir(engagementId, home);
|
|
26921
27486
|
if (dir === null)
|
|
26922
27487
|
return null;
|
|
26923
27488
|
try {
|
|
26924
|
-
const v = JSON.parse(
|
|
27489
|
+
const v = JSON.parse(readFileSync20(nodePath5.join(dir, BUILD_NUMBER_FILENAME), "utf-8"));
|
|
26925
27490
|
const n = v["number"];
|
|
26926
27491
|
if (typeof v["phase"] === "string" && typeof n === "number" && Number.isInteger(n) && n >= 1 && n <= PACE_AGENTS_MAX && typeof v["namedByOwner"] === "boolean") {
|
|
26927
27492
|
return { phase: v["phase"], number: n, namedByOwner: v["namedByOwner"] };
|
|
@@ -26938,11 +27503,11 @@ function writeBuildNumber(engagementId, value, home) {
|
|
|
26938
27503
|
const dir = enginePacingDir(engagementId, home);
|
|
26939
27504
|
if (dir === null)
|
|
26940
27505
|
throw new Error("not an engagement id");
|
|
26941
|
-
|
|
26942
|
-
const path =
|
|
27506
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
27507
|
+
const path = nodePath5.join(dir, BUILD_NUMBER_FILENAME);
|
|
26943
27508
|
const tmp = `${path}.${String(process.pid)}.tmp`;
|
|
26944
|
-
|
|
26945
|
-
|
|
27509
|
+
writeFileSync12(tmp, JSON.stringify(value), { mode: 384 });
|
|
27510
|
+
renameSync10(tmp, path);
|
|
26946
27511
|
}
|
|
26947
27512
|
function liveSubAgentsIn(cwd, deps = {}) {
|
|
26948
27513
|
try {
|
|
@@ -26958,7 +27523,7 @@ function liveSubAgentsIn(cwd, deps = {}) {
|
|
|
26958
27523
|
if (p === null || p.key !== key || p.agentId === null)
|
|
26959
27524
|
continue;
|
|
26960
27525
|
try {
|
|
26961
|
-
if (now - statSync6(
|
|
27526
|
+
if (now - statSync6(nodePath5.join(dir, name)).mtimeMs <= LIVE_WINDOW_MS)
|
|
26962
27527
|
n += 1;
|
|
26963
27528
|
} catch {
|
|
26964
27529
|
}
|
|
@@ -27109,6 +27674,8 @@ async function runPaceVerb(args2, deps = {}) {
|
|
|
27109
27674
|
refreshCodexWindows(key, scanDeps);
|
|
27110
27675
|
const learned = codex ? null : readThisAccount(key, scanDeps, stderr);
|
|
27111
27676
|
const reported = readReportedAccount(key, scanDeps);
|
|
27677
|
+
const weekCeilingTokens = weekCeilingFor(key, deps.home);
|
|
27678
|
+
const ceiling = weekCeilingTokens === null ? {} : { weekCeilingTokens };
|
|
27112
27679
|
let number4;
|
|
27113
27680
|
let suggestion;
|
|
27114
27681
|
let limitFile = null;
|
|
@@ -27131,7 +27698,7 @@ async function runPaceVerb(args2, deps = {}) {
|
|
|
27131
27698
|
return { stdout: null, stderr: [...stderr, PACE_ONLY_PERSON_RAISES], code: 2 };
|
|
27132
27699
|
}
|
|
27133
27700
|
const named = parsed.agents ?? kept;
|
|
27134
|
-
suggestion = named === null ? suggested : suggestFor(named);
|
|
27701
|
+
suggestion = { ...named === null ? suggested : suggestFor(named), ...ceiling };
|
|
27135
27702
|
number4 = suggestion.number;
|
|
27136
27703
|
writeBuildNumber(engagementId, { phase: parsed.phase, number: number4, namedByOwner: named !== null }, deps.home);
|
|
27137
27704
|
const limitBasis = basis === null ? null : { tasks: sameGraph ? basis.tasks : [], medianTaskTokens: basis.medianTaskTokens };
|
|
@@ -27185,14 +27752,15 @@ async function runPaceVerb(args2, deps = {}) {
|
|
|
27185
27752
|
...decision.until !== null ? { until: decision.until.toISOString() } : {},
|
|
27186
27753
|
keepFreePercent,
|
|
27187
27754
|
...suggestion !== void 0 ? { suggestion } : {},
|
|
27188
|
-
...limitFile !== null ? { usage: { used: readPhaseUsage(pacingDir2, limitFile.phase), limit: limitFile.limit } } : {},
|
|
27755
|
+
...limitFile !== null ? { usage: { used: readPhaseUsage(pacingDir2, limitFile.phase), limit: limitFile.limit, ...ceiling } } : {},
|
|
27189
27756
|
...atLimit ? {
|
|
27190
27757
|
limit: "reached",
|
|
27191
27758
|
limitHeld: {
|
|
27192
27759
|
used: readPhaseUsage(pacingDir2, limitFile.phase),
|
|
27193
27760
|
limit: limitFile.limit,
|
|
27194
27761
|
raiseBy: estimateOf(limitFile),
|
|
27195
|
-
working: live
|
|
27762
|
+
working: live,
|
|
27763
|
+
...ceiling
|
|
27196
27764
|
}
|
|
27197
27765
|
} : {}
|
|
27198
27766
|
};
|
|
@@ -27217,17 +27785,17 @@ function objectOf2(v) {
|
|
|
27217
27785
|
}
|
|
27218
27786
|
function readJson(path) {
|
|
27219
27787
|
try {
|
|
27220
|
-
return objectOf2(JSON.parse(
|
|
27788
|
+
return objectOf2(JSON.parse(readFileSync21(path, "utf-8")));
|
|
27221
27789
|
} catch {
|
|
27222
27790
|
return null;
|
|
27223
27791
|
}
|
|
27224
27792
|
}
|
|
27225
27793
|
function writeJsonWhole2(path, value) {
|
|
27226
|
-
|
|
27794
|
+
mkdirSync9(nodePath6.dirname(path), { recursive: true, mode: 448 });
|
|
27227
27795
|
const tmp = `${path}.${String(process.pid)}.${Math.random().toString(36).slice(2, 10)}.tmp`;
|
|
27228
27796
|
try {
|
|
27229
|
-
|
|
27230
|
-
|
|
27797
|
+
writeFileSync13(tmp, JSON.stringify(value), { mode: 384 });
|
|
27798
|
+
renameSync11(tmp, path);
|
|
27231
27799
|
} catch (err) {
|
|
27232
27800
|
try {
|
|
27233
27801
|
unlinkSync8(tmp);
|
|
@@ -27340,7 +27908,7 @@ async function paceAtTurnEnd(input, reply, deps = {}) {
|
|
|
27340
27908
|
return;
|
|
27341
27909
|
}
|
|
27342
27910
|
const working = liveCount(readLiveness(field2(input, "session_id"), field2(input, "cwd") ?? process.cwd(), deps.liveness));
|
|
27343
|
-
const limitText = limitAtTurnEnd(dir, basis.phase, read !== null && read.phase === basis.phase ? { tasks: read.tasks, medianTaskTokens: read.medianTaskTokens } : null, working);
|
|
27911
|
+
const limitText = limitAtTurnEnd(dir, basis.phase, read !== null && read.phase === basis.phase ? { tasks: read.tasks, medianTaskTokens: read.medianTaskTokens } : null, working, key, deps.home);
|
|
27344
27912
|
let learned = null;
|
|
27345
27913
|
if (deps.configFolder === "codex-home") {
|
|
27346
27914
|
refreshCodexWindows(key, { home: deps.home, now: () => now });
|
|
@@ -27390,13 +27958,13 @@ async function paceAtTurnEnd(input, reply, deps = {}) {
|
|
|
27390
27958
|
} catch {
|
|
27391
27959
|
}
|
|
27392
27960
|
}
|
|
27393
|
-
function limitAtTurnEnd(dir, phase, basis, working) {
|
|
27961
|
+
function limitAtTurnEnd(dir, phase, basis, working, key, home) {
|
|
27394
27962
|
try {
|
|
27395
27963
|
const tokens = readPhaseUsage(dir, phase);
|
|
27396
27964
|
const file2 = limitInForce(dir, phase, basis, tokens);
|
|
27397
27965
|
if (file2 === null)
|
|
27398
27966
|
return null;
|
|
27399
|
-
const step = turnEndLimitLine(file2, tokens, working);
|
|
27967
|
+
const step = turnEndLimitLine(file2, tokens, working, weekCeilingFor(key, home));
|
|
27400
27968
|
if (step.text === null)
|
|
27401
27969
|
return null;
|
|
27402
27970
|
writePhaseLimit(dir, step.file);
|
|
@@ -27407,7 +27975,7 @@ function limitAtTurnEnd(dir, phase, basis, working) {
|
|
|
27407
27975
|
}
|
|
27408
27976
|
function readStarts(dir) {
|
|
27409
27977
|
const out = {};
|
|
27410
|
-
for (const [key, sessions] of Object.entries(objectOf2(readJson(
|
|
27978
|
+
for (const [key, sessions] of Object.entries(objectOf2(readJson(nodePath6.join(dir, PACE_STARTS_FILENAME))?.["accounts"]) ?? {})) {
|
|
27411
27979
|
const s = {};
|
|
27412
27980
|
for (const [session, list] of Object.entries(objectOf2(sessions) ?? {})) {
|
|
27413
27981
|
if (Array.isArray(list))
|
|
@@ -27435,7 +28003,7 @@ function sleepSync3(ms) {
|
|
|
27435
28003
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
27436
28004
|
}
|
|
27437
28005
|
function underStartsLock(dir, giveUpMs, fn) {
|
|
27438
|
-
const lock =
|
|
28006
|
+
const lock = nodePath6.join(dir, PACE_STARTS_LOCK_FILENAME);
|
|
27439
28007
|
const giveUpAt = Date.now() + giveUpMs;
|
|
27440
28008
|
while (!tryTakeLockFile(lock, PACE_STARTS_LOCK_STALE_MS)) {
|
|
27441
28009
|
if (Date.now() >= giveUpAt)
|
|
@@ -27473,7 +28041,7 @@ function retirePendingStart(input, deps = {}) {
|
|
|
27473
28041
|
if (list === void 0 || list.length === 0)
|
|
27474
28042
|
return false;
|
|
27475
28043
|
list.shift();
|
|
27476
|
-
writeJsonWhole2(
|
|
28044
|
+
writeJsonWhole2(nodePath6.join(where.dir, PACE_STARTS_FILENAME), { accounts: pruneStarts(file2, nowMs) });
|
|
27477
28045
|
return true;
|
|
27478
28046
|
}) ?? false;
|
|
27479
28047
|
} catch {
|
|
@@ -27492,7 +28060,7 @@ function paceHoldText(input, toolInput, deps = {}) {
|
|
|
27492
28060
|
const beside = () => runsBesideOtherWork(toolInput, withoutAgent(record2, field2(input, "agent_id")));
|
|
27493
28061
|
const atLimit = openPhaseLimit(where.dir, stateFile.basis);
|
|
27494
28062
|
if (atLimit !== null && atLimit.awaiting && beside())
|
|
27495
|
-
return limitHeldStartTextOf(atLimit.limit);
|
|
28063
|
+
return limitHeldStartTextOf(atLimit.limit, weekCeilingFor(where.key, deps.home));
|
|
27496
28064
|
const entry = stateFile.accounts[where.key];
|
|
27497
28065
|
if (entry === void 0)
|
|
27498
28066
|
return null;
|
|
@@ -27525,7 +28093,7 @@ function paceHoldText(input, toolInput, deps = {}) {
|
|
|
27525
28093
|
if (live + list.length >= allowance)
|
|
27526
28094
|
return true;
|
|
27527
28095
|
const sessions = { ...file2[where.key] ?? {}, [session]: [...list, nowMs] };
|
|
27528
|
-
writeJsonWhole2(
|
|
28096
|
+
writeJsonWhole2(nodePath6.join(where.dir, PACE_STARTS_FILENAME), { accounts: { ...file2, [where.key]: sessions } });
|
|
27529
28097
|
return false;
|
|
27530
28098
|
});
|
|
27531
28099
|
return pending === true ? held() : null;
|
|
@@ -27536,12 +28104,12 @@ function paceHoldText(input, toolInput, deps = {}) {
|
|
|
27536
28104
|
|
|
27537
28105
|
// dist/risky/account-names.js
|
|
27538
28106
|
import { randomBytes } from "node:crypto";
|
|
27539
|
-
import { mkdirSync as
|
|
28107
|
+
import { mkdirSync as mkdirSync10, readFileSync as readFileSync23, renameSync as renameSync12, rmSync as rmSync3, statSync as statSync8, writeFileSync as writeFileSync14 } from "node:fs";
|
|
27540
28108
|
import { homedir as homedir11 } from "node:os";
|
|
27541
28109
|
import { isAbsolute as isAbsolute5, join as join16, posix as posix2, resolve as resolve7, sep as sep6 } from "node:path";
|
|
27542
28110
|
|
|
27543
28111
|
// dist/risky/facts.js
|
|
27544
|
-
import { existsSync as existsSync8, lstatSync as lstatSync3, readdirSync as readdirSync9, readFileSync as
|
|
28112
|
+
import { existsSync as existsSync8, lstatSync as lstatSync3, readdirSync as readdirSync9, readFileSync as readFileSync22, realpathSync as realpathSync7, statSync as statSync7 } from "node:fs";
|
|
27545
28113
|
import { homedir as homedir10, tmpdir as tmpdir2 } from "node:os";
|
|
27546
28114
|
import { basename as pathBasename, dirname as dirname6, isAbsolute as isAbsolute4, join as join15, relative as relative7, resolve as resolve6, sep as sep5 } from "node:path";
|
|
27547
28115
|
|
|
@@ -29779,7 +30347,7 @@ var Env = class {
|
|
|
29779
30347
|
return this.description;
|
|
29780
30348
|
this.description = null;
|
|
29781
30349
|
try {
|
|
29782
|
-
const raw = JSON.parse(
|
|
30350
|
+
const raw = JSON.parse(readFileSync22(join15(repoRoot, SYSTEM_DESCRIPTION_REL), "utf-8"));
|
|
29783
30351
|
const checked = checkSystemDescription(raw);
|
|
29784
30352
|
if (checked.ok)
|
|
29785
30353
|
this.description = checked.description;
|
|
@@ -30965,7 +31533,7 @@ function publishFacts(m, env) {
|
|
|
30965
31533
|
const start = startFolder(m, env);
|
|
30966
31534
|
if (start !== null && PACKAGE_JSON_PROGRAMS.has(m.program)) {
|
|
30967
31535
|
try {
|
|
30968
|
-
const pkg = JSON.parse(
|
|
31536
|
+
const pkg = JSON.parse(readFileSync22(join15(start, "package.json"), "utf-8"));
|
|
30969
31537
|
if (typeof pkg["name"] === "string" && typeof pkg["version"] === "string" && pkg["name"] !== "" && pkg["version"] !== "") {
|
|
30970
31538
|
name = pkg["name"];
|
|
30971
31539
|
version2 = pkg["version"];
|
|
@@ -31015,7 +31583,7 @@ function shrinkRecordFacts(m, env) {
|
|
|
31015
31583
|
try {
|
|
31016
31584
|
if (!lstatSync3(file2.abs).isFile())
|
|
31017
31585
|
continue;
|
|
31018
|
-
before =
|
|
31586
|
+
before = readFileSync22(file2.abs, "utf-8");
|
|
31019
31587
|
} catch {
|
|
31020
31588
|
continue;
|
|
31021
31589
|
}
|
|
@@ -31250,7 +31818,7 @@ function canonical(stored) {
|
|
|
31250
31818
|
function readSource(path, parse3) {
|
|
31251
31819
|
let text;
|
|
31252
31820
|
try {
|
|
31253
|
-
text =
|
|
31821
|
+
text = readFileSync23(path, "utf-8");
|
|
31254
31822
|
} catch (e) {
|
|
31255
31823
|
const code = e.code;
|
|
31256
31824
|
return { names: [], broken: code !== "ENOENT" && code !== "ENOTDIR" };
|
|
@@ -31279,7 +31847,7 @@ function namesFromList(p) {
|
|
|
31279
31847
|
}
|
|
31280
31848
|
let lines2;
|
|
31281
31849
|
try {
|
|
31282
|
-
lines2 =
|
|
31850
|
+
lines2 = readFileSync23(p.list, "utf-8").split("\n");
|
|
31283
31851
|
} catch {
|
|
31284
31852
|
return null;
|
|
31285
31853
|
}
|
|
@@ -31295,10 +31863,10 @@ function writeList(p, names) {
|
|
|
31295
31863
|
const lines2 = [p.firstLine, ...comparable.length === names.length ? [] : [ACCOUNT_NAMES_ANY], ...comparable];
|
|
31296
31864
|
const temp = `${p.list}.${String(process.pid)}.${randomBytes(4).toString("hex")}`;
|
|
31297
31865
|
try {
|
|
31298
|
-
|
|
31299
|
-
|
|
31866
|
+
mkdirSync10(join16(p.home, HALFCYCLE_DIR_NAME), { recursive: true, mode: 448 });
|
|
31867
|
+
writeFileSync14(temp, `${lines2.join("\n")}
|
|
31300
31868
|
`, { mode: 384, flag: "wx" });
|
|
31301
|
-
|
|
31869
|
+
renameSync12(temp, p.list);
|
|
31302
31870
|
} catch {
|
|
31303
31871
|
try {
|
|
31304
31872
|
rmSync3(temp, { force: true });
|
|
@@ -31357,7 +31925,7 @@ function sumOf(texts, name) {
|
|
|
31357
31925
|
}
|
|
31358
31926
|
function textOf(path) {
|
|
31359
31927
|
try {
|
|
31360
|
-
return
|
|
31928
|
+
return readFileSync23(path, "utf-8");
|
|
31361
31929
|
} catch {
|
|
31362
31930
|
return "";
|
|
31363
31931
|
}
|
|
@@ -31980,7 +32548,7 @@ function isOneCall(call) {
|
|
|
31980
32548
|
|
|
31981
32549
|
// dist/risky/allow-once.js
|
|
31982
32550
|
import { createHash as createHash5 } from "node:crypto";
|
|
31983
|
-
import { appendFileSync as appendFileSync5, readFileSync as
|
|
32551
|
+
import { appendFileSync as appendFileSync5, readFileSync as readFileSync24, realpathSync as realpathSync8, renameSync as renameSync13, statSync as statSync9, unlinkSync as unlinkSync9, writeFileSync as writeFileSync15 } from "node:fs";
|
|
31984
32552
|
import { isAbsolute as isAbsolute6, relative as relative8, resolve as resolve8, sep as sep7 } from "node:path";
|
|
31985
32553
|
var ALLOW_ONCE_MS = 5 * 60 * 1e3;
|
|
31986
32554
|
var HELD_STEP_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
@@ -32141,7 +32709,7 @@ function numberKept(path, key) {
|
|
|
32141
32709
|
function readNumbers(path) {
|
|
32142
32710
|
let text;
|
|
32143
32711
|
try {
|
|
32144
|
-
text =
|
|
32712
|
+
text = readFileSync24(path, "utf8");
|
|
32145
32713
|
} catch (err) {
|
|
32146
32714
|
return err.code === "ENOENT" ? { next: 1, steps: /* @__PURE__ */ new Map() } : null;
|
|
32147
32715
|
}
|
|
@@ -32253,13 +32821,13 @@ function distinctSteps(held, numbersPath) {
|
|
|
32253
32821
|
function claimHeld(path, session, now) {
|
|
32254
32822
|
const claimed = `${path}.${process.pid}.${now}.claim`;
|
|
32255
32823
|
try {
|
|
32256
|
-
|
|
32824
|
+
renameSync13(path, claimed);
|
|
32257
32825
|
} catch {
|
|
32258
32826
|
return [];
|
|
32259
32827
|
}
|
|
32260
32828
|
let text = "";
|
|
32261
32829
|
try {
|
|
32262
|
-
text =
|
|
32830
|
+
text = readFileSync24(claimed, "utf8");
|
|
32263
32831
|
} catch {
|
|
32264
32832
|
text = "";
|
|
32265
32833
|
}
|
|
@@ -32314,7 +32882,7 @@ function nowOf(deps) {
|
|
|
32314
32882
|
}
|
|
32315
32883
|
function readRecord2(path, session) {
|
|
32316
32884
|
try {
|
|
32317
|
-
return parseRecord(
|
|
32885
|
+
return parseRecord(readFileSync24(path, "utf8"), session);
|
|
32318
32886
|
} catch {
|
|
32319
32887
|
return null;
|
|
32320
32888
|
}
|
|
@@ -32352,8 +32920,8 @@ function writeRecord(path, record2) {
|
|
|
32352
32920
|
function writeWhole2(path, body) {
|
|
32353
32921
|
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
32354
32922
|
try {
|
|
32355
|
-
|
|
32356
|
-
|
|
32923
|
+
writeFileSync15(tmp, body, { mode: 384 });
|
|
32924
|
+
renameSync13(tmp, path);
|
|
32357
32925
|
return true;
|
|
32358
32926
|
} catch {
|
|
32359
32927
|
removeQuietly(tmp);
|
|
@@ -32453,7 +33021,7 @@ function decideAutonomous(facts, mayPublishNow) {
|
|
|
32453
33021
|
}
|
|
32454
33022
|
|
|
32455
33023
|
// dist/risky/own-copy.js
|
|
32456
|
-
import { readFileSync as
|
|
33024
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
32457
33025
|
import { join as join17, posix as posix3, win32 as win322 } from "node:path";
|
|
32458
33026
|
var OWN_COPY_START_TOOL = "Agent";
|
|
32459
33027
|
var OWN_COPY_WRITE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
|
|
@@ -32475,7 +33043,7 @@ function stringField2(o, key) {
|
|
|
32475
33043
|
}
|
|
32476
33044
|
function readOr(deps, path) {
|
|
32477
33045
|
try {
|
|
32478
|
-
return (deps.readFile ?? ((p) =>
|
|
33046
|
+
return (deps.readFile ?? ((p) => readFileSync25(p, "utf-8")))(path);
|
|
32479
33047
|
} catch {
|
|
32480
33048
|
return null;
|
|
32481
33049
|
}
|
|
@@ -32621,7 +33189,7 @@ function judgeChange(input, call, deps) {
|
|
|
32621
33189
|
|
|
32622
33190
|
// dist/risky/save.js
|
|
32623
33191
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
32624
|
-
import { chmodSync as chmodSync2, constants as fsConstants, copyFileSync, lstatSync as lstatSync4, mkdirSync as
|
|
33192
|
+
import { chmodSync as chmodSync2, constants as fsConstants, copyFileSync, lstatSync as lstatSync4, mkdirSync as mkdirSync11, readdirSync as readdirSync10, readFileSync as readFileSync26, readlinkSync, realpathSync as realpathSync9, renameSync as renameSync14, rmSync as rmSync4, statSync as statSync10, symlinkSync, writeFileSync as writeFileSync16 } from "node:fs";
|
|
32625
33193
|
import { homedir as homedir12 } from "node:os";
|
|
32626
33194
|
import { dirname as dirname7, isAbsolute as isAbsolute7, join as join18, resolve as resolve9 } from "node:path";
|
|
32627
33195
|
var SAVE_LIMIT_BYTES = 2e8;
|
|
@@ -32667,7 +33235,7 @@ function saveFirst(staked, ctx) {
|
|
|
32667
33235
|
const repository = repositoryOf(g);
|
|
32668
33236
|
if (repository === null)
|
|
32669
33237
|
return failed(saveDir);
|
|
32670
|
-
|
|
33238
|
+
writeFileSync16(join18(saveDir, SAVED_REPOSITORY_FILE_NAME), `${repository}
|
|
32671
33239
|
`, { mode: 384 });
|
|
32672
33240
|
const privateIndex = join18(saveDir, PRIVATE_INDEX_NAME);
|
|
32673
33241
|
const commit = saveCommit(id, headCommit2, found2.tracked, plan.lines, privateIndex, g, now());
|
|
@@ -32693,9 +33261,9 @@ function saveFirst(staked, ctx) {
|
|
|
32693
33261
|
if (!description.success)
|
|
32694
33262
|
return failed(saveDir);
|
|
32695
33263
|
const file2 = join18(saveDir, SAVED_FILE_NAME);
|
|
32696
|
-
|
|
33264
|
+
writeFileSync16(`${file2}.part`, `${JSON.stringify(description.data, null, 2)}
|
|
32697
33265
|
`, { mode: 384 });
|
|
32698
|
-
|
|
33266
|
+
renameSync14(`${file2}.part`, file2);
|
|
32699
33267
|
ctx.beforeRef?.();
|
|
32700
33268
|
const ref = g.run(["update-ref", "--no-deref", savedRefOf(id), commit, ""]);
|
|
32701
33269
|
if (!ref.ok)
|
|
@@ -32815,7 +33383,7 @@ function copyOne(src, dst) {
|
|
|
32815
33383
|
const st = lstatOrNull(src);
|
|
32816
33384
|
if (st === null)
|
|
32817
33385
|
return false;
|
|
32818
|
-
|
|
33386
|
+
mkdirSync11(dirname7(dst), { recursive: true, mode: 448 });
|
|
32819
33387
|
if (st.isSymbolicLink()) {
|
|
32820
33388
|
symlinkSync(readlinkSync(src), dst);
|
|
32821
33389
|
return true;
|
|
@@ -32891,13 +33459,13 @@ var SaveGit = class {
|
|
|
32891
33459
|
}
|
|
32892
33460
|
};
|
|
32893
33461
|
function freshId(folder2, newId) {
|
|
32894
|
-
|
|
33462
|
+
mkdirSync11(folder2, { recursive: true, mode: 448 });
|
|
32895
33463
|
for (let i = 0; i < 5; i++) {
|
|
32896
33464
|
const id = newId?.() ?? defaultId();
|
|
32897
33465
|
if (!savedIdSchema.safeParse(id).success)
|
|
32898
33466
|
return null;
|
|
32899
33467
|
try {
|
|
32900
|
-
|
|
33468
|
+
mkdirSync11(join18(folder2, id), { mode: 448 });
|
|
32901
33469
|
return id;
|
|
32902
33470
|
} catch (e) {
|
|
32903
33471
|
if (e.code !== "EEXIST")
|
|
@@ -32922,7 +33490,7 @@ function repositoryOf(g) {
|
|
|
32922
33490
|
}
|
|
32923
33491
|
function markedRepository(dir) {
|
|
32924
33492
|
try {
|
|
32925
|
-
const text =
|
|
33493
|
+
const text = readFileSync26(join18(dir, SAVED_REPOSITORY_FILE_NAME), "utf-8").trim();
|
|
32926
33494
|
return text === "" ? null : text;
|
|
32927
33495
|
} catch {
|
|
32928
33496
|
return null;
|
|
@@ -32995,7 +33563,7 @@ function realOrSelf3(p) {
|
|
|
32995
33563
|
|
|
32996
33564
|
// dist/autonomy-state.js
|
|
32997
33565
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
32998
|
-
import { chmodSync as chmodSync3, mkdirSync as
|
|
33566
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync12, readFileSync as readFileSync27, renameSync as renameSync15, rmSync as rmSync5, writeFileSync as writeFileSync17 } from "node:fs";
|
|
32999
33567
|
import { homedir as homedir13, platform as platform2 } from "node:os";
|
|
33000
33568
|
import { dirname as dirname8, join as join19 } from "node:path";
|
|
33001
33569
|
var AUTONOMY_STATE_FILENAME = "autonomy.json";
|
|
@@ -33007,7 +33575,7 @@ function readCachedAutonomy(engagementId, nowMs, home) {
|
|
|
33007
33575
|
if (!isEngagementId(engagementId))
|
|
33008
33576
|
return null;
|
|
33009
33577
|
try {
|
|
33010
|
-
const parsed = autonomyStateFileSchema.safeParse(JSON.parse(
|
|
33578
|
+
const parsed = autonomyStateFileSchema.safeParse(JSON.parse(readFileSync27(autonomyStateFilePath(engagementId, home), "utf-8")));
|
|
33011
33579
|
if (!parsed.success || !parsed.data.on)
|
|
33012
33580
|
return null;
|
|
33013
33581
|
const age = nowMs - Date.parse(parsed.data.readAt);
|
|
@@ -33056,12 +33624,12 @@ function writeAutonomyStateFile(engagementId, file2, home) {
|
|
|
33056
33624
|
const target = autonomyStateFilePath(engagementId, home);
|
|
33057
33625
|
const temp = join19(dirname8(target), `.${AUTONOMY_STATE_FILENAME}.${process.pid}.tmp`);
|
|
33058
33626
|
try {
|
|
33059
|
-
|
|
33060
|
-
|
|
33627
|
+
mkdirSync12(dirname8(target), { recursive: true, mode: 448 });
|
|
33628
|
+
writeFileSync17(temp, `${JSON.stringify(file2)}
|
|
33061
33629
|
`, { mode: 384 });
|
|
33062
33630
|
if (platform2() !== "win32")
|
|
33063
33631
|
chmodSync3(temp, 384);
|
|
33064
|
-
|
|
33632
|
+
renameSync15(temp, target);
|
|
33065
33633
|
return true;
|
|
33066
33634
|
} catch {
|
|
33067
33635
|
try {
|
|
@@ -33537,7 +34105,7 @@ async function evaluateSession(input, kind, reply, readSeat, profile) {
|
|
|
33537
34105
|
const changeSet = buildChangeSet(fileDiffEntries, { ...context, excerpts: readExcerptConfig() });
|
|
33538
34106
|
const configResult = readConfig();
|
|
33539
34107
|
if (!configResult.config) {
|
|
33540
|
-
await emitRunRecord({ runType: "hook", outcome: "unconfigured", changeSet, diffBase });
|
|
34108
|
+
await emitRunRecord({ runType: "hook", outcome: "unconfigured", changeSet, diffBase, repoFacts: context.repoFacts });
|
|
33541
34109
|
if (!firstNoticeThisSession("credential-missing", repoRoot, sessionId))
|
|
33542
34110
|
return;
|
|
33543
34111
|
emitNeverConfigured(UNCONFIGURED_EXIT_STOP_FAMILY, readNeverConfiguredReason(), pinnedEngagementId(projectFolder()), reply);
|
|
@@ -33561,6 +34129,7 @@ async function evaluateSession(input, kind, reply, readSeat, profile) {
|
|
|
33561
34129
|
outcome: outcomeForClientFailure(clientResult.kind),
|
|
33562
34130
|
failureReason: failure.reason,
|
|
33563
34131
|
changeSet,
|
|
34132
|
+
repoFacts: context.repoFacts,
|
|
33564
34133
|
diffBase,
|
|
33565
34134
|
credential: evaluation.token,
|
|
33566
34135
|
credentialRefused: failure.kind === "credential"
|
|
@@ -33594,6 +34163,7 @@ async function evaluateSession(input, kind, reply, readSeat, profile) {
|
|
|
33594
34163
|
phase: telemetryConfig.phase,
|
|
33595
34164
|
outcome: "evaluated",
|
|
33596
34165
|
changeSet,
|
|
34166
|
+
repoFacts: context.repoFacts,
|
|
33597
34167
|
result: clientResult.envelope,
|
|
33598
34168
|
diffBase
|
|
33599
34169
|
});
|
|
@@ -33712,18 +34282,19 @@ function subagentStopped(input, deps = {}) {
|
|
|
33712
34282
|
}
|
|
33713
34283
|
|
|
33714
34284
|
// dist/hooks/stop.js
|
|
33715
|
-
async function runStop(observeDeps = {}, timeDeps = {}, paceDeps = {}, profile = AGENT_PROFILES["claude-code"]) {
|
|
34285
|
+
async function runStop(observeDeps = {}, timeDeps = {}, paceDeps = {}, profile = AGENT_PROFILES["claude-code"], planDeps = {}) {
|
|
33716
34286
|
const input = hookInputForRule(await readHookStdin(), profile.configFolder);
|
|
33717
34287
|
recordTimeEvent("turn-end", input);
|
|
33718
34288
|
await runSessionDiff(input, "stop", readSeatConfiguration, async (reply) => {
|
|
33719
34289
|
await observeChanges(input.session_id, reply, observeDeps);
|
|
33720
34290
|
await sendTimeRecord(timeDeps, { agent: profile.id });
|
|
33721
34291
|
await paceAtTurnEnd(input, reply, { configFolder: profile.configFolder, ...paceDeps });
|
|
34292
|
+
await planUsageReport(input, { configFolder: profile.configFolder, ...planDeps });
|
|
33722
34293
|
}, profile);
|
|
33723
34294
|
}
|
|
33724
34295
|
|
|
33725
34296
|
// dist/relayed-choices.js
|
|
33726
|
-
import { mkdirSync as
|
|
34297
|
+
import { mkdirSync as mkdirSync13, readFileSync as readFileSync28, renameSync as renameSync16, rmSync as rmSync6, writeFileSync as writeFileSync18 } from "node:fs";
|
|
33727
34298
|
import { homedir as homedir15 } from "node:os";
|
|
33728
34299
|
import { dirname as dirname9, join as join21 } from "node:path";
|
|
33729
34300
|
function relayedChoicesFilePath(engagementId, home) {
|
|
@@ -33736,7 +34307,7 @@ function readRelayedChoices(engagementId, phase, home) {
|
|
|
33736
34307
|
if (path === null)
|
|
33737
34308
|
return null;
|
|
33738
34309
|
try {
|
|
33739
|
-
const parsed = relayedChoicesFileSchema.safeParse(JSON.parse(
|
|
34310
|
+
const parsed = relayedChoicesFileSchema.safeParse(JSON.parse(readFileSync28(path, "utf-8")));
|
|
33740
34311
|
return parsed.success && parsed.data.phase === phase ? parsed.data : null;
|
|
33741
34312
|
} catch {
|
|
33742
34313
|
return null;
|
|
@@ -33767,10 +34338,10 @@ function recordRelayedChoice(opts) {
|
|
|
33767
34338
|
return false;
|
|
33768
34339
|
const temp = join21(dirname9(target), `.${RELAYED_CHOICES_FILENAME}.${process.pid}.tmp`);
|
|
33769
34340
|
try {
|
|
33770
|
-
|
|
33771
|
-
|
|
34341
|
+
mkdirSync13(dirname9(target), { recursive: true, mode: 448 });
|
|
34342
|
+
writeFileSync18(temp, `${JSON.stringify(file2.data)}
|
|
33772
34343
|
`, { mode: 384 });
|
|
33773
|
-
|
|
34344
|
+
renameSync16(temp, target);
|
|
33774
34345
|
return true;
|
|
33775
34346
|
} catch {
|
|
33776
34347
|
try {
|
|
@@ -33834,6 +34405,7 @@ var KEEP_GOING = /^keep going$/i;
|
|
|
33834
34405
|
var STOP = /^stop(?: here)?$/i;
|
|
33835
34406
|
var TIMES = /^limit it to ([0-9]{1,9}(?:\.[0-9]{1,2})?) times$/i;
|
|
33836
34407
|
var FIGURE = /^limit it to ([0-9]{1,9}(?:\.[0-9]{1,2})?) (million|billion)(?: tokens)?$/i;
|
|
34408
|
+
var SHARE = /^limit it to ([0-9]{1,3})% of the week$/i;
|
|
33837
34409
|
function limitPhraseShape(prompt) {
|
|
33838
34410
|
if (typeof prompt !== "string")
|
|
33839
34411
|
return null;
|
|
@@ -33852,6 +34424,11 @@ function limitPhraseShape(prompt) {
|
|
|
33852
34424
|
const unit = figure[2].toLowerCase() === "billion" ? 1e9 : 1e6;
|
|
33853
34425
|
return { kind: "figure", tokens: Math.round(Number(figure[1]) * unit) };
|
|
33854
34426
|
}
|
|
34427
|
+
const share = SHARE.exec(line2);
|
|
34428
|
+
if (share !== null) {
|
|
34429
|
+
const percent = Number(share[1]);
|
|
34430
|
+
return percent >= 1 && percent <= 100 ? { kind: "share", percent } : null;
|
|
34431
|
+
}
|
|
33855
34432
|
return null;
|
|
33856
34433
|
}
|
|
33857
34434
|
|
|
@@ -33993,7 +34570,7 @@ function matchReviewPhraseShape(shape, reviews) {
|
|
|
33993
34570
|
}
|
|
33994
34571
|
|
|
33995
34572
|
// dist/hooks/shown-record.js
|
|
33996
|
-
import { chmodSync as chmodSync4, readFileSync as
|
|
34573
|
+
import { chmodSync as chmodSync4, readFileSync as readFileSync29, renameSync as renameSync17, unlinkSync as unlinkSync11, writeFileSync as writeFileSync19 } from "node:fs";
|
|
33997
34574
|
import { homedir as homedir16, platform as platform3 } from "node:os";
|
|
33998
34575
|
import { join as join22 } from "node:path";
|
|
33999
34576
|
function recordDir(engagementId, home) {
|
|
@@ -34006,7 +34583,7 @@ function readShownRecord(engagementId, home) {
|
|
|
34006
34583
|
if (dir === null)
|
|
34007
34584
|
return { entries: [], reviews: [] };
|
|
34008
34585
|
try {
|
|
34009
|
-
return parseShownRecord(
|
|
34586
|
+
return parseShownRecord(readFileSync29(join22(dir, SHOWN_PLANS_FILENAME), "utf-8"));
|
|
34010
34587
|
} catch {
|
|
34011
34588
|
return { entries: [], reviews: [] };
|
|
34012
34589
|
}
|
|
@@ -34028,7 +34605,7 @@ function moveListedReviewForward(engagementId, home, listed, reviewVersion, deci
|
|
|
34028
34605
|
if (dir === null)
|
|
34029
34606
|
return false;
|
|
34030
34607
|
const path = join22(dir, SHOWN_PLANS_FILENAME);
|
|
34031
|
-
const current = parseShownRecord(
|
|
34608
|
+
const current = parseShownRecord(readFileSync29(path, "utf-8"));
|
|
34032
34609
|
const at = current.reviews.findIndex((r) => r.phase === listed.phase && r.shownAt === listed.shownAt && r.reviewVersion === listed.reviewVersion);
|
|
34033
34610
|
if (at === -1)
|
|
34034
34611
|
return false;
|
|
@@ -34036,10 +34613,10 @@ function moveListedReviewForward(engagementId, home, listed, reviewVersion, deci
|
|
|
34036
34613
|
const reviews = current.reviews.map((review, i) => i === at ? { ...review, reviewVersion, parts: review.parts.map((p) => movedPart(p, acts.get(p.part))) } : review);
|
|
34037
34614
|
const body = serialiseShownRecord({ entries: current.entries, reviews });
|
|
34038
34615
|
temp = join22(dir, `.${SHOWN_PLANS_FILENAME}.${process.pid}.tmp`);
|
|
34039
|
-
|
|
34616
|
+
writeFileSync19(temp, body, { mode: 384 });
|
|
34040
34617
|
if (platform3() !== "win32")
|
|
34041
34618
|
chmodSync4(temp, 384);
|
|
34042
|
-
|
|
34619
|
+
renameSync17(temp, path);
|
|
34043
34620
|
return true;
|
|
34044
34621
|
} catch {
|
|
34045
34622
|
if (temp !== null) {
|
|
@@ -34558,20 +35135,17 @@ function paceNoOwnerText() {
|
|
|
34558
35135
|
function paceCannotReachText() {
|
|
34559
35136
|
return `${PACE_NOTHING_CHANGED_OPENING}: Halfcycle could not be reached just now. Type the line again in a minute.`;
|
|
34560
35137
|
}
|
|
34561
|
-
function
|
|
34562
|
-
return limit
|
|
34563
|
-
}
|
|
34564
|
-
function limitKeepGoingDoneText(limit, used) {
|
|
34565
|
-
return `Done. The limit is now ${tokenCountWordsOf(limit)} tokens. This phase has used ${tokenCountWordsOf(used)}. New work can start again.`;
|
|
35138
|
+
function limitKeepGoingDoneText(limit, used, weekCeilingTokens = null) {
|
|
35139
|
+
return limitKeepGoingShareText(limit, used, weekCeilingTokens);
|
|
34566
35140
|
}
|
|
34567
35141
|
function limitStopDoneText() {
|
|
34568
35142
|
return 'Done. This phase is paused at its usage limit. Nothing is lost, and the agents already working will finish. Say "keep going" whenever you want to carry on.';
|
|
34569
35143
|
}
|
|
34570
|
-
function limitTimesDoneText(limit, typed, used) {
|
|
34571
|
-
return
|
|
35144
|
+
function limitTimesDoneText(limit, typed, used, weekCeilingTokens = null) {
|
|
35145
|
+
return limitTimesShareText(limit, typed, used, weekCeilingTokens);
|
|
34572
35146
|
}
|
|
34573
|
-
function limitFigureDoneText(limit, used) {
|
|
34574
|
-
return
|
|
35147
|
+
function limitFigureDoneText(limit, used, weekCeilingTokens = null) {
|
|
35148
|
+
return limitFigureShareText(limit, used, weekCeilingTokens);
|
|
34575
35149
|
}
|
|
34576
35150
|
function limitNotReachedText() {
|
|
34577
35151
|
return `${PACE_NOTHING_CHANGED_OPENING}: this phase has not reached its usage limit, so there is nothing to answer.`;
|
|
@@ -34579,11 +35153,14 @@ function limitNotReachedText() {
|
|
|
34579
35153
|
function limitNoBuildText() {
|
|
34580
35154
|
return `${PACE_NOTHING_CHANGED_OPENING}: no build is running in this project yet.`;
|
|
34581
35155
|
}
|
|
34582
|
-
function limitTimesRangeText() {
|
|
34583
|
-
return
|
|
35156
|
+
function limitTimesRangeText(weekCeilingTokens = null) {
|
|
35157
|
+
return limitTimesRangeShareText(LIMIT_MULTIPLE_RANGE, weekCeilingTokens);
|
|
35158
|
+
}
|
|
35159
|
+
function limitNoExpectedText(weekCeilingTokens = null) {
|
|
35160
|
+
return limitNoExpectedShareText(weekCeilingTokens);
|
|
34584
35161
|
}
|
|
34585
|
-
function
|
|
34586
|
-
return
|
|
35162
|
+
function limitShareNotSetText() {
|
|
35163
|
+
return LIMIT_SHARE_NOT_SET_TEXT;
|
|
34587
35164
|
}
|
|
34588
35165
|
function limitFigureRangeText() {
|
|
34589
35166
|
return `${PACE_NOTHING_CHANGED_OPENING}: a limit is between ${tokenCountWordsOf(LIMIT_FIGURE_RANGE.min)} and ${tokenCountWordsOf(LIMIT_FIGURE_RANGE.max)} tokens.`;
|
|
@@ -34860,8 +35437,11 @@ function decideLimit(shape, opts) {
|
|
|
34860
35437
|
const file2 = dir === null ? null : openPhaseLimit(dir, readPaceStateFile(dir).basis);
|
|
34861
35438
|
if (dir === null || file2 === null)
|
|
34862
35439
|
return say(limitNoBuildText());
|
|
35440
|
+
const ceiling = weeklyCeilingHere(opts, agent);
|
|
35441
|
+
if (shape.kind === "share" && ceiling === null)
|
|
35442
|
+
return say(limitShareNotSetText());
|
|
34863
35443
|
if (shape.kind === "times" && !multipleInRange(shape.multiple))
|
|
34864
|
-
return say(limitTimesRangeText());
|
|
35444
|
+
return say(limitTimesRangeText(ceiling));
|
|
34865
35445
|
if (shape.kind === "figure" && !figureInRange(shape.tokens))
|
|
34866
35446
|
return say(limitFigureRangeText());
|
|
34867
35447
|
const used = readPhaseUsage(dir, file2.phase);
|
|
@@ -34885,11 +35465,11 @@ function decideLimit(shape, opts) {
|
|
|
34885
35465
|
return say(limitNotSavedText());
|
|
34886
35466
|
if (typed === "cannot-tell")
|
|
34887
35467
|
relay();
|
|
34888
|
-
return say(limitKeepGoingDoneText(next2.limit, used));
|
|
35468
|
+
return say(limitKeepGoingDoneText(next2.limit, used, ceiling));
|
|
34889
35469
|
}
|
|
34890
35470
|
if (shape.kind === "times" && !(file2.expected > 0))
|
|
34891
|
-
return say(limitNoExpectedText());
|
|
34892
|
-
const limit = shape.kind === "times" ? limitOf(file2.expected, shape.multiple) : shape.tokens;
|
|
35471
|
+
return say(limitNoExpectedText(ceiling));
|
|
35472
|
+
const limit = shape.kind === "times" ? limitOf(file2.expected, shape.multiple) : shape.kind === "share" ? Math.max(1, Math.round(shape.percent / 100 * (ceiling ?? 0))) : shape.tokens;
|
|
34893
35473
|
const raise = limit > file2.limit;
|
|
34894
35474
|
if (raise && typed === "not-attended")
|
|
34895
35475
|
return say(limitNotAttendedText());
|
|
@@ -34898,7 +35478,32 @@ function decideLimit(shape, opts) {
|
|
|
34898
35478
|
return say(limitNotSavedText());
|
|
34899
35479
|
if (raise && typed === "cannot-tell")
|
|
34900
35480
|
relay();
|
|
34901
|
-
return say(shape.kind === "times" ? limitTimesDoneText(limit, shape.typed, used) : limitFigureDoneText(limit, used));
|
|
35481
|
+
return say(shape.kind === "times" ? limitTimesDoneText(limit, shape.typed, used, ceiling) : limitFigureDoneText(limit, used, ceiling));
|
|
35482
|
+
}
|
|
35483
|
+
function weeklyCeilingHere(opts, agent) {
|
|
35484
|
+
try {
|
|
35485
|
+
const said = promptRecordPath(opts.input);
|
|
35486
|
+
const key = configFolderKey({
|
|
35487
|
+
env: opts.env ?? process.env,
|
|
35488
|
+
transcriptPath: said,
|
|
35489
|
+
home: opts.home,
|
|
35490
|
+
...agent === "codex" ? { rule: "codex-home" } : {}
|
|
35491
|
+
});
|
|
35492
|
+
return weeklyCeilingOf(key, { home: opts.home });
|
|
35493
|
+
} catch {
|
|
35494
|
+
return null;
|
|
35495
|
+
}
|
|
35496
|
+
}
|
|
35497
|
+
function promptRecordPath(input) {
|
|
35498
|
+
try {
|
|
35499
|
+
const parsed = JSON.parse(input);
|
|
35500
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
35501
|
+
return null;
|
|
35502
|
+
const said = parsed["transcript_path"];
|
|
35503
|
+
return typeof said === "string" && said !== "" ? said : null;
|
|
35504
|
+
} catch {
|
|
35505
|
+
return null;
|
|
35506
|
+
}
|
|
34902
35507
|
}
|
|
34903
35508
|
function adjustPaceState(dir, opts, number4) {
|
|
34904
35509
|
try {
|
|
@@ -35221,7 +35826,7 @@ function runUserPromptFindings(opts) {
|
|
|
35221
35826
|
}
|
|
35222
35827
|
|
|
35223
35828
|
// dist/resolve-engagement.js
|
|
35224
|
-
import { existsSync as existsSync9, readFileSync as
|
|
35829
|
+
import { existsSync as existsSync9, readFileSync as readFileSync30, realpathSync as realpathSync10 } from "node:fs";
|
|
35225
35830
|
import { join as join23, sep as sep8 } from "node:path";
|
|
35226
35831
|
import { homedir as homedir17 } from "node:os";
|
|
35227
35832
|
function defaultRegistryPath() {
|
|
@@ -35231,7 +35836,7 @@ function readRegistry(registryPath = defaultRegistryPath()) {
|
|
|
35231
35836
|
if (!existsSync9(registryPath))
|
|
35232
35837
|
return {};
|
|
35233
35838
|
try {
|
|
35234
|
-
const parsed = JSON.parse(
|
|
35839
|
+
const parsed = JSON.parse(readFileSync30(registryPath, "utf-8"));
|
|
35235
35840
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
35236
35841
|
return {};
|
|
35237
35842
|
const out = {};
|
|
@@ -35279,12 +35884,12 @@ function runResolveEngagement(cwd, registryPath) {
|
|
|
35279
35884
|
}
|
|
35280
35885
|
|
|
35281
35886
|
// dist/refresh-credential.js
|
|
35282
|
-
import { lstatSync as lstatSync5, readFileSync as
|
|
35887
|
+
import { lstatSync as lstatSync5, readFileSync as readFileSync32, realpathSync as realpathSync11 } from "node:fs";
|
|
35283
35888
|
import { homedir as homedir19 } from "node:os";
|
|
35284
35889
|
import { join as join24, resolve as resolve12 } from "node:path";
|
|
35285
35890
|
|
|
35286
35891
|
// dist/mcp-headers.js
|
|
35287
|
-
import { readFileSync as
|
|
35892
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
35288
35893
|
import { homedir as homedir18 } from "node:os";
|
|
35289
35894
|
import { dirname as dirname10, resolve as resolve11 } from "node:path";
|
|
35290
35895
|
var URL_FLAG = "--url";
|
|
@@ -35318,7 +35923,7 @@ function projectRootFromBinary(binaryPath) {
|
|
|
35318
35923
|
function readPinnedVersion(root) {
|
|
35319
35924
|
let raw;
|
|
35320
35925
|
try {
|
|
35321
|
-
raw =
|
|
35926
|
+
raw = readFileSync31(resolve11(root, BUNDLE_PIN_REL), "utf-8");
|
|
35322
35927
|
} catch {
|
|
35323
35928
|
return void 0;
|
|
35324
35929
|
}
|
|
@@ -35580,7 +36185,7 @@ var SESSION_START_PROBE_ATTEMPTS = 2;
|
|
|
35580
36185
|
function registeredMcpUrl(projectRoot) {
|
|
35581
36186
|
let parsed;
|
|
35582
36187
|
try {
|
|
35583
|
-
parsed = JSON.parse(
|
|
36188
|
+
parsed = JSON.parse(readFileSync32(resolve12(projectRoot, MCP_REGISTRATION_REL), "utf-8"));
|
|
35584
36189
|
} catch {
|
|
35585
36190
|
return void 0;
|
|
35586
36191
|
}
|
|
@@ -35769,7 +36374,7 @@ function headlessInUntrustedFolder(input, profile, opts) {
|
|
|
35769
36374
|
const cwd = input["cwd"];
|
|
35770
36375
|
const folder2 = typeof cwd === "string" && cwd !== "" ? cwd : projectRootFromBinary(opts.binaryPath);
|
|
35771
36376
|
const stateFile = join24(readClaudeConfigFolder() ?? opts.home ?? homedir19(), CLAUDE_STATE_FILENAME);
|
|
35772
|
-
return trustOfWorkingFolder(folder2, stateFile, process.platform, { lstatSync: lstatSync5, readFileSync:
|
|
36377
|
+
return trustOfWorkingFolder(folder2, stateFile, process.platform, { lstatSync: lstatSync5, readFileSync: readFileSync32, realpathSync: realpathSync11 }) === "not-trusted";
|
|
35773
36378
|
}
|
|
35774
36379
|
async function runRefreshCredential(opts) {
|
|
35775
36380
|
const writeErr = opts.writeErr ?? defaultWriteErr2;
|
|
@@ -35862,7 +36467,7 @@ async function runRefreshCredential(opts) {
|
|
|
35862
36467
|
import { fileURLToPath } from "node:url";
|
|
35863
36468
|
|
|
35864
36469
|
// dist/capture.js
|
|
35865
|
-
import { readFileSync as
|
|
36470
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync20, mkdirSync as mkdirSync14, existsSync as existsSync10 } from "node:fs";
|
|
35866
36471
|
import { dirname as dirname11 } from "node:path";
|
|
35867
36472
|
function runCapture(provider, endpoint, opts = {}) {
|
|
35868
36473
|
const repoRoot = opts.repoRoot ?? process.cwd();
|
|
@@ -35898,8 +36503,8 @@ function runCapture(provider, endpoint, opts = {}) {
|
|
|
35898
36503
|
const fixture = fixturePath(repoRoot, provider, slug);
|
|
35899
36504
|
const manifestFile = manifestPath(repoRoot);
|
|
35900
36505
|
try {
|
|
35901
|
-
|
|
35902
|
-
|
|
36506
|
+
mkdirSync14(dirname11(fixture), { recursive: true });
|
|
36507
|
+
writeFileSync20(fixture, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
|
|
35903
36508
|
} catch (err) {
|
|
35904
36509
|
const msg = err instanceof Error ? err.message : String(err);
|
|
35905
36510
|
return { ok: false, kind: "write-failed", message: `could not write fixture: ${msg}` };
|
|
@@ -35930,7 +36535,7 @@ function readInputFile(fromFile) {
|
|
|
35930
36535
|
if (!fromFile)
|
|
35931
36536
|
return void 0;
|
|
35932
36537
|
try {
|
|
35933
|
-
return
|
|
36538
|
+
return readFileSync33(fromFile, "utf-8");
|
|
35934
36539
|
} catch {
|
|
35935
36540
|
return void 0;
|
|
35936
36541
|
}
|
|
@@ -35943,7 +36548,7 @@ function relativeFixturePath(repoRoot, fixture) {
|
|
|
35943
36548
|
// dist/prove.js
|
|
35944
36549
|
import { spawn as spawn2, spawnSync as spawnSync3 } from "node:child_process";
|
|
35945
36550
|
import { createHash as createHash6, randomUUID as randomUUID3 } from "node:crypto";
|
|
35946
|
-
import { createWriteStream, mkdirSync as
|
|
36551
|
+
import { createWriteStream, mkdirSync as mkdirSync15, readdirSync as readdirSync11, readFileSync as readFileSync34, renameSync as renameSync18, unlinkSync as unlinkSync12, writeFileSync as writeFileSync21 } from "node:fs";
|
|
35947
36552
|
import { homedir as homedir20 } from "node:os";
|
|
35948
36553
|
import { dirname as dirname12, join as join25 } from "node:path";
|
|
35949
36554
|
|
|
@@ -36140,10 +36745,10 @@ function parseProveArgs(args2) {
|
|
|
36140
36745
|
};
|
|
36141
36746
|
}
|
|
36142
36747
|
function writeJsonFile2(path, value) {
|
|
36143
|
-
|
|
36748
|
+
mkdirSync15(dirname12(path), { recursive: true, mode: 448 });
|
|
36144
36749
|
const tmp = `${path}.${process.pid}.${randomUUID3()}.tmp`;
|
|
36145
|
-
|
|
36146
|
-
|
|
36750
|
+
writeFileSync21(tmp, JSON.stringify(value), { mode: 384 });
|
|
36751
|
+
renameSync18(tmp, path);
|
|
36147
36752
|
}
|
|
36148
36753
|
function subjectKey(subject) {
|
|
36149
36754
|
return subject.kind === "task" ? ["task", subject.phase, subject.task] : ["change", subject.change];
|
|
@@ -36154,7 +36759,7 @@ function keptCheckPath(dir, subject, label) {
|
|
|
36154
36759
|
}
|
|
36155
36760
|
function readKeptCheck(dir, subject, label) {
|
|
36156
36761
|
try {
|
|
36157
|
-
const raw = JSON.parse(
|
|
36762
|
+
const raw = JSON.parse(readFileSync34(keptCheckPath(dir, subject, label), "utf-8"));
|
|
36158
36763
|
if (typeof raw.command !== "string" || raw.command === "" || typeof raw.commandId !== "string")
|
|
36159
36764
|
return null;
|
|
36160
36765
|
const b = raw.before;
|
|
@@ -36179,7 +36784,7 @@ function readQueue(dir) {
|
|
|
36179
36784
|
const path = join25(dir, QUEUE_DIR_NAME, name);
|
|
36180
36785
|
let parsed = null;
|
|
36181
36786
|
try {
|
|
36182
|
-
parsed = testRunReportSchema.safeParse(JSON.parse(
|
|
36787
|
+
parsed = testRunReportSchema.safeParse(JSON.parse(readFileSync34(path, "utf-8")));
|
|
36183
36788
|
} catch {
|
|
36184
36789
|
parsed = null;
|
|
36185
36790
|
}
|
|
@@ -36256,7 +36861,7 @@ function runCommand(command, repoRoot, logPath2, env, deps) {
|
|
|
36256
36861
|
const deadline = deps.deadlineMs ?? PROVE_RUN_DEADLINE_MS;
|
|
36257
36862
|
const childEnv = { ...env };
|
|
36258
36863
|
delete childEnv[SERVICE_TOKEN_VAR];
|
|
36259
|
-
|
|
36864
|
+
mkdirSync15(dirname12(logPath2), { recursive: true, mode: 448 });
|
|
36260
36865
|
const log = createWriteStream(logPath2, { mode: 384 });
|
|
36261
36866
|
const began = process.hrtime.bigint();
|
|
36262
36867
|
return new Promise((resolve13) => {
|
|
@@ -36422,7 +37027,7 @@ ${PROVE_USAGE}`);
|
|
|
36422
37027
|
const end = await runCommand(command, repoRoot, logPath2, env, deps);
|
|
36423
37028
|
let output = "";
|
|
36424
37029
|
try {
|
|
36425
|
-
output =
|
|
37030
|
+
output = readFileSync34(logPath2, "utf-8");
|
|
36426
37031
|
} catch {
|
|
36427
37032
|
output = "";
|
|
36428
37033
|
}
|
|
@@ -36472,8 +37077,8 @@ ${PROVE_USAGE}`);
|
|
|
36472
37077
|
|
|
36473
37078
|
// dist/statusline.js
|
|
36474
37079
|
import { spawn as spawn3 } from "node:child_process";
|
|
36475
|
-
import { readFileSync as
|
|
36476
|
-
import
|
|
37080
|
+
import { readFileSync as readFileSync35 } from "node:fs";
|
|
37081
|
+
import nodePath7 from "node:path";
|
|
36477
37082
|
var OWN_STATUS_LINE_DEADLINE_MS = 5e3;
|
|
36478
37083
|
var PERSON_SETTINGS_FILENAME = "settings.json";
|
|
36479
37084
|
var OWN_COMMAND_MARK = /guard-runner\.sh["']?\s+statusline\b/;
|
|
@@ -36510,7 +37115,7 @@ function halfcycleStatusLineOf(figures) {
|
|
|
36510
37115
|
}
|
|
36511
37116
|
function personStatusLineCommand(configFolder) {
|
|
36512
37117
|
try {
|
|
36513
|
-
const v = JSON.parse(
|
|
37118
|
+
const v = JSON.parse(readFileSync35(nodePath7.join(configFolder, PERSON_SETTINGS_FILENAME), "utf-8"));
|
|
36514
37119
|
const line2 = v["statusLine"];
|
|
36515
37120
|
if (typeof line2 !== "object" || line2 === null)
|
|
36516
37121
|
return null;
|