@dorokuma/herdsman-pi 0.14.9 → 0.15.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/package.json +6 -6
- package/src/index.ts +38 -2
- package/src/wake.ts +13 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dorokuma/herdsman-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Pi extension bridge for Herdsman agent history.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"url": "git+https://github.com/dorokuma/herdsman.git",
|
|
22
22
|
"directory": "packages/herdsman-pi"
|
|
23
23
|
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
26
|
+
},
|
|
24
27
|
"pi": {
|
|
25
28
|
"extensions": [
|
|
26
29
|
"./src/index.ts"
|
|
@@ -34,8 +37,5 @@
|
|
|
34
37
|
"bugs": {
|
|
35
38
|
"url": "https://github.com/dorokuma/herdsman/issues"
|
|
36
39
|
},
|
|
37
|
-
"homepage": "https://github.com/dorokuma/herdsman#readme"
|
|
38
|
-
|
|
39
|
-
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
40
|
+
"homepage": "https://github.com/dorokuma/herdsman#readme"
|
|
41
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -97,6 +97,7 @@ type DeliveredBatch = {
|
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
type HerdsmanState = {
|
|
100
|
+
autoClaimAttempted: boolean;
|
|
100
101
|
client: HerdsmanDaemonClient | undefined;
|
|
101
102
|
connected: boolean;
|
|
102
103
|
currentScope: CurrentScope | undefined;
|
|
@@ -450,6 +451,7 @@ export function createHerdsmanPiExtension(options: ExtensionOptions = {}) {
|
|
|
450
451
|
const wakeFilter = options.wakeFilter ?? loadWakeFilterConfig();
|
|
451
452
|
|
|
452
453
|
const state: HerdsmanState = {
|
|
454
|
+
autoClaimAttempted: false,
|
|
453
455
|
client: undefined,
|
|
454
456
|
connected: false,
|
|
455
457
|
currentScope: undefined,
|
|
@@ -2021,10 +2023,32 @@ export function createHerdsmanPiExtension(options: ExtensionOptions = {}) {
|
|
|
2021
2023
|
subscriberKind: "pi",
|
|
2022
2024
|
workspaceId: state.currentScope?.workspaceId ?? launchIdentity.workspaceId,
|
|
2023
2025
|
})
|
|
2024
|
-
.then((
|
|
2026
|
+
.then(async (rawResponse) => {
|
|
2025
2027
|
state.connected = true;
|
|
2026
2028
|
startKeepalive(client);
|
|
2027
|
-
|
|
2029
|
+
let response = rawResponse as ConnectionStateResponse;
|
|
2030
|
+
const currentPaneId = state.currentScope?.paneId ?? launchIdentity.paneId;
|
|
2031
|
+
if (
|
|
2032
|
+
process.env.HERDSMAN_AUTO_ON === "1" &&
|
|
2033
|
+
!state.autoClaimAttempted &&
|
|
2034
|
+
isMainOrchestratorPane(currentPaneId) &&
|
|
2035
|
+
!isDispatchedRoleSession(sessionRef.value, process.env)
|
|
2036
|
+
) {
|
|
2037
|
+
state.autoClaimAttempted = true;
|
|
2038
|
+
if (!isLocalOwner(response) && !response.state?.owner) {
|
|
2039
|
+
try {
|
|
2040
|
+
state.roleMutationInFlight = true;
|
|
2041
|
+
response = (await client.request("agent.orchestrator.set", {
|
|
2042
|
+
enabled: true,
|
|
2043
|
+
})) as ConnectionStateResponse;
|
|
2044
|
+
} catch {
|
|
2045
|
+
// Ignore race if another terminal claimed the workspace concurrently.
|
|
2046
|
+
} finally {
|
|
2047
|
+
state.roleMutationInFlight = false;
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
applyConnectionStateResponse(response, ctx, {
|
|
2028
2052
|
notifyReconnectLoss: true,
|
|
2029
2053
|
});
|
|
2030
2054
|
})
|
|
@@ -2095,6 +2119,7 @@ export function createHerdsmanPiExtension(options: ExtensionOptions = {}) {
|
|
|
2095
2119
|
|
|
2096
2120
|
pi.on("session_start", (_event: unknown, ctx: PiContext) => {
|
|
2097
2121
|
activeContext = ctx;
|
|
2122
|
+
state.autoClaimAttempted = false;
|
|
2098
2123
|
state.subscriberId = ctx.sessionManager.getSessionId();
|
|
2099
2124
|
state.sessionRef = {
|
|
2100
2125
|
agent: "pi",
|
|
@@ -2438,6 +2463,17 @@ function herdrLaunchIdentity(environment: NodeJS.ProcessEnv): LaunchIdentity | u
|
|
|
2438
2463
|
return { herdrSocketPath, paneId, workspaceId };
|
|
2439
2464
|
}
|
|
2440
2465
|
|
|
2466
|
+
function isMainOrchestratorPane(paneId: string): boolean {
|
|
2467
|
+
return paneId.trim().endsWith(":p1");
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
function isDispatchedRoleSession(sessionPath: string, environment: NodeJS.ProcessEnv): boolean {
|
|
2471
|
+
if (typeof environment.CTXMODE_ROLE === "string" && environment.CTXMODE_ROLE.trim().length > 0) {
|
|
2472
|
+
return true;
|
|
2473
|
+
}
|
|
2474
|
+
return sessionPath.startsWith("/tmp/herdr-role-sessions/");
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2441
2477
|
|
|
2442
2478
|
function stringValue(value: unknown): string | null {
|
|
2443
2479
|
return typeof value === "string" && value.length > 0 ? value : null;
|
package/src/wake.ts
CHANGED
|
@@ -11,6 +11,7 @@ export const WAKE_SETTLE_MS = 0;
|
|
|
11
11
|
// value is the contract; duplicated here because `@dorokuma/herdsman-pi` ships
|
|
12
12
|
// standalone `src/` without root `src/`).
|
|
13
13
|
export const PLAN_WAITING_HISTORY = "PLAN_WAITING_HISTORY";
|
|
14
|
+
export const PLAN_STALLED = "PLAN_STALLED";
|
|
14
15
|
|
|
15
16
|
export type AgentOutcome = {
|
|
16
17
|
agent: string;
|
|
@@ -93,8 +94,18 @@ function outcomeKind(event: AgentEventWireRecord): AgentOutcome["kind"] | undefi
|
|
|
93
94
|
return "failed";
|
|
94
95
|
}
|
|
95
96
|
if (event.type === "agent.discarded") {
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
const payload = asRecord(event.payload);
|
|
98
|
+
const agent = stringValue(payload.agent);
|
|
99
|
+
const isAgyOrEmpty = agent === undefined || agent === "agy";
|
|
100
|
+
if (isAgyOrEmpty) {
|
|
101
|
+
const reason = stringValue(payload.reason);
|
|
102
|
+
if (reason === PLAN_WAITING_HISTORY || reason === "degraded") {
|
|
103
|
+
if (payload.fallbackOutcome === true) {
|
|
104
|
+
return "failed";
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
98
109
|
return "failed";
|
|
99
110
|
}
|
|
100
111
|
const payload = asRecord(event.payload);
|