@quolu/lattice 0.57.1 → 0.57.2
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/bin/lattice-bridge.mjs
CHANGED
|
@@ -140,12 +140,15 @@ timer = setInterval(async () => {
|
|
|
140
140
|
// the terminal identity file) reaches this catch.
|
|
141
141
|
try {
|
|
142
142
|
const heartbeat = await hubHeartbeat.tick({ config });
|
|
143
|
-
|
|
143
|
+
// 直前に書いた指紋は、健全な状態へ戻った時にだけ捨てる。判定より前に捨てると
|
|
144
|
+
// 比較相手が毎周期nullになり、同じ結果をpoll周期ごとに書き続ける。stderrの
|
|
145
|
+
// 消費者が居ない常駐(WindowsのStartup launcher、LaunchAgent)では、この
|
|
146
|
+
// 書込みが積み上がること自体が常駐を不安定にする。
|
|
144
147
|
if (['unreachable', 'rejected', 'partial'].includes(heartbeat?.state)) {
|
|
145
148
|
const fingerprint = JSON.stringify(heartbeat);
|
|
146
149
|
if (fingerprint !== hubHeartbeatError) process.stderr.write(`${fingerprint}\n`);
|
|
147
150
|
hubHeartbeatError = fingerprint;
|
|
148
|
-
}
|
|
151
|
+
} else hubHeartbeatError = null;
|
|
149
152
|
} catch (error) {
|
|
150
153
|
const failure = { schema: 'lattice.bridge_daemon_error.v1',
|
|
151
154
|
code: error?.code ?? 'BRIDGE_HUB_HEARTBEAT_FAILED',
|
package/docs/bridge-setup.md
CHANGED
|
@@ -54,6 +54,11 @@ bridgeが無効な間は以下すべてnullで、bridgeを有効にしている
|
|
|
54
54
|
| `node_path`・`node_exists` | 起動するNode実行体と、それが今も存在するか |
|
|
55
55
|
| `bridge_path`・`bridge_exists` | 起動するbridge scriptと、それが今も存在するか |
|
|
56
56
|
| `error` | `unreadable`のときだけtyped code(例`BRIDGE_LAUNCH_AGENT_PLIST_UNSAFE`) |
|
|
57
|
+
| `error=BRIDGE_PERSISTENCE_STATE_SPLIT` | launcherまたはplistの片割れだけが残った状態。手でfileを消さず、`lattice bridge reconfigure --json`で常駐設定を揃える(0.57.2以降) |
|
|
58
|
+
|
|
59
|
+
`BRIDGE_PERSISTENCE_STATE_SPLIT`は、常駐設定の一方(macOSのplist、またはWindowsのlauncher/descriptor)だけが
|
|
60
|
+
存在することを示す。これは復旧対象そのものが壊れている状態なので、手作業でfileを削除せず、
|
|
61
|
+
`lattice bridge reconfigure --json`を実行して正規のinstall経路で両方を再生成する。
|
|
57
62
|
|
|
58
63
|
**`runtime`** — いま応答しているprocess自身の申告。`state`は`running`/`not_running`/`unattested`/
|
|
59
64
|
`descriptor_invalid`で、`running`以外では各値がnullになる。`running`でも、identityを返さない
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quolu/lattice",
|
|
3
|
-
"version": "0.57.
|
|
3
|
+
"version": "0.57.2",
|
|
4
4
|
"description": "Schedulability compiler for multi-agent development: observe real code boundaries, refactor the conflicting seam, recompile the plan for parallel execution",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Quo / クオ at kitepon.dev",
|
package/src/bridge-cli.mjs
CHANGED
|
@@ -112,6 +112,10 @@ async function bridgePersistence({ launchAgent, env }) {
|
|
|
112
112
|
// `loaded` is launchd-specific; the Windows Startup folder has no such
|
|
113
113
|
// concept and reports null rather than pretending to know.
|
|
114
114
|
const loaded = typeof snapshot?.loaded === 'boolean' ? snapshot.loaded : null;
|
|
115
|
+
if (snapshot?.split === true) {
|
|
116
|
+
return { state: 'unreadable', ...UNREADABLE_PERSISTENCE, loaded,
|
|
117
|
+
error: 'BRIDGE_PERSISTENCE_STATE_SPLIT' };
|
|
118
|
+
}
|
|
115
119
|
if (described === null) return { state: 'not_installed', ...UNREADABLE_PERSISTENCE, loaded, error: null };
|
|
116
120
|
return { state: 'installed', loaded, ...described, error: null };
|
|
117
121
|
} catch (error) {
|
|
@@ -247,10 +247,8 @@ export async function snapshotBridgeLaunchAgent({ env = process.env,
|
|
|
247
247
|
await prepareDirectory(refs.directory, uid);
|
|
248
248
|
const content = await strictPlist(refs.plist, uid);
|
|
249
249
|
const loaded = await loadedState(runner, uid);
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
return Object.freeze({ installed: content !== null, loaded, content });
|
|
250
|
+
const split = loaded && content === null;
|
|
251
|
+
return Object.freeze({ installed: content !== null, loaded, split, content });
|
|
254
252
|
}
|
|
255
253
|
|
|
256
254
|
const PROGRAM_ARGUMENTS_PATTERN =
|
|
@@ -346,6 +344,10 @@ export async function restoreBridgeLaunchAgent({ snapshot, listen = null, env =
|
|
|
346
344
|
await prepareDirectory(refs.directory, uid);
|
|
347
345
|
const stopped = await bootoutIfLoaded({ runner, uid });
|
|
348
346
|
if (stopped) await waitStopped({ listen, env });
|
|
347
|
+
if (snapshot.split === true) {
|
|
348
|
+
await rm(refs.plist, { force: true });
|
|
349
|
+
return snapshot;
|
|
350
|
+
}
|
|
349
351
|
if (snapshot.installed) await atomicPlist(refs.plist, snapshot.content);
|
|
350
352
|
else await rm(refs.plist, { force: true });
|
|
351
353
|
if (snapshot.loaded) {
|
|
@@ -239,10 +239,9 @@ export async function snapshotBridgeStartupFolder({ env = process.env } = {}) {
|
|
|
239
239
|
await prepareDirectory(refs.runtimeDirectory);
|
|
240
240
|
const launcherContent = await strictFile(refs.launcher);
|
|
241
241
|
const descriptorContent = await strictFile(refs.descriptor);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return Object.freeze({ installed: launcherContent !== null, launcherContent, descriptorContent });
|
|
242
|
+
const split = (launcherContent === null) !== (descriptorContent === null);
|
|
243
|
+
return Object.freeze({ installed: launcherContent !== null && descriptorContent !== null,
|
|
244
|
+
split, launcherContent, descriptorContent });
|
|
246
245
|
}
|
|
247
246
|
|
|
248
247
|
async function pathPresent(ref) {
|