@agfpd/iapeer 0.4.119 → 0.4.120
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/package.json +1 -1
- package/src/transport/index.ts +20 -1
package/package.json
CHANGED
package/src/transport/index.ts
CHANGED
|
@@ -1080,12 +1080,31 @@ export interface ControlResult {
|
|
|
1080
1080
|
* "specify runtime"). The clean-slash control namespace (interrupt/compact/…) is the
|
|
1081
1081
|
* caller's; /alias_* expansions are message, not control (docs/Control §namespace).
|
|
1082
1082
|
*/
|
|
1083
|
+
/**
|
|
1084
|
+
* Which session an operator control (interrupt / compact / …) WITHOUT a runtime acts on. An operator
|
|
1085
|
+
* commands the DIALOGUE they see, not a session they must name: the dialogue a runtime-less send
|
|
1086
|
+
* reaches is the peer's default_runtime (config-anchored, resolvePeerDeliveryTarget), so a LIVE
|
|
1087
|
+
* default wins even when other runtimes are live too (incident 18.10: /stop on a peer with claude AND
|
|
1088
|
+
* opencode live answered «specify runtime» while the opencode turn ran on). A dead default with
|
|
1089
|
+
* exactly one live endpoint → that one (the only running session). Only a dead default with SEVERAL
|
|
1090
|
+
* live endpoints stays ambiguous → explicit refusal. An explicit runtime is exact.
|
|
1091
|
+
*/
|
|
1092
|
+
export function resolveControlTarget(personality: string, runtime: string | undefined, env: NodeJS.ProcessEnv = process.env): Result<DeliveryTarget> {
|
|
1093
|
+
if (runtime) return resolveDeliveryTarget({ personality, runtime, env })
|
|
1094
|
+
const peer = findPeer(readPeersIndex({ env }), personality)
|
|
1095
|
+
if (peer) {
|
|
1096
|
+
const anchored = resolveDeliveryTarget({ personality, runtime: peer.runtime, env })
|
|
1097
|
+
if (anchored.ok) return anchored
|
|
1098
|
+
}
|
|
1099
|
+
return resolveDeliveryTarget({ personality, env })
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1083
1102
|
export async function routeControl(personality: string, runtime: string | undefined, command: ControlCommand): Promise<Result<ControlResult>> {
|
|
1084
1103
|
if (!isValidName(personality)) {
|
|
1085
1104
|
return err(`invalid personality "${personality}" — must match /^[a-z][a-z0-9-]{0,31}$/`)
|
|
1086
1105
|
}
|
|
1087
1106
|
if (runtime && !isRuntime(runtime)) return err(`invalid runtime "${runtime}"`)
|
|
1088
|
-
const target =
|
|
1107
|
+
const target = resolveControlTarget(personality, runtime)
|
|
1089
1108
|
if (!target.ok) return err(`cannot control "${personality}": ${target.error.message}`)
|
|
1090
1109
|
const done = await executeControlOnTarget(target.value, command)
|
|
1091
1110
|
if (!done.ok) return done
|