@indigoai-us/hq-cli 5.244.0 → 5.246.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/CHANGELOG.md +41 -10
- package/dist/command-catalog.generated.d.ts +5 -2
- package/dist/command-catalog.generated.js +6 -2
- package/dist/commands/mesh.js +2 -16
- package/dist/lib/agent-kit/creds.d.ts +2 -12
- package/dist/lib/agent-kit/creds.js +1 -60
- package/dist/lib/agent-kit/fallback.js +2 -1
- package/dist/lib/agent-kit/inbox-state.js +2 -2
- package/dist/lib/agent-kit/kit-config.js +2 -2
- package/dist/lib/agent-kit/mcp/attachments.js +4 -16
- package/dist/lib/agent-kit/private-file.d.ts +29 -0
- package/dist/lib/agent-kit/private-file.js +91 -0
- package/dist/lib/agent-kit/run/heartbeat.js +2 -2
- package/dist/lib/agent-kit/run/inbox.js +3 -4
- package/dist/lib/agent-kit/wake.js +5 -4
- package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
- package/dist/lib/flag-registry-worker-source.generated.js +1 -1
- package/dist/lib/work-context/reconcile.js +28 -14
- package/dist/lib/work-context/state.d.ts +8 -0
- package/dist/lib/work-context/state.js +36 -3
- package/package.json +2 -2
|
@@ -690,32 +690,46 @@ export async function reconcileObservation(obs, deps) {
|
|
|
690
690
|
registerClassification = "needs_project";
|
|
691
691
|
diagnostics.push(`company rebind to ${resolvedCompany.slug ?? resolvedCompany.uid}; cleared project`);
|
|
692
692
|
}
|
|
693
|
+
// Acked register operations for this session. A register that did not come
|
|
694
|
+
// back bound yields no binding episode, so its receipt (not the session's
|
|
695
|
+
// bindingEpisodeId) is what identifies an already acknowledged binding.
|
|
696
|
+
const ackedRegisters = prior
|
|
697
|
+
? listOutboxOperations(deps.root).filter((operation) => operation.kind === "register" &&
|
|
698
|
+
operation.delivery === "acked" &&
|
|
699
|
+
operation.sessionId === sessionId &&
|
|
700
|
+
Boolean(operation.receiptId))
|
|
701
|
+
: [];
|
|
693
702
|
const stateClassification = registerClassification === "unresolved" &&
|
|
694
703
|
prior?.contextStatus === "needs_project" &&
|
|
695
704
|
prior.companyUid === resolvedCompany.uid &&
|
|
696
|
-
prior.bindingEpisodeId
|
|
705
|
+
(prior.bindingEpisodeId ||
|
|
706
|
+
ackedRegisters.some((operation) => operation.companyUid === resolvedCompany.uid))
|
|
697
707
|
? "needs_project"
|
|
698
708
|
: registerClassification;
|
|
699
709
|
// Re-observing an already acknowledged binding is normal for hooks and the
|
|
700
710
|
// resident daemon. A fresh clientOperationId must not turn that observation
|
|
701
711
|
// into a second semantic register operation: the prior receipt is the stable
|
|
702
712
|
// identity for this exact company/project/task binding.
|
|
703
|
-
const
|
|
713
|
+
const priorBindingIsBound = Boolean(projectId && taskId);
|
|
714
|
+
const acknowledgedReceipt = prior &&
|
|
704
715
|
prior.companyUid === resolvedCompany.uid &&
|
|
705
716
|
prior.companySlug === resolvedCompany.slug &&
|
|
706
717
|
prior.projectId === projectId &&
|
|
707
|
-
prior.taskId === taskId
|
|
708
|
-
|
|
709
|
-
operation.
|
|
710
|
-
operation.
|
|
711
|
-
operation.receiptId === prior.bindingEpisodeId &&
|
|
718
|
+
prior.taskId === taskId
|
|
719
|
+
? ackedRegisters.find((operation) => (priorBindingIsBound
|
|
720
|
+
? operation.receiptId === prior.bindingEpisodeId
|
|
721
|
+
: !prior.bindingEpisodeId || operation.receiptId === prior.bindingEpisodeId) &&
|
|
712
722
|
operation.companyUid === resolvedCompany.uid &&
|
|
713
723
|
operation.companySlug === resolvedCompany.slug &&
|
|
714
724
|
operation.projectId === projectId &&
|
|
715
|
-
operation.taskId === taskId)
|
|
716
|
-
|
|
717
|
-
|
|
725
|
+
operation.taskId === taskId)?.receiptId
|
|
726
|
+
: undefined;
|
|
727
|
+
const acknowledgedPrior = acknowledgedReceipt ? prior : null;
|
|
718
728
|
if (acknowledgedPrior) {
|
|
729
|
+
// A partial (not bound) acknowledged register carries no server episode.
|
|
730
|
+
const retainedEpisodeId = priorBindingIsBound
|
|
731
|
+
? acknowledgedPrior.bindingEpisodeId
|
|
732
|
+
: undefined;
|
|
719
733
|
// Activity is local progress, not binding identity. Retain the receipt
|
|
720
734
|
// without another register while carrying hook counters forward so the
|
|
721
735
|
// normal clarification threshold still advances.
|
|
@@ -727,7 +741,7 @@ export async function reconcileObservation(obs, deps) {
|
|
|
727
741
|
contextStatus: stateClassification,
|
|
728
742
|
projectId,
|
|
729
743
|
taskId,
|
|
730
|
-
bindingEpisodeId:
|
|
744
|
+
bindingEpisodeId: retainedEpisodeId,
|
|
731
745
|
updatedAt: nowIso,
|
|
732
746
|
startedAt,
|
|
733
747
|
...(typeof toolWrites === "number" ? { toolWrites } : {}),
|
|
@@ -735,7 +749,7 @@ export async function reconcileObservation(obs, deps) {
|
|
|
735
749
|
...(decision ? { decision } : {}),
|
|
736
750
|
...bindStateFields,
|
|
737
751
|
...transcriptFields,
|
|
738
|
-
}, prior), deps.root);
|
|
752
|
+
}, prior, { preserveBindingEpisode: priorBindingIsBound }), deps.root);
|
|
739
753
|
const kind = registerClassification === "bound"
|
|
740
754
|
? "bound"
|
|
741
755
|
: registerClassification === "needs_task"
|
|
@@ -743,7 +757,7 @@ export async function reconcileObservation(obs, deps) {
|
|
|
743
757
|
: registerClassification === "needs_project"
|
|
744
758
|
? "needs_project"
|
|
745
759
|
: "queued";
|
|
746
|
-
diagnostics.push(`binding unchanged; retained receipt=${
|
|
760
|
+
diagnostics.push(`binding unchanged; retained receipt=${acknowledgedReceipt}`);
|
|
747
761
|
return {
|
|
748
762
|
result: resultOf({
|
|
749
763
|
kind,
|
|
@@ -755,7 +769,7 @@ export async function reconcileObservation(obs, deps) {
|
|
|
755
769
|
companySlug: resolvedCompany.slug,
|
|
756
770
|
projectId,
|
|
757
771
|
taskId,
|
|
758
|
-
bindingEpisodeId:
|
|
772
|
+
...(retainedEpisodeId ? { bindingEpisodeId: retainedEpisodeId } : {}),
|
|
759
773
|
...bindResultFields,
|
|
760
774
|
}),
|
|
761
775
|
exitCode: EXIT_OK,
|
|
@@ -174,4 +174,12 @@ export declare function authoritativeCompanyFromState(state: SessionStateFile |
|
|
|
174
174
|
slug?: string;
|
|
175
175
|
uid?: string;
|
|
176
176
|
} | null;
|
|
177
|
+
/**
|
|
178
|
+
* Apply `hq mesh context bind-project`: an operator's local project choice.
|
|
179
|
+
*
|
|
180
|
+
* The server issues no binding episode for this local choice, so any prior
|
|
181
|
+
* bindingEpisodeId (older clients stored a register receipt there) is cleared.
|
|
182
|
+
* Carrying it forward makes the server drop every later session-event batch.
|
|
183
|
+
*/
|
|
184
|
+
export declare function applyOperatorProjectBinding(state: SessionStateFile, projectId: string, now?: () => Date): SessionStateFile;
|
|
177
185
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -367,6 +367,19 @@ export function writeAcknowledgedRegisterBinding(binding, root, now = () => new
|
|
|
367
367
|
const acknowledgementStrength = acknowledged === "bound" ? 3 : acknowledged === "needs_task" ? 2 : 1;
|
|
368
368
|
const priorStrength = bindingStrength(prior);
|
|
369
369
|
const preservePriorBinding = Boolean(prior.companyUid === binding.companyUid && priorStrength > acknowledgementStrength);
|
|
370
|
+
// The server issues no binding episode for a register that did not come
|
|
371
|
+
// back bound (unresolved / needs_project / needs_task). Its receipt must
|
|
372
|
+
// never stand in for one: session-event batches carry bindingEpisodeId and
|
|
373
|
+
// the server drops batches whose episode it does not recognise. Older
|
|
374
|
+
// clients stored that receipt here, so also repair a prior value that is
|
|
375
|
+
// exactly this partial register's receipt.
|
|
376
|
+
const receiptEpisode = acknowledged === "bound" ? binding.receiptId : undefined;
|
|
377
|
+
const priorEpisode = acknowledged !== "bound" && prior.bindingEpisodeId === binding.receiptId
|
|
378
|
+
? undefined
|
|
379
|
+
: prior.bindingEpisodeId;
|
|
380
|
+
const sameBindingAsPrior = prior.companyUid === binding.companyUid &&
|
|
381
|
+
prior.projectId === binding.projectId &&
|
|
382
|
+
prior.taskId === binding.taskId;
|
|
370
383
|
const next = mergeLocalSessionFields({
|
|
371
384
|
contractVersion: WORK_CONTEXT_CONTRACT_VERSION,
|
|
372
385
|
sessionId: binding.sessionId,
|
|
@@ -376,10 +389,10 @@ export function writeAcknowledgedRegisterBinding(binding, root, now = () => new
|
|
|
376
389
|
projectId: preservePriorBinding ? prior.projectId : binding.projectId,
|
|
377
390
|
taskId: preservePriorBinding ? prior.taskId : binding.taskId,
|
|
378
391
|
bindingEpisodeId: preservePriorBinding
|
|
379
|
-
?
|
|
380
|
-
:
|
|
392
|
+
? priorEpisode ?? receiptEpisode
|
|
393
|
+
: receiptEpisode ?? (sameBindingAsPrior ? priorEpisode : undefined),
|
|
381
394
|
updatedAt: now().toISOString(),
|
|
382
|
-
}, prior);
|
|
395
|
+
}, prior, { preserveBindingEpisode: false });
|
|
383
396
|
if (prior.companyUid === next.companyUid &&
|
|
384
397
|
prior.companySlug === next.companySlug &&
|
|
385
398
|
prior.contextStatus === next.contextStatus &&
|
|
@@ -418,4 +431,24 @@ export function authoritativeCompanyFromState(state) {
|
|
|
418
431
|
return null;
|
|
419
432
|
return { slug: state.companySlug, uid: state.companyUid };
|
|
420
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Apply `hq mesh context bind-project`: an operator's local project choice.
|
|
436
|
+
*
|
|
437
|
+
* The server issues no binding episode for this local choice, so any prior
|
|
438
|
+
* bindingEpisodeId (older clients stored a register receipt there) is cleared.
|
|
439
|
+
* Carrying it forward makes the server drop every later session-event batch.
|
|
440
|
+
*/
|
|
441
|
+
export function applyOperatorProjectBinding(state, projectId, now = () => new Date()) {
|
|
442
|
+
return {
|
|
443
|
+
...state,
|
|
444
|
+
contractVersion: WORK_CONTEXT_CONTRACT_VERSION,
|
|
445
|
+
contextStatus: state.taskId ? "bound" : "needs_task",
|
|
446
|
+
projectId,
|
|
447
|
+
bindingEpisodeId: undefined,
|
|
448
|
+
projectGate: undefined,
|
|
449
|
+
projectCandidates: undefined,
|
|
450
|
+
projectBindReason: `operator selected ${projectId}`,
|
|
451
|
+
updatedAt: now().toISOString(),
|
|
452
|
+
};
|
|
453
|
+
}
|
|
421
454
|
//# sourceMappingURL=state.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indigoai-us/hq-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.246.0",
|
|
4
4
|
"description": "HQ by Indigo management CLI — modules and cloud sync",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@aws-sdk/client-iot-data-plane": "^3.1096.0",
|
|
46
46
|
"@aws-sdk/client-s3": "^3.1049.0",
|
|
47
|
-
"@indigoai-us/hq-cloud": "~6.18.
|
|
47
|
+
"@indigoai-us/hq-cloud": "~6.18.10",
|
|
48
48
|
"@indigoai-us/hq-flags-client": "^0.1.2",
|
|
49
49
|
"@sentry/node": "^10.49.0",
|
|
50
50
|
"@tobilu/qmd": "2.5.3",
|