@indigoai-us/hq-cli 5.186.0 → 5.187.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
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.187.0] — 2026-09-25
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- `hq mesh context prd-sync` sends only stories whose Board status changed (a first snapshot of already-done stories is not re-emitted). Quiet `session_end` summaries read Claude Code `result` lines and Codex/Grok `item.completed` agent messages, not only `type=assistant` turns.
|
|
10
|
+
|
|
5
11
|
## [5.186.0] — 2026-09-25
|
|
6
12
|
|
|
7
13
|
### Changed
|
package/dist/commands/mesh.js
CHANGED
|
@@ -14,7 +14,7 @@ import chalk from "chalk";
|
|
|
14
14
|
import { loadCachedTokens, isMachineIdentity } from "../utils/cognito-session.js";
|
|
15
15
|
import * as readline from "node:readline/promises";
|
|
16
16
|
import { STORY_STATUSES, appendThreadEvent, ensureProjectThread, eventPayload, getProjectView, listActiveMembershipCompanies, listActiveThreads, patchStory, putProjectView, registerMeshProject, resolveActiveMembershipCompany, resolveMeshPrincipalUid, warmMeshConversationCache, } from "../lib/mesh/api.js";
|
|
17
|
-
import { closeSupersededProjectThread, ensureMissingBoardStories, ensureProjectBoard, formatStoryStatusChanges, mergeProjectStories, } from "../lib/mesh/project-board.js";
|
|
17
|
+
import { closeSupersededProjectThread, ensureMissingBoardStories, ensureProjectBoard, formatStoryStatusChanges, mergeProjectStories, prdSyncEventsThatChangeBoard, } from "../lib/mesh/project-board.js";
|
|
18
18
|
import { buildPreflightFixtures } from "../lib/work-context/preflight-contract.js";
|
|
19
19
|
import { createCandidatesFetcher, createMigratePoster, createOrganizePoster, createWorkSessionDeliverer, fetchCompanyLive, formatCompanyLiveTable, openMeshTransport, probeMigrationCapabilityForMemberships, requireToken, } from "../lib/mesh/client.js";
|
|
20
20
|
import { clearDefaultCompany, isDefaultCompanyDisabled, readDeviceConfig, recordMigrationCapabilitySnapshot, setRepairHeldWithDefault, setDefaultCompany, } from "../lib/work-context/config.js";
|
|
@@ -603,7 +603,25 @@ async function runPrdSync(opts) {
|
|
|
603
603
|
...(bound?.projectId ? { project: bound.projectId } : {}),
|
|
604
604
|
touchedPaths: [resolvePath(file)],
|
|
605
605
|
};
|
|
606
|
+
let toEmit = plan.events;
|
|
606
607
|
if (bound?.companyUid && bound.projectId) {
|
|
608
|
+
try {
|
|
609
|
+
const live = await getProjectView(token, bound.companyUid, bound.projectId);
|
|
610
|
+
toEmit = prdSyncEventsThatChangeBoard(plan.events, live.stories);
|
|
611
|
+
}
|
|
612
|
+
catch {
|
|
613
|
+
// Board unread — emit the snapshot diff; the server drops same-status.
|
|
614
|
+
}
|
|
615
|
+
if (toEmit.length === 0) {
|
|
616
|
+
plan.commit();
|
|
617
|
+
if (opts.json) {
|
|
618
|
+
console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed: 0 }));
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
console.log("Work mesh: prd-sync unchanged");
|
|
622
|
+
}
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
607
625
|
try {
|
|
608
626
|
const source = parseProjectPlan(readFileSync(file, "utf8"), file);
|
|
609
627
|
await ensureMissingBoardStories({
|
|
@@ -617,7 +635,7 @@ async function runPrdSync(opts) {
|
|
|
617
635
|
description: source.description ?? "",
|
|
618
636
|
stories: source.stories,
|
|
619
637
|
repos: source.repos ?? [],
|
|
620
|
-
requiredIds:
|
|
638
|
+
requiredIds: toEmit.map((event) => event.taskId),
|
|
621
639
|
});
|
|
622
640
|
}
|
|
623
641
|
catch (err) {
|
|
@@ -625,9 +643,12 @@ async function runPrdSync(opts) {
|
|
|
625
643
|
console.error(`work-mesh: prd-sync ensure failed; emitting anyway (${reason.slice(0, 160)})`);
|
|
626
644
|
}
|
|
627
645
|
}
|
|
646
|
+
const alreadyOnBoard = plan.events
|
|
647
|
+
.filter((event) => !toEmit.some((row) => row.taskId === event.taskId))
|
|
648
|
+
.map((event) => event.taskId);
|
|
628
649
|
const meshRoot = workMeshHomeRoot();
|
|
629
|
-
const seqFirst = reserveSessionSeq(sessionId,
|
|
630
|
-
const events =
|
|
650
|
+
const seqFirst = reserveSessionSeq(sessionId, toEmit.length);
|
|
651
|
+
const events = toEmit.map((event, index) => buildMeshEmitEvent({
|
|
631
652
|
eventId: generateUlid(Date.now() + index),
|
|
632
653
|
kind: "task_status",
|
|
633
654
|
sessionId,
|
|
@@ -659,7 +680,7 @@ async function runPrdSync(opts) {
|
|
|
659
680
|
blocked.add(id);
|
|
660
681
|
}
|
|
661
682
|
const advanced = events.flatMap((event) => (event.eventId && event.taskId && !blocked.has(event.eventId) ? [event.taskId] : []));
|
|
662
|
-
plan.commit(advanced);
|
|
683
|
+
plan.commit([...alreadyOnBoard, ...advanced]);
|
|
663
684
|
if (plan.taskId && advanced.includes(plan.taskId)) {
|
|
664
685
|
updateSessionState(sessionId, root, (current) => {
|
|
665
686
|
if (!current)
|
|
@@ -673,10 +694,10 @@ async function runPrdSync(opts) {
|
|
|
673
694
|
});
|
|
674
695
|
}
|
|
675
696
|
if (opts.json) {
|
|
676
|
-
console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed:
|
|
697
|
+
console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed: toEmit.length, taskId: plan.taskId }));
|
|
677
698
|
return;
|
|
678
699
|
}
|
|
679
|
-
console.log(`Work mesh: prd-sync emitted ${
|
|
700
|
+
console.log(`Work mesh: prd-sync emitted ${toEmit.length} task_status`);
|
|
680
701
|
}
|
|
681
702
|
function noteCallingSessionBound(projectId, company) {
|
|
682
703
|
try {
|
|
@@ -75,14 +75,27 @@ export function extractLastAssistantText(jsonl) {
|
|
|
75
75
|
const type = typeof obj.type === "string" ? obj.type : "";
|
|
76
76
|
const role = typeof obj.role === "string" ? obj.role : "";
|
|
77
77
|
const payload = obj.payload;
|
|
78
|
+
const item = obj.item;
|
|
79
|
+
const message = obj.message;
|
|
78
80
|
let text = "";
|
|
79
81
|
if (type === "assistant" || role === "assistant") {
|
|
80
82
|
text = textFromUnknown(obj.message ?? obj.content);
|
|
81
83
|
}
|
|
84
|
+
else if (message && (message.role === "assistant" || message.type === "assistant")) {
|
|
85
|
+
text = textFromUnknown(message.content ?? message.text ?? message);
|
|
86
|
+
}
|
|
82
87
|
else if (payload &&
|
|
83
88
|
(payload.type === "agent_message" || payload.type === "assistant")) {
|
|
84
89
|
text = textFromUnknown(payload.message ?? payload.content ?? payload.text);
|
|
85
90
|
}
|
|
91
|
+
else if (type === "item.completed" &&
|
|
92
|
+
item &&
|
|
93
|
+
item.type === "agent_message") {
|
|
94
|
+
text = textFromUnknown(item.text ?? item.content ?? item.message);
|
|
95
|
+
}
|
|
96
|
+
else if (type === "result" && typeof obj.result === "string") {
|
|
97
|
+
text = obj.result;
|
|
98
|
+
}
|
|
86
99
|
const trimmed = text.trim();
|
|
87
100
|
if (trimmed)
|
|
88
101
|
last = trimmed;
|
|
@@ -4,6 +4,15 @@ export declare function mergeProjectStories(current: MeshProjectStoryInput[], pl
|
|
|
4
4
|
resetStatus?: boolean;
|
|
5
5
|
}): MeshProjectStoryInput[];
|
|
6
6
|
export declare function boardStoryStatus(story: MeshProjectStoryInput): string;
|
|
7
|
+
/**
|
|
8
|
+
* Keep only prd-sync task_status events whose Board status actually differs.
|
|
9
|
+
* Missing Board rows stay (ensure will add them). Same-status replays of
|
|
10
|
+
* already-done stories must not be sent again (US-051b).
|
|
11
|
+
*/
|
|
12
|
+
export declare function prdSyncEventsThatChangeBoard<T extends {
|
|
13
|
+
taskId: string;
|
|
14
|
+
status: string;
|
|
15
|
+
}>(events: readonly T[], boardStories: readonly MeshProjectStoryInput[]): T[];
|
|
7
16
|
/** One-line summary of live→next status diffs for existing story ids. */
|
|
8
17
|
export declare function formatStoryStatusChanges(current: MeshProjectStoryInput[], next: MeshProjectStoryInput[]): string | undefined;
|
|
9
18
|
/**
|
|
@@ -34,6 +34,15 @@ export function boardStoryStatus(story) {
|
|
|
34
34
|
return story.status;
|
|
35
35
|
return story.passes === true ? "done" : "queued";
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Keep only prd-sync task_status events whose Board status actually differs.
|
|
39
|
+
* Missing Board rows stay (ensure will add them). Same-status replays of
|
|
40
|
+
* already-done stories must not be sent again (US-051b).
|
|
41
|
+
*/
|
|
42
|
+
export function prdSyncEventsThatChangeBoard(events, boardStories) {
|
|
43
|
+
const byId = new Map(boardStories.map((story) => [story.id, boardStoryStatus(story)]));
|
|
44
|
+
return events.filter((event) => byId.get(event.taskId) !== event.status);
|
|
45
|
+
}
|
|
37
46
|
/** One-line summary of live→next status diffs for existing story ids. */
|
|
38
47
|
export function formatStoryStatusChanges(current, next) {
|
|
39
48
|
const currentById = new Map(current.map((story) => [story.id, story]));
|