@link-assistant/hive-mind 1.57.1 → 1.57.3
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
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.57.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5c65c29: Fix /log and /terminal_watch falsely rejecting real `$` isolation sessions (issue #1700)
|
|
8
|
+
|
|
9
|
+
`parseSessionStatusOutput` looked for the isolation backend at `data.isolation`
|
|
10
|
+
or `data.options.isolation`, but the published `link-foundation/start` 0.25.x
|
|
11
|
+
CLI reports it at `options.isolated` in both JSON and the default
|
|
12
|
+
`links-notation` output. As a result, replying `/log` (or `/terminal_watch`) to
|
|
13
|
+
a `Work session finished` message rejected every screen / tmux / docker session
|
|
14
|
+
with `❌ This command currently supports only sessions launched with $
|
|
15
|
+
isolation`. The parser now reads `options.isolated` first and keeps the legacy
|
|
16
|
+
field names as fallbacks. The rejection site additionally emits a `[VERBOSE]`
|
|
17
|
+
diagnostic line so future contract drifts can be triaged from a single bot log
|
|
18
|
+
entry. Regression test in `tests/test-issue-1700-isolation-parsing.mjs`.
|
|
19
|
+
|
|
20
|
+
## 1.57.2
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- aff6d1d: Add a stable test runner and suite markers to avoid package.json test-script conflicts.
|
|
25
|
+
|
|
3
26
|
## 1.57.1
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@link-assistant/hive-mind",
|
|
3
|
-
"version": "1.57.
|
|
3
|
+
"version": "1.57.3",
|
|
4
4
|
"description": "AI-powered issue solver and hive mind for collaborative problem solving",
|
|
5
5
|
"main": "src/hive.mjs",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"hive-telegram-bot": "./src/telegram-bot.mjs"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
-
"test": "node
|
|
18
|
+
"test": "node scripts/run-tests.mjs --suite default",
|
|
19
19
|
"test:queue": "node tests/solve-queue.test.mjs",
|
|
20
20
|
"test:limits-display": "node tests/limits-display.test.mjs",
|
|
21
21
|
"test:usage-limit": "node tests/test-usage-limit.mjs",
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
"husky": "^9.1.7",
|
|
65
65
|
"jscpd": "^4.0.5",
|
|
66
66
|
"lint-staged": "^16.2.7",
|
|
67
|
-
"prettier": "^3.6.2"
|
|
67
|
+
"prettier": "^3.6.2",
|
|
68
|
+
"test-anywhere": "^0.9.1"
|
|
68
69
|
},
|
|
69
70
|
"dependencies": {
|
|
70
71
|
"@secretlint/core": "^11.2.5",
|
|
@@ -52,7 +52,12 @@ export function parseSessionStatusOutput(output) {
|
|
|
52
52
|
try {
|
|
53
53
|
const parsed = JSON.parse(raw);
|
|
54
54
|
const data = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
55
|
-
|
|
55
|
+
// start-command (link-foundation/start) reports the isolation backend at
|
|
56
|
+
// `options.isolated` in both JSON and links-notation output. Older
|
|
57
|
+
// hypothetical layouts used `options.isolation` or a top-level `isolation`
|
|
58
|
+
// field — keep accepting all three so we are tolerant of future renames.
|
|
59
|
+
// See https://github.com/link-assistant/hive-mind/issues/1700.
|
|
60
|
+
const isolationCandidate = (typeof data?.isolation === 'string' && data.isolation) || (typeof data?.options?.isolated === 'string' && data.options.isolated) || (typeof data?.options?.isolation === 'string' && data.options.isolation) || null;
|
|
56
61
|
return {
|
|
57
62
|
exists: true,
|
|
58
63
|
uuid: data?.uuid || null,
|
|
@@ -63,7 +68,7 @@ export function parseSessionStatusOutput(output) {
|
|
|
63
68
|
currentTime: data?.currentTime || null,
|
|
64
69
|
logPath: data?.logPath || null,
|
|
65
70
|
command: data?.command || null,
|
|
66
|
-
isolation:
|
|
71
|
+
isolation: isolationCandidate ? isolationCandidate.toLowerCase() : null,
|
|
67
72
|
workingDirectory: data?.workingDirectory || null,
|
|
68
73
|
raw,
|
|
69
74
|
};
|
|
@@ -83,6 +88,13 @@ export function parseSessionStatusOutput(output) {
|
|
|
83
88
|
|
|
84
89
|
const status = readField('status')?.toLowerCase() || null;
|
|
85
90
|
const exitCodeText = readField('exitCode');
|
|
91
|
+
// `start-command` links-notation output nests the isolation backend under
|
|
92
|
+
// `options` as `isolated <backend>` (not `isolation`). The leading indent
|
|
93
|
+
// varies by depth, but `readField` is anchored with `^\s*` which already
|
|
94
|
+
// matches indented lines. Older code only looked for `isolation`, which
|
|
95
|
+
// returned null for every real session and made /log + /terminal_watch
|
|
96
|
+
// reject screen/tmux/docker sessions. See issue #1700.
|
|
97
|
+
const isolationText = readField('isolated') || readField('isolation');
|
|
86
98
|
|
|
87
99
|
return {
|
|
88
100
|
exists: Boolean(status || firstLine),
|
|
@@ -94,7 +106,7 @@ export function parseSessionStatusOutput(output) {
|
|
|
94
106
|
currentTime: readField('currentTime'),
|
|
95
107
|
logPath: readField('logPath'),
|
|
96
108
|
command: readField('command'),
|
|
97
|
-
isolation:
|
|
109
|
+
isolation: isolationText?.toLowerCase() || null,
|
|
98
110
|
workingDirectory: readField('workingDirectory'),
|
|
99
111
|
raw,
|
|
100
112
|
};
|
|
@@ -260,6 +260,9 @@ export async function registerLogCommand(bot, options) {
|
|
|
260
260
|
// 4. Decide the destination.
|
|
261
261
|
const decision = decideLogDestination({ statusResult, sessionInfo, repoVisibility, chatType });
|
|
262
262
|
if (decision.destination === 'reject') {
|
|
263
|
+
// Surface enough state to diagnose false-rejections like issue #1700,
|
|
264
|
+
// where the parser missed the isolation field name reported by the host.
|
|
265
|
+
VERBOSE && console.log(`[VERBOSE] /log rejected session ${sessionId}: reason="${decision.reason}" parsedIsolation=${JSON.stringify(statusResult?.isolation)} sessionInfoBackend=${JSON.stringify(sessionInfo?.isolationBackend)} rawHead=${JSON.stringify((statusResult?.raw || '').slice(0, 240))}`);
|
|
263
266
|
await ctx.reply(`❌ ${decision.reason}`, { reply_to_message_id: message.message_id });
|
|
264
267
|
return;
|
|
265
268
|
}
|
|
@@ -382,6 +382,8 @@ export async function registerTerminalWatchCommand(bot, options) {
|
|
|
382
382
|
const { repoVisibility, repoDescription } = await resolveTerminalWatchRepository({ sessionInfo, statusResult, parseGitHubUrl, detectRepositoryVisibility });
|
|
383
383
|
const decision = decideLogDestination({ statusResult, sessionInfo, repoVisibility, chatType: chat.type });
|
|
384
384
|
if (decision.destination === 'reject') {
|
|
385
|
+
// Surface enough state to diagnose false-rejections like issue #1700.
|
|
386
|
+
VERBOSE && console.log(`[VERBOSE] /terminal_watch rejected session ${sessionId}: reason="${decision.reason}" parsedIsolation=${JSON.stringify(statusResult?.isolation)} sessionInfoBackend=${JSON.stringify(sessionInfo?.isolationBackend)} rawHead=${JSON.stringify((statusResult?.raw || '').slice(0, 240))}`);
|
|
385
387
|
await ctx.reply(`❌ ${decision.reason}`, { reply_to_message_id: message.message_id });
|
|
386
388
|
return;
|
|
387
389
|
}
|