@quickchatai/quickreview 1.1.0 → 1.2.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/README.md +35 -19
- package/config.example.toml +41 -9
- package/dist/extensions/cli/login-route.js +5 -0
- package/dist/extensions/cli/login-route.js.map +1 -0
- package/dist/extensions/login-route.js +180 -0
- package/dist/extensions/login-route.js.map +1 -0
- package/dist/extensions/onboarding.js +29 -6
- package/dist/extensions/onboarding.js.map +1 -1
- package/dist/src/ciretry.js +2 -1
- package/dist/src/ciretry.js.map +1 -1
- package/dist/src/cli.js +43 -12
- package/dist/src/cli.js.map +1 -1
- package/dist/src/cliops.js +3 -2
- package/dist/src/cliops.js.map +1 -1
- package/dist/src/commands.js +25 -2
- package/dist/src/commands.js.map +1 -1
- package/dist/src/config.js +16 -2
- package/dist/src/config.js.map +1 -1
- package/dist/src/daemon.js +24 -8
- package/dist/src/daemon.js.map +1 -1
- package/dist/src/debugroundpi.js +5 -1
- package/dist/src/debugroundpi.js.map +1 -1
- package/dist/src/dispatch.js +5 -4
- package/dist/src/dispatch.js.map +1 -1
- package/dist/src/engine/debugpi.js +17 -5
- package/dist/src/engine/debugpi.js.map +1 -1
- package/dist/src/execboundary.js +10 -3
- package/dist/src/execboundary.js.map +1 -1
- package/dist/src/github.js +51 -16
- package/dist/src/github.js.map +1 -1
- package/dist/src/githubtoken.js +346 -0
- package/dist/src/githubtoken.js.map +1 -0
- package/dist/src/loginhint.js +8 -3
- package/dist/src/loginhint.js.map +1 -1
- package/dist/src/loginrefresh/pirefresh.js +3 -0
- package/dist/src/loginrefresh/pirefresh.js.map +1 -1
- package/dist/src/npmverbs.js +4 -2
- package/dist/src/npmverbs.js.map +1 -1
- package/dist/src/onboard/choices.js +29 -1
- package/dist/src/onboard/choices.js.map +1 -1
- package/dist/src/onboard/engine.js +8 -23
- package/dist/src/onboard/engine.js.map +1 -1
- package/dist/src/onboard/launch.js +12 -20
- package/dist/src/onboard/launch.js.map +1 -1
- package/dist/src/onboard/pipin.js +22 -0
- package/dist/src/onboard/pipin.js.map +1 -0
- package/dist/src/onboard/stepforward.js +41 -0
- package/dist/src/onboard/stepforward.js.map +1 -0
- package/dist/src/onboard/steps/appslug.js +4 -1
- package/dist/src/onboard/steps/appslug.js.map +1 -1
- package/dist/src/onboard/steps/compose.js +29 -0
- package/dist/src/onboard/steps/compose.js.map +1 -1
- package/dist/src/onboard/steps/configfill.js +102 -32
- package/dist/src/onboard/steps/configfill.js.map +1 -1
- package/dist/src/onboard/steps/githubaccount.js +595 -0
- package/dist/src/onboard/steps/githubaccount.js.map +1 -0
- package/dist/src/onboard/steps/githubapp.js +65 -7
- package/dist/src/onboard/steps/githubapp.js.map +1 -1
- package/dist/src/onboard/steps/golive.js +2 -0
- package/dist/src/onboard/steps/golive.js.map +1 -1
- package/dist/src/onboard/steps/index.js +11 -0
- package/dist/src/onboard/steps/index.js.map +1 -1
- package/dist/src/onboard/steps/ingress.js +80 -25
- package/dist/src/onboard/steps/ingress.js.map +1 -1
- package/dist/src/onboard/steps/llmauth.js +103 -30
- package/dist/src/onboard/steps/llmauth.js.map +1 -1
- package/dist/src/onboard/steps/memory.js +53 -1
- package/dist/src/onboard/steps/memory.js.map +1 -1
- package/dist/src/onboard/steps/proof.js +366 -56
- package/dist/src/onboard/steps/proof.js.map +1 -1
- package/dist/src/onboard/steps/topology.js +6 -6
- package/dist/src/onboard/steps/topology.js.map +1 -1
- package/dist/src/onboard/steps/transport.js +9 -1
- package/dist/src/onboard/steps/transport.js.map +1 -1
- package/dist/src/onboard/steps/tuiroute.js +102 -0
- package/dist/src/onboard/steps/tuiroute.js.map +1 -0
- package/dist/src/onboard/steps/verifyup.js +17 -1
- package/dist/src/onboard/steps/verifyup.js.map +1 -1
- package/dist/src/onboard/toolnames.js +30 -0
- package/dist/src/onboard/toolnames.js.map +1 -0
- package/dist/src/operatorwrite.js +23 -0
- package/dist/src/operatorwrite.js.map +1 -0
- package/dist/src/outcomes.js +4 -1
- package/dist/src/outcomes.js.map +1 -1
- package/dist/src/posting-journal.js +2 -1
- package/dist/src/posting-journal.js.map +1 -1
- package/dist/src/posting-outbox.js +6 -2
- package/dist/src/posting-outbox.js.map +1 -1
- package/dist/src/posting-receipt.js +14 -1
- package/dist/src/posting-receipt.js.map +1 -1
- package/dist/src/recheck.js +2 -1
- package/dist/src/recheck.js.map +1 -1
- package/dist/src/reconcile.js +22 -2
- package/dist/src/reconcile.js.map +1 -1
- package/dist/src/reviewhistory.js +32 -6
- package/dist/src/reviewhistory.js.map +1 -1
- package/dist/src/reviewnow.js +45 -0
- package/dist/src/reviewnow.js.map +1 -0
- package/dist/src/state.js.map +1 -1
- package/dist/src/statemachine.js +4 -1
- package/dist/src/statemachine.js.map +1 -1
- package/dist/src/takeoverpi.js +13 -0
- package/dist/src/takeoverpi.js.map +1 -1
- package/dist/src/tui/app.js +49 -0
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/board.js +88 -12
- package/dist/src/tui/board.js.map +1 -1
- package/dist/src/tui/cmdbar.js +4 -1
- package/dist/src/tui/cmdbar.js.map +1 -1
- package/dist/src/tui/companion.js +74 -10
- package/dist/src/tui/companion.js.map +1 -1
- package/dist/src/tui/connect.js +7 -1
- package/dist/src/tui/connect.js.map +1 -1
- package/dist/src/tui/filters.js +5 -2
- package/dist/src/tui/filters.js.map +1 -1
- package/dist/src/tui/ghread.js +61 -5
- package/dist/src/tui/ghread.js.map +1 -1
- package/dist/src/tui/index.js +106 -20
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/memforward.js +39 -2
- package/dist/src/tui/memforward.js.map +1 -1
- package/dist/src/tui/model.js +25 -0
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/prpause.js +7 -0
- package/dist/src/tui/prpause.js.map +1 -1
- package/dist/src/tui/remote.js +7 -1
- package/dist/src/tui/remote.js.map +1 -1
- package/dist/src/tui/route.js +143 -0
- package/dist/src/tui/route.js.map +1 -0
- package/dist/src/tui/setupstate.js +29 -0
- package/dist/src/tui/setupstate.js.map +1 -0
- package/dist/src/tui/sshtriage.js +102 -5
- package/dist/src/tui/sshtriage.js.map +1 -1
- package/dist/src/tui/theme.js +2 -1
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/unwedge.js +2 -12
- package/dist/src/tui/unwedge.js.map +1 -1
- package/dist/src/verdicts.js +17 -5
- package/dist/src/verdicts.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/src/webhook.js +12 -1
- package/dist/src/webhook.js.map +1 -1
- package/dist/src/wire.js +28 -6
- package/dist/src/wire.js.map +1 -1
- package/dist/src/workerworld.js +7 -1
- package/dist/src/workerworld.js.map +1 -1
- package/docker/companion/entrypoint.sh +20 -1
- package/docker/entrypoint.sh +17 -0
- package/extensions/cli/login-route.ts +10 -0
- package/extensions/login-route.ts +220 -0
- package/extensions/onboarding.ts +35 -6
- package/package.json +2 -2
- package/prompts/onboarding.md +57 -18
- package/scripts/mint-token.sh +25 -4
- package/src/ciretry.ts +2 -1
- package/src/cli.ts +49 -14
- package/src/cliops.ts +3 -2
- package/src/commands.ts +28 -2
- package/src/config.ts +24 -4
- package/src/daemon.ts +32 -7
- package/src/debugroundpi.ts +11 -1
- package/src/dispatch.ts +5 -4
- package/src/engine/debugpi.ts +17 -5
- package/src/execboundary.ts +16 -4
- package/src/github.ts +57 -15
- package/src/githubtoken.ts +435 -0
- package/src/loginhint.ts +8 -3
- package/src/loginrefresh/pirefresh.ts +3 -0
- package/src/npmverbs.ts +4 -2
- package/src/onboard/choices.ts +34 -1
- package/src/onboard/engine.ts +22 -3
- package/src/onboard/launch.ts +17 -29
- package/src/onboard/pipin.ts +31 -0
- package/src/onboard/stepforward.ts +61 -0
- package/src/onboard/steps/appslug.ts +4 -1
- package/src/onboard/steps/compose.ts +31 -0
- package/src/onboard/steps/configfill.ts +121 -33
- package/src/onboard/steps/githubaccount.ts +716 -0
- package/src/onboard/steps/githubapp.ts +92 -8
- package/src/onboard/steps/golive.ts +2 -0
- package/src/onboard/steps/index.ts +11 -0
- package/src/onboard/steps/ingress.ts +98 -31
- package/src/onboard/steps/llmauth.ts +114 -29
- package/src/onboard/steps/memory.ts +58 -1
- package/src/onboard/steps/proof.ts +473 -55
- package/src/onboard/steps/topology.ts +7 -6
- package/src/onboard/steps/transport.ts +15 -0
- package/src/onboard/steps/tuiroute.ts +119 -0
- package/src/onboard/steps/verifyup.ts +20 -1
- package/src/onboard/toolnames.ts +34 -0
- package/src/operatorwrite.ts +25 -0
- package/src/outcomes.ts +8 -1
- package/src/posting-journal.ts +6 -1
- package/src/posting-outbox.ts +10 -2
- package/src/posting-receipt.ts +17 -0
- package/src/recheck.ts +2 -1
- package/src/reconcile.ts +29 -3
- package/src/reviewhistory.ts +20 -6
- package/src/reviewnow.ts +76 -0
- package/src/state.ts +18 -0
- package/src/statemachine.ts +4 -1
- package/src/takeoverpi.ts +13 -0
- package/src/tui/app.ts +47 -0
- package/src/tui/board.ts +111 -14
- package/src/tui/cmdbar.ts +4 -1
- package/src/tui/companion.ts +78 -10
- package/src/tui/connect.ts +7 -1
- package/src/tui/filters.ts +7 -3
- package/src/tui/ghread.ts +74 -7
- package/src/tui/index.ts +114 -23
- package/src/tui/memforward.ts +52 -3
- package/src/tui/model.ts +36 -2
- package/src/tui/prpause.ts +11 -2
- package/src/tui/remote.ts +9 -1
- package/src/tui/route.ts +173 -0
- package/src/tui/setupstate.ts +52 -0
- package/src/tui/sshtriage.ts +127 -6
- package/src/tui/theme.ts +2 -1
- package/src/tui/unwedge.ts +2 -14
- package/src/verdicts.ts +23 -5
- package/src/version.ts +1 -1
- package/src/webhook.ts +10 -1
- package/src/wire.ts +36 -7
- package/src/workerworld.ts +7 -1
package/src/verdicts.ts
CHANGED
|
@@ -15,6 +15,11 @@ import {
|
|
|
15
15
|
// write the companion inbox. There is no path here that touches an existing review:
|
|
16
16
|
// the invariant against retracting an approval is structural, not prompted
|
|
17
17
|
// (AGENTS.md invariant 2).
|
|
18
|
+
import {
|
|
19
|
+
botAccountLogin,
|
|
20
|
+
isPersonMode,
|
|
21
|
+
ownLogins,
|
|
22
|
+
} from "@quickchatai/pi-quickreview/src/identity.js";
|
|
18
23
|
import {
|
|
19
24
|
normalizePassPhase,
|
|
20
25
|
normalizeSweepClaim,
|
|
@@ -406,6 +411,15 @@ export function decidedVerdictFromReceipt(receipt: PostingReceipt): ReceiptDecis
|
|
|
406
411
|
return { verdict: "REQUEST_CHANGES" };
|
|
407
412
|
if (receipt.intended_event === "APPROVE" && receipt.actual_event === "APPROVE")
|
|
408
413
|
return { verdict: "APPROVE" };
|
|
414
|
+
// Person mode posts every review as a COMMENT: the approval the session
|
|
415
|
+
// asked for is the decision, and it was not withheld.
|
|
416
|
+
if (
|
|
417
|
+
receipt.person_mode === true &&
|
|
418
|
+
receipt.intended_event === "APPROVE" &&
|
|
419
|
+
receipt.actual_event === "COMMENT" &&
|
|
420
|
+
receipt.reconciled !== true
|
|
421
|
+
)
|
|
422
|
+
return { verdict: "APPROVE" };
|
|
409
423
|
if (
|
|
410
424
|
receipt.intended_event === "COMMENT" &&
|
|
411
425
|
receipt.actual_event === "COMMENT" &&
|
|
@@ -1537,12 +1551,11 @@ export class VerdictWatcher {
|
|
|
1537
1551
|
if (!this.deps.cfg.dry_run && this.deps.adapter.listReviewsFull) {
|
|
1538
1552
|
try {
|
|
1539
1553
|
const marker = postingMarker(round.posting_key);
|
|
1540
|
-
const bot = this.deps.cfg.github.bot_login;
|
|
1541
1554
|
const reviews = await this.deps.adapter.listReviewsFull(round.pr);
|
|
1542
1555
|
reconciled = true;
|
|
1543
1556
|
const matches = reviews.filter(
|
|
1544
1557
|
(review) =>
|
|
1545
|
-
(
|
|
1558
|
+
ownLogins(this.deps.cfg.github).includes(review.user) &&
|
|
1546
1559
|
review.commit_id?.toLowerCase() === expectedHead.toLowerCase() &&
|
|
1547
1560
|
review.body.includes(marker),
|
|
1548
1561
|
);
|
|
@@ -1596,6 +1609,7 @@ export class VerdictWatcher {
|
|
|
1596
1609
|
gh_commit_id: match.commit_id,
|
|
1597
1610
|
gh_state: match.state,
|
|
1598
1611
|
...(verifiedIntent ? {} : { reconciled: true }),
|
|
1612
|
+
...(isPersonMode(this.deps.cfg.github) ? { person_mode: true as const } : {}),
|
|
1599
1613
|
};
|
|
1600
1614
|
if (verdict && !receiptMatchesVerdict(synthetic, verdict)) {
|
|
1601
1615
|
return {
|
|
@@ -1804,7 +1818,7 @@ export class VerdictWatcher {
|
|
|
1804
1818
|
);
|
|
1805
1819
|
}
|
|
1806
1820
|
const restored = restoreStandingLifecycle(store, round.pr, standing, {
|
|
1807
|
-
botLogin: cfg.github
|
|
1821
|
+
botLogin: botAccountLogin(cfg.github),
|
|
1808
1822
|
now: () => this.now(),
|
|
1809
1823
|
reason: standing
|
|
1810
1824
|
? `posting-guarded-noop:${standing}`
|
|
@@ -2339,7 +2353,11 @@ export class VerdictWatcher {
|
|
|
2339
2353
|
v.pr,
|
|
2340
2354
|
{ type: "verdict", verdict: v.verdict },
|
|
2341
2355
|
{ head_sha: v.head_sha },
|
|
2342
|
-
{
|
|
2356
|
+
{
|
|
2357
|
+
botLogin: botAccountLogin(cfg.github),
|
|
2358
|
+
now: () => this.now(),
|
|
2359
|
+
reason: `verdict:${v.verdict}`,
|
|
2360
|
+
},
|
|
2343
2361
|
);
|
|
2344
2362
|
store.logEvent("verdict_applied", v.pr, {
|
|
2345
2363
|
file: name,
|
|
@@ -3486,7 +3504,7 @@ export class VerdictWatcher {
|
|
|
3486
3504
|
pr,
|
|
3487
3505
|
{ type: "round_overdue", standing },
|
|
3488
3506
|
{},
|
|
3489
|
-
{ botLogin: cfg.github
|
|
3507
|
+
{ botLogin: botAccountLogin(cfg.github), now: () => this.now(), reason: `anomaly:${kind}` },
|
|
3490
3508
|
);
|
|
3491
3509
|
const command = round ? store.sessionCommandForRound(pr, round.round_no) : undefined;
|
|
3492
3510
|
const successor = store.successorFor(pr);
|
package/src/version.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
SCAN_SCHEMA_VERSION,
|
|
9
9
|
VERSION_SCHEMA_VERSION,
|
|
10
10
|
} from "@quickchatai/pi-quickreview/src/contract.js";
|
|
11
|
-
import { piPinFromPackageJson } from "./onboard/
|
|
11
|
+
import { piPinFromPackageJson } from "./onboard/pipin.js";
|
|
12
12
|
|
|
13
13
|
export interface VersionInfo {
|
|
14
14
|
schema_version: number;
|
package/src/webhook.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { createHmac, timingSafeEqual } from "node:crypto";
|
|
|
9
9
|
import { createServer, type IncomingMessage, type Server, type ServerResponse } from "node:http";
|
|
10
10
|
import { captureFromEvent, recordCapturedComment } from "./capture.js";
|
|
11
11
|
import { reviewTeamSlug, type Config } from "./config.js";
|
|
12
|
+
import { botAccountLogin } from "@quickchatai/pi-quickreview/src/identity.js";
|
|
12
13
|
import { interpretReviewEvent, isFeedbackBody, ledgerFeedbackSignal } from "./feedback.js";
|
|
13
14
|
import { applyEvent as applyEventFor, mergedOverBlock } from "./statemachine.js";
|
|
14
15
|
import type { StateStore, StatusSnapshot } from "./state.js";
|
|
@@ -20,6 +21,8 @@ import { blockedPrAuthor } from "./pr-conversation.js";
|
|
|
20
21
|
* header, a wrong prefix, or a length mismatch (timingSafeEqual throws on
|
|
21
22
|
* unequal lengths — we must not let that leak as a 500). */
|
|
22
23
|
export function verifySignature(raw: Buffer, header: string | undefined, secret: string): boolean {
|
|
24
|
+
// An empty secret signs nothing: anyone can compute that HMAC.
|
|
25
|
+
if (secret === "") return false;
|
|
23
26
|
if (!header || !header.startsWith("sha256=")) return false;
|
|
24
27
|
const expected = Buffer.from(signBody(raw, secret), "utf8");
|
|
25
28
|
const given = Buffer.from(header, "utf8");
|
|
@@ -499,6 +502,10 @@ export function handleDelivery(
|
|
|
499
502
|
raw: Buffer,
|
|
500
503
|
): WebhookHandleResult {
|
|
501
504
|
const log = deps.log ?? (() => {});
|
|
505
|
+
// The polling shape (and so `[github] auth = "user"`) takes no webhooks:
|
|
506
|
+
// the daemon hands no secret, and every delivery is refused unread. The
|
|
507
|
+
// reconcile poll is that install's only trigger.
|
|
508
|
+
if (deps.secret === "") return { status: 404, reason: "webhooks-disabled" };
|
|
502
509
|
if (!verifySignature(raw, headers.signature, deps.secret)) {
|
|
503
510
|
logRejection(deps, log, headers);
|
|
504
511
|
return { status: 403, reason: "bad-signature" };
|
|
@@ -810,7 +817,9 @@ export async function applyInterpretation(
|
|
|
810
817
|
i: Interpretation,
|
|
811
818
|
): Promise<void> {
|
|
812
819
|
const { store, cfg } = deps;
|
|
813
|
-
|
|
820
|
+
// The bot ACCOUNT for PR authorship. Person mode has none; no webhook
|
|
821
|
+
// arrives there, but the state machine reads one rule everywhere.
|
|
822
|
+
const opts = { botLogin: botAccountLogin(cfg.github) };
|
|
814
823
|
const local = <T>(run: () => T): T => store.webhookLocalOnce(deps.deliveryGuid, run);
|
|
815
824
|
switch (i.kind) {
|
|
816
825
|
case "trigger":
|
package/src/wire.ts
CHANGED
|
@@ -54,7 +54,11 @@ import { priorSidecarPath } from "@quickchatai/pi-quickreview/src/priorfindings.
|
|
|
54
54
|
import { completeRecordedFindings } from "./recordedfindings.js";
|
|
55
55
|
import { makePostingGuard } from "@quickchatai/pi-quickreview/src/guards.js";
|
|
56
56
|
import { classifyCi, ciBlocksApproval } from "@quickchatai/pi-quickreview/src/cigate.js";
|
|
57
|
-
import {
|
|
57
|
+
import {
|
|
58
|
+
githubCredential,
|
|
59
|
+
type GitHubCredential,
|
|
60
|
+
} from "@quickchatai/pi-quickreview/src/githubAuth.js";
|
|
61
|
+
import { botAccountLogin, isPersonMode } from "@quickchatai/pi-quickreview/src/identity.js";
|
|
58
62
|
import {
|
|
59
63
|
FeedbackEngine,
|
|
60
64
|
FeedbackMemoryPump,
|
|
@@ -125,6 +129,7 @@ import {
|
|
|
125
129
|
} from "./openviking/provisionreport.js";
|
|
126
130
|
import { countedGapSink } from "./openviking/gapsink.js";
|
|
127
131
|
import { recoverPrForOperator } from "./operator-recovery.js";
|
|
132
|
+
import { reviewNow } from "./reviewnow.js";
|
|
128
133
|
import { createWorkerLiveness, inFlightPrs } from "./workerliveness.js";
|
|
129
134
|
import { resolveTerminalFailure } from "./terminal-failure.js";
|
|
130
135
|
import type { MemoryStore } from "./memory/store.js";
|
|
@@ -158,7 +163,8 @@ import { buildWorkerWorld } from "./workerworld.js";
|
|
|
158
163
|
export interface ProductionParts {
|
|
159
164
|
cfg: Config;
|
|
160
165
|
root: string;
|
|
161
|
-
|
|
166
|
+
/** The `[github] auth` credential: the App minter, or the person's token file. */
|
|
167
|
+
minter: GitHubCredential;
|
|
162
168
|
gate: MutationGate;
|
|
163
169
|
adapter: GitHubAdapter;
|
|
164
170
|
/** The tmux manager: it serves what has not moved to workers yet (the overseer) and
|
|
@@ -225,7 +231,7 @@ export function buildParts(
|
|
|
225
231
|
process.env.QCR_OPENVIKING_BOOT_DISABLED === "1" && overlaid.openviking.enabled
|
|
226
232
|
? "OpenViking state migration is incomplete; memory is unavailable for this boot — original files were retained; retry after correcting storage and restarting"
|
|
227
233
|
: undefined;
|
|
228
|
-
const minter =
|
|
234
|
+
const minter = githubCredential(cfg.github);
|
|
229
235
|
const gate: MutationGate = new MutationGate(
|
|
230
236
|
cfg.dry_run,
|
|
231
237
|
join(root, "state", "dryrun"),
|
|
@@ -1052,7 +1058,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1052
1058
|
// the base clone; the daemon's own bot identity never qualifies.
|
|
1053
1059
|
directiveAuthor: (sha, paths) =>
|
|
1054
1060
|
sessions.worktrees.lastHumanAuthor(sha, paths, {
|
|
1055
|
-
|
|
1061
|
+
// Person mode has no bot account: the person's own commits are a
|
|
1062
|
+
// human's, and they may well be the one to mention.
|
|
1063
|
+
botLogins: isPersonMode(cfg.github) ? [] : [cfg.github.bot_login, cfg.github.app_slug],
|
|
1056
1064
|
}),
|
|
1057
1065
|
log,
|
|
1058
1066
|
// Lazy on purpose: the Slack subsystem is built in onStart, after the
|
|
@@ -1552,7 +1560,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1552
1560
|
outcomes: d.outcomes,
|
|
1553
1561
|
memory,
|
|
1554
1562
|
repo: cfg.github.repo,
|
|
1555
|
-
|
|
1563
|
+
// The bot ACCOUNT, against captured human comments: none in person
|
|
1564
|
+
// mode, where the person's replies are a human's.
|
|
1565
|
+
botLogin: botAccountLogin(cfg.github),
|
|
1556
1566
|
healthy: () => health.currentState() === "healthy",
|
|
1557
1567
|
// No case batch starts while a review round reads memory (its seed,
|
|
1558
1568
|
// its lesson selection); every batch sent reports its embedding
|
|
@@ -1580,7 +1590,7 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1580
1590
|
root,
|
|
1581
1591
|
eodTime: cfg.eod.time,
|
|
1582
1592
|
timeZone: cfg.eod.timezone,
|
|
1583
|
-
botLogin: cfg.github
|
|
1593
|
+
botLogin: botAccountLogin(cfg.github),
|
|
1584
1594
|
baseBranch: cfg.github.base_branch,
|
|
1585
1595
|
config: learnerKnobsOf(cfg.memory),
|
|
1586
1596
|
git: sessions.worktrees,
|
|
@@ -1696,6 +1706,21 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1696
1706
|
"restart-session",
|
|
1697
1707
|
);
|
|
1698
1708
|
},
|
|
1709
|
+
// The operator's "review this PR now" (the onboarding proof round):
|
|
1710
|
+
// the label path's state-machine trigger, with no GitHub write to ask.
|
|
1711
|
+
reviewNow(pr) {
|
|
1712
|
+
return reviewNow(
|
|
1713
|
+
{
|
|
1714
|
+
store: d.store,
|
|
1715
|
+
getPr: (n) => adapter.getPr(n),
|
|
1716
|
+
pump: () => d.pump(),
|
|
1717
|
+
// On the own-account route the bot login is the person, whose
|
|
1718
|
+
// own PRs are the point; only an App's bot is never reviewed.
|
|
1719
|
+
...(isPersonMode(cfg.github) ? {} : { botLogin: cfg.github.bot_login }),
|
|
1720
|
+
},
|
|
1721
|
+
pr,
|
|
1722
|
+
);
|
|
1723
|
+
},
|
|
1699
1724
|
resolveTerminalFailure(payload) {
|
|
1700
1725
|
return resolveTerminalFailure(
|
|
1701
1726
|
{
|
|
@@ -1861,7 +1886,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1861
1886
|
// Webhook-URL self-heal: only under the tunnel-file ingress shape. The
|
|
1862
1887
|
// gated PATCH rides the app-self-config class, so it executes even in
|
|
1863
1888
|
// dry-run (AGENTS.md invariant 6) — loudly.
|
|
1864
|
-
|
|
1889
|
+
// Never under the person's credential: there is no App whose webhook
|
|
1890
|
+
// URL could be re-pointed (config load already refuses the shape).
|
|
1891
|
+
if (cfg.ingress.shape === "tunnel-file" && !isPersonMode(cfg.github)) {
|
|
1865
1892
|
webhookHeal = new WebhookHealer({
|
|
1866
1893
|
hostnameFile: ingressHostnameFile(cfg, root),
|
|
1867
1894
|
readConfig: () => adapter.getAppWebhookConfig(),
|
|
@@ -2112,6 +2139,8 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
2112
2139
|
adapter,
|
|
2113
2140
|
botLogin: cfg.github.bot_login,
|
|
2114
2141
|
guards: cfg.guards,
|
|
2142
|
+
// Person mode: every review event posts as COMMENT (guards.ts).
|
|
2143
|
+
personMode: isPersonMode(cfg.github),
|
|
2115
2144
|
log,
|
|
2116
2145
|
}),
|
|
2117
2146
|
);
|
package/src/workerworld.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
// PiSessionManager that still exists serves what has not moved yet (the overseer, for now)
|
|
19
19
|
// and lends its path helpers and environment, which is what keeps a worker's session the same
|
|
20
20
|
// session a tmux round saw.
|
|
21
|
+
import { isPersonMode } from "@quickchatai/pi-quickreview/src/identity.js";
|
|
21
22
|
import { mkdirSync, readFileSync } from "node:fs";
|
|
22
23
|
import { join } from "node:path";
|
|
23
24
|
import { AnswerHost, answerCapsOf } from "./answerworker.js";
|
|
@@ -223,6 +224,7 @@ export function buildWorkerWorld(o: WorkerWorldOptions): WorkerWorld {
|
|
|
223
224
|
const journal = new PostingJournal({
|
|
224
225
|
dir: join(stateDir, "posting-receipts"),
|
|
225
226
|
repo: cfg.github.repo,
|
|
227
|
+
personMode: isPersonMode(cfg.github),
|
|
226
228
|
});
|
|
227
229
|
|
|
228
230
|
// The takeover and debug managers are built before the supervisor (it takes their gates)
|
|
@@ -311,7 +313,11 @@ export function buildWorkerWorld(o: WorkerWorldOptions): WorkerWorld {
|
|
|
311
313
|
store,
|
|
312
314
|
journal,
|
|
313
315
|
cfg,
|
|
314
|
-
|
|
316
|
+
// Marker-matched (posting-outbox.ts markedReviewsOf), so the person's
|
|
317
|
+
// login alone is safe in person mode: there is no App slug to add.
|
|
318
|
+
botLogins: isPersonMode(cfg.github)
|
|
319
|
+
? [cfg.github.bot_login]
|
|
320
|
+
: [cfg.github.bot_login, cfg.github.app_slug],
|
|
315
321
|
roundOf: commandRoundOf(store, headOf),
|
|
316
322
|
log,
|
|
317
323
|
},
|