@indigoai-us/hq-cli 5.188.0 → 5.189.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 +16 -0
- package/dist/command-catalog.generated.d.ts +28 -0
- package/dist/command-catalog.generated.js +37 -0
- package/dist/commands/lanes.d.ts +5 -1
- package/dist/commands/lanes.js +395 -69
- package/dist/lib/lanes/hire-grant-dispatch.d.ts +21 -0
- package/dist/lib/lanes/hire-grant-dispatch.js +167 -0
- package/dist/lib/lanes/hire-grants.d.ts +3 -2
- package/dist/lib/lanes/outpost-dispatch.d.ts +6 -1
- package/dist/lib/lanes/outpost-dispatch.js +9 -0
- package/dist/lib/lanes/spawn.d.ts +3 -0
- package/dist/lib/lanes/spawn.js +8 -2
- package/dist/lib/lanes/ssm-command-context.d.ts +12 -0
- package/dist/lib/lanes/ssm-command-context.js +52 -0
- package/dist/lib/lanes/types.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type LaneRecord, type LaneState, type SeniorRef } from "./types.js";
|
|
2
|
+
declare const HIRE_GRANT_CONTEXT_SCHEMA: "hq-lane-hire-grant-context.v1";
|
|
3
|
+
export interface HireGrantLaneSnapshot {
|
|
4
|
+
lane_id: string;
|
|
5
|
+
state: LaneState;
|
|
6
|
+
senior: SeniorRef;
|
|
7
|
+
hire_grant?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface OutpostHireGrantContext {
|
|
10
|
+
schema_version: typeof HIRE_GRANT_CONTEXT_SCHEMA;
|
|
11
|
+
enforcement_enabled: boolean;
|
|
12
|
+
expected_senior: SeniorRef;
|
|
13
|
+
hierarchy: HireGrantLaneSnapshot[];
|
|
14
|
+
}
|
|
15
|
+
/** Encode only the owner-relevant hierarchy from the primary's complete store. */
|
|
16
|
+
export declare function createOutpostHireGrantContext(target: LaneRecord, lanes: readonly LaneRecord[], enforcementEnabled: boolean): string;
|
|
17
|
+
/** Decode and validate an owner grant context, binding it to the target lane. */
|
|
18
|
+
export declare function parseOutpostHireGrantContext(encoded: string, targetLaneId: string): OutpostHireGrantContext;
|
|
19
|
+
export declare function sameHireGrantSenior(a: SeniorRef, b: SeniorRef): boolean;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=hire-grant-dispatch.d.ts.map
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { aliveDirectChildren } from "./hire-grants.js";
|
|
2
|
+
import { LanesError } from "./errors.js";
|
|
3
|
+
import { isLaneState, isSeniorKind, } from "./types.js";
|
|
4
|
+
const HIRE_GRANT_CONTEXT_SCHEMA = "hq-lane-hire-grant-context.v1";
|
|
5
|
+
const MAX_CONTEXT_BYTES = 48 * 1024;
|
|
6
|
+
const MAX_CONTEXT_LANES = 256;
|
|
7
|
+
function contextError(message) {
|
|
8
|
+
return new LanesError("hire_grant_context_invalid", message, {});
|
|
9
|
+
}
|
|
10
|
+
function sameSenior(a, b) {
|
|
11
|
+
return a.kind === b.kind && a.id === b.id;
|
|
12
|
+
}
|
|
13
|
+
function copySenior(senior) {
|
|
14
|
+
return senior.id === undefined
|
|
15
|
+
? { kind: senior.kind }
|
|
16
|
+
: { kind: senior.kind, id: senior.id };
|
|
17
|
+
}
|
|
18
|
+
function snapshot(lane) {
|
|
19
|
+
return {
|
|
20
|
+
lane_id: lane.lane_id,
|
|
21
|
+
state: lane.state,
|
|
22
|
+
senior: copySenior(lane.senior),
|
|
23
|
+
...(lane.hire_grant === undefined ? {} : { hire_grant: lane.hire_grant }),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Encode only the owner-relevant hierarchy from the primary's complete store. */
|
|
27
|
+
export function createOutpostHireGrantContext(target, lanes, enforcementEnabled) {
|
|
28
|
+
const current = lanes.find((lane) => lane.lane_id === target.lane_id);
|
|
29
|
+
if (!current || !sameSenior(current.senior, target.senior)) {
|
|
30
|
+
throw new LanesError("hire_grant_hierarchy_unavailable", `Cannot build an authoritative hire-grant hierarchy for lane ${target.lane_id}`, { lane_id: target.lane_id });
|
|
31
|
+
}
|
|
32
|
+
const relevant = new Map();
|
|
33
|
+
relevant.set(current.lane_id, current);
|
|
34
|
+
if (enforcementEnabled) {
|
|
35
|
+
if (current.senior.kind === "lane") {
|
|
36
|
+
const parentId = current.senior.id;
|
|
37
|
+
const parent = parentId ? lanes.find((lane) => lane.lane_id === parentId) : undefined;
|
|
38
|
+
if (!parent) {
|
|
39
|
+
throw new LanesError("hire_grant_senior_invalid", `Lane ${target.lane_id} has no senior lane in the primary hierarchy`, { lane_id: target.lane_id, senior_lane_id: parentId ?? null });
|
|
40
|
+
}
|
|
41
|
+
relevant.set(parent.lane_id, parent);
|
|
42
|
+
for (const sibling of aliveDirectChildren(lanes, parent.lane_id)) {
|
|
43
|
+
relevant.set(sibling.lane_id, sibling);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const child of aliveDirectChildren(lanes, current.lane_id)) {
|
|
47
|
+
relevant.set(child.lane_id, child);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const hierarchy = [...relevant.values()]
|
|
51
|
+
.map(snapshot)
|
|
52
|
+
.sort((a, b) => a.lane_id.localeCompare(b.lane_id));
|
|
53
|
+
if (hierarchy.length > MAX_CONTEXT_LANES) {
|
|
54
|
+
throw new LanesError("hire_grant_hierarchy_too_large", `Lane ${target.lane_id} has too many related lanes to dispatch a bounded grant check`, { lane_id: target.lane_id, related_lane_count: hierarchy.length });
|
|
55
|
+
}
|
|
56
|
+
const context = {
|
|
57
|
+
schema_version: HIRE_GRANT_CONTEXT_SCHEMA,
|
|
58
|
+
enforcement_enabled: enforcementEnabled,
|
|
59
|
+
expected_senior: copySenior(current.senior),
|
|
60
|
+
hierarchy,
|
|
61
|
+
};
|
|
62
|
+
const encoded = Buffer.from(JSON.stringify(context), "utf8").toString("base64url");
|
|
63
|
+
if (Buffer.byteLength(encoded, "utf8") > MAX_CONTEXT_BYTES) {
|
|
64
|
+
throw new LanesError("hire_grant_hierarchy_too_large", `Lane ${target.lane_id} has too much related state to dispatch a bounded grant check`, { lane_id: target.lane_id, encoded_bytes: Buffer.byteLength(encoded, "utf8") });
|
|
65
|
+
}
|
|
66
|
+
return encoded;
|
|
67
|
+
}
|
|
68
|
+
function parseSenior(value) {
|
|
69
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
70
|
+
return null;
|
|
71
|
+
const record = value;
|
|
72
|
+
if (Object.keys(record).some((key) => key !== "kind" && key !== "id"))
|
|
73
|
+
return null;
|
|
74
|
+
if (!isSeniorKind(record.kind))
|
|
75
|
+
return null;
|
|
76
|
+
if (record.id !== undefined &&
|
|
77
|
+
(typeof record.id !== "string" || !record.id.trim() || record.id.trim() !== record.id))
|
|
78
|
+
return null;
|
|
79
|
+
if ((record.kind === "session" || record.kind === "lane") && record.id === undefined)
|
|
80
|
+
return null;
|
|
81
|
+
if (record.kind === "user" && record.id !== undefined)
|
|
82
|
+
return null;
|
|
83
|
+
return record.id === undefined
|
|
84
|
+
? { kind: record.kind }
|
|
85
|
+
: { kind: record.kind, id: record.id };
|
|
86
|
+
}
|
|
87
|
+
function parseLaneSnapshot(value) {
|
|
88
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
89
|
+
return null;
|
|
90
|
+
const record = value;
|
|
91
|
+
if (Object.keys(record).some((key) => !["lane_id", "state", "senior", "hire_grant"].includes(key)))
|
|
92
|
+
return null;
|
|
93
|
+
if (typeof record.lane_id !== "string" || !record.lane_id.trim())
|
|
94
|
+
return null;
|
|
95
|
+
if (!isLaneState(record.state))
|
|
96
|
+
return null;
|
|
97
|
+
const senior = parseSenior(record.senior);
|
|
98
|
+
if (!senior)
|
|
99
|
+
return null;
|
|
100
|
+
if (record.hire_grant !== undefined &&
|
|
101
|
+
(typeof record.hire_grant !== "number" || !Number.isSafeInteger(record.hire_grant) || record.hire_grant < 0)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
lane_id: record.lane_id,
|
|
106
|
+
state: record.state,
|
|
107
|
+
senior,
|
|
108
|
+
...(record.hire_grant === undefined ? {} : { hire_grant: record.hire_grant }),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/** Decode and validate an owner grant context, binding it to the target lane. */
|
|
112
|
+
export function parseOutpostHireGrantContext(encoded, targetLaneId) {
|
|
113
|
+
if (!encoded || !/^[A-Za-z0-9_-]+$/.test(encoded) ||
|
|
114
|
+
Buffer.byteLength(encoded, "utf8") > MAX_CONTEXT_BYTES ||
|
|
115
|
+
Buffer.from(encoded, "base64url").toString("base64url") !== encoded) {
|
|
116
|
+
throw contextError("Outpost grant context is not canonical base64url");
|
|
117
|
+
}
|
|
118
|
+
let raw;
|
|
119
|
+
try {
|
|
120
|
+
const decoded = new TextDecoder("utf-8", { fatal: true }).decode(Buffer.from(encoded, "base64url"));
|
|
121
|
+
raw = JSON.parse(decoded);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
throw contextError("Outpost grant context is not valid UTF-8 JSON");
|
|
125
|
+
}
|
|
126
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
127
|
+
throw contextError("Outpost grant context must be an object");
|
|
128
|
+
}
|
|
129
|
+
const record = raw;
|
|
130
|
+
if (Object.keys(record).some((key) => !["schema_version", "enforcement_enabled", "expected_senior", "hierarchy"].includes(key))) {
|
|
131
|
+
throw contextError("Outpost grant context contains unknown fields");
|
|
132
|
+
}
|
|
133
|
+
if (record.schema_version !== HIRE_GRANT_CONTEXT_SCHEMA ||
|
|
134
|
+
typeof record.enforcement_enabled !== "boolean" ||
|
|
135
|
+
!Array.isArray(record.hierarchy) ||
|
|
136
|
+
record.hierarchy.length === 0 || record.hierarchy.length > MAX_CONTEXT_LANES) {
|
|
137
|
+
throw contextError("Outpost grant context has an unsupported or incomplete shape");
|
|
138
|
+
}
|
|
139
|
+
const expectedSenior = parseSenior(record.expected_senior);
|
|
140
|
+
const hierarchy = record.hierarchy.map(parseLaneSnapshot);
|
|
141
|
+
if (!expectedSenior || hierarchy.some((lane) => lane === null)) {
|
|
142
|
+
throw contextError("Outpost grant context contains an invalid senior or lane snapshot");
|
|
143
|
+
}
|
|
144
|
+
const snapshots = hierarchy;
|
|
145
|
+
const byId = new Map(snapshots.map((lane) => [lane.lane_id, lane]));
|
|
146
|
+
if (byId.size !== snapshots.length) {
|
|
147
|
+
throw contextError("Outpost grant context contains duplicate lane snapshots");
|
|
148
|
+
}
|
|
149
|
+
const target = byId.get(targetLaneId);
|
|
150
|
+
if (!target || !sameSenior(target.senior, expectedSenior)) {
|
|
151
|
+
throw contextError("Outpost grant context does not match the target's expected senior");
|
|
152
|
+
}
|
|
153
|
+
if (record.enforcement_enabled && expectedSenior.kind === "lane" &&
|
|
154
|
+
(!expectedSenior.id || !byId.has(expectedSenior.id))) {
|
|
155
|
+
throw contextError("Outpost grant context is missing the target's senior lane");
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
schema_version: HIRE_GRANT_CONTEXT_SCHEMA,
|
|
159
|
+
enforcement_enabled: record.enforcement_enabled,
|
|
160
|
+
expected_senior: expectedSenior,
|
|
161
|
+
hierarchy: snapshots,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
export function sameHireGrantSenior(a, b) {
|
|
165
|
+
return sameSenior(a, b);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=hire-grant-dispatch.js.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type LaneRecord } from "./types.js";
|
|
2
2
|
export declare const LANE_HIRE_GRANTS_FLAG = "lanes.hire-grants";
|
|
3
|
-
export
|
|
4
|
-
export declare function
|
|
3
|
+
export type LaneHireGrantRow = Pick<LaneRecord, "lane_id" | "state" | "senior" | "hire_grant">;
|
|
4
|
+
export declare function aliveDirectChildren<T extends LaneHireGrantRow>(lanes: readonly T[], parentLaneId: string): T[];
|
|
5
|
+
export declare function assignedChildHireGrants(children: readonly LaneHireGrantRow[], exceptLaneId?: string): number;
|
|
5
6
|
export interface HireGrantAdmissionSnapshot {
|
|
6
7
|
parent: LaneRecord;
|
|
7
8
|
children: LaneRecord[];
|
|
@@ -27,7 +27,7 @@ export interface OutpostDispatchResult {
|
|
|
27
27
|
stderr: string;
|
|
28
28
|
}
|
|
29
29
|
export interface OutpostLaneCommand {
|
|
30
|
-
action: "message" | "resume" | "stop" | "show" | "grant";
|
|
30
|
+
action: "message" | "resume" | "stop" | "show" | "grant" | "grant-target";
|
|
31
31
|
laneId: string;
|
|
32
32
|
hqBinary?: string;
|
|
33
33
|
text?: string;
|
|
@@ -35,7 +35,10 @@ export interface OutpostLaneCommand {
|
|
|
35
35
|
story?: string;
|
|
36
36
|
account?: string;
|
|
37
37
|
model?: string;
|
|
38
|
+
effort?: string;
|
|
39
|
+
worker?: string;
|
|
38
40
|
hire?: string;
|
|
41
|
+
grantContext?: string;
|
|
39
42
|
compact?: boolean;
|
|
40
43
|
}
|
|
41
44
|
export interface OutpostExecPort {
|
|
@@ -80,6 +83,8 @@ export declare function buildOutpostBalanceMoveCommand(input: {
|
|
|
80
83
|
export declare function buildOutpostIdentityBackfillCommand(expectedId: string): string;
|
|
81
84
|
/** Build the same `hq outposts exec` remote command used by lane pickup. */
|
|
82
85
|
export declare function buildOutpostLaneCommand(input: OutpostLaneCommand): string;
|
|
86
|
+
/** True when a remote CLI exited after rejecting the forwarded effort flag. */
|
|
87
|
+
export declare function outpostRejectedEffortOption(result: Pick<OutpostDispatchResult, "exitCode" | "stdout" | "stderr">): boolean;
|
|
83
88
|
export declare function stageOutpostPayload(port: Pick<OutpostExecPort, "stageExecInput">, outpostId: string, bytes: Uint8Array, put?: typeof fetch): Promise<{
|
|
84
89
|
getUrl: string;
|
|
85
90
|
}>;
|
|
@@ -104,7 +104,10 @@ export function buildOutpostLaneCommand(input) {
|
|
|
104
104
|
["--story", input.story],
|
|
105
105
|
["--account", input.account],
|
|
106
106
|
["--model", input.model],
|
|
107
|
+
["--effort", input.effort],
|
|
108
|
+
["--worker", input.worker],
|
|
107
109
|
["--hire", input.hire],
|
|
110
|
+
["--grant-context", input.grantContext],
|
|
108
111
|
]) {
|
|
109
112
|
if (value !== undefined)
|
|
110
113
|
args.push(flag, value);
|
|
@@ -113,6 +116,12 @@ export function buildOutpostLaneCommand(input) {
|
|
|
113
116
|
args.push("--no-compact");
|
|
114
117
|
return withRemoteHqDir(joinCommandParts(args));
|
|
115
118
|
}
|
|
119
|
+
/** True when a remote CLI exited after rejecting the forwarded effort flag. */
|
|
120
|
+
export function outpostRejectedEffortOption(result) {
|
|
121
|
+
if (result.exitCode === 0)
|
|
122
|
+
return false;
|
|
123
|
+
return /(?:unknown|unrecognized) option[^\n]{0,120}--effort/i.test(`${result.stderr}\n${result.stdout}`);
|
|
124
|
+
}
|
|
116
125
|
export async function stageOutpostPayload(port, outpostId, bytes, put = fetch) {
|
|
117
126
|
const staged = await port.stageExecInput(outpostId);
|
|
118
127
|
const upload = await put(staged.putUrl, {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { PROVIDER_HOME_ENV } from "./accounts.js";
|
|
11
11
|
import { type RunCompactionFn } from "./compaction.js";
|
|
12
|
+
import { type ResolvedEffort } from "./effort.js";
|
|
12
13
|
import { type KnownModelsDeps } from "./models.js";
|
|
13
14
|
import { type LaunchTrigger } from "./delivery.js";
|
|
14
15
|
import { type MachineIdentity } from "./machine-identity.js";
|
|
@@ -283,6 +284,8 @@ export interface SpawnLaunchOptions {
|
|
|
283
284
|
* (`hq lanes message --no-compact`). Default true.
|
|
284
285
|
*/
|
|
285
286
|
compact?: boolean;
|
|
287
|
+
/** Effort resolved by an explicit resume/message request, or pinned from its record. */
|
|
288
|
+
effort?: ResolvedEffort;
|
|
286
289
|
}
|
|
287
290
|
/**
|
|
288
291
|
* Bind the account, spawn the worker and its watcher outside the caller's
|
package/dist/lib/lanes/spawn.js
CHANGED
|
@@ -15,7 +15,7 @@ import { PROVIDER_HOME_ENV, accountStatus, isLoggedOut, resolveAccount, selectBa
|
|
|
15
15
|
import { COMPACTION_PROMPT, compactionAfterUsage, compactionDue, compactLaneSession, } from "./compaction.js";
|
|
16
16
|
import { installDrainHook } from "./hooks-install.js";
|
|
17
17
|
import { loadLanesConfig, providerAutoCompactTokens, providerCompactAfterMs, } from "./config.js";
|
|
18
|
-
import { appendEffortFlag, resolveLaneEffort } from "./effort.js";
|
|
18
|
+
import { appendEffortFlag, resolveLaneEffort, } from "./effort.js";
|
|
19
19
|
import { defaultProbe, validateLaneModel, validateProfileLaneModel, } from "./models.js";
|
|
20
20
|
import { claimableStatesFor, planLaneLaunch, providerSupportsSessionResume, } from "./delivery.js";
|
|
21
21
|
import { AccountResolutionError, LanesError } from "./errors.js";
|
|
@@ -1719,7 +1719,13 @@ export function spawnLaneWorker(hqRoot, lane, deps = {}, launch = {}) {
|
|
|
1719
1719
|
accountModel: accountCfg?.model,
|
|
1720
1720
|
providerModel: config.providers[lane.provider].model,
|
|
1721
1721
|
});
|
|
1722
|
-
const
|
|
1722
|
+
const pendingResumeEffort = pendingResume !== undefined
|
|
1723
|
+
? {
|
|
1724
|
+
...(existing.effort !== undefined ? { effort: existing.effort } : {}),
|
|
1725
|
+
source: existing.effort_source ?? "none",
|
|
1726
|
+
}
|
|
1727
|
+
: undefined;
|
|
1728
|
+
const effort = launch.effort ?? pendingResumeEffort ?? resolveLaneEffort({
|
|
1723
1729
|
cliEffort: existing.effort_source === "cli" ? existing.effort : undefined,
|
|
1724
1730
|
profileEffort,
|
|
1725
1731
|
accountEffort: accountCfg?.effort,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SsmRunCommandContextDeps {
|
|
2
|
+
platform?: string;
|
|
3
|
+
parentPid?: number;
|
|
4
|
+
readFileSync?: (path: string, encoding: "utf8") => string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* True only for a Linux process descended from the root-owned SSM Run Command
|
|
8
|
+
* worker chain. Outpost owner-only lane mutations use this to distinguish an
|
|
9
|
+
* SSM dispatch from a normal local CLI invocation.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isSsmRunCommandProcess(deps?: SsmRunCommandContextDeps): boolean;
|
|
12
|
+
//# sourceMappingURL=ssm-command-context.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
const SSM_WORKER_CHAIN = [
|
|
3
|
+
"ssm-document-wo",
|
|
4
|
+
"ssm-agent-worke",
|
|
5
|
+
"amazon-ssm-agen",
|
|
6
|
+
];
|
|
7
|
+
/**
|
|
8
|
+
* True only for a Linux process descended from the root-owned SSM Run Command
|
|
9
|
+
* worker chain. Outpost owner-only lane mutations use this to distinguish an
|
|
10
|
+
* SSM dispatch from a normal local CLI invocation.
|
|
11
|
+
*/
|
|
12
|
+
export function isSsmRunCommandProcess(deps = {}) {
|
|
13
|
+
if ((deps.platform ?? process.platform) !== "linux")
|
|
14
|
+
return false;
|
|
15
|
+
const readFileSync = deps.readFileSync ?? ((filePath, encoding) => fs.readFileSync(filePath, encoding));
|
|
16
|
+
let pid = deps.parentPid ?? process.ppid;
|
|
17
|
+
const lineage = [];
|
|
18
|
+
for (let depth = 0; depth < 32 && pid > 1; depth += 1) {
|
|
19
|
+
let status;
|
|
20
|
+
let command;
|
|
21
|
+
try {
|
|
22
|
+
status = readFileSync(`/proc/${pid}/status`, "utf8");
|
|
23
|
+
command = readFileSync(`/proc/${pid}/comm`, "utf8").trim();
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const code = err !== null && typeof err === "object" && "code" in err
|
|
27
|
+
? err.code
|
|
28
|
+
: undefined;
|
|
29
|
+
if (code === "ENOENT" || code === "EACCES" || code === "EPERM")
|
|
30
|
+
return false;
|
|
31
|
+
throw err;
|
|
32
|
+
}
|
|
33
|
+
const parentMatch = /^PPid:\s*(\d+)\s*$/m.exec(status);
|
|
34
|
+
const uidMatch = /^Uid:\s*\d+\s+(\d+)\s+\d+\s+\d+\s*$/m.exec(status);
|
|
35
|
+
if (!parentMatch || !uidMatch || !command)
|
|
36
|
+
return false;
|
|
37
|
+
const parentPid = Number(parentMatch[1]);
|
|
38
|
+
const effectiveUid = Number(uidMatch[1]);
|
|
39
|
+
if (!Number.isSafeInteger(parentPid) || !Number.isSafeInteger(effectiveUid))
|
|
40
|
+
return false;
|
|
41
|
+
lineage.push({ pid, parentPid, command, effectiveUid });
|
|
42
|
+
pid = parentPid;
|
|
43
|
+
}
|
|
44
|
+
for (let start = 0; start <= lineage.length - SSM_WORKER_CHAIN.length; start += 1) {
|
|
45
|
+
const chain = lineage.slice(start, start + SSM_WORKER_CHAIN.length);
|
|
46
|
+
if (chain.every((entry, index) => entry.effectiveUid === 0 && entry.command.startsWith(SSM_WORKER_CHAIN[index]))) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ssm-command-context.js.map
|
package/dist/lib/lanes/types.js
CHANGED
|
@@ -226,7 +226,7 @@ export const LANE_FIELD_WRITERS = {
|
|
|
226
226
|
priority: ["command"], worker: ["creator", "command"], worker_path: ["creator", "command"], worker_pack: ["creator", "command"], worker_profile: ["creator", "command"], worker_profile_hash: ["creator", "command", "spawn"], worker_profile_ignored: ["creator", "command", "spawn"], worker_policy_delivery: ["command", "spawn"],
|
|
227
227
|
provider: ["creator"], account: ["creator", "spawn", "command", "watcher", "reconcile"], account_selection: ["creator", "command"], admission_accounts: ["creator", "command"], account_history: ["command", "spawn", "watcher", "reconcile"], pending_resume: ["command", "spawn", "watcher", "reconcile"], placement_default: ["creator"], host: ["creator", "command"], origin_host: ["creator"], origin_host_source: ["creator"],
|
|
228
228
|
version: ["creator"], created_at: ["creator"], updated_at: ["creator"], attribution_history: ["command"],
|
|
229
|
-
last_envelope: ["watcher", "reconcile"], model: ["creator", "spawn", "command"], model_source: ["creator", "spawn", "command"], effort: ["creator", "spawn"], effort_source: ["creator", "spawn"], fast_mode: ["spawn"],
|
|
229
|
+
last_envelope: ["watcher", "reconcile"], model: ["creator", "spawn", "command"], model_source: ["creator", "spawn", "command"], effort: ["creator", "spawn", "command"], effort_source: ["creator", "spawn", "command"], fast_mode: ["spawn"],
|
|
230
230
|
last_message_at: ["command"], last_compaction: ["spawn"], story_complete: ["watcher", "reconcile"], story_complete_reason: ["watcher", "reconcile"], story_status: ["watcher", "reconcile"],
|
|
231
231
|
overdue: ["reconcile"], overdue_at: ["reconcile"], last_host_report_at: ["watcher", "spawn", "reconcile"], stalled: ["watcher"], stalled_at: ["watcher"], stalled_reason: ["watcher"],
|
|
232
232
|
admitted_reason: ["command", "reconcile"], terminal_reason: ["command", "watcher", "spawn", "reconcile"], terminal_details: ["command", "spawn", "watcher", "reconcile"],
|