@indigoai-us/hq-cli 5.345.197 → 5.345.199
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 +111 -0
- package/dist/command-catalog.generated.d.ts +393 -12
- package/dist/command-catalog.generated.js +482 -12
- package/dist/commands/bot-events.d.ts +19 -0
- package/dist/commands/bot-events.js +46 -0
- package/dist/commands/bot-jobs.d.ts +2 -0
- package/dist/commands/bot-jobs.js +43 -2
- package/dist/commands/bot.d.ts +5 -0
- package/dist/commands/bot.js +33 -1
- package/dist/commands/core-resolve-company-native.d.ts +2 -1
- package/dist/commands/core-resolve-company-native.js +2 -24
- package/dist/commands/deploy-domains.d.ts +14 -2
- package/dist/commands/deploy-domains.js +726 -42
- package/dist/commands/integrations-connect.js +41 -3
- package/dist/commands/lanes-report.d.ts +2 -1
- package/dist/commands/lanes-report.js +44 -1
- package/dist/commands/lanes.d.ts +9 -0
- package/dist/commands/lanes.js +95 -9
- package/dist/commands/meetings.js +1 -21
- package/dist/commands/secrets.js +27 -6
- package/dist/commands/signals-run.d.ts +2 -0
- package/dist/commands/signals-run.js +6 -1
- package/dist/lanes-drain-hook.js +9 -0
- package/dist/lib/bot/api.d.ts +5 -0
- package/dist/lib/bot/claude-login.d.ts +31 -0
- package/dist/lib/bot/claude-login.js +160 -0
- package/dist/lib/bot/company-bind.d.ts +34 -0
- package/dist/lib/bot/company-bind.js +112 -0
- package/dist/lib/bot/config.js +3 -1
- package/dist/lib/bot/events.d.ts +18 -0
- package/dist/lib/bot/events.js +160 -0
- package/dist/lib/bot/executive-settings.d.ts +10 -0
- package/dist/lib/bot/executive-settings.js +43 -0
- package/dist/lib/bot/fleet-cron.js +4 -0
- package/dist/lib/bot/fleet-local.d.ts +12 -0
- package/dist/lib/bot/fleet-local.js +50 -20
- package/dist/lib/bot/job-run.js +1 -1
- package/dist/lib/bot/jobs/hot-signal-sync.d.ts +8 -0
- package/dist/lib/bot/jobs/hot-signal-sync.js +2 -0
- package/dist/lib/bot/jobs/meeting-detect.d.ts +28 -0
- package/dist/lib/bot/jobs/meeting-detect.js +176 -0
- package/dist/lib/bot/jobs/meeting-rider.d.ts +53 -0
- package/dist/lib/bot/jobs/meeting-rider.js +284 -0
- package/dist/lib/bot/jobs/signal-to-lane.d.ts +32 -0
- package/dist/lib/bot/jobs/signal-to-lane.js +169 -0
- package/dist/lib/bot/local-jobs.d.ts +15 -2
- package/dist/lib/bot/local-jobs.js +24 -7
- package/dist/lib/bot/run.d.ts +7 -49
- package/dist/lib/bot/run.js +135 -12
- package/dist/lib/bot/session.d.ts +19 -1
- package/dist/lib/bot/session.js +75 -28
- package/dist/lib/bot/status.d.ts +21 -0
- package/dist/lib/core-utils/manifest-slugs.d.ts +2 -0
- package/dist/lib/core-utils/manifest-slugs.js +26 -0
- package/dist/lib/doctor/checks/bots.d.ts +6 -0
- package/dist/lib/doctor/checks/bots.js +47 -1
- package/dist/lib/hot-channels/adapters/meetings.d.ts +1 -0
- package/dist/lib/hot-channels/adapters/meetings.js +3 -1
- package/dist/lib/hot-channels/meeting-source-ref.d.ts +3 -0
- package/dist/lib/hot-channels/meeting-source-ref.js +7 -0
- package/dist/lib/hot-channels/schedule.js +2 -2
- package/dist/lib/hot-channels/signals-pass.d.ts +9 -32
- package/dist/lib/hot-channels/signals-pass.js +51 -17
- package/dist/lib/lanes/admission.d.ts +2 -0
- package/dist/lib/lanes/admission.js +4 -0
- package/dist/lib/lanes/approval-gate.js +4 -1
- package/dist/lib/lanes/links.d.ts +8 -1
- package/dist/lib/lanes/links.js +84 -3
- package/dist/lib/lanes/outcome.d.ts +154 -0
- package/dist/lib/lanes/outcome.js +151 -0
- package/dist/lib/lanes/reconcile.js +1 -0
- package/dist/lib/lanes/signal-brief-template.d.ts +7 -0
- package/dist/lib/lanes/signal-brief-template.js +40 -0
- package/dist/lib/lanes/signal-lane.d.ts +24 -0
- package/dist/lib/lanes/signal-lane.js +99 -0
- package/dist/lib/lanes/source-report.d.ts +37 -0
- package/dist/lib/lanes/source-report.js +66 -0
- package/dist/lib/lanes/spawn.d.ts +6 -0
- package/dist/lib/lanes/spawn.js +21 -0
- package/dist/lib/lanes/store.d.ts +3 -0
- package/dist/lib/lanes/store.js +64 -0
- package/dist/lib/lanes/story-ledger.d.ts +3 -0
- package/dist/lib/lanes/story-ledger.js +1 -0
- package/dist/lib/lanes/types.d.ts +137 -0
- package/dist/lib/lanes/types.js +17 -2
- package/dist/lib/lanes/watcher.js +4 -0
- package/dist/lib/live-meetings.d.ts +19 -0
- package/dist/lib/live-meetings.js +23 -0
- package/dist/lib/mesh/live/daemon/doctor.js +6 -7
- package/dist/lib/mesh/live/spool.d.ts +8 -0
- package/dist/lib/mesh/live/spool.js +59 -40
- package/dist/lib/plan-limit-nag.d.ts +30 -4
- package/dist/lib/plan-limit-nag.js +68 -17
- package/dist/lib/signals/engine.d.ts +4 -0
- package/dist/lib/signals/engine.js +25 -5
- package/dist/lib/signals/incremental.d.ts +42 -0
- package/dist/lib/signals/incremental.js +191 -0
- package/dist/lib/signals/prior-signals.d.ts +11 -0
- package/dist/lib/signals/prior-signals.js +44 -0
- package/dist/lib/signals/reply.js +6 -1
- package/dist/lib/signals/settings.d.ts +5 -0
- package/dist/lib/signals/settings.js +17 -0
- package/dist/lib/signals/steps/extract.d.ts +30 -2
- package/dist/lib/signals/steps/extract.js +153 -11
- package/dist/lib/signals/steps/types.d.ts +1 -0
- package/dist/lib/signals/write-guard.js +7 -0
- package/dist/secrets-env-action.d.ts +70 -0
- package/dist/secrets-env-action.js +220 -2
- package/dist/utils/cognito-callback-port.d.ts +15 -0
- package/dist/utils/cognito-callback-port.js +51 -0
- package/dist/utils/cognito-config.js +2 -3
- package/dist/utils/cognito-session.d.ts +7 -6
- package/dist/utils/cognito-session.js +14 -14
- package/dist/utils/interactive-caller.d.ts +15 -0
- package/dist/utils/interactive-caller.js +70 -0
- package/dist/utils/login-browser.js +3 -1
- package/dist/utils/resident-package-preload.js +4 -0
- package/package.json +9 -7
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* §4, §5.5, §6.2). Finite sets are string-literal unions plus `const` arrays
|
|
4
4
|
* so the command layer can validate flags explicitly.
|
|
5
5
|
*/
|
|
6
|
+
import { type LaneOutcome } from "./outcome.js";
|
|
6
7
|
export declare const LANE_SCHEMA_VERSION: "hq-lane.v1";
|
|
7
8
|
export declare const QUESTION_SCHEMA_VERSION: "hq-lane-question.v1";
|
|
8
9
|
export declare const ENVELOPE_SCHEMA_VERSION: "hq-lane-envelope.v1";
|
|
@@ -85,6 +86,76 @@ export declare const LANE_ENVELOPE_JSON_SCHEMA: {
|
|
|
85
86
|
readonly type: readonly ["string", "null"];
|
|
86
87
|
readonly description: "Optional worker fingerprint (hq fingerprint self); null when it could not be built. Older readers ignore it.";
|
|
87
88
|
};
|
|
89
|
+
readonly outcome: {
|
|
90
|
+
readonly type: "object";
|
|
91
|
+
readonly additionalProperties: false;
|
|
92
|
+
readonly required: readonly ["state", "outcome", "gathered", "next_steps"];
|
|
93
|
+
readonly properties: {
|
|
94
|
+
readonly state: {
|
|
95
|
+
readonly enum: readonly ["done", "needs_decision", "partial"];
|
|
96
|
+
};
|
|
97
|
+
readonly outcome: {
|
|
98
|
+
readonly type: "string";
|
|
99
|
+
readonly minLength: 1;
|
|
100
|
+
readonly pattern: "\\S";
|
|
101
|
+
};
|
|
102
|
+
readonly gathered: {
|
|
103
|
+
readonly type: "array";
|
|
104
|
+
readonly items: {
|
|
105
|
+
readonly type: "object";
|
|
106
|
+
readonly additionalProperties: false;
|
|
107
|
+
readonly required: readonly ["label", "text"];
|
|
108
|
+
readonly properties: {
|
|
109
|
+
readonly label: {
|
|
110
|
+
readonly type: "string";
|
|
111
|
+
readonly minLength: 1;
|
|
112
|
+
readonly pattern: "\\S";
|
|
113
|
+
};
|
|
114
|
+
readonly text: {
|
|
115
|
+
readonly type: "string";
|
|
116
|
+
readonly minLength: 1;
|
|
117
|
+
readonly pattern: "\\S";
|
|
118
|
+
};
|
|
119
|
+
readonly ref: {
|
|
120
|
+
readonly type: "string";
|
|
121
|
+
readonly minLength: 1;
|
|
122
|
+
readonly pattern: "\\S";
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
readonly next_steps: {
|
|
128
|
+
readonly type: "array";
|
|
129
|
+
readonly items: {
|
|
130
|
+
readonly type: "string";
|
|
131
|
+
readonly minLength: 1;
|
|
132
|
+
readonly pattern: "\\S";
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
readonly decision_id: {
|
|
136
|
+
readonly type: "string";
|
|
137
|
+
readonly minLength: 1;
|
|
138
|
+
readonly pattern: "\\S";
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
readonly allOf: readonly [{
|
|
142
|
+
readonly if: {
|
|
143
|
+
readonly properties: {
|
|
144
|
+
readonly state: {
|
|
145
|
+
readonly const: "partial";
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
readonly then: {
|
|
150
|
+
readonly properties: {
|
|
151
|
+
readonly next_steps: {
|
|
152
|
+
readonly minItems: 1;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
}];
|
|
157
|
+
readonly description: string;
|
|
158
|
+
};
|
|
88
159
|
};
|
|
89
160
|
readonly allOf: readonly [{
|
|
90
161
|
readonly if: {
|
|
@@ -171,6 +242,57 @@ export declare const LANE_ENVELOPE_JSON_SCHEMA: {
|
|
|
171
242
|
};
|
|
172
243
|
};
|
|
173
244
|
};
|
|
245
|
+
}, {
|
|
246
|
+
readonly if: {
|
|
247
|
+
readonly required: readonly ["outcome"];
|
|
248
|
+
readonly properties: {
|
|
249
|
+
readonly outcome: {
|
|
250
|
+
readonly properties: {
|
|
251
|
+
readonly state: {
|
|
252
|
+
readonly const: "needs_decision";
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
readonly then: {
|
|
259
|
+
readonly anyOf: readonly [{
|
|
260
|
+
readonly properties: {
|
|
261
|
+
readonly outcome: {
|
|
262
|
+
readonly required: readonly ["decision_id"];
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
}, {
|
|
266
|
+
readonly required: readonly ["questions"];
|
|
267
|
+
readonly properties: {
|
|
268
|
+
readonly questions: {
|
|
269
|
+
readonly minItems: 1;
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
}];
|
|
273
|
+
};
|
|
274
|
+
}, {
|
|
275
|
+
readonly if: {
|
|
276
|
+
readonly required: readonly ["outcome"];
|
|
277
|
+
readonly properties: {
|
|
278
|
+
readonly decision: {
|
|
279
|
+
readonly const: "blocked";
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
readonly then: {
|
|
284
|
+
readonly properties: {
|
|
285
|
+
readonly outcome: {
|
|
286
|
+
readonly properties: {
|
|
287
|
+
readonly state: {
|
|
288
|
+
readonly not: {
|
|
289
|
+
readonly const: "done";
|
|
290
|
+
};
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
};
|
|
174
296
|
}];
|
|
175
297
|
readonly description: string;
|
|
176
298
|
};
|
|
@@ -523,7 +645,15 @@ export interface LaneStory {
|
|
|
523
645
|
verified_at?: string;
|
|
524
646
|
verified_by?: SeniorRef;
|
|
525
647
|
}
|
|
648
|
+
export interface LaneSignal {
|
|
649
|
+
signal_id: string;
|
|
650
|
+
type: string;
|
|
651
|
+
source_ref: string;
|
|
652
|
+
title: string;
|
|
653
|
+
}
|
|
526
654
|
export interface LaneRecord {
|
|
655
|
+
signal?: LaneSignal;
|
|
656
|
+
signal_link?: string;
|
|
527
657
|
schema_version: typeof LANE_SCHEMA_VERSION | string;
|
|
528
658
|
lane_id: string;
|
|
529
659
|
/** CLI release that most recently wrote this lane record. Absent on legacy rows. */
|
|
@@ -729,6 +859,11 @@ export interface LaneRecord {
|
|
|
729
859
|
story_status?: StoryStatus;
|
|
730
860
|
/** Envelope parser failures retained when a usable ask is recovered. */
|
|
731
861
|
envelope_validation_errors?: string[];
|
|
862
|
+
/**
|
|
863
|
+
* Copied from the last ingested envelope's optional `outcome` block.
|
|
864
|
+
* Cleared when a later envelope carries no outcome.
|
|
865
|
+
*/
|
|
866
|
+
outcome?: LaneOutcome;
|
|
732
867
|
/** Set by the reconcile pass when `--timeout` has passed (spec §5.7). */
|
|
733
868
|
overdue?: boolean;
|
|
734
869
|
overdue_at?: string;
|
|
@@ -1027,6 +1162,8 @@ export interface LaneEnvelope {
|
|
|
1027
1162
|
story_complete_reason?: string;
|
|
1028
1163
|
/** The worker's fingerprint, or null when it could not be built. Optional. */
|
|
1029
1164
|
fingerprint?: string | null;
|
|
1165
|
+
/** Optional structured result block (see outcome.ts). */
|
|
1166
|
+
outcome?: LaneOutcome;
|
|
1030
1167
|
}
|
|
1031
1168
|
export interface AccountConfig {
|
|
1032
1169
|
/** Company slug or UID owning this account. Untagged accounts are personal. */
|
package/dist/lib/lanes/types.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* so the command layer can validate flags explicitly.
|
|
5
5
|
*/
|
|
6
6
|
import { LanesError, LaneSchemaError } from "./errors.js";
|
|
7
|
+
import { LANE_OUTCOME_ENVELOPE_RULES, LANE_OUTCOME_JSON_SCHEMA, parseLaneOutcome, } from "./outcome.js";
|
|
7
8
|
export const LANE_SCHEMA_VERSION = "hq-lane.v1";
|
|
8
9
|
export const QUESTION_SCHEMA_VERSION = "hq-lane-question.v1";
|
|
9
10
|
export const ENVELOPE_SCHEMA_VERSION = "hq-lane-envelope.v1";
|
|
@@ -53,6 +54,7 @@ export const LANE_ENVELOPE_JSON_SCHEMA = {
|
|
|
53
54
|
type: ["string", "null"],
|
|
54
55
|
description: "Optional worker fingerprint (hq fingerprint self); null when it could not be built. Older readers ignore it.",
|
|
55
56
|
},
|
|
57
|
+
outcome: LANE_OUTCOME_JSON_SCHEMA,
|
|
56
58
|
},
|
|
57
59
|
allOf: [
|
|
58
60
|
{
|
|
@@ -80,11 +82,16 @@ export const LANE_ENVELOPE_JSON_SCHEMA = {
|
|
|
80
82
|
else: { not: { required: ["story_complete_reason"] } },
|
|
81
83
|
},
|
|
82
84
|
},
|
|
85
|
+
...LANE_OUTCOME_ENVELOPE_RULES,
|
|
83
86
|
],
|
|
84
87
|
description: "questions is present and non-empty exactly when decision is ask. " +
|
|
85
88
|
"blocked_reason is present exactly when decision is blocked. " +
|
|
86
89
|
"story_complete true requires story_status done; story_complete false requires story_status other than done; " +
|
|
87
|
-
"story_complete_reason is required whenever story_complete is present."
|
|
90
|
+
"story_complete_reason is required whenever story_complete is present. " +
|
|
91
|
+
"outcome is optional; outcome.state is done, needs_decision or partial. " +
|
|
92
|
+
"needs_decision requires outcome.decision_id or a non-empty questions[]; " +
|
|
93
|
+
"partial requires at least one outcome.next_steps entry; " +
|
|
94
|
+
"outcome.state done is rejected when decision is blocked.",
|
|
88
95
|
};
|
|
89
96
|
export const LANE_STATES = [
|
|
90
97
|
"queued",
|
|
@@ -247,6 +254,7 @@ export const REQUIRED_LANE_RECORD_FIELDS = [
|
|
|
247
254
|
export const LANE_WRITERS = ["creator", "command", "watcher", "reconcile", "spawn", "story-ledger"];
|
|
248
255
|
/** Field ownership at the durable-record mutation boundary (spec §10.1). */
|
|
249
256
|
export const LANE_FIELD_WRITERS = {
|
|
257
|
+
signal: ["creator"], signal_link: ["creator"],
|
|
250
258
|
schema_version: ["creator"], lane_id: ["creator"], written_by_version: [], owner_written_by_version: [], company: ["creator", "command"], company_history: ["command"],
|
|
251
259
|
project_id: ["command"], story_id: ["command"], no_story_reason: ["creator", "command"], focus_overrides: ["command"], ledger_sync_error: ["story-ledger"], pending_question_ids: ["story-ledger"], stories: ["creator", "command", "watcher", "reconcile", "spawn"], thread_id: ["creator", "command", "spawn"], mesh_company: ["creator", "command"],
|
|
252
260
|
depth: ["command"], senior: ["command"], senior_history: ["command"],
|
|
@@ -260,7 +268,7 @@ export const LANE_FIELD_WRITERS = {
|
|
|
260
268
|
provider: ["creator", "command"], runner: ["creator"], remote_control: ["creator"], remote_control_title: ["creator"], provider_source: ["creator", "command"], account: ["creator", "spawn", "command", "watcher", "reconcile"], account_source: ["creator", "command"], profile_settings_pinned: ["command"], account_selection: ["creator", "command"], account_pick: ["creator"], admission_accounts: ["creator", "command"], account_history: ["command", "spawn", "watcher", "reconcile"], failed_resume_history: ["command"], fallback_question_cancellation_failures: ["command"], pending_resume: ["command", "spawn", "watcher", "reconcile"], placement_default: ["creator"], host: ["creator", "command"], origin_host: ["creator"], origin_host_source: ["creator"],
|
|
261
269
|
version: ["creator"], created_at: ["creator"], updated_at: ["creator"], ended_at: ["reconcile"], envelope_summary: ["reconcile"], attribution_history: ["command", "watcher", "reconcile"], story_switch_pending: ["command", "watcher", "reconcile"], story_switch_unacknowledged: ["command", "watcher", "reconcile"],
|
|
262
270
|
last_envelope: ["watcher", "reconcile"], model: ["creator", "spawn", "command"], model_source: ["creator", "spawn", "command"], effort: ["creator", "spawn", "command"], effort_source: ["creator", "spawn", "command"], fast_mode: ["spawn"],
|
|
263
|
-
last_message_at: ["creator", "command"], status_gate: ["spawn", "watcher"], status_gate_history: ["watcher", "reconcile"], blocker_freshness_state: ["watcher"], kr_freshness_state: ["watcher"], last_compaction: ["spawn"], story_complete: ["watcher", "reconcile"], story_complete_reason: ["watcher", "reconcile"], story_status: ["watcher", "reconcile"],
|
|
271
|
+
last_message_at: ["creator", "command"], status_gate: ["spawn", "watcher"], status_gate_history: ["watcher", "reconcile"], blocker_freshness_state: ["watcher"], kr_freshness_state: ["watcher"], last_compaction: ["spawn"], story_complete: ["watcher", "reconcile"], story_complete_reason: ["watcher", "reconcile"], story_status: ["watcher", "reconcile"], outcome: ["watcher", "reconcile"],
|
|
264
272
|
overdue: ["reconcile"], overdue_at: ["reconcile"], last_host_report_at: ["watcher", "spawn", "reconcile"], stalled: ["watcher"], stalled_at: ["watcher"], stalled_reason: ["watcher"],
|
|
265
273
|
admitted_reason: ["command", "reconcile"], terminal_reason: ["command", "watcher", "spawn", "reconcile"], stop_history: ["command", "reconcile"], settings_history: ["command"], pending_settings: ["command", "spawn"], interrupted_at: ["command", "watcher", "reconcile", "spawn"], terminal_details: ["command", "spawn", "watcher", "reconcile"],
|
|
266
274
|
quota_reset_at: ["watcher", "reconcile", "spawn", "command"], model_quota_marker: ["watcher", "reconcile"], outpost_command_id: ["command"],
|
|
@@ -322,6 +330,7 @@ export function parseLaneEnvelope(raw, options = {}) {
|
|
|
322
330
|
"story_complete",
|
|
323
331
|
"story_complete_reason",
|
|
324
332
|
"fingerprint",
|
|
333
|
+
"outcome",
|
|
325
334
|
].includes(key));
|
|
326
335
|
if (extra.length > 0) {
|
|
327
336
|
throw new LaneSchemaError(`Lane envelope rejects unknown properties: ${extra.join(", ")}`, { extra });
|
|
@@ -453,6 +462,12 @@ export function parseLaneEnvelope(raw, options = {}) {
|
|
|
453
462
|
if (typeof raw.blocked_reason === "string") {
|
|
454
463
|
envelope.blocked_reason = raw.blocked_reason;
|
|
455
464
|
}
|
|
465
|
+
if (raw.outcome !== undefined) {
|
|
466
|
+
envelope.outcome = parseLaneOutcome(raw.outcome, {
|
|
467
|
+
decision: envelope.decision,
|
|
468
|
+
questionCount: envelope.questions?.length ?? 0,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
456
471
|
return envelope;
|
|
457
472
|
}
|
|
458
473
|
//# sourceMappingURL=types.js.map
|
|
@@ -425,6 +425,8 @@ function applyTerminalToLaneWithResult(hqRoot, laneId, classification, opts = {}
|
|
|
425
425
|
},
|
|
426
426
|
...(envelope.decision !== "blocked" ? { keep_alive_blocked_resume_streak: 0 } : {}),
|
|
427
427
|
envelope_validation_errors: opts.envelopeValidationErrors,
|
|
428
|
+
// The last envelope's outcome block; undefined clears a stale one.
|
|
429
|
+
outcome: envelope.outcome,
|
|
428
430
|
};
|
|
429
431
|
if (!approvalGate.violation && approvalGate.approvedIdsToConsume.length > 0) {
|
|
430
432
|
next.registry_worker_approval_history = approvalGate.approvedIdsToConsume.reduce((history, approvalId) => appendCappedHistory(history, {
|
|
@@ -509,6 +511,8 @@ function applyTerminalToLaneWithResult(hqRoot, laneId, classification, opts = {}
|
|
|
509
511
|
const storySwitch = applyStorySwitchEnvelope(current, envelope, at, envelopeRef);
|
|
510
512
|
if (envelope.decision !== "blocked")
|
|
511
513
|
next.keep_alive_blocked_resume_streak = 0;
|
|
514
|
+
// The last envelope's outcome block; undefined clears a stale one.
|
|
515
|
+
next.outcome = envelope.outcome;
|
|
512
516
|
next.last_envelope = {
|
|
513
517
|
ref: envelopeRef,
|
|
514
518
|
decision: envelope.decision,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface LiveMeetingBot {
|
|
2
|
+
meetingId?: string;
|
|
3
|
+
meetingUrl?: string;
|
|
4
|
+
recallBotId?: string;
|
|
5
|
+
botId?: string;
|
|
6
|
+
companyId?: string;
|
|
7
|
+
meetingTitle?: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
status?: string;
|
|
10
|
+
scheduledStartTime?: string;
|
|
11
|
+
createdAt?: string;
|
|
12
|
+
linesSoFar?: number;
|
|
13
|
+
transcriptLineCount?: number;
|
|
14
|
+
sourceLanded?: boolean;
|
|
15
|
+
savedTranscriptPath?: string;
|
|
16
|
+
}
|
|
17
|
+
/** The attended list used by meetings live and the Executive's poll producer. */
|
|
18
|
+
export declare function fetchAttendedLiveBots(token: string, companyId: string, strict?: boolean, signal?: AbortSignal): Promise<LiveMeetingBot[]>;
|
|
19
|
+
//# sourceMappingURL=live-meetings.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { vaultApiFetch } from "../utils/vault-api.js";
|
|
2
|
+
/** The attended list used by meetings live and the Executive's poll producer. */
|
|
3
|
+
export async function fetchAttendedLiveBots(token, companyId, strict = false, signal) {
|
|
4
|
+
try {
|
|
5
|
+
const res = await vaultApiFetch({ token, path: "/v1/meetings", query: { companyId, view: "live" }, ...(signal ? { signal } : {}) });
|
|
6
|
+
if (!res.ok) {
|
|
7
|
+
if (strict)
|
|
8
|
+
throw new Error("Could not list attended meetings");
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
const data = (await res.json());
|
|
12
|
+
if (strict && !Array.isArray(data.bots))
|
|
13
|
+
throw new Error("Invalid attended meetings response");
|
|
14
|
+
return Array.isArray(data.bots) ? data.bots : [];
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
if (strict)
|
|
18
|
+
throw err;
|
|
19
|
+
// Older servers and offline callers retain the CLI's own-notetaker list.
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=live-meetings.js.map
|
|
@@ -12,7 +12,7 @@ import { workContextRoot } from "../../../work-context/paths.js";
|
|
|
12
12
|
import { outboxQuarantineStatusEnabled } from "../../../work-context/outbox-quarantine-status-flag.js";
|
|
13
13
|
import { formatDroppedPresenceCompany } from "./credentials.js";
|
|
14
14
|
import { formatOwnerPushStatus, ownerPushStatusForAccount, readOwnerInboxPushState, } from "./owner-inbox-push.js";
|
|
15
|
-
import { countDistinctHeldEvents, countJsonlLines, countUnattributedEvents, } from "../spool.js";
|
|
15
|
+
import { countDistinctHeldEvents, countJsonlLines, countUnattributedEvents, forEachJsonlLine, } from "../spool.js";
|
|
16
16
|
import { workMeshDeadLetterPath, workMeshHeldPath, workMeshRoot, workMeshSpoolPath, } from "../paths.js";
|
|
17
17
|
import { daemonDir, daemonPidPath } from "./paths.js";
|
|
18
18
|
import { readEmitState } from "../emit.js";
|
|
@@ -31,11 +31,10 @@ function oldestJsonlAgeMs(filePath, nowMs) {
|
|
|
31
31
|
if (!fs.existsSync(filePath))
|
|
32
32
|
return undefined;
|
|
33
33
|
try {
|
|
34
|
-
const text = fs.readFileSync(filePath, "utf8");
|
|
35
34
|
let oldest;
|
|
36
|
-
|
|
35
|
+
forEachJsonlLine(filePath, (line) => {
|
|
37
36
|
if (!line.trim())
|
|
38
|
-
|
|
37
|
+
return;
|
|
39
38
|
try {
|
|
40
39
|
const obj = JSON.parse(line);
|
|
41
40
|
const at = (typeof obj.at === "string" && obj.at) ||
|
|
@@ -43,10 +42,10 @@ function oldestJsonlAgeMs(filePath, nowMs) {
|
|
|
43
42
|
(obj.event && typeof obj.event.at === "string" && obj.event.at) ||
|
|
44
43
|
undefined;
|
|
45
44
|
if (!at)
|
|
46
|
-
|
|
45
|
+
return;
|
|
47
46
|
const t = Date.parse(at);
|
|
48
47
|
if (!Number.isFinite(t))
|
|
49
|
-
|
|
48
|
+
return;
|
|
50
49
|
const age = nowMs - t;
|
|
51
50
|
if (oldest === undefined || age > oldest)
|
|
52
51
|
oldest = age;
|
|
@@ -54,7 +53,7 @@ function oldestJsonlAgeMs(filePath, nowMs) {
|
|
|
54
53
|
catch {
|
|
55
54
|
/* skip */
|
|
56
55
|
}
|
|
57
|
-
}
|
|
56
|
+
});
|
|
58
57
|
return oldest;
|
|
59
58
|
}
|
|
60
59
|
catch {
|
|
@@ -44,6 +44,14 @@ export declare function recoverOrphanClaims(root: string): {
|
|
|
44
44
|
};
|
|
45
45
|
export declare function removeClaimFile(claimPath: string | null): void;
|
|
46
46
|
export declare function deadLetterNonEmpty(root?: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Visit each line of a JSONL file without loading the whole file into one
|
|
49
|
+
* string. Queue files (dead-letter especially) can grow past V8's ~512 MB
|
|
50
|
+
* string ceiling, where readFileSync(..., "utf8") throws. Splits on the raw
|
|
51
|
+
* newline byte so multi-byte UTF-8 sequences are never cut. Returns false when
|
|
52
|
+
* the file cannot be opened.
|
|
53
|
+
*/
|
|
54
|
+
export declare function forEachJsonlLine(filePath: string, visit: (line: string) => void): boolean;
|
|
47
55
|
export declare function countJsonlLines(filePath: string): number;
|
|
48
56
|
/** Count held eventIds once; legacy rows without an eventId remain line-counted. */
|
|
49
57
|
export declare function countDistinctHeldEvents(filePath: string): number;
|
|
@@ -334,40 +334,71 @@ export function deadLetterNonEmpty(root) {
|
|
|
334
334
|
return false;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
+
/** Chunk size for streaming JSONL reads. */
|
|
338
|
+
const JSONL_READ_CHUNK_BYTES = 1024 * 1024;
|
|
339
|
+
/**
|
|
340
|
+
* Visit each line of a JSONL file without loading the whole file into one
|
|
341
|
+
* string. Queue files (dead-letter especially) can grow past V8's ~512 MB
|
|
342
|
+
* string ceiling, where readFileSync(..., "utf8") throws. Splits on the raw
|
|
343
|
+
* newline byte so multi-byte UTF-8 sequences are never cut. Returns false when
|
|
344
|
+
* the file cannot be opened.
|
|
345
|
+
*/
|
|
346
|
+
export function forEachJsonlLine(filePath, visit) {
|
|
347
|
+
let fd;
|
|
348
|
+
try {
|
|
349
|
+
fd = fs.openSync(filePath, "r");
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
const chunk = Buffer.alloc(JSONL_READ_CHUNK_BYTES);
|
|
356
|
+
let carry = Buffer.alloc(0);
|
|
357
|
+
for (;;) {
|
|
358
|
+
const n = fs.readSync(fd, chunk, 0, chunk.length, null);
|
|
359
|
+
if (n <= 0)
|
|
360
|
+
break;
|
|
361
|
+
let data = carry.length > 0 ? Buffer.concat([carry, chunk.subarray(0, n)]) : chunk.subarray(0, n);
|
|
362
|
+
let start = 0;
|
|
363
|
+
for (let nl = data.indexOf(0x0a, start); nl !== -1; nl = data.indexOf(0x0a, start)) {
|
|
364
|
+
visit(data.toString("utf8", start, nl));
|
|
365
|
+
start = nl + 1;
|
|
366
|
+
}
|
|
367
|
+
carry = Buffer.from(data.subarray(start));
|
|
368
|
+
data = Buffer.alloc(0);
|
|
369
|
+
}
|
|
370
|
+
if (carry.length > 0)
|
|
371
|
+
visit(carry.toString("utf8"));
|
|
372
|
+
}
|
|
373
|
+
finally {
|
|
374
|
+
fs.closeSync(fd);
|
|
375
|
+
}
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
337
378
|
export function countJsonlLines(filePath) {
|
|
338
|
-
if (!fs.existsSync(filePath))
|
|
339
|
-
return 0;
|
|
340
|
-
const raw = fs.readFileSync(filePath, "utf8");
|
|
341
379
|
let n = 0;
|
|
342
|
-
|
|
380
|
+
forEachJsonlLine(filePath, (line) => {
|
|
343
381
|
if (line.trim())
|
|
344
382
|
n += 1;
|
|
345
|
-
}
|
|
383
|
+
});
|
|
346
384
|
return n;
|
|
347
385
|
}
|
|
348
386
|
/** Count held eventIds once; legacy rows without an eventId remain line-counted. */
|
|
349
387
|
export function countDistinctHeldEvents(filePath) {
|
|
350
|
-
let raw;
|
|
351
|
-
try {
|
|
352
|
-
raw = fs.readFileSync(filePath, "utf8");
|
|
353
|
-
}
|
|
354
|
-
catch {
|
|
355
|
-
// A concurrent claim can rename held.jsonl between existence and read checks.
|
|
356
|
-
return 0;
|
|
357
|
-
}
|
|
358
388
|
const seen = new Set();
|
|
359
389
|
let count = 0;
|
|
360
|
-
|
|
390
|
+
// A concurrent claim can rename held.jsonl away; a missing file counts as 0.
|
|
391
|
+
forEachJsonlLine(filePath, (line) => {
|
|
361
392
|
if (!line.trim())
|
|
362
|
-
|
|
393
|
+
return;
|
|
363
394
|
const eventId = heldEventId(line);
|
|
364
395
|
if (eventId) {
|
|
365
396
|
if (seen.has(eventId))
|
|
366
|
-
|
|
397
|
+
return;
|
|
367
398
|
seen.add(eventId);
|
|
368
399
|
}
|
|
369
400
|
count += 1;
|
|
370
|
-
}
|
|
401
|
+
});
|
|
371
402
|
return count;
|
|
372
403
|
}
|
|
373
404
|
function record(value) {
|
|
@@ -413,17 +444,12 @@ function isUnattributedLine(line) {
|
|
|
413
444
|
}
|
|
414
445
|
}
|
|
415
446
|
function countUnattributedJsonlLines(filePath) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
.filter((line) => line.trim() && isUnattributedLine(line)).length;
|
|
423
|
-
}
|
|
424
|
-
catch {
|
|
425
|
-
return 0;
|
|
426
|
-
}
|
|
447
|
+
let n = 0;
|
|
448
|
+
forEachJsonlLine(filePath, (line) => {
|
|
449
|
+
if (line.trim() && isUnattributedLine(line))
|
|
450
|
+
n += 1;
|
|
451
|
+
});
|
|
452
|
+
return n;
|
|
427
453
|
}
|
|
428
454
|
/**
|
|
429
455
|
* Count the actionable, unfiled events across all local delivery queues.
|
|
@@ -438,27 +464,20 @@ export function countUnattributedEvents(root) {
|
|
|
438
464
|
return { spool, held, deadLetter, total: spool + held + deadLetter };
|
|
439
465
|
}
|
|
440
466
|
function countUnattributedHeldEvents(filePath) {
|
|
441
|
-
let raw;
|
|
442
|
-
try {
|
|
443
|
-
raw = fs.readFileSync(filePath, "utf8");
|
|
444
|
-
}
|
|
445
|
-
catch {
|
|
446
|
-
// A concurrent held claim may rename this file between the read and open.
|
|
447
|
-
return 0;
|
|
448
|
-
}
|
|
449
467
|
const seen = new Set();
|
|
450
468
|
let count = 0;
|
|
451
|
-
|
|
469
|
+
// A concurrent held claim may rename this file away; a missing file counts as 0.
|
|
470
|
+
forEachJsonlLine(filePath, (line) => {
|
|
452
471
|
if (!line.trim() || !isUnattributedLine(line))
|
|
453
|
-
|
|
472
|
+
return;
|
|
454
473
|
const eventId = heldEventId(line);
|
|
455
474
|
if (eventId) {
|
|
456
475
|
if (seen.has(eventId))
|
|
457
|
-
|
|
476
|
+
return;
|
|
458
477
|
seen.add(eventId);
|
|
459
478
|
}
|
|
460
479
|
count += 1;
|
|
461
|
-
}
|
|
480
|
+
});
|
|
462
481
|
return count;
|
|
463
482
|
}
|
|
464
483
|
//# sourceMappingURL=spool.js.map
|
|
@@ -49,6 +49,28 @@ export declare const OVER_NAG_INTERVAL_MS: number;
|
|
|
49
49
|
* as the bare key rather than a guess.
|
|
50
50
|
*/
|
|
51
51
|
export declare const PLAN_LIMIT_DIMENSION_LABELS: Record<string, string>;
|
|
52
|
+
/**
|
|
53
|
+
* The account a nag payload is about, as hq-pro labels it (`account` beside
|
|
54
|
+
* `planLimits`). One command can touch a personal vault and a company vault,
|
|
55
|
+
* so the line names which one is over (feedback_b1867fe6).
|
|
56
|
+
*/
|
|
57
|
+
export type PlanLimitAccount = {
|
|
58
|
+
kind: "person";
|
|
59
|
+
} | {
|
|
60
|
+
kind: "company";
|
|
61
|
+
slug: string | null;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Render one amount of a resource. Storage arrives in bytes; printed raw it
|
|
65
|
+
* reads as "47012700666 of 10737418240". It is shown in GB with one decimal,
|
|
66
|
+
* so a 10 GB ceiling reads "10.0 GB", matching the plan's own wording.
|
|
67
|
+
*/
|
|
68
|
+
export declare function formatPlanLimitAmount(key: string, n: number): string;
|
|
69
|
+
/**
|
|
70
|
+
* The account as a noun phrase: "your personal account", "the acme company",
|
|
71
|
+
* or "this account" when an older hq-pro sent no label.
|
|
72
|
+
*/
|
|
73
|
+
export declare function planLimitAccountPhrase(account: PlanLimitAccount | null | undefined): string;
|
|
52
74
|
export interface PlanLimitEntry {
|
|
53
75
|
used: number;
|
|
54
76
|
limit: number;
|
|
@@ -75,10 +97,13 @@ export declare function recordPlanLimitStatus(body: unknown, opts?: {
|
|
|
75
97
|
/**
|
|
76
98
|
* The over-limit per-turn line (US-036 §2.2). One line, not the old box: it
|
|
77
99
|
* now repeats up to four times a day, and a multi-line box at that cadence
|
|
78
|
-
* reads as breakage rather than as a nag. It
|
|
79
|
-
*
|
|
100
|
+
* reads as breakage rather than as a nag. It names the account and states the
|
|
101
|
+
* facts. It claims no pause: being over is not being refused. A refusal comes
|
|
102
|
+
* back from hq-pro as its own error with its own sentence, and that is the
|
|
103
|
+
* only place a pause is reported (feedback_b1867fe6, where this line told a
|
|
104
|
+
* person their uploads were paused right after two uploads succeeded).
|
|
80
105
|
*/
|
|
81
|
-
export declare function buildOverLine(overEntries: Array<[string, PlanLimitEntry]>, upgradeUrl: string): string;
|
|
106
|
+
export declare function buildOverLine(overEntries: Array<[string, PlanLimitEntry]>, upgradeUrl: string, account?: PlanLimitAccount | null): string;
|
|
82
107
|
/**
|
|
83
108
|
* The notice a personal feature refusal prints. `upgradeUrl` is the server's
|
|
84
109
|
* own checkout target; an older hq-pro sends none, and the line then names the
|
|
@@ -95,7 +120,7 @@ export declare function renderPersonalPlanFeatureNotice(feature: string, upgrade
|
|
|
95
120
|
* their own story, and a notice that announces a pause nobody is experiencing
|
|
96
121
|
* reads as a bug.
|
|
97
122
|
*/
|
|
98
|
-
export declare function renderThresholdNotice(crossing: PlanLimitThresholdCrossing, upgradeUrl: string): string;
|
|
123
|
+
export declare function renderThresholdNotice(crossing: PlanLimitThresholdCrossing, upgradeUrl: string, account?: PlanLimitAccount | null): string;
|
|
99
124
|
/**
|
|
100
125
|
* Print every crossing this machine has not already printed for this episode.
|
|
101
126
|
*
|
|
@@ -106,6 +131,7 @@ export declare function renderThresholdNotice(crossing: PlanLimitThresholdCrossi
|
|
|
106
131
|
export declare function emitPlanLimitThresholdNotice(crossings: readonly PlanLimitThresholdCrossing[], upgradeUrl: string | null, opts?: {
|
|
107
132
|
write?: (s: string) => void;
|
|
108
133
|
statePath?: string;
|
|
134
|
+
account?: PlanLimitAccount | null;
|
|
109
135
|
}): void;
|
|
110
136
|
/**
|
|
111
137
|
* Emit a plan-limit nag to stderr at command completion.
|