toolroll 0.9.67 → 0.9.68
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/CHANGELOG.md +36 -0
- package/dist/acp-client.js +1 -3
- package/dist/agent-board.d.ts +0 -1
- package/dist/agent-board.js +0 -1
- package/dist/agent-fence.js +3 -0
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +31 -29
- package/dist/builder.js +3 -26
- package/dist/canonical-json.d.ts +14 -0
- package/dist/canonical-json.js +36 -0
- package/dist/chat-actions.js +1 -2
- package/dist/chat-admission.d.ts +19 -0
- package/dist/chat-admission.js +22 -0
- package/dist/chat-channel.js +1 -1
- package/dist/chat-delivery.js +0 -1
- package/dist/chat-follow.d.ts +17 -0
- package/dist/chat-follow.js +32 -0
- package/dist/chat-messages.js +0 -1
- package/dist/chat-settings-page.d.ts +23 -0
- package/dist/chat-settings-page.js +41 -0
- package/dist/claim.js +3 -6
- package/dist/claude-print.d.ts +12 -0
- package/dist/claude-print.js +34 -0
- package/dist/cli-http.d.ts +0 -7
- package/dist/cli-http.js +0 -21
- package/dist/cli.d.ts +3 -10
- package/dist/cli.js +15 -24
- package/dist/coding-provider.js +2 -1
- package/dist/coding-workspace.js +1 -1
- package/dist/{team-cli.d.ts → connect-cli.d.ts} +5 -9
- package/dist/connect-cli.js +331 -0
- package/dist/containment.d.ts +0 -2
- package/dist/containment.js +2 -6
- package/dist/contracts/chat-actions.d.ts +0 -1
- package/dist/contracts/chat-content.d.ts +0 -4
- package/dist/contracts/chat-content.js +0 -2
- package/dist/contracts/chat-tables.d.ts +0 -1
- package/dist/contracts/cli.d.ts +0 -62
- package/dist/contracts/cli.js +0 -4
- package/dist/contracts/coding-workspace.js +1 -1
- package/dist/contracts/contract.js +1 -1
- package/dist/contracts/flow-card.d.ts +0 -1
- package/dist/contracts/flow-propose.d.ts +0 -1
- package/dist/contracts/flow-send.js +1 -1
- package/dist/contracts/gateway-tools.d.ts +0 -1
- package/dist/contracts/integration-metadata.js +1 -1
- package/dist/contracts/lead-tools.d.ts +0 -1
- package/dist/contracts/memory-pass.d.ts +0 -1
- package/dist/contracts/memory-pass.js +1 -1
- package/dist/contracts/plan.js +1 -1
- package/dist/contracts/project-knowledge.js +1 -1
- package/dist/contracts/project-skills.d.ts +0 -1
- package/dist/contracts/proof.js +1 -1
- package/dist/contracts/recipes.js +1 -1
- package/dist/contracts/scope.js +1 -1
- package/dist/contracts/scout-report.js +1 -1
- package/dist/contracts/teams-callback.d.ts +0 -1
- package/dist/converse.d.ts +0 -6
- package/dist/converse.js +0 -19
- package/dist/daemon.js +3 -2
- package/dist/decision.d.ts +1 -3
- package/dist/deprecations.d.ts +12 -4
- package/dist/deprecations.js +27 -4
- package/dist/desktop-update-recovery.js +1 -1
- package/dist/desktop-update.js +3 -2
- package/dist/discord-chat.js +4 -15
- package/dist/discord-settings.d.ts +2 -6
- package/dist/discord-settings.js +10 -38
- package/dist/discord.js +12 -23
- package/dist/evidence.d.ts +0 -1
- package/dist/evidence.js +0 -3
- package/dist/exec.d.ts +0 -9
- package/dist/exec.js +3 -81
- package/dist/flow-actions.js +0 -3
- package/dist/flow-draft.d.ts +1 -3
- package/dist/flow-draft.js +15 -28
- package/dist/flow-scripts.d.ts +1 -8
- package/dist/flow-scripts.js +0 -13
- package/dist/flow-send.js +1 -1
- package/dist/flow-share.d.ts +0 -2
- package/dist/flow-share.js +1 -6
- package/dist/flow-steps.js +1 -1
- package/dist/flow-triggers.d.ts +0 -1
- package/dist/flow-triggers.js +1 -2
- package/dist/flow-unattended.js +1 -12
- package/dist/flows.js +1 -1
- package/dist/health-cli.d.ts +2 -2
- package/dist/health-cli.js +1 -1
- package/dist/invoke.d.ts +0 -3
- package/dist/invoke.js +5 -3
- package/dist/is-record.d.ts +2 -0
- package/dist/is-record.js +2 -0
- package/dist/lead-doors.d.ts +1 -5
- package/dist/lead-doors.js +0 -4
- package/dist/lead-tools.js +3 -6
- package/dist/live-detail.d.ts +0 -1
- package/dist/live-detail.js +0 -6
- package/dist/live-terminal.js +2 -1
- package/dist/live.d.ts +0 -1
- package/dist/live.js +1 -2
- package/dist/mcp-core.js +0 -2
- package/dist/memory-pass.js +1 -1
- package/dist/model-catalog.js +1 -1
- package/dist/modes.js +1 -12
- package/dist/operate.js +383 -750
- package/dist/password-bearer.d.ts +0 -2
- package/dist/password-bearer.js +0 -4
- package/dist/peek-cli.js +2 -1
- package/dist/peek.d.ts +2 -26
- package/dist/peek.js +2 -168
- package/dist/phase-routing.d.ts +0 -4
- package/dist/phase-routing.js +2 -21
- package/dist/planner-source.d.ts +2 -1
- package/dist/planner-source.js +2 -12
- package/dist/planner.js +2 -14
- package/dist/process-tree.d.ts +0 -2
- package/dist/process-tree.js +0 -10
- package/dist/project-delete.d.ts +0 -2
- package/dist/project-delete.js +1 -3
- package/dist/project-learning.d.ts +0 -14
- package/dist/project-skills.d.ts +0 -1
- package/dist/project-skills.js +0 -14
- package/dist/project-tools.js +2 -10
- package/dist/provider.d.ts +0 -17
- package/dist/provider.js +0 -26
- package/dist/pulls.d.ts +0 -2
- package/dist/pulls.js +0 -9
- package/dist/release-adapters.d.ts +3 -0
- package/dist/release-adapters.js +15 -5
- package/dist/remote-exec.d.ts +3 -2
- package/dist/remote-exec.js +3 -2
- package/dist/repos.d.ts +0 -5
- package/dist/repos.js +2 -10
- package/dist/repository-context.d.ts +0 -2
- package/dist/repository-context.js +0 -4
- package/dist/restart-certification.d.ts +0 -2
- package/dist/restart-certification.js +1 -5
- package/dist/result-follow-ups.d.ts +1 -4
- package/dist/result-follow-ups.js +1 -6
- package/dist/result-review.d.ts +0 -2
- package/dist/result-review.js +0 -2
- package/dist/retention.d.ts +0 -1
- package/dist/retention.js +0 -1
- package/dist/review-context.d.ts +0 -1
- package/dist/review-context.js +1 -12
- package/dist/reviewer.d.ts +0 -16
- package/dist/reviewer.js +0 -18
- package/dist/run-closeout.js +2 -1
- package/dist/scope.js +1 -13
- package/dist/scout-browser.js +2 -1
- package/dist/serve.js +2 -2
- package/dist/server/console.css +5 -133
- package/dist/server/flows.js +2 -2
- package/dist/server/http.d.ts +2 -0
- package/dist/server/http.js +5 -0
- package/dist/server/pages.js +2 -2
- package/dist/server/people-tokens.js +3 -4
- package/dist/server/remote.js +1 -6
- package/dist/server/render-chat.d.ts +9 -2
- package/dist/server/render-chat.js +53 -7
- package/dist/server/render-results.d.ts +0 -6
- package/dist/server/render-results.js +3 -9
- package/dist/server/render-tasks.js +4 -5
- package/dist/server/route-table.d.ts +0 -4
- package/dist/server/route-table.js +0 -6
- package/dist/server/settings.js +23 -23
- package/dist/server/task-views.js +1 -1
- package/dist/server/tasks.js +3 -3
- package/dist/setup-guide.d.ts +2 -2
- package/dist/skills.d.ts +0 -6
- package/dist/skills.js +0 -8
- package/dist/slack-chat.d.ts +1 -7
- package/dist/slack-chat.js +5 -18
- package/dist/slack-settings.d.ts +2 -6
- package/dist/slack-settings.js +10 -38
- package/dist/slack.js +12 -23
- package/dist/sleep.d.ts +2 -0
- package/dist/sleep.js +2 -0
- package/dist/store.d.ts +0 -73
- package/dist/store.js +3 -177
- package/dist/structured-output.d.ts +0 -1
- package/dist/structured-output.js +0 -1
- package/dist/subagent-work.d.ts +0 -2
- package/dist/subagent-work.js +0 -2
- package/dist/subagents.d.ts +1 -3
- package/dist/subagents.js +20 -33
- package/dist/subscription-chat.d.ts +1 -3
- package/dist/subscription-chat.js +2 -3
- package/dist/task-sizing.d.ts +1 -4
- package/dist/task-sizing.js +3 -10
- package/dist/teams-chat.js +4 -11
- package/dist/teams.js +12 -19
- package/dist/telegram-lead.js +2 -2
- package/dist/telegram.js +1 -1
- package/dist/token-notices.d.ts +0 -11
- package/dist/token-notices.js +1 -5
- package/dist/tool-secret-store.d.ts +0 -3
- package/dist/tool-secret-store.js +2 -11
- package/dist/toolroll-update.d.ts +0 -2
- package/dist/toolroll-update.js +2 -2
- package/dist/verification-evidence.d.ts +0 -1
- package/dist/verification-evidence.js +0 -1
- package/dist/webhooks.d.ts +0 -1
- package/dist/webhooks.js +0 -1
- package/dist/workspace-ui.d.ts +0 -8
- package/dist/workspace-ui.js +1 -6
- package/package.json +1 -1
- package/dist/contracts/native-census.d.ts +0 -42
- package/dist/contracts/native-census.js +0 -36
- package/dist/process-recovery-anchor.d.ts +0 -75
- package/dist/process-recovery-anchor.js +0 -188
- package/dist/process-recovery-coalition.d.ts +0 -25
- package/dist/process-recovery-coalition.js +0 -105
- package/dist/process-recovery-eligibility.d.ts +0 -179
- package/dist/process-recovery-eligibility.js +0 -174
- package/dist/process-recovery-native.d.ts +0 -161
- package/dist/process-recovery-native.js +0 -595
- package/dist/process-recovery-provenance.d.ts +0 -163
- package/dist/process-recovery-provenance.js +0 -292
- package/dist/process-recovery-services.d.ts +0 -56
- package/dist/process-recovery-services.js +0 -191
- package/dist/process-recovery-settlement.d.ts +0 -32
- package/dist/process-recovery-settlement.js +0 -133
- package/dist/process-recovery.d.ts +0 -41
- package/dist/process-recovery.js +0 -91
- package/dist/session-brief.d.ts +0 -8
- package/dist/session-brief.js +0 -24
- package/dist/session-cli.d.ts +0 -42
- package/dist/session-cli.js +0 -271
- package/dist/session-contract.d.ts +0 -183
- package/dist/session-contract.js +0 -122
- package/dist/session-remote.d.ts +0 -19
- package/dist/session-remote.js +0 -86
- package/dist/session-service.d.ts +0 -22
- package/dist/session-service.js +0 -157
- package/dist/team-cli.js +0 -692
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { TEXT_LIMITS } from "../text-limits.js";
|
|
9
9
|
import { limited, readVersioned, toModelSchema, versioned } from "./contract.js";
|
|
10
|
+
import { isRecord } from "../is-record.js";
|
|
10
11
|
export const MEMORY_EFFECTS = ["harm", "non-compliance", "irrelevant"];
|
|
11
12
|
export const MEMORY_DOMAINS = ["project", "orchestration"];
|
|
12
13
|
export const MEMORY_PROPOSAL_KINDS = ["instruction-add", "instruction-remove", "decision-add"];
|
|
@@ -64,7 +65,6 @@ export const memoryVerdictReadSchema = memoryVerdictSchema.strip().extend({
|
|
|
64
65
|
export const MEMORY_VERDICT_VERSION = 1;
|
|
65
66
|
/** A verdict as a session keeps it. */
|
|
66
67
|
export const savedVerdictSchema = versioned(MEMORY_VERDICT_VERSION, verdictShape(saved));
|
|
67
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
68
68
|
/**
|
|
69
69
|
* A verdict kept before it carried `version` (through 0.9.36), as version 1. Those left a gap's `matchesGap` out when
|
|
70
70
|
* there was none; that reads as null. Values are never rewritten.
|
package/dist/contracts/plan.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { ACCEPTANCE_LIMITS, EVIDENCE_KINDS } from "../scope.js";
|
|
9
9
|
import { limited, readVersioned, toModelSchema, versioned } from "./contract.js";
|
|
10
|
+
import { isRecord } from "../is-record.js";
|
|
10
11
|
/** How many paths a plan may say it touches. */
|
|
11
12
|
export const PLAN_TOUCHES = 32;
|
|
12
13
|
/** One acceptance criterion: the scope's own shape (scope.ts `AcceptanceCriterion`), `how` advisory and unsigned. */
|
|
@@ -37,7 +38,6 @@ function pick(body, fields) {
|
|
|
37
38
|
}
|
|
38
39
|
return out;
|
|
39
40
|
}
|
|
40
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41
41
|
/**
|
|
42
42
|
* A plan written before plans carried `version` (every plan through 0.9.33), as version 1. The old parser read only
|
|
43
43
|
* the fields it knew and ignored any others, read a null goal, plan or acceptance as missing and null touches as
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { limited, readVersioned, versioned } from "./contract.js";
|
|
10
10
|
import { decisionLineSchema } from "./project-memory.js";
|
|
11
|
+
import { isRecord } from "../is-record.js";
|
|
11
12
|
/** How many references a project keeps, and how many a run is given. Text limits live in TEXT_LIMITS. */
|
|
12
13
|
export const KNOWLEDGE_COUNTS = { references: 12, selected: 3, decisions: 8 };
|
|
13
14
|
const written = limited;
|
|
@@ -30,7 +31,6 @@ export const KNOWLEDGE_VERSION = 1;
|
|
|
30
31
|
export const knowledgeSchema = versioned(KNOWLEDGE_VERSION, knowledgeShape(written));
|
|
31
32
|
/** Knowledge as it is read back. */
|
|
32
33
|
export const savedKnowledgeSchema = versioned(KNOWLEDGE_VERSION, knowledgeShape(saved));
|
|
33
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34
34
|
function pick(body, fields) {
|
|
35
35
|
const out = {};
|
|
36
36
|
for (const field of fields)
|
|
@@ -83,7 +83,6 @@ export declare const skillSelectionSchema: z.ZodRecord<z.ZodString, z.ZodObject<
|
|
|
83
83
|
sha: z.ZodString;
|
|
84
84
|
enabled: z.ZodBoolean;
|
|
85
85
|
}, z.core.$strict>>;
|
|
86
|
-
export type SkillChoice = z.infer<typeof skillChoiceSchema>;
|
|
87
86
|
export type SkillSelection = z.infer<typeof skillSelectionSchema>;
|
|
88
87
|
export declare const SKILLS_SNAPSHOT_VERSION = 1;
|
|
89
88
|
/** The versions a run is pinned to, as frozen: the packages by digest. */
|
package/dist/contracts/proof.js
CHANGED
|
@@ -8,6 +8,7 @@ import { z } from "zod";
|
|
|
8
8
|
import { TEXT_LIMITS } from "../text-limits.js";
|
|
9
9
|
import { EVIDENCE_KINDS } from "../scope.js";
|
|
10
10
|
import { limited, readVersioned, versioned } from "./contract.js";
|
|
11
|
+
import { isRecord } from "../is-record.js";
|
|
11
12
|
/** How many entries each proof list may hold. Text limits live in TEXT_LIMITS. */
|
|
12
13
|
export const PROOF_COUNTS = { criteria: 12, evidencePerCriterion: 4, checks: 12, changed: 64, caveats: 8, screenshots: 8 };
|
|
13
14
|
/** Every proof limit by its long-standing name: the counts above and the byte limits from TEXT_LIMITS. */
|
|
@@ -62,7 +63,6 @@ export const proofSchema = versioned(PROOF_VERSION, {
|
|
|
62
63
|
caveats: z.array(line("caveat")).max(PROOF_COUNTS.caveats),
|
|
63
64
|
screenshots: z.array(proofScreenshotSchema).max(PROOF_COUNTS.screenshots),
|
|
64
65
|
});
|
|
65
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
66
66
|
/** The listed fields of `body`, a null or missing one left out (the old parser read null text as missing). */
|
|
67
67
|
function pick(body, fields) {
|
|
68
68
|
const out = {};
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
import { parseContract, versioned } from "./contract.js";
|
|
15
15
|
import { savedCriterionSchema } from "./scope.js";
|
|
16
|
+
import { isRecord } from "../is-record.js";
|
|
16
17
|
export const RECIPE_FORMAT = "standing-orders-recipe";
|
|
17
18
|
/** Numbers the recipe rules use, in plain code after parsing (bytes of the whole document, characters of a field). */
|
|
18
19
|
export const RECIPE_LIMITS = { documentBytes: 32_768, description: 400, inputs: 8, label: 80, answer: 500 };
|
|
@@ -38,7 +39,6 @@ const recipeFields = {
|
|
|
38
39
|
export const recipeV1Schema = versioned(1, recipeFields);
|
|
39
40
|
export const recipeV2Schema = versioned(2, { ...recipeFields, inputs: z.array(recipeInputSchema).min(1).max(RECIPE_LIMITS.inputs) });
|
|
40
41
|
export const recipeDocumentSchema = z.discriminatedUnion("version", [recipeV1Schema, recipeV2Schema]);
|
|
41
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42
42
|
/** A success check as the scope reader reads it: an absent or empty `how` is null; every other key, known or not, as given. */
|
|
43
43
|
function checkBody(entry) {
|
|
44
44
|
if (!isRecord(entry) || (entry["how"] !== undefined && entry["how"] !== ""))
|
package/dist/contracts/scope.js
CHANGED
|
@@ -18,6 +18,7 @@ import { TEXT_LIMITS } from "../text-limits.js";
|
|
|
18
18
|
import { ACCEPTANCE_LIMITS } from "./acceptance-terms.js";
|
|
19
19
|
import { contractProblemOf, parseContract } from "./contract.js";
|
|
20
20
|
import { acceptanceCriterionSchema as planCriterionSchema, planSchema } from "./plan.js";
|
|
21
|
+
import { isRecord } from "../is-record.js";
|
|
21
22
|
/** A criterion as saved and as every reader returns it: the plan's criterion with `how` always present (null for none). */
|
|
22
23
|
export const savedCriterionSchema = z.lazy(() => planCriterionSchema.extend({ how: planCriterionSchema.shape.how.unwrap() }));
|
|
23
24
|
/** A rubric as saved: at most twelve criteria (an empty one is a scope filed before rubrics, or by a road with none). */
|
|
@@ -33,7 +34,6 @@ export const scopeTermsSchema = z.lazy(() => z.strictObject({
|
|
|
33
34
|
touches: z.array(planSchema.shape.touches.unwrap().element).max(TEXT_LIMITS.scopeTouches).optional(),
|
|
34
35
|
acceptance: rubricSchema.optional(),
|
|
35
36
|
}));
|
|
36
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37
37
|
/** A criterion as the reader takes it: only the fields it knows, a null or empty `how` as null. Anything else as is. */
|
|
38
38
|
function criterionBody(entry) {
|
|
39
39
|
if (!isRecord(entry))
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { limitRule, TEXT_LIMITS } from "../text-limits.js";
|
|
10
10
|
import { limited, readVersioned, toModelSchema, versioned } from "./contract.js";
|
|
11
|
+
import { isRecord } from "../is-record.js";
|
|
11
12
|
/** How many follow-ups, items and screenshots a report may carry. */
|
|
12
13
|
export const REPORT_COUNTS = { followUps: 5, items: 6, images: 8 };
|
|
13
14
|
/** Caps are BYTES of UTF-8 (v4 review, finding 11): a 64 KiB report is 64 KiB whatever script it is written in. They
|
|
@@ -96,7 +97,6 @@ export const scoutHandbackSchema = z.strictObject({
|
|
|
96
97
|
decision: scoutDecisionSchema.optional(),
|
|
97
98
|
});
|
|
98
99
|
export const SCOUT_OUTPUT_JSON_SCHEMA = toModelSchema(scoutHandbackSchema);
|
|
99
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
100
100
|
function pick(body, fields) {
|
|
101
101
|
const out = {};
|
|
102
102
|
for (const field of fields) {
|
|
@@ -9,6 +9,5 @@ import { type ContractResult } from "./contract.js";
|
|
|
9
9
|
export declare const teamsSubmitSchema: z.ZodObject<{
|
|
10
10
|
so: z.ZodString;
|
|
11
11
|
}, z.core.$strip>;
|
|
12
|
-
export type TeamsSubmit = z.infer<typeof teamsSubmitSchema>;
|
|
13
12
|
/** A submit's one-time token. */
|
|
14
13
|
export declare function readTeamsSubmit(value: unknown): ContractResult<string>;
|
package/dist/converse.d.ts
CHANGED
|
@@ -66,10 +66,6 @@ export declare function priceForConfig(config: {
|
|
|
66
66
|
}): ModelPrice | null;
|
|
67
67
|
export declare function worstCaseForPrice(price: ModelPrice, promptBytes: number): number;
|
|
68
68
|
export declare function settleForPrice(price: ModelPrice, tokensIn: number, tokensOut: number): number;
|
|
69
|
-
/** The worst a turn can cost, in integer micro-dollars: every prompt byte
|
|
70
|
-
* as a token-third (generous) plus the full output allowance. */
|
|
71
|
-
export declare function worstCaseMicrousd(model: string, promptBytes: number): number | null;
|
|
72
|
-
export declare function settleMicrousd(model: string, tokensIn: number, tokensOut: number): number | null;
|
|
73
69
|
export declare const DIRECT_CHAT_PROVIDERS: readonly DirectChatProviderId[];
|
|
74
70
|
export declare const SUBSCRIPTION_CHAT_PROVIDERS: readonly SubscriptionChatProviderId[];
|
|
75
71
|
export declare function isDirectChatProvider(provider: ChatProviderId): provider is DirectChatProviderId;
|
|
@@ -167,8 +163,6 @@ export declare function leadWorstCaseForPrice(price: ModelPrice, baseBytes: numb
|
|
|
167
163
|
callCap?: number;
|
|
168
164
|
textCap?: number;
|
|
169
165
|
}): number;
|
|
170
|
-
/** The bytes a tool result costs on the wire: its JSON string form. */
|
|
171
|
-
export declare function embeddedBytes(text: string): number;
|
|
172
166
|
export type LeadToolSchema = {
|
|
173
167
|
name: string;
|
|
174
168
|
description: string;
|
package/dist/converse.js
CHANGED
|
@@ -131,21 +131,6 @@ export function worstCaseForPrice(price, promptBytes) {
|
|
|
131
131
|
export function settleForPrice(price, tokensIn, tokensOut) {
|
|
132
132
|
return tokensIn * price.inMicrousd + tokensOut * price.outMicrousd;
|
|
133
133
|
}
|
|
134
|
-
/** The worst a turn can cost, in integer micro-dollars: every prompt byte
|
|
135
|
-
* as a token-third (generous) plus the full output allowance. */
|
|
136
|
-
export function worstCaseMicrousd(model, promptBytes) {
|
|
137
|
-
const price = priceOf(model);
|
|
138
|
-
if (price === null)
|
|
139
|
-
return null;
|
|
140
|
-
const inputTokens = Math.ceil(promptBytes / 3);
|
|
141
|
-
return inputTokens * price.inMicrousd + MAX_OUTPUT_TOKENS * price.outMicrousd;
|
|
142
|
-
}
|
|
143
|
-
export function settleMicrousd(model, tokensIn, tokensOut) {
|
|
144
|
-
const price = priceOf(model);
|
|
145
|
-
if (price === null)
|
|
146
|
-
return null;
|
|
147
|
-
return tokensIn * price.inMicrousd + tokensOut * price.outMicrousd;
|
|
148
|
-
}
|
|
149
134
|
// ---------------------------------------------------------------- keys
|
|
150
135
|
export const DIRECT_CHAT_PROVIDERS = ["anthropic-api", "openrouter-api"];
|
|
151
136
|
export const SUBSCRIPTION_CHAT_PROVIDERS = ["claude-subscription", "codex-subscription"];
|
|
@@ -389,10 +374,6 @@ export function leadWorstCaseForPrice(price, baseBytes, caps = {}) {
|
|
|
389
374
|
}
|
|
390
375
|
return input * price.inMicrousd + S * MAX_OUTPUT_TOKENS * price.outMicrousd;
|
|
391
376
|
}
|
|
392
|
-
/** The bytes a tool result costs on the wire: its JSON string form. */
|
|
393
|
-
export function embeddedBytes(text) {
|
|
394
|
-
return Buffer.byteLength(JSON.stringify(text), "utf8");
|
|
395
|
-
}
|
|
396
377
|
/** Anthropic prices a cache write at 1.25x and a cache read at 0.1x the input price (5-minute cache). */
|
|
397
378
|
export const CACHE_WRITE_RATIO = 1.25;
|
|
398
379
|
export const CACHE_READ_RATIO = 0.1;
|
package/dist/daemon.js
CHANGED
|
@@ -42,6 +42,7 @@ import { fileURLToPath } from "node:url";
|
|
|
42
42
|
import { dirname, join } from "node:path";
|
|
43
43
|
import { isAlive } from "./runner.js";
|
|
44
44
|
import { envTwins } from "./names.js";
|
|
45
|
+
import { sleep as defaultSleep } from "./sleep.js";
|
|
45
46
|
/** A stable fingerprint of a unit's text: the changed-definition test. */
|
|
46
47
|
export function definitionDigest(unitContent) {
|
|
47
48
|
return createHash("sha256").update(unitContent).digest("hex").slice(0, 16);
|
|
@@ -52,7 +53,7 @@ export function definitionDigest(unitContent) {
|
|
|
52
53
|
* appears to succeed, then the pending bootout removes the new job too. Wait
|
|
53
54
|
* for the observable supervisor boundary before loading the replacement.
|
|
54
55
|
*/
|
|
55
|
-
async function waitForLaunchdBootout(run, service, attempts = 50, sleep =
|
|
56
|
+
async function waitForLaunchdBootout(run, service, attempts = 50, sleep = defaultSleep) {
|
|
56
57
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
57
58
|
const status = await run("launchctl", ["print", service]);
|
|
58
59
|
if (status.code !== 0)
|
|
@@ -624,7 +625,7 @@ export async function daemonStatus(plan, run) {
|
|
|
624
625
|
* FRESH one, newer than what stood before the start, so a stale row from
|
|
625
626
|
* the previous incarnation cannot pass for the new controller.
|
|
626
627
|
*/
|
|
627
|
-
export async function awaitFreshHeartbeat(store, runnerName, heartbeatBefore, deadlineMs = 5_000, sleep =
|
|
628
|
+
export async function awaitFreshHeartbeat(store, runnerName, heartbeatBefore, deadlineMs = 5_000, sleep = defaultSleep) {
|
|
628
629
|
const deadline = Date.now() + deadlineMs;
|
|
629
630
|
for (;;) {
|
|
630
631
|
const live = store.getRunner(runnerName)?.runner ?? null;
|
package/dist/decision.d.ts
CHANGED
|
@@ -14,9 +14,7 @@
|
|
|
14
14
|
* caps also keep one screen one screen: an option list that needs scrolling
|
|
15
15
|
* has already failed the milestone sentence.
|
|
16
16
|
*/
|
|
17
|
-
import { type
|
|
18
|
-
/** One option as a decision keeps it (src/contracts/decision.ts). */
|
|
19
|
-
export type ParsedOption = DecisionOption;
|
|
17
|
+
import { type DecisionPayload } from "./contracts/decision.js";
|
|
20
18
|
/** A decision as read: the payload's fields, its text trimmed, and the optional ones present or null. */
|
|
21
19
|
export type ParsedDecision = Omit<DecisionPayload, "assignee" | "deadline"> & {
|
|
22
20
|
assignee: string | null;
|
package/dist/deprecations.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* D5 (schema v117): one AI concept, the lead. The central team service (
|
|
2
|
+
* D5 (schema v117): one AI concept, the lead. The central team service's CLI (the central `lead list|create|update|
|
|
3
3
|
* member|transfer`, `conversation …`, and `chat`/`brief` with --lead, --conversation or a saved profile) and native
|
|
4
|
-
* coding sessions (`session …`)
|
|
5
|
-
*
|
|
6
|
-
* `--json` answer stays one envelope. Their code goes in the next minor release.
|
|
4
|
+
* coding sessions (`session …`) were deprecated in 0.9.56 and are removed now: each answers with one line naming what
|
|
5
|
+
* to use instead, changing nothing. `connect` stays — remote commands and `toolroll health` use the profile it saves.
|
|
7
6
|
*/
|
|
8
7
|
export type Deprecated = "team" | "session";
|
|
9
8
|
/** The one line a deprecated command prints on stderr: what it is, when it goes, and what to use instead. */
|
|
10
9
|
export declare function deprecationWarning(command: string, kind: Deprecated): string;
|
|
11
10
|
/** What a deprecated console page or API says about itself. */
|
|
12
11
|
export declare const DEPRECATED_PAGE: Record<Deprecated, string>;
|
|
12
|
+
/** The removed command an invocation names, as `{ named, kind }`; null when it is a live command. `chat`/`brief`
|
|
13
|
+
* without --local went to the central service whenever a profile was saved (`savedProfile`, asked only then): that
|
|
14
|
+
* invocation is removed too, never quietly run against this computer's lead instead. */
|
|
15
|
+
export declare function removedCommand(argv: readonly string[], savedProfile?: () => boolean): {
|
|
16
|
+
named: string;
|
|
17
|
+
kind: Deprecated;
|
|
18
|
+
} | null;
|
|
19
|
+
/** The one line a removed command answers with. */
|
|
20
|
+
export declare function removedMessage(named: string, kind: Deprecated): string;
|
package/dist/deprecations.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* D5 (schema v117): one AI concept, the lead. The central team service (
|
|
2
|
+
* D5 (schema v117): one AI concept, the lead. The central team service's CLI (the central `lead list|create|update|
|
|
3
3
|
* member|transfer`, `conversation …`, and `chat`/`brief` with --lead, --conversation or a saved profile) and native
|
|
4
|
-
* coding sessions (`session …`)
|
|
5
|
-
*
|
|
6
|
-
* `--json` answer stays one envelope. Their code goes in the next minor release.
|
|
4
|
+
* coding sessions (`session …`) were deprecated in 0.9.56 and are removed now: each answers with one line naming what
|
|
5
|
+
* to use instead, changing nothing. `connect` stays — remote commands and `toolroll health` use the profile it saves.
|
|
7
6
|
*/
|
|
8
7
|
const NEXT_STEP = {
|
|
9
8
|
team: "Talk to your lead with `toolroll chat`.",
|
|
@@ -18,3 +17,27 @@ export const DEPRECATED_PAGE = {
|
|
|
18
17
|
team: "Team chat is deprecated and will be removed in the next minor release. Your lead in Chat does the same work.",
|
|
19
18
|
session: "Coding sessions are deprecated and will be removed in the next minor release. Queue work as a task instead.",
|
|
20
19
|
};
|
|
20
|
+
const CENTRAL_LEAD_ACTIONS = ["list", "create", "update", "member", "transfer"];
|
|
21
|
+
const CENTRAL_CHAT_FLAGS = ["--profile", "--lead", "--conversation", "--authorize", "--terms-digest", "--request-id"];
|
|
22
|
+
/** The removed command an invocation names, as `{ named, kind }`; null when it is a live command. `chat`/`brief`
|
|
23
|
+
* without --local went to the central service whenever a profile was saved (`savedProfile`, asked only then): that
|
|
24
|
+
* invocation is removed too, never quietly run against this computer's lead instead. */
|
|
25
|
+
export function removedCommand(argv, savedProfile = () => false) {
|
|
26
|
+
const [first, second] = argv;
|
|
27
|
+
const verb = () => argv.slice(1).find(arg => !arg.startsWith("-")) ?? "";
|
|
28
|
+
if (first === "session")
|
|
29
|
+
return { named: `session ${verb()}`.trim(), kind: "session" };
|
|
30
|
+
if (first === "conversation")
|
|
31
|
+
return { named: `conversation ${verb()}`.trim(), kind: "team" };
|
|
32
|
+
if (first === "lead" && second !== "token" && second !== "say" && argv.some(arg => arg === "--profile" || CENTRAL_LEAD_ACTIONS.includes(arg)))
|
|
33
|
+
return { named: `lead ${verb()}`.trim(), kind: "team" };
|
|
34
|
+
if ((first === "chat" || first === "brief") && argv.some(arg => CENTRAL_CHAT_FLAGS.includes(arg)))
|
|
35
|
+
return { named: `${first} --conversation`, kind: "team" };
|
|
36
|
+
if ((first === "chat" || first === "brief") && !argv.includes("--local") && savedProfile())
|
|
37
|
+
return { named: `${first} --conversation`, kind: "team" };
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/** The one line a removed command answers with. */
|
|
41
|
+
export function removedMessage(named, kind) {
|
|
42
|
+
return `\`toolroll ${named}\` was removed. ${NEXT_STEP[kind]}`;
|
|
43
|
+
}
|
|
@@ -8,9 +8,9 @@ import { bundleHash } from "./desktop-bundle.js";
|
|
|
8
8
|
import { installLaunchdService, launchdPlist } from "./daemon.js";
|
|
9
9
|
import { run } from "./exec.js";
|
|
10
10
|
import { desktopUpdateStatus, durableJson, installationLock, pauseUpdateRecovery, readUpdateJournal, requestUpdateRestore, sqliteLock, updateTerminal } from "./desktop-update.js";
|
|
11
|
+
import { sleep } from "./sleep.js";
|
|
11
12
|
const recordFile = (j) => join(j.workDir, "recovery.json");
|
|
12
13
|
const app = (j) => join(j.workDir, "Updater.app");
|
|
13
|
-
const sleep = (ms) => new Promise(done => setTimeout(done, ms));
|
|
14
14
|
function readRecovery(j) {
|
|
15
15
|
const file = recordFile(j);
|
|
16
16
|
if (!existsSync(file))
|
package/dist/desktop-update.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { closeSync, chmodSync, copyFileSync, cpSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync,
|
|
2
|
+
import { closeSync, chmodSync, copyFileSync, cpSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
@@ -14,6 +14,7 @@ import { currentDesktopAccess } from "./desktop-access.js";
|
|
|
14
14
|
import { assertCodingUpdateStopped, backupCodingCatalog, codingCatalogExists, releaseStaleCodingOwner } from "./coding-update.js";
|
|
15
15
|
import { processMayBeAlive } from "./process-liveness.js";
|
|
16
16
|
import { readDesktopRecoveryView, readDesktopUpdateJournal, supervisorPidsOf, updateRequestIs } from "./contracts/update-journal.js";
|
|
17
|
+
import { sleep as defaultSleep } from "./sleep.js";
|
|
17
18
|
/** Loaded on first use (as backup.ts and store.ts do), so modules that only import this one (the console,
|
|
18
19
|
* and tests that load it in a browser-like environment) never need `node:sqlite` itself. */
|
|
19
20
|
function sqlite() {
|
|
@@ -657,7 +658,7 @@ export async function runDesktopUpdate(stateDir, hooks = {}) {
|
|
|
657
658
|
lock.close();
|
|
658
659
|
throw Error("Another updater is working on this app. Its operation was not interrupted.");
|
|
659
660
|
}
|
|
660
|
-
const sleep = hooks.sleep ??
|
|
661
|
+
const sleep = hooks.sleep ?? defaultSleep;
|
|
661
662
|
const control = async (action, bundle, journal) => {
|
|
662
663
|
if (action === "start" && updateStopRequested(journal))
|
|
663
664
|
throw Error("You stopped the background service. Automatic restart is disabled for this update.");
|
package/dist/discord-chat.js
CHANGED
|
@@ -3,8 +3,7 @@ import { chatQuestionButtons } from "./subagent-question.js";
|
|
|
3
3
|
import { chatAskButtons } from "./chat-ask.js";
|
|
4
4
|
import { chatFlowButtons } from "./chat-flow.js";
|
|
5
5
|
import { refuseResultShots, resultShotsPruned, shotWaitsUntil } from "./result-shots.js";
|
|
6
|
-
import {
|
|
7
|
-
import { roomCommand } from "./chat-rooms.js";
|
|
6
|
+
import { admitChatEvent } from "./chat-admission.js";
|
|
8
7
|
import { ChatState, ChatDeliveryError, chatHash, partContent, } from "./chat-delivery-state.js";
|
|
9
8
|
import { readChatPart } from "./contracts/chat-content.js";
|
|
10
9
|
import { readDiscordButtonToken, readDiscordComponentInteraction } from "./contracts/discord-callback.js";
|
|
@@ -100,20 +99,10 @@ export function receiveDiscord(state, identity, type, raw, now) {
|
|
|
100
99
|
!discordId(thread) ||
|
|
101
100
|
member === identity.bot)
|
|
102
101
|
return false;
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
const inbox = isRoom && kind === "message" ? channelInbox(state.store, "discord", identity.installation, String(channel), words) : { watched: false, command: false };
|
|
106
|
-
const roomish = isRoom && (state.room(identity.installation, String(channel)) !== null || (kind === "message" && roomCommand(words) !== null) || inbox.watched || inbox.command);
|
|
107
|
-
if (isRoom && !roomish)
|
|
108
|
-
return false;
|
|
109
|
-
const binding = state.bindingFor(identity.installation, member);
|
|
110
|
-
const open = inbox.watched && !inbox.command;
|
|
111
|
-
if (kind === "pair"
|
|
112
|
-
? !!binding || isRoom
|
|
113
|
-
: !open && (!binding ||
|
|
114
|
-
!state.live(binding) ||
|
|
115
|
-
(binding.channel !== channel && !roomish)))
|
|
102
|
+
const admitted = admitChatEvent(state, "discord", identity.installation, { kind, member, channel, isRoom, payload });
|
|
103
|
+
if (admitted === null)
|
|
116
104
|
return false;
|
|
105
|
+
const { binding } = admitted;
|
|
117
106
|
return state.enqueue({
|
|
118
107
|
id: chatHash(`${identity.installation}:${kind === "action" ? "interaction" : "message"}:${id}`),
|
|
119
108
|
installation: identity.installation,
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import type { Store } from "./store.js";
|
|
2
2
|
import { type Html } from "./html.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
problem?: string;
|
|
6
|
-
now?: Date;
|
|
7
|
-
who?: string;
|
|
8
|
-
}): Html;
|
|
3
|
+
import { type ChatSettingsOptions } from "./chat-settings-page.js";
|
|
4
|
+
export declare function discordSettingsHtml(store: Store, dir: string, options?: ChatSettingsOptions): Html;
|
package/dist/discord-settings.js
CHANGED
|
@@ -1,41 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { html, postForm } from "./html.js";
|
|
1
|
+
import { html } from "./html.js";
|
|
3
2
|
import { loadDiscordCredentials } from "./discord-api.js";
|
|
4
|
-
import {
|
|
3
|
+
import { chatSettingsHtml } from "./chat-settings-page.js";
|
|
5
4
|
export function discordSettingsHtml(store, dir, options = {}) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const parts = [];
|
|
15
|
-
if (!credentials) {
|
|
16
|
-
parts.push(html `<p>Manage projects and review results in a private Discord conversation.</p>`, html `<details open><summary>Create your Discord app</summary><ol><li><a href="https://discord.com/developers/applications" target="_blank" rel="noopener noreferrer">Create an application</a>, then copy its token from the Bot page.</li><li>Keep the Interactions Endpoint URL empty and privileged intents off.</li><li>Under Installation, enable Guild Install with the bot scope and no server permissions. Use its install link to add it to your server, then open a direct message to the bot.</li></ol></details>`, post("connect", html `<label>Bot token<input style="min-height:44px" type="password" name="bot-token" autocomplete="off" required></label>${password}<p class="meta">The token stays on this installation. Next, pair your own Discord account.</p><button type="submit">Connect Discord</button>`));
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
parts.push(html `<p><strong>${credentials.workspace}</strong> · ${live ? "Connected" : "Waiting for connection"}</p>`);
|
|
20
|
-
if (runtime?.problem)
|
|
21
|
-
parts.push(html `<p role="status">${String(runtime.problem)}</p>`);
|
|
22
|
-
if (!live && !runtime?.problem)
|
|
23
|
-
parts.push(html `<p>Keep the Toolroll worker running to receive Discord messages.</p>`);
|
|
24
|
-
if (options.code) {
|
|
25
|
-
parts.push(html `<h2>Pair your account</h2><p>Send this in a direct message to your Toolroll Discord app. It expires in 10 minutes.</p>`, html `<label>Pairing message<input type="text" readonly value="pair ${options.code}" autocomplete="off" style="width:100%;max-width:100%;font-size:14px;min-height:44px"></label>`, html `<a class="button-link" style="min-height:44px;white-space:nowrap" href="/settings/discord">Check connection</a>`);
|
|
26
|
-
}
|
|
27
|
-
else if (binding && state.live(binding)) {
|
|
28
|
-
const { pending, dropped: failed } = state.partCounts(binding.id);
|
|
29
|
-
parts.push(html `<p>Your Discord account is paired.${others ? ` ${others} teammate${others === 1 ? " is" : "s are"} paired too.` : ""}${pending ? ` ${pending} replies waiting to send.` : ""}${failed ? ` ${failed} replies could not be delivered. Open the saved chat to recover them.` : ""}</p>`, html `<p>Try “What needs my attention?” or “Show the evidence for the latest result.”</p>`, html `<p><a href="/chat">Open saved chat</a></p>`, loadPrimary(process.env, dir) === "discord"
|
|
30
|
-
? html `<p>Task updates are sent here.</p>`
|
|
31
|
-
: post("alerts", html `<button type="submit">Send task updates here</button>`));
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
parts.push(post("pair", html `<h2>Pair your account</h2><p>Your paired Discord account can read your connected projects and confirm proposed changes. Password approvals still open in Toolroll.${others ? ` ${others} teammate${others === 1 ? " is" : "s are"} already paired.` : ""}</p>${password}<button type="submit">Create pairing code</button>`));
|
|
35
|
-
}
|
|
36
|
-
if (binding && state.live(binding) && !options.code)
|
|
37
|
-
parts.push(post("unpair", html `${password}<p class="meta">Unpairing ends every open button in your chat. Teammates are unaffected.</p><button type="submit">Unpair my account</button>`));
|
|
38
|
-
parts.push(html `<details><summary>Connection settings</summary>${post("disconnect", html `${password}<button type="submit">Disconnect Discord</button>`)}</details>`);
|
|
39
|
-
}
|
|
40
|
-
return html `<section style="max-width:42rem;overflow-wrap:anywhere"><p><a href="/settings">Settings</a></p><h1>Discord</h1>${options.problem ? html `<p class="problem" role="alert">${options.problem}</p>` : ""}${parts}<details><summary>Access and setup</summary><p>Private messages and replies use your Toolroll permissions. Shared channels are not supported. Secure review links use this installation’s configured HTTPS console address.</p><p>The worker connects out to Discord. It does not need a public webhook or a Tailscale account.</p></details></section>`;
|
|
5
|
+
return chatSettingsHtml(store, dir, options, {
|
|
6
|
+
provider: "discord",
|
|
7
|
+
label: "Discord",
|
|
8
|
+
credentials: loadDiscordCredentials(dir),
|
|
9
|
+
setup: html `<details open><summary>Create your Discord app</summary><ol><li><a href="https://discord.com/developers/applications" target="_blank" rel="noopener noreferrer">Create an application</a>, then copy its token from the Bot page.</li><li>Keep the Interactions Endpoint URL empty and privileged intents off.</li><li>Under Installation, enable Guild Install with the bot scope and no server permissions. Use its install link to add it to your server, then open a direct message to the bot.</li></ol></details>`,
|
|
10
|
+
connect: password => html `<label>Bot token<input style="min-height:44px" type="password" name="bot-token" autocomplete="off" required></label>${password}<p class="meta">The token stays on this installation. Next, pair your own Discord account.</p><button type="submit">Connect Discord</button>`,
|
|
11
|
+
access: html `<p>Private messages and replies use your Toolroll permissions. Shared channels are not supported. Secure review links use this installation’s configured HTTPS console address.</p><p>The worker connects out to Discord. It does not need a public webhook or a Tailscale account.</p>`,
|
|
12
|
+
});
|
|
41
13
|
}
|
package/dist/discord.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** A single leased Discord Gateway connection, hosted by the ordinary worker. */
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
|
-
import {
|
|
3
|
+
import { abortablePause, workChatQueue } from "./chat-follow.js";
|
|
4
4
|
import { loadDiscordCredentials, discordApi, object, discordId, } from "./discord-api.js";
|
|
5
5
|
import { ChatState, chatHash } from "./chat-delivery-state.js";
|
|
6
6
|
import { receiveDiscord, processDiscordEvent, deliverDiscordPart, planDiscordNotifications, planDiscordRooms, } from "./discord-chat.js";
|
|
@@ -12,14 +12,7 @@ export function discordReadyMatches(raw, identity) {
|
|
|
12
12
|
}
|
|
13
13
|
export async function followDiscord(options) {
|
|
14
14
|
const owner = randomBytes(16).toString("hex"), state = new ChatState(options.store, "discord");
|
|
15
|
-
const pause =
|
|
16
|
-
try {
|
|
17
|
-
await sleep(ms, undefined, { signal: options.signal });
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
/* shutdown */
|
|
21
|
-
}
|
|
22
|
-
};
|
|
15
|
+
const pause = abortablePause(options.signal);
|
|
23
16
|
while (!options.signal.aborted) {
|
|
24
17
|
const credentials = loadDiscordCredentials(options.dir);
|
|
25
18
|
if (!credentials ||
|
|
@@ -129,20 +122,16 @@ export async function followDiscord(options) {
|
|
|
129
122
|
};
|
|
130
123
|
try {
|
|
131
124
|
await client.login(credentials.botToken);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (same() && options.notifications())
|
|
143
|
-
await planDiscordNotifications(chat);
|
|
144
|
-
await pause(1000);
|
|
145
|
-
}
|
|
125
|
+
await workChatQueue({
|
|
126
|
+
same,
|
|
127
|
+
ready: () => connected && !(state.retryAt(credentials.installation) > new Date().toISOString()),
|
|
128
|
+
pause,
|
|
129
|
+
notifications: () => options.notifications(),
|
|
130
|
+
process: () => processDiscordEvent(chat),
|
|
131
|
+
rooms: () => planDiscordRooms(chat),
|
|
132
|
+
deliver: () => deliverDiscordPart(chat),
|
|
133
|
+
notify: () => planDiscordNotifications(chat),
|
|
134
|
+
});
|
|
146
135
|
}
|
|
147
136
|
catch {
|
|
148
137
|
if (alive)
|
package/dist/evidence.d.ts
CHANGED
|
@@ -80,7 +80,6 @@ export declare function evidenceRoot(home: string): string;
|
|
|
80
80
|
* name. The agent learns the name from its brief and nowhere else.
|
|
81
81
|
*/
|
|
82
82
|
export declare function mailboxName(): string;
|
|
83
|
-
export declare function looksLikeMailbox(name: string): boolean;
|
|
84
83
|
/** Every protocol file the sweep must never let an old attempt leave behind.
|
|
85
84
|
* The pre-rename NIGHTORDERS- prefix stays recognized here — a worktree cut
|
|
86
85
|
* down before 2026-08-13 may still hold one, and cleanup has no vintage. */
|
package/dist/evidence.js
CHANGED
|
@@ -128,9 +128,6 @@ export function evidenceRoot(home) {
|
|
|
128
128
|
export function mailboxName() {
|
|
129
129
|
return `${MAILBOX_PREFIX}${randomBytes(8).toString("hex")}${MAILBOX_SUFFIX}`;
|
|
130
130
|
}
|
|
131
|
-
export function looksLikeMailbox(name) {
|
|
132
|
-
return name.startsWith(MAILBOX_PREFIX) && name.endsWith(MAILBOX_SUFFIX);
|
|
133
|
-
}
|
|
134
131
|
/** Every protocol file the sweep must never let an old attempt leave behind.
|
|
135
132
|
* The pre-rename NIGHTORDERS- prefix stays recognized here — a worktree cut
|
|
136
133
|
* down before 2026-08-13 may still hold one, and cleanup has no vintage. */
|
package/dist/exec.d.ts
CHANGED
|
@@ -246,15 +246,6 @@ export declare function run(file: string, args: readonly string[], options?: Run
|
|
|
246
246
|
* worst useful case while remaining a hard, per-event memory boundary.
|
|
247
247
|
*/
|
|
248
248
|
export declare const JSONL_EVENT_HARD_CAP: number;
|
|
249
|
-
/**
|
|
250
|
-
* The accounting an oversized Claude result still carries, read by a bounded scan of its kept prefix and tail: the
|
|
251
|
-
* session's running `total_cost_usd`, its `usage` and `num_turns`, and whether it is a main result at all (an
|
|
252
|
-
* `origin` naming anything but a person makes it a background task's). Anything unreadable or seen twice is absent.
|
|
253
|
-
*/
|
|
254
|
-
export declare function scanOversizedClaudeResult(prefix: Buffer, tail: Buffer | undefined): {
|
|
255
|
-
primary: boolean;
|
|
256
|
-
account: Record<string, unknown>;
|
|
257
|
-
};
|
|
258
249
|
/** Marks a Claude result whose session cost could not be read: the gateway charges the run's dollar cap instead. */
|
|
259
250
|
export declare const CLAUDE_COST_UNKNOWN = "standing_orders_cost_unknown";
|
|
260
251
|
export declare function runStreamJsonl(file: string, args: readonly string[], options?: RunOptions): Promise<ExecResult>;
|