@pushpalsdev/cli 1.1.10 → 1.1.12
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/dist/pushpals-cli.js +76 -11
- package/monitor-ui/+not-found.html +1 -1
- package/monitor-ui/_expo/static/js/web/{entry-ff425ab85ad13c1920b8ee00abfae7dd.js → entry-e8aa7049f746aaa8f1e865615e248f21.js} +1 -1
- package/monitor-ui/_sitemap.html +1 -1
- package/monitor-ui/index.html +1 -1
- package/monitor-ui/modal.html +1 -1
- package/package.json +1 -1
- package/runtime/configs/default.toml +1 -1
- package/runtime/protocol/schemas/events.schema.json +2 -1
- package/runtime/sandbox/.pushpals-remotebuddy-fallback.js +1 -1
- package/runtime/sandbox/apps/workerpals/src/backends/openai_codex/openai_codex_executor.py +6 -1
- package/runtime/sandbox/apps/workerpals/src/backends/openai_codex/test_openai_codex_runtime_config.py +78 -0
- package/runtime/sandbox/apps/workerpals/src/backends/openai_codex_backend.ts +0 -1
- package/runtime/sandbox/apps/workerpals/src/backends/shared/executor_base.py +70 -0
- package/runtime/sandbox/apps/workerpals/src/common/generic_python_executor.ts +39 -1
- package/runtime/sandbox/apps/workerpals/src/docker_executor.ts +9 -8
- package/runtime/sandbox/apps/workerpals/src/execute_job.ts +155 -1
- package/runtime/sandbox/apps/workerpals/src/workerpals_main.ts +77 -4
- package/runtime/sandbox/configs/default.toml +1 -1
- package/runtime/sandbox/packages/protocol/src/schemas/events.schema.json +2 -1
- package/runtime/sandbox/packages/protocol/src/types.ts +1 -0
- package/runtime/sandbox/packages/shared/src/config.ts +1 -1
- package/runtime/sandbox/protocol/schemas/events.schema.json +2 -1
package/dist/pushpals-cli.js
CHANGED
|
@@ -1023,7 +1023,7 @@ function loadPushPalsConfig(options = {}) {
|
|
|
1023
1023
|
workerpalLabels: firstNonEmpty(process.env.REMOTEBUDDY_WORKERPAL_LABELS) ? firstNonEmpty(process.env.REMOTEBUDDY_WORKERPAL_LABELS).split(",").map((value) => value.trim()).filter(Boolean) : asStringArray(remoteNode.workerpal_labels),
|
|
1024
1024
|
executionBudgetInteractiveMs: Math.max(60000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_INTERACTIVE_MS") ?? remoteNode.execution_budget_interactive_ms, 300000)),
|
|
1025
1025
|
executionBudgetNormalMs: Math.max(120000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_NORMAL_MS") ?? remoteNode.execution_budget_normal_ms, 900000)),
|
|
1026
|
-
executionBudgetBackgroundMs: Math.max(180000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_BACKGROUND_MS") ?? remoteNode.execution_budget_background_ms,
|
|
1026
|
+
executionBudgetBackgroundMs: Math.max(180000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_BACKGROUND_MS") ?? remoteNode.execution_budget_background_ms, 1200000)),
|
|
1027
1027
|
finalizationBudgetMs: Math.max(30000, asInt(parseIntEnv("REMOTEBUDDY_FINALIZATION_BUDGET_MS") ?? remoteNode.finalization_budget_ms, 120000)),
|
|
1028
1028
|
crashRestartEnabled: parseBoolEnv("REMOTEBUDDY_CRASH_RESTART_ENABLED") ?? asBoolean(remoteNode.crash_restart_enabled, true),
|
|
1029
1029
|
crashRestartMaxRestarts: Math.max(0, asInt(parseIntEnv("REMOTEBUDDY_CRASH_RESTART_MAX_RESTARTS") ?? remoteNode.crash_restart_max_restarts, 3)),
|
|
@@ -3036,6 +3036,17 @@ async function downloadBinaryAssetWithWindowsCurlFallback(url, outPath, cause) {
|
|
|
3036
3036
|
renameSync(tmpPath, outPath);
|
|
3037
3037
|
return true;
|
|
3038
3038
|
}
|
|
3039
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
3040
|
+
const workerCount = Math.max(1, Math.min(items.length, Math.floor(concurrency)));
|
|
3041
|
+
let nextIndex = 0;
|
|
3042
|
+
await Promise.all(Array.from({ length: workerCount }, async () => {
|
|
3043
|
+
while (nextIndex < items.length) {
|
|
3044
|
+
const currentIndex = nextIndex;
|
|
3045
|
+
nextIndex += 1;
|
|
3046
|
+
await worker(items[currentIndex], currentIndex);
|
|
3047
|
+
}
|
|
3048
|
+
}));
|
|
3049
|
+
}
|
|
3039
3050
|
async function ensureRuntimeBinaries(runtimeRoot, runtimeTag) {
|
|
3040
3051
|
const platformKey = resolveRuntimePlatformKey();
|
|
3041
3052
|
console.log(`[pushpals] Preparing embedded runtime binaries for ${runtimeTag} (${platformKey})...`);
|
|
@@ -3057,14 +3068,15 @@ async function ensureRuntimeBinaries(runtimeRoot, runtimeTag) {
|
|
|
3057
3068
|
runtimeBinaries.sourceControlManager
|
|
3058
3069
|
];
|
|
3059
3070
|
const shouldRefreshAll = installedTag !== runtimeTag;
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3071
|
+
const assetsToDownload = requiredAssets.filter((binaryPath) => shouldRefreshAll || !existsSync5(binaryPath));
|
|
3072
|
+
if (assetsToDownload.length > 1) {
|
|
3073
|
+
console.log(`[pushpals] Downloading ${assetsToDownload.length} runtime binary asset(s) with bounded parallelism...`);
|
|
3074
|
+
}
|
|
3075
|
+
await runWithConcurrency(assetsToDownload, 3, async (binaryPath) => {
|
|
3064
3076
|
const assetName = binaryPath.split(/[\\/]/).pop() || "";
|
|
3065
3077
|
await downloadBinaryAsset(runtimeTag, assetName, binaryPath);
|
|
3066
|
-
|
|
3067
|
-
|
|
3078
|
+
});
|
|
3079
|
+
const downloadedCount = assetsToDownload.length;
|
|
3068
3080
|
writeFileSync(tagMarkerPath, `${runtimeTag}
|
|
3069
3081
|
`, "utf8");
|
|
3070
3082
|
cleanupLegacyRuntimeBinaryLayouts(runtimeRoot, platformKey, binDir);
|
|
@@ -4695,6 +4707,8 @@ ${tail}` : ""}`);
|
|
|
4695
4707
|
const deadline = Date.now() + DEFAULT_RUNTIME_BOOT_TIMEOUT_MS;
|
|
4696
4708
|
const readinessPhaseStartedAt = Date.now();
|
|
4697
4709
|
const optionalServiceExitWarned = new Set;
|
|
4710
|
+
let lastReadinessWaitLogAt = 0;
|
|
4711
|
+
let lastReadinessWaitDetail = "";
|
|
4698
4712
|
while (Date.now() < deadline) {
|
|
4699
4713
|
reportRemoteBuddyAutonomousEngineState();
|
|
4700
4714
|
if (maybeActivateRemoteBuddyWindowsFallback("silent_startup")) {
|
|
@@ -4738,6 +4752,17 @@ ${tail}` : ""}`);
|
|
|
4738
4752
|
}
|
|
4739
4753
|
const health = localBuddyEnabled ? await probeLocalBuddy(opts.localAgentUrl) : null;
|
|
4740
4754
|
const remoteBuddyHealth2 = await probeRemoteBuddySessionConsumer(opts.serverUrl, opts.sessionId);
|
|
4755
|
+
if (localBuddyEnabled && !health?.ok || !remoteBuddyHealth2.ok) {
|
|
4756
|
+
const localBuddyDetail = localBuddyEnabled ? health?.ok ? "LocalBuddy ready" : "LocalBuddy not ready" : "LocalBuddy skipped";
|
|
4757
|
+
const readinessDetail = `${localBuddyDetail}; ${remoteBuddyHealth2.detail}`;
|
|
4758
|
+
const now = Date.now();
|
|
4759
|
+
if (readinessDetail !== lastReadinessWaitDetail || now - lastReadinessWaitLogAt >= 5000) {
|
|
4760
|
+
console.log(`[pushpals] Waiting for embedded runtime readiness: ${readinessDetail}`);
|
|
4761
|
+
appendRuntimeServicesLogLine(runtimeServicesLogPath, `[pushpals] waiting for embedded runtime readiness: ${readinessDetail}`);
|
|
4762
|
+
lastReadinessWaitDetail = readinessDetail;
|
|
4763
|
+
lastReadinessWaitLogAt = now;
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4741
4766
|
if ((!localBuddyEnabled || health?.ok) && remoteBuddyHealth2.ok) {
|
|
4742
4767
|
reportRemoteBuddyAutonomousEngineState();
|
|
4743
4768
|
const stabilityDeadline = Date.now() + DEFAULT_SERVICE_STABILITY_GRACE_MS;
|
|
@@ -5208,8 +5233,10 @@ function formatSessionEventLine(event) {
|
|
|
5208
5233
|
if (type === "job_log") {
|
|
5209
5234
|
const jobId = String(payload.jobId ?? "").slice(0, 8);
|
|
5210
5235
|
const stream = String(payload.stream ?? "").toLowerCase() === "stderr" ? " stderr" : "";
|
|
5211
|
-
const
|
|
5212
|
-
|
|
5236
|
+
const phase = compactCliSessionJobLogLine(String(payload.phase ?? "").trim());
|
|
5237
|
+
const phaseLabel = phase ? ` phase:${phase}` : "";
|
|
5238
|
+
const line = formatCliSessionJobLogLine(String(payload.line ?? "").trim());
|
|
5239
|
+
return line ? `[job ${jobId}${stream}${phaseLabel}] ${line}` : null;
|
|
5213
5240
|
}
|
|
5214
5241
|
if (type === "job_failed") {
|
|
5215
5242
|
const jobId = String(payload.jobId ?? "").slice(0, 8);
|
|
@@ -5247,8 +5274,7 @@ function formatSessionEventLine(event) {
|
|
|
5247
5274
|
return `[job ${jobId}] completed${summary ? `: ${summary}` : ""}`;
|
|
5248
5275
|
}
|
|
5249
5276
|
if (type === "error") {
|
|
5250
|
-
|
|
5251
|
-
return `[event error] ${message || "unknown"}`;
|
|
5277
|
+
return null;
|
|
5252
5278
|
}
|
|
5253
5279
|
if (type === "status") {
|
|
5254
5280
|
const state = String(payload.state ?? "").trim();
|
|
@@ -5264,6 +5290,45 @@ function compactCliSessionJobLogLine(line) {
|
|
|
5264
5290
|
return compacted;
|
|
5265
5291
|
return `${compacted.slice(0, CLI_SESSION_JOB_LOG_MAX_CHARS - 3)}...`;
|
|
5266
5292
|
}
|
|
5293
|
+
function formatCliSessionJobLogLine(line) {
|
|
5294
|
+
const compacted = compactCliSessionJobLogLine(line);
|
|
5295
|
+
if (!compacted)
|
|
5296
|
+
return null;
|
|
5297
|
+
if (shouldSuppressCliSessionJobLogLine(compacted))
|
|
5298
|
+
return null;
|
|
5299
|
+
const codexItem = compacted.match(/^\[OpenAICodexExecutor\]\s+\[codex\]\s+item\.(?:completed|updated)\s+\|\s+(.+)$/i);
|
|
5300
|
+
if (codexItem?.[1]) {
|
|
5301
|
+
return `[codex] ${compactCliSessionJobLogLine(codexItem[1])}`;
|
|
5302
|
+
}
|
|
5303
|
+
return compacted;
|
|
5304
|
+
}
|
|
5305
|
+
function shouldSuppressCliSessionJobLogLine(line) {
|
|
5306
|
+
const text = String(line ?? "").trim();
|
|
5307
|
+
if (!text)
|
|
5308
|
+
return true;
|
|
5309
|
+
if (/^(___RESULT___|__PUSHPALS_OH_RESULT__)\b/.test(text))
|
|
5310
|
+
return true;
|
|
5311
|
+
if (/^\[DockerExecutor\]\s+Linked worktree dependency artifact/i.test(text))
|
|
5312
|
+
return true;
|
|
5313
|
+
if (/^\[OpenAICodexExecutor\]\s+(?:Planner guidance|Codex auth mode|ChatGPT auth mode|Starting codex exec|codex exec finished|Codex JSON stream captured|Codex stdout captured|No reasoning-like|Reasoning-like event|Usage observed|Temporarily masked repo-local)/i.test(text)) {
|
|
5314
|
+
return true;
|
|
5315
|
+
}
|
|
5316
|
+
if (/^\[OpenAICodexExecutor\]\s+codex exec still running\b/i.test(text))
|
|
5317
|
+
return true;
|
|
5318
|
+
if (/^\[OpenAICodexExecutor\]\s+\[codex\]\s+(?:thread|turn)\.started\b/i.test(text)) {
|
|
5319
|
+
return true;
|
|
5320
|
+
}
|
|
5321
|
+
if (/^\[OpenAICodexExecutor\]\s+\[codex\]\s+item\.started\b/i.test(text))
|
|
5322
|
+
return true;
|
|
5323
|
+
if (/^\[OpenAICodexExecutor\]\s+\[codex\]\s+item\.completed\s*$/i.test(text))
|
|
5324
|
+
return true;
|
|
5325
|
+
if (/^\[OpenAICodexExecutor\]\s+\[codex\]\s+item\.updated\s*$/i.test(text))
|
|
5326
|
+
return true;
|
|
5327
|
+
if (/^\[OpenAICodexExecutor\]\s+\[stderr\].*codex_core::tools::router: error=exec_command failed/i.test(text)) {
|
|
5328
|
+
return true;
|
|
5329
|
+
}
|
|
5330
|
+
return false;
|
|
5331
|
+
}
|
|
5267
5332
|
function buildSessionEventReplayFingerprint(event) {
|
|
5268
5333
|
const type = String(event.type ?? "").trim().toLowerCase();
|
|
5269
5334
|
if (type !== "status")
|
|
@@ -435,5 +435,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
435
435
|
@keyframes r-1pzkwqh{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
|
|
436
436
|
@keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
|
|
437
437
|
@keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
|
|
438
|
-
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/static/js/web/entry-
|
|
438
|
+
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/static/js/web/entry-e8aa7049f746aaa8f1e865615e248f21.js" defer></script>
|
|
439
439
|
</body></html>
|
|
@@ -1117,7 +1117,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{v
|
|
|
1117
1117
|
__d(function(g,r,i,a,m,_e,d){"use strict";function f(f,t){return{validate:f,compare:t}}function t(f){return f%4==0&&(f%100!=0||f%400==0)}Object.defineProperty(_e,"__esModule",{value:!0}),_e.formatNames=_e.fastFormats=_e.fullFormats=void 0,_e.fullFormats={date:f(u,o),time:f(s(!0),$),"date-time":f(_(!0),v),"iso-time":f(s(),c),"iso-date-time":f(_(),p),duration:/^P(?!$)((\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?|(\d+W)?)$/,uri:function(f){return b.test(f)&&x.test(f)},"uri-reference":/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,"uri-template":/^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,url:/^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,email:/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,hostname:/^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/,ipv6:/^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,regex:function(f){if(j.test(f))return!1;try{return new RegExp(f),!0}catch(f){return!1}},uuid:/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,"json-pointer":/^(?:\/(?:[^~/]|~0|~1)*)*$/,"json-pointer-uri-fragment":/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,"relative-json-pointer":/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,byte:function(f){return y.lastIndex=0,y.test(f)},int32:{type:"number",validate:function(f){return Number.isInteger(f)&&f<=F&&f>=w}},int64:{type:"number",validate:function(f){return Number.isInteger(f)}},float:{type:"number",validate:O},double:{type:"number",validate:O},password:!0,binary:!0},_e.fastFormats={..._e.fullFormats,date:f(/^\d\d\d\d-[0-1]\d-[0-3]\d$/,o),time:f(/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i,$),"date-time":f(/^\d\d\d\d-[0-1]\d-[0-3]\dt(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i,v),"iso-time":f(/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i,c),"iso-date-time":f(/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i,p),uri:/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/)?[^\s]*$/i,"uri-reference":/^(?:(?:[a-z][a-z0-9+\-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,email:/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i},_e.formatNames=Object.keys(_e.fullFormats);const e=/^(\d\d\d\d)-(\d\d)-(\d\d)$/,n=[0,31,28,31,30,31,30,31,31,30,31,30,31];function u(f){const u=e.exec(f);if(!u)return!1;const o=+u[1],z=+u[2],s=+u[3];return z>=1&&z<=12&&s>=1&&s<=(2===z&&t(o)?29:n[z])}function o(f,t){if(f&&t)return f>t?1:f<t?-1:0}const z=/^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;function s(f){return function(t){const e=z.exec(t);if(!e)return!1;const n=+e[1],u=+e[2],o=+e[3],s=e[4],$="-"===e[5]?-1:1,c=+(e[6]||0),l=+(e[7]||0);if(c>23||l>59||f&&!s)return!1;if(n<=23&&u<=59&&o<60)return!0;const _=u-l*$,v=n-c*$-(_<0?1:0);return(23===v||-1===v)&&(59===_||-1===_)&&o<61}}function $(f,t){if(!f||!t)return;const e=new Date("2020-01-01T"+f).valueOf(),n=new Date("2020-01-01T"+t).valueOf();return e&&n?e-n:void 0}function c(f,t){if(!f||!t)return;const e=z.exec(f),n=z.exec(t);return e&&n?(f=e[1]+e[2]+e[3])>(t=n[1]+n[2]+n[3])?1:f<t?-1:0:void 0}const l=/t|\s/i;function _(f){const t=s(f);return function(f){const e=f.split(l);return 2===e.length&&u(e[0])&&t(e[1])}}function v(f,t){if(!f||!t)return;const e=new Date(f).valueOf(),n=new Date(t).valueOf();return e&&n?e-n:void 0}function p(f,t){if(!f||!t)return;const[e,n]=f.split(l),[u,z]=t.split(l),s=o(e,u);return void 0!==s?s||$(n,z):void 0}const b=/\/|:/,x=/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;const y=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;const w=-2147483648,F=2147483647;function O(){return!0}const j=/[^\\]\\Z/},1100,[]);
|
|
1118
1118
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.formatLimitDefinition=void 0;const o=r(d[0]),t=r(d[1]),f=t.operators,n={formatMaximum:{okStr:"<=",ok:f.LTE,fail:f.GT},formatMinimum:{okStr:">=",ok:f.GTE,fail:f.LT},formatExclusiveMaximum:{okStr:"<",ok:f.LT,fail:f.GTE},formatExclusiveMinimum:{okStr:">",ok:f.GT,fail:f.LTE}},s={message:({keyword:o,schemaCode:f})=>t.str`should be ${n[o].okStr} ${f}`,params:({keyword:o,schemaCode:f})=>t._`{comparison: ${n[o].okStr}, limit: ${f}}`};e.formatLimitDefinition={keyword:Object.keys(n),type:"string",schemaType:"string",$data:!0,error:s,code(f){const{gen:s,data:c,schemaCode:u,keyword:p,it:$}=f,{opts:l,self:k}=$;if(!l.validateFormats)return;const y=new o.KeywordCxt($,k.RULES.all.format.definition,"format");function _(o){return t._`${o}.compare(${c}, ${u}) ${n[p].fail} 0`}y.$data?(function(){const o=s.scopeValue("formats",{ref:k.formats,code:l.code.formats}),n=s.const("fmt",t._`${o}[${y.schemaCode}]`);f.fail$data((0,t.or)(t._`typeof ${n} != "object"`,t._`${n} instanceof RegExp`,t._`typeof ${n}.compare != "function"`,_(n)))})():(function(){const o=y.schema,n=k.formats[o];if(!n||!0===n)return;if("object"!=typeof n||n instanceof RegExp||"function"!=typeof n.compare)throw new Error(`"${p}": format "${o}" does not define "compare" function`);const c=s.scopeValue("formats",{key:o,ref:n,code:l.code.formats?t._`${l.code.formats}${(0,t.getProperty)(o)}`:void 0});f.fail$data(_(c))})()},dependencies:["format"]};e.default=o=>(o.addKeyword(e.formatLimitDefinition),o)},1101,[1032,1037]);
|
|
1119
1119
|
__d(function(e,t,o,s,i,r,n){i.exports={$schema:"http://json-schema.org/draft-07/schema#",title:"EventEnvelope",type:"object",required:["protocolVersion","id","ts","sessionId","type","payload"],properties:{protocolVersion:{type:"string",const:"0.1.0",description:"Protocol version must be 0.1.0"},id:{type:"string",description:"Unique event identifier (e.g., UUID)"},ts:{type:"string",format:"date-time",description:"ISO-8601 timestamp"},sessionId:{type:"string",description:"Session identifier"},type:{type:"string",enum:["log","scan_result","suggestions","diff_ready","approval_required","approved","denied","committed","assistant_message","error","done","agent_status","task_created","task_started","task_progress","task_completed","task_failed","tool_call","tool_result","delegate_request","delegate_response","job_enqueued","job_claimed","job_completed","job_failed","message","job_log","status","autonomy_cycle_started","autonomy_candidates_generated","autonomy_objective_dispatched","autonomy_objective_blocked","autonomy_feedback_recorded","question_asked","question_answered"],description:"Event type discriminator"},traceId:{type:"string",description:"Optional trace ID for debugging"},from:{type:"string",description:"Originator identifier (e.g. client, agent:local1, worker:lint)"},to:{type:"string",description:"Destination identifier (e.g. broadcast, agent:local1, worker:queue:default)"},correlationId:{type:"string",description:"Threads a whole conversation turn together"},parentId:{type:"string",description:"Links tool calls/results under their parent task event"},turnId:{type:"string",description:"One per user message; groups all downstream events"},payload:{type:"object",description:"Payload depends on event type"}},additionalProperties:!1}},1102,[]);
|
|
1120
|
-
__d(function(e,t,r,i,p,o,a){p.exports={$schema:"http://json-schema.org/draft-07/schema#",title:"EventTypePayloads",definitions:{artifact:{type:"object",required:["kind"],properties:{kind:{type:"string"},uri:{type:"string"},text:{type:"string"}},additionalProperties:!1}},oneOf:[{type:"object",required:["type","payload"],properties:{type:{const:"log"},payload:{type:"object",required:["level","message"],properties:{level:{type:"string",enum:["debug","info","warn","error"]},message:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"scan_result"},payload:{type:"object",required:["summary","filesRead","gitStatusPorcelain","gitDiff"],properties:{summary:{type:"string"},filesRead:{type:"array",items:{type:"string"}},gitStatusPorcelain:{type:"string"},gitDiff:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"suggestions"},payload:{type:"object",required:["items"],properties:{items:{type:"array",items:{type:"object",required:["id","title","detail","effort"],properties:{id:{type:"string"},title:{type:"string"},detail:{type:"string"},effort:{type:"string",enum:["S","M","L"]}},additionalProperties:!1}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"assistant_message"},payload:{type:"object",required:["text"],properties:{text:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"diff_ready"},payload:{type:"object",required:["unifiedDiff","diffStat","branch"],properties:{unifiedDiff:{type:"string"},diffStat:{type:"string"},branch:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"approval_required"},payload:{type:"object",required:["approvalId","action","summary","details"],properties:{approvalId:{type:"string"},action:{type:"string",enum:["git.commit","git.push","other"]},summary:{type:"string"},details:{type:"object",additionalProperties:!0}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"approved"},payload:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"denied"},payload:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"committed"},payload:{type:"object",required:["branch","commitHash","message"],properties:{branch:{type:"string"},commitHash:{type:"string"},message:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"error"},payload:{type:"object",required:["message"],properties:{message:{type:"string"},detail:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"done"},payload:{type:"object",required:["ok"],properties:{ok:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"agent_status"},payload:{type:"object",required:["agentId","status"],properties:{agentId:{type:"string"},status:{type:"string",enum:["idle","busy","error"]},message:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_created"},payload:{type:"object",required:["taskId","title","description","createdBy"],properties:{taskId:{type:"string"},title:{type:"string"},description:{type:"string"},createdBy:{type:"string"},priority:{type:"string"},tags:{type:"array",items:{type:"string"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_started"},payload:{type:"object",required:["taskId"],properties:{taskId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_progress"},payload:{type:"object",required:["taskId","message"],properties:{taskId:{type:"string"},message:{type:"string"},percent:{type:"number",minimum:0,maximum:100}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_completed"},payload:{type:"object",required:["taskId","summary"],properties:{taskId:{type:"string"},summary:{type:"string"},origin:{type:"string",enum:["user","autonomy"]},artifacts:{type:"array",items:{$ref:"#/definitions/artifact"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_failed"},payload:{type:"object",required:["taskId","message"],properties:{taskId:{type:"string"},message:{type:"string"},detail:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"tool_call"},payload:{type:"object",required:["toolCallId","tool","args"],properties:{toolCallId:{type:"string"},taskId:{type:"string"},tool:{type:"string"},args:{type:"object",additionalProperties:!0},requiresApproval:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"tool_result"},payload:{type:"object",required:["toolCallId","ok"],properties:{toolCallId:{type:"string"},taskId:{type:"string"},ok:{type:"boolean"},stdout:{type:"string"},stderr:{type:"string"},exitCode:{type:"integer"},artifacts:{type:"array",items:{$ref:"#/definitions/artifact"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"delegate_request"},payload:{type:"object",required:["requestId","toAgentId","input"],properties:{requestId:{type:"string"},toAgentId:{type:"string"},input:{type:"object",additionalProperties:!0}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"delegate_response"},payload:{type:"object",required:["requestId","ok"],properties:{requestId:{type:"string"},ok:{type:"boolean"},output:{type:"object",additionalProperties:!0},error:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_enqueued"},payload:{type:"object",required:["jobId","taskId","kind","params"],properties:{jobId:{type:"string"},taskId:{type:"string"},kind:{type:"string"},params:{type:"object",additionalProperties:!0},origin:{type:"string",enum:["user","autonomy"]},autonomy:{type:"object",properties:{objectiveId:{type:"string"},runId:{type:"string"},snapshotId:{type:"string"},patternKey:{type:"string"}},additionalProperties:!1}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_claimed"},payload:{type:"object",required:["jobId","workerId"],properties:{jobId:{type:"string"},workerId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_completed"},payload:{type:"object",required:["jobId"],properties:{jobId:{type:"string"},summary:{type:"string"},origin:{type:"string",enum:["user","autonomy"]},artifacts:{type:"array",items:{$ref:"#/definitions/artifact"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_failed"},payload:{type:"object",required:["jobId","message"],properties:{jobId:{type:"string"},message:{type:"string"},detail:{type:"string"},origin:{type:"string",enum:["user","autonomy"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"message"},payload:{type:"object",required:["text"],properties:{text:{type:"string"},intent:{type:"object",additionalProperties:!0}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_log"},payload:{type:"object",required:["jobId","stream","seq","line"],properties:{jobId:{type:"string"},stream:{type:"string",enum:["stdout","stderr"]},seq:{type:"integer",minimum:1},line:{type:"string"},ts:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"status"},payload:{type:"object",required:["agentId","state"],properties:{agentId:{type:"string"},state:{type:"string",enum:["idle","busy","error","shutting_down"]},uptimeMs:{type:"number"},detail:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_cycle_started"},payload:{type:"object",required:["runId","snapshotId"],properties:{runId:{type:"string"},snapshotId:{type:"string"},phase:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_candidates_generated"},payload:{type:"object",required:["runId","snapshotId","candidateCount"],properties:{runId:{type:"string"},snapshotId:{type:"string"},candidateCount:{type:"integer",minimum:0},topCandidateIds:{type:"array",items:{type:"string"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_objective_dispatched"},payload:{type:"object",required:["runId","snapshotId","objectiveId","requestId","patternKey"],properties:{runId:{type:"string"},snapshotId:{type:"string"},objectiveId:{type:"string"},requestId:{type:"string"},patternKey:{type:"string"},origin:{type:"string",enum:["autonomy"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_objective_blocked"},payload:{type:"object",required:["runId","snapshotId","objectiveId","reason"],properties:{runId:{type:"string"},snapshotId:{type:"string"},objectiveId:{type:"string"},reason:{type:"string"},questionId:{type:"string"},patternKey:{type:"string"},origin:{type:"string",enum:["autonomy"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_feedback_recorded"},payload:{type:"object",required:["objectiveId","patternKey","outcome","success"],properties:{objectiveId:{type:"string"},patternKey:{type:"string"},outcome:{type:"string"},success:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"question_asked"},payload:{type:"object",required:["questionId","objectiveId","question","questionType"],properties:{questionId:{type:"string"},objectiveId:{type:"string"},question:{type:"string"},questionType:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"question_answered"},payload:{type:"object",required:["questionId","objectiveId","status"],properties:{questionId:{type:"string"},objectiveId:{type:"string"},status:{type:"string",enum:["valid","invalid"]},answerSummary:{type:"string"}},additionalProperties:!1}},additionalProperties:!1}]}},1103,[]);
|
|
1120
|
+
__d(function(e,t,r,i,p,o,a){p.exports={$schema:"http://json-schema.org/draft-07/schema#",title:"EventTypePayloads",definitions:{artifact:{type:"object",required:["kind"],properties:{kind:{type:"string"},uri:{type:"string"},text:{type:"string"}},additionalProperties:!1}},oneOf:[{type:"object",required:["type","payload"],properties:{type:{const:"log"},payload:{type:"object",required:["level","message"],properties:{level:{type:"string",enum:["debug","info","warn","error"]},message:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"scan_result"},payload:{type:"object",required:["summary","filesRead","gitStatusPorcelain","gitDiff"],properties:{summary:{type:"string"},filesRead:{type:"array",items:{type:"string"}},gitStatusPorcelain:{type:"string"},gitDiff:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"suggestions"},payload:{type:"object",required:["items"],properties:{items:{type:"array",items:{type:"object",required:["id","title","detail","effort"],properties:{id:{type:"string"},title:{type:"string"},detail:{type:"string"},effort:{type:"string",enum:["S","M","L"]}},additionalProperties:!1}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"assistant_message"},payload:{type:"object",required:["text"],properties:{text:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"diff_ready"},payload:{type:"object",required:["unifiedDiff","diffStat","branch"],properties:{unifiedDiff:{type:"string"},diffStat:{type:"string"},branch:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"approval_required"},payload:{type:"object",required:["approvalId","action","summary","details"],properties:{approvalId:{type:"string"},action:{type:"string",enum:["git.commit","git.push","other"]},summary:{type:"string"},details:{type:"object",additionalProperties:!0}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"approved"},payload:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"denied"},payload:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"committed"},payload:{type:"object",required:["branch","commitHash","message"],properties:{branch:{type:"string"},commitHash:{type:"string"},message:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"error"},payload:{type:"object",required:["message"],properties:{message:{type:"string"},detail:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"done"},payload:{type:"object",required:["ok"],properties:{ok:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"agent_status"},payload:{type:"object",required:["agentId","status"],properties:{agentId:{type:"string"},status:{type:"string",enum:["idle","busy","error"]},message:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_created"},payload:{type:"object",required:["taskId","title","description","createdBy"],properties:{taskId:{type:"string"},title:{type:"string"},description:{type:"string"},createdBy:{type:"string"},priority:{type:"string"},tags:{type:"array",items:{type:"string"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_started"},payload:{type:"object",required:["taskId"],properties:{taskId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_progress"},payload:{type:"object",required:["taskId","message"],properties:{taskId:{type:"string"},message:{type:"string"},percent:{type:"number",minimum:0,maximum:100}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_completed"},payload:{type:"object",required:["taskId","summary"],properties:{taskId:{type:"string"},summary:{type:"string"},origin:{type:"string",enum:["user","autonomy"]},artifacts:{type:"array",items:{$ref:"#/definitions/artifact"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"task_failed"},payload:{type:"object",required:["taskId","message"],properties:{taskId:{type:"string"},message:{type:"string"},detail:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"tool_call"},payload:{type:"object",required:["toolCallId","tool","args"],properties:{toolCallId:{type:"string"},taskId:{type:"string"},tool:{type:"string"},args:{type:"object",additionalProperties:!0},requiresApproval:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"tool_result"},payload:{type:"object",required:["toolCallId","ok"],properties:{toolCallId:{type:"string"},taskId:{type:"string"},ok:{type:"boolean"},stdout:{type:"string"},stderr:{type:"string"},exitCode:{type:"integer"},artifacts:{type:"array",items:{$ref:"#/definitions/artifact"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"delegate_request"},payload:{type:"object",required:["requestId","toAgentId","input"],properties:{requestId:{type:"string"},toAgentId:{type:"string"},input:{type:"object",additionalProperties:!0}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"delegate_response"},payload:{type:"object",required:["requestId","ok"],properties:{requestId:{type:"string"},ok:{type:"boolean"},output:{type:"object",additionalProperties:!0},error:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_enqueued"},payload:{type:"object",required:["jobId","taskId","kind","params"],properties:{jobId:{type:"string"},taskId:{type:"string"},kind:{type:"string"},params:{type:"object",additionalProperties:!0},origin:{type:"string",enum:["user","autonomy"]},autonomy:{type:"object",properties:{objectiveId:{type:"string"},runId:{type:"string"},snapshotId:{type:"string"},patternKey:{type:"string"}},additionalProperties:!1}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_claimed"},payload:{type:"object",required:["jobId","workerId"],properties:{jobId:{type:"string"},workerId:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_completed"},payload:{type:"object",required:["jobId"],properties:{jobId:{type:"string"},summary:{type:"string"},origin:{type:"string",enum:["user","autonomy"]},artifacts:{type:"array",items:{$ref:"#/definitions/artifact"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_failed"},payload:{type:"object",required:["jobId","message"],properties:{jobId:{type:"string"},message:{type:"string"},detail:{type:"string"},origin:{type:"string",enum:["user","autonomy"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"message"},payload:{type:"object",required:["text"],properties:{text:{type:"string"},intent:{type:"object",additionalProperties:!0}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"job_log"},payload:{type:"object",required:["jobId","stream","seq","line"],properties:{jobId:{type:"string"},stream:{type:"string",enum:["stdout","stderr"]},seq:{type:"integer",minimum:1},line:{type:"string"},ts:{type:"string"},phase:{type:["string","null"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"status"},payload:{type:"object",required:["agentId","state"],properties:{agentId:{type:"string"},state:{type:"string",enum:["idle","busy","error","shutting_down"]},uptimeMs:{type:"number"},detail:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_cycle_started"},payload:{type:"object",required:["runId","snapshotId"],properties:{runId:{type:"string"},snapshotId:{type:"string"},phase:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_candidates_generated"},payload:{type:"object",required:["runId","snapshotId","candidateCount"],properties:{runId:{type:"string"},snapshotId:{type:"string"},candidateCount:{type:"integer",minimum:0},topCandidateIds:{type:"array",items:{type:"string"}}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_objective_dispatched"},payload:{type:"object",required:["runId","snapshotId","objectiveId","requestId","patternKey"],properties:{runId:{type:"string"},snapshotId:{type:"string"},objectiveId:{type:"string"},requestId:{type:"string"},patternKey:{type:"string"},origin:{type:"string",enum:["autonomy"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_objective_blocked"},payload:{type:"object",required:["runId","snapshotId","objectiveId","reason"],properties:{runId:{type:"string"},snapshotId:{type:"string"},objectiveId:{type:"string"},reason:{type:"string"},questionId:{type:"string"},patternKey:{type:"string"},origin:{type:"string",enum:["autonomy"]}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"autonomy_feedback_recorded"},payload:{type:"object",required:["objectiveId","patternKey","outcome","success"],properties:{objectiveId:{type:"string"},patternKey:{type:"string"},outcome:{type:"string"},success:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"question_asked"},payload:{type:"object",required:["questionId","objectiveId","question","questionType"],properties:{questionId:{type:"string"},objectiveId:{type:"string"},question:{type:"string"},questionType:{type:"string"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",required:["type","payload"],properties:{type:{const:"question_answered"},payload:{type:"object",required:["questionId","objectiveId","status"],properties:{questionId:{type:"string"},objectiveId:{type:"string"},status:{type:"string",enum:["valid","invalid"]},answerSummary:{type:"string"}},additionalProperties:!1}},additionalProperties:!1}]}},1103,[]);
|
|
1121
1121
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.usePushPalsSession=function(p="http://localhost:3001"){const v="string"==typeof p?{baseUrl:p}:p??{},f=String(v.baseUrl??"http://localhost:3001").trim().replace(/\/+$/,""),y=String(v.sessionId??"dev").trim()||"dev",I=String(v.authToken??"").trim()||void 0,b=v.clientInfo,[k,h]=(0,t.useState)({sessionId:null,events:[],isConnected:!1,error:null}),[S,_]=(0,t.useReducer)(o.eventReducer,(0,o.initialState)()),[w,C]=(0,t.useState)({}),M=(0,t.useRef)(null),j=(0,t.useRef)(0),R=(0,t.useRef)(null);(0,t.useEffect)(()=>((async()=>{try{const t=await(0,n.resolveClientRegistration)(b,y);R.current=t;const o=await(0,s.createSession)(f,y,I,t);if(!o)return void h(t=>({...t,error:"Failed to create session"}));const c=o.sessionId;h(t=>({...t,sessionId:c,isConnected:!0}));const p=o.created?0:await l(c);j.current=p,o.created&&(0,u.setItem)(`pushpals:cursor:${c}`,"0");const v=(0,s.subscribeEvents)(f,c,(t,s)=>{h(s=>({...s,events:[...s.events,t]})),_({type:"event",envelope:t,cursor:s}),s>j.current&&(j.current=s,(0,u.setItem)(`pushpals:cursor:${c}`,String(s)))},void 0,p,I,t);M.current=v}catch(t){h(s=>({...s,error:String(t)}))}})(),()=>{M.current&&M.current()}),[I,f,y]);const A=(0,t.useCallback)(async t=>!!k.sessionId&&(0,s.sendSessionMessage)(f,k.sessionId,t),[f,k.sessionId]),E=(0,t.useCallback)(async t=>(0,s.submitApprovalDecision)(f,t,"approve",I),[I,f]),F=(0,t.useCallback)(async t=>(0,s.submitApprovalDecision)(f,t,"deny",I),[I,f]),T=(0,t.useMemo)(()=>{const t=new Set;for(const s of k.events)s.from&&t.add(s.from);return Array.from(t).sort()},[k.events]),$=(0,t.useMemo)(()=>{const t=new Set;for(const s of k.events)s.turnId&&t.add(s.turnId);return Array.from(t)},[k.events]),D=(0,t.useMemo)(()=>{const t=new Map,s=new Map;for(const n of k.events){const o=n.payload,u="string"==typeof o?.taskId?o.taskId:void 0,c="string"==typeof o?.jobId?o.jobId:void 0;"job_enqueued"===n.type&&u&&c&&s.set(c,u);const l=u??("job_failed"===n.type&&c?s.get(c):void 0);if(!l)continue;t.has(l)||t.set(l,{taskId:l,title:o.title??l,status:"created",events:[]});const p=t.get(l);p.events.push(n),p.title&&p.title!==l||"string"!=typeof o?.title||!o.title.trim()||(p.title=o.title),"task_started"===n.type?p.status="started":"task_progress"===n.type?p.status="in_progress":"task_completed"===n.type?p.status="completed":("task_failed"===n.type||"job_failed"===n.type&&"completed"!==p.status)&&(p.status="failed")}return Array.from(t.values())},[k.events]),P=(0,t.useMemo)(()=>k.events.filter(t=>{if(!(0,c.shouldDisplayInteractiveSessionEvent)(t))return!1;if(w.agentFrom&&t.from!==w.agentFrom)return!1;if(w.turnId&&t.turnId!==w.turnId)return!1;if(w.taskId){const s=t.payload;if(s?.taskId!==w.taskId)return!1}return!(w.eventTypes&&w.eventTypes.length>0&&!w.eventTypes.includes(t.type))}),[k.events,w]);return{sessionId:k.sessionId,events:k.events,filteredEvents:P,isConnected:k.isConnected,error:k.error,send:A,approve:E,deny:F,tasks:D,agents:T,turnIds:$,filters:w,setFilters:C,state:S}};var t=r(d[0]),s=r(d[1]),n=r(d[2]),o=r(d[3]),u=r(d[4]),c=r(d[5]);async function l(t){const s=await(0,u.getItem)(`pushpals:cursor:${t}`);return s&&Number(s)||0}},1104,[21,1028,1105,1114,1106,1026]);
|
|
1122
1122
|
__d(function(g,r,i,a,m,e,d){"use strict";async function t(t){const n=await r(d[1])(d[0],d.paths);return await n.getItem(t)}async function n(t,n){const o=await r(d[1])(d[0],d.paths);await o.setItem(t,n)}function o(t,n){const o=String(t??"").trim();return o?o.length<=n?o:o.slice(0,n):""}function c(t){switch(t){case"cli_monitor":return"CLI Monitor";case"web":return"Web Client";case"vscode":return"VS Code";case"cli":return"CLI";default:return t||"Client"}}function l(t){const n=o(t,48).toLowerCase();return n&&n.replace(/[^a-z0-9._-]+/g,"_")||"web"}function s(t,n){return`pushpals:client-id:${l(t)}:${o(n,128)||"dev"}`}function u(t){return"function"==typeof globalThis.crypto?.randomUUID?`${t}-${globalThis.crypto.randomUUID()}`:`${t}-${Date.now()}-${Math.random().toString(16).slice(2)}`}Object.defineProperty(e,'__esModule',{value:!0}),e.normalizeClientKind=l,e.buildClientIdentityStorageKey=s,e.defaultClientIdFactory=u,e.resolveClientRegistration=async function(f,p,w={}){const I=l(f?.kind),y=o(f?.clientId,128),C=w.read??t,b=w.write??n,h=w.createId??u;let $=y;if(!$){const t=s(I,p);$=o(await C(t),128),$||($=h(I),await b(t,$))}const _=o(f?.label,120)||c(I),v=o(f?.version,64),S=o(f?.platform,120),U=o(f?.repoRoot,400);return{clientId:$,kind:I,label:_,...v?{version:v}:{},...S?{platform:S}:{},...U?{repoRoot:U}:{}}}},1105,{"0":1106,"1":1112,"paths":{}});
|
|
1123
1123
|
__d(function(g,r,i,a,m,e,d){"use strict";let t;Object.defineProperty(e,'__esModule',{value:!0}),e.getItem=async function(t){try{return window.localStorage?.getItem(t)??null}catch{return null}try{const n=await s();return n?await n.getItem(t)??null:null}catch{return null}},e.setItem=async function(t,n){try{window.localStorage?.setItem(t,n)}catch{}return},r(d[0]);let n=null,l=!1;async function s(){return void 0!==t?t:n||(n=(async()=>{try{const n=await r(d[2])(d[1],d.paths,"@react-native-async-storage/async-storage"),l=n.default??n;if(!l?.getItem||!l?.setItem)throw new Error("module loaded but getItem/setItem missing");return t=l,t}catch{return t=null,l||(l=!0,console.warn("[PushPals] @react-native-async-storage/async-storage is not available. Cursor persistence disabled on native. Install with: bun add @react-native-async-storage/async-storage")),null}finally{n=null}})(),n)}},1106,{"0":114,"1":1202,"2":1112,"paths":{"1202":"/_expo/static/js/web/index-ec13ec62e2b37ed3c5f6d324ef6784e1.js"}});
|
package/monitor-ui/_sitemap.html
CHANGED
|
@@ -435,5 +435,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
435
435
|
@keyframes r-1pzkwqh{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
|
|
436
436
|
@keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
|
|
437
437
|
@keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
|
|
438
|
-
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/static/js/web/entry-
|
|
438
|
+
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/static/js/web/entry-e8aa7049f746aaa8f1e865615e248f21.js" defer></script>
|
|
439
439
|
</body></html>
|
package/monitor-ui/index.html
CHANGED
|
@@ -435,5 +435,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
435
435
|
@keyframes r-1pzkwqh{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
|
|
436
436
|
@keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
|
|
437
437
|
@keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
|
|
438
|
-
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"><!--$--><div style="position:absolute;left:0;right:0;top:0;bottom:0;pointer-events:none;visibility:hidden"></div><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0 r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af" style="background-color:rgba(242,242,242,1.00);display:flex"><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0"><!--$--><div class="css-g5y9jx r-13awgt0" style="background-color:rgba(236,242,245,1.00)"><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-cpet4d r-u8s1d r-g7s1ez r-15zx4ds r-a4e7m4 r-j33s3c r-1ovo9ad" style="background-color:rgba(0,126,119,0.13)"></div><div class="css-g5y9jx r-cpet4d r-u8s1d r-g7s1ez r-5fjp4n r-9s5a0n r-1hy2ut r-9dcw1g" style="background-color:rgba(199,133,30,0.09)"></div><div class="css-g5y9jx r-cpet4d r-u8s1d r-g7s1ez r-1iuttuq r-pbsvq8 r-1b0pg27 r-1sxiqef" style="background-color:rgba(22,154,88,0.09)"></div><div class="css-g5y9jx r-150rngu r-eqz5dr r-16y2uox r-1wbh5a2 r-11yh6sk r-1rnoaur r-agouwx r-13awgt0"><div class="css-g5y9jx r-16y2uox r-2llsf r-kzbkwu"><div class="css-g5y9jx r-16uyjmq r-rs99b7 r-13awgt0 r-hv52eu r-ifefl9 r-1udh08x" style="background-color:rgba(247,250,252,1.00);border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);opacity:0;transform:translateY(18px)"><div class="css-g5y9jx r-1habvwh r-18u37iz r-1wtj0ep r-kzbkwu r-u9wvl5 r-131miar"><div class="css-g5y9jx r-13awgt0 r-j2kj52"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1q67n59 r-15zivkp r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">pushpals operations console</div><div dir="auto" class="css-146c3p1 r-1ra0lkn r-b88u0q r-zl2h9q" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Mission Control</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo r-1cmskyw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Coordinate your edits with autonomous buddy execution across planning, jobs, and integration in one live board.</div><div dir="auto" class="css-146c3p1 r-1enofrn r-5fcqz0 r-kc8jnq" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Current repo:<!-- --> <span class="css-1jxf684 r-1enofrn" style="color:rgba(84,112,134,1.00);font-family:'IBM Plex Mono', 'JetBrains Mono', monospace">unavailable</span></div><div dir="auto" class="css-146c3p1 r-1enofrn r-5fcqz0 r-14gqq1x" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Snapshot:<!-- --> <span class="css-1jxf684 r-1enofrn" style="color:rgba(17,34,48,1.00);font-family:'IBM Plex Mono', 'JetBrains Mono', monospace">waiting for /system/status</span></div></div><div class="css-g5y9jx r-k200y r-1q9bdsx r-rs99b7 r-18u37iz r-1udh08x" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><button aria-label="Set theme mode to auto" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1yd117h r-1ubuhtd" style="background-color:rgba(217,244,241,1.00)" type="button"><div dir="auto" class="css-146c3p1 r-1enofrn r-1kfrs79 r-1ozqkpa" style="color:rgba(2,92,86,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">auto</div></button><button aria-label="Set theme mode to light" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1yd117h r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-1enofrn r-1kfrs79 r-1ozqkpa" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">light</div></button><button aria-label="Set theme mode to dark" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1yd117h r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-1enofrn r-1kfrs79 r-1ozqkpa" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">dark</div></button></div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-15d164r r-bhtmuz r-ytbthy r-1ubuhtd" style="background-color:rgba(244,248,251,1.00);border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00)"><div class="css-g5y9jx r-150rngu r-18u37iz r-16y2uox r-1wbh5a2 r-lltvgl r-buy8e9 r-agouwx r-2eszeu"><div class="css-g5y9jx r-18u37iz"><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(199,133,30,0.40);border-right-color:rgba(199,133,30,0.40);border-bottom-color:rgba(199,133,30,0.40);border-left-color:rgba(199,133,30,0.40);background-color:rgba(199,133,30,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(199,133,30,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">1. You</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Awaiting input</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(0,126,119,0.40);border-right-color:rgba(0,126,119,0.40);border-bottom-color:rgba(0,126,119,0.40);border-left-color:rgba(0,126,119,0.40);background-color:rgba(0,126,119,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">2. Session</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Ready</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(22,154,88,0.40);border-right-color:rgba(22,154,88,0.40);border-bottom-color:rgba(22,154,88,0.40);border-left-color:rgba(22,154,88,0.40);background-color:rgba(22,154,88,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">3. RemoteBuddy</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 pending, 0 claimed</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(22,154,88,0.40);border-right-color:rgba(22,154,88,0.40);border-bottom-color:rgba(22,154,88,0.40);border-left-color:rgba(22,154,88,0.40);background-color:rgba(22,154,88,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">4. WorkerPals</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 online, 0 busy, 0 queued</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(0,126,119,0.40);border-right-color:rgba(0,126,119,0.40);border-bottom-color:rgba(0,126,119,0.40);border-left-color:rgba(0,126,119,0.40);background-color:rgba(0,126,119,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">5. SCM</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 ready, 0 pending</div></div></div></div></div></div><div class="css-g5y9jx r-18u37iz r-1w6e6rj r-1mi0q7o r-u9wvl5"><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Connection</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(214,69,83,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Disconnected</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 events</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Pending Work</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 requests | 0 jobs</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Active Workers</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 busy</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Last Sync</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">--</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">waiting</div></div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-18u37iz r-15d164r r-bhtmuz r-146eth8" style="background-color:rgba(244,248,251,1.00);border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00)"><button aria-label="Coordination tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" style="background-color:rgba(0,126,119,1.00);border-top-color:rgba(0,126,119,1.00);border-right-color:rgba(0,126,119,1.00);border-bottom-color:rgba(0,126,119,1.00);border-left-color:rgba(0,126,119,1.00)" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(255,255,255,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Coordination<!-- --> (0)</div></button><button aria-label="Chat tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Chat<!-- --> (0)</div></button><button aria-label="Requests tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Requests<!-- --> (0)</div></button><button aria-label="Jobs & Traces tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Jobs & Traces<!-- --> (0)</div></button><button aria-label="System tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">System<!-- --> (0)</div></button><button aria-label="Config tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Config</div></button></div><div class="css-g5y9jx r-13awgt0 r-ifefl9" style="opacity:1;transform:translateY(0px)"><div class="css-g5y9jx r-150rngu r-eqz5dr r-16y2uox r-1wbh5a2 r-11yh6sk r-1rnoaur r-agouwx r-13awgt0"><div class="css-g5y9jx r-1t2hasf r-u9wvl5"><div class="css-g5y9jx r-18u37iz r-1w6e6rj r-1mi0q7o"><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Ready For Review</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 processed completions</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Active Handoffs</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 running jobs</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Awaiting Remote</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 pending requests</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Blocked</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 failed jobs</div></div></div><div class="css-g5y9jx r-eqz5dr"><div class="css-g5y9jx r-1867qdf r-rs99b7 r-k3250r r-15d164r r-xyw6el" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(255,255,255,1.00)"><div class="css-g5y9jx r-1awozwy r-18u37iz r-1wtj0ep"><div dir="auto" class="css-146c3p1 r-ubezar r-b88u0q r-5oul0u" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Change Coordination Board</div><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1g94qm0" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0<!-- --> latest requests</div></div><div class="css-g5y9jx r-1habvwh r-1867qdf r-nsbfu8"><div dir="auto" class="css-146c3p1 r-1i10wst r-b88u0q r-15zivkp" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Nothing to coordinate yet</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Send a task from chat and this board will trace the full handoff from request to integration.</div></div></div><div class="css-g5y9jx r-1867qdf r-rs99b7 r-jprt8p r-15d164r r-11wrixw r-xyw6el" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(255,255,255,1.00)"><div dir="auto" class="css-146c3p1 r-ubezar r-b88u0q r-5oul0u" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Review Queue</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">No processed completions yet.</div><div dir="auto" class="css-146c3p1 r-ubezar r-b88u0q r-5oul0u" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif;margin-top:14px">Needs Attention</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">No failed coordination chains.</div></div></div></div></div></div></div></div></div></div></div><!--/$--></div></div></div></div><!--/$--></div></div><script src="/_expo/static/js/web/entry-ff425ab85ad13c1920b8ee00abfae7dd.js" defer></script>
|
|
438
|
+
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"><!--$--><div style="position:absolute;left:0;right:0;top:0;bottom:0;pointer-events:none;visibility:hidden"></div><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0 r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af" style="background-color:rgba(242,242,242,1.00);display:flex"><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0"><!--$--><div class="css-g5y9jx r-13awgt0" style="background-color:rgba(236,242,245,1.00)"><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-cpet4d r-u8s1d r-g7s1ez r-15zx4ds r-a4e7m4 r-j33s3c r-1ovo9ad" style="background-color:rgba(0,126,119,0.13)"></div><div class="css-g5y9jx r-cpet4d r-u8s1d r-g7s1ez r-5fjp4n r-9s5a0n r-1hy2ut r-9dcw1g" style="background-color:rgba(199,133,30,0.09)"></div><div class="css-g5y9jx r-cpet4d r-u8s1d r-g7s1ez r-1iuttuq r-pbsvq8 r-1b0pg27 r-1sxiqef" style="background-color:rgba(22,154,88,0.09)"></div><div class="css-g5y9jx r-150rngu r-eqz5dr r-16y2uox r-1wbh5a2 r-11yh6sk r-1rnoaur r-agouwx r-13awgt0"><div class="css-g5y9jx r-16y2uox r-2llsf r-kzbkwu"><div class="css-g5y9jx r-16uyjmq r-rs99b7 r-13awgt0 r-hv52eu r-ifefl9 r-1udh08x" style="background-color:rgba(247,250,252,1.00);border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);opacity:0;transform:translateY(18px)"><div class="css-g5y9jx r-1habvwh r-18u37iz r-1wtj0ep r-kzbkwu r-u9wvl5 r-131miar"><div class="css-g5y9jx r-13awgt0 r-j2kj52"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1q67n59 r-15zivkp r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">pushpals operations console</div><div dir="auto" class="css-146c3p1 r-1ra0lkn r-b88u0q r-zl2h9q" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Mission Control</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo r-1cmskyw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Coordinate your edits with autonomous buddy execution across planning, jobs, and integration in one live board.</div><div dir="auto" class="css-146c3p1 r-1enofrn r-5fcqz0 r-kc8jnq" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Current repo:<!-- --> <span class="css-1jxf684 r-1enofrn" style="color:rgba(84,112,134,1.00);font-family:'IBM Plex Mono', 'JetBrains Mono', monospace">unavailable</span></div><div dir="auto" class="css-146c3p1 r-1enofrn r-5fcqz0 r-14gqq1x" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Snapshot:<!-- --> <span class="css-1jxf684 r-1enofrn" style="color:rgba(17,34,48,1.00);font-family:'IBM Plex Mono', 'JetBrains Mono', monospace">waiting for /system/status</span></div></div><div class="css-g5y9jx r-k200y r-1q9bdsx r-rs99b7 r-18u37iz r-1udh08x" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><button aria-label="Set theme mode to auto" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1yd117h r-1ubuhtd" style="background-color:rgba(217,244,241,1.00)" type="button"><div dir="auto" class="css-146c3p1 r-1enofrn r-1kfrs79 r-1ozqkpa" style="color:rgba(2,92,86,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">auto</div></button><button aria-label="Set theme mode to light" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1yd117h r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-1enofrn r-1kfrs79 r-1ozqkpa" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">light</div></button><button aria-label="Set theme mode to dark" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1yd117h r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-1enofrn r-1kfrs79 r-1ozqkpa" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">dark</div></button></div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-15d164r r-bhtmuz r-ytbthy r-1ubuhtd" style="background-color:rgba(244,248,251,1.00);border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00)"><div class="css-g5y9jx r-150rngu r-18u37iz r-16y2uox r-1wbh5a2 r-lltvgl r-buy8e9 r-agouwx r-2eszeu"><div class="css-g5y9jx r-18u37iz"><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(199,133,30,0.40);border-right-color:rgba(199,133,30,0.40);border-bottom-color:rgba(199,133,30,0.40);border-left-color:rgba(199,133,30,0.40);background-color:rgba(199,133,30,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(199,133,30,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">1. You</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Awaiting input</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(0,126,119,0.40);border-right-color:rgba(0,126,119,0.40);border-bottom-color:rgba(0,126,119,0.40);border-left-color:rgba(0,126,119,0.40);background-color:rgba(0,126,119,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">2. Session</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Ready</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(22,154,88,0.40);border-right-color:rgba(22,154,88,0.40);border-bottom-color:rgba(22,154,88,0.40);border-left-color:rgba(22,154,88,0.40);background-color:rgba(22,154,88,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">3. RemoteBuddy</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 pending, 0 claimed</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(22,154,88,0.40);border-right-color:rgba(22,154,88,0.40);border-bottom-color:rgba(22,154,88,0.40);border-left-color:rgba(22,154,88,0.40);background-color:rgba(22,154,88,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">4. WorkerPals</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 online, 0 busy, 0 queued</div></div><div class="css-g5y9jx r-109y4c4 r-8dgmk1 r-12ym1je" style="background-color:rgba(207,218,226,0.80)"></div></div><div class="css-g5y9jx r-1awozwy r-18u37iz"><div class="css-g5y9jx r-1q9bdsx r-rs99b7 r-1s5swlz r-1ubuhtd r-13i4ljo" style="border-top-color:rgba(0,126,119,0.40);border-right-color:rgba(0,126,119,0.40);border-bottom-color:rgba(0,126,119,0.40);border-left-color:rgba(0,126,119,0.40);background-color:rgba(0,126,119,0.09)"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1gkfh8e r-b88u0q r-1dpkw9 r-tsynxw" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">5. SCM</div><div dir="auto" class="css-146c3p1 r-8akbws r-krxsd3 r-dnmrzs r-1qsk4np r-1udbk01 r-1enofrn r-1cwl3u0 r-14gqq1x" style="-webkit-line-clamp:2;color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 ready, 0 pending</div></div></div></div></div></div><div class="css-g5y9jx r-18u37iz r-1w6e6rj r-1mi0q7o r-u9wvl5"><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Connection</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(214,69,83,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Disconnected</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 events</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Pending Work</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 requests | 0 jobs</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Active Workers</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 busy</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Last Sync</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">--</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">waiting</div></div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-18u37iz r-15d164r r-bhtmuz r-146eth8" style="background-color:rgba(244,248,251,1.00);border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00)"><button aria-label="Coordination tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" style="background-color:rgba(0,126,119,1.00);border-top-color:rgba(0,126,119,1.00);border-right-color:rgba(0,126,119,1.00);border-bottom-color:rgba(0,126,119,1.00);border-left-color:rgba(0,126,119,1.00)" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(255,255,255,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Coordination<!-- --> (0)</div></button><button aria-label="Chat tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Chat<!-- --> (0)</div></button><button aria-label="Requests tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Requests<!-- --> (0)</div></button><button aria-label="Jobs & Traces tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Jobs & Traces<!-- --> (0)</div></button><button aria-label="System tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">System<!-- --> (0)</div></button><button aria-label="Config tab" role="button" tabindex="0" class="css-g5y9jx r-1loqt21 r-1otgn73 r-1awozwy r-42olwf r-1dzdj1l r-rs99b7 r-13awgt0 r-1777fci r-11f147o r-1ubuhtd" type="button"><div dir="auto" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1enofrn r-b88u0q" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Config</div></button></div><div class="css-g5y9jx r-13awgt0 r-ifefl9" style="opacity:1;transform:translateY(0px)"><div class="css-g5y9jx r-150rngu r-eqz5dr r-16y2uox r-1wbh5a2 r-11yh6sk r-1rnoaur r-agouwx r-13awgt0"><div class="css-g5y9jx r-1t2hasf r-u9wvl5"><div class="css-g5y9jx r-18u37iz r-1w6e6rj r-1mi0q7o"><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Ready For Review</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 processed completions</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Active Handoffs</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(0,126,119,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 running jobs</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Awaiting Remote</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 pending requests</div></div><div class="css-g5y9jx r-t23y2h r-rs99b7 r-16y2uox r-5oul0u r-1kb76zh r-bgnin r-ytbthy r-3o4zer" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(244,248,251,1.00)"><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1cm7zt9 r-tsynxw" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Blocked</div><div dir="auto" class="css-146c3p1 r-evnaw r-b88u0q r-19qrga8" style="color:rgba(22,154,88,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0</div><div dir="auto" class="css-146c3p1 r-1enofrn r-19qrga8" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0 failed jobs</div></div></div><div class="css-g5y9jx r-eqz5dr"><div class="css-g5y9jx r-1867qdf r-rs99b7 r-k3250r r-15d164r r-xyw6el" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(255,255,255,1.00)"><div class="css-g5y9jx r-1awozwy r-18u37iz r-1wtj0ep"><div dir="auto" class="css-146c3p1 r-ubezar r-b88u0q r-5oul0u" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Change Coordination Board</div><div dir="auto" class="css-146c3p1 r-1gkfh8e r-1g94qm0" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">0<!-- --> latest requests</div></div><div class="css-g5y9jx r-1habvwh r-1867qdf r-nsbfu8"><div dir="auto" class="css-146c3p1 r-1i10wst r-b88u0q r-15zivkp" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Nothing to coordinate yet</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Send a task from chat and this board will trace the full handoff from request to integration.</div></div></div><div class="css-g5y9jx r-1867qdf r-rs99b7 r-jprt8p r-15d164r r-11wrixw r-xyw6el" style="border-top-color:rgba(207,218,226,1.00);border-right-color:rgba(207,218,226,1.00);border-bottom-color:rgba(207,218,226,1.00);border-left-color:rgba(207,218,226,1.00);background-color:rgba(255,255,255,1.00)"><div dir="auto" class="css-146c3p1 r-ubezar r-b88u0q r-5oul0u" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">Review Queue</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">No processed completions yet.</div><div dir="auto" class="css-146c3p1 r-ubezar r-b88u0q r-5oul0u" style="color:rgba(17,34,48,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif;margin-top:14px">Needs Attention</div><div dir="auto" class="css-146c3p1 r-n6v787 r-hjklzo" style="color:rgba(84,112,134,1.00);font-family:'Space Grotesk', 'Avenir Next', 'Trebuchet MS', sans-serif">No failed coordination chains.</div></div></div></div></div></div></div></div></div></div></div><!--/$--></div></div></div></div><!--/$--></div></div><script src="/_expo/static/js/web/entry-e8aa7049f746aaa8f1e865615e248f21.js" defer></script>
|
|
439
439
|
</body></html>
|
package/monitor-ui/modal.html
CHANGED
|
@@ -435,5 +435,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
435
435
|
@keyframes r-1pzkwqh{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
|
|
436
436
|
@keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
|
|
437
437
|
@keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
|
|
438
|
-
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"><!--$--><div style="position:absolute;left:0;right:0;top:0;bottom:0;pointer-events:none;visibility:hidden"></div><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0 r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af" style="background-color:rgba(242,242,242,1.00);display:flex"><div class="css-g5y9jx r-184en5c r-12vffkv"><div class="css-g5y9jx r-12vffkv" style="height:64px"><div class="css-g5y9jx r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af r-12vffkv"><div class="css-g5y9jx r-qklmqi r-13awgt0 r-105ug2t" style="background-color:rgba(255,255,255,1.00);border-bottom-color:rgba(216,216,216,1.00)"></div></div><div class="css-g5y9jx r-633pao" style="height:0px"></div><div class="css-g5y9jx r-1oszu61 r-13awgt0 r-18u37iz r-12vffkv"><div class="css-g5y9jx r-1awozwy r-18u37iz r-1h0z5md r-12vffkv" style="margin-left:0px"></div><div class="css-g5y9jx r-1777fci r-12vffkv" style="max-width:-32px;margin-right:16px;margin-left:16px"><h1 dir="auto" aria-level="1" role="heading" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1i10wst" style="color:rgba(28,28,30,1.00);font-family:system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-weight:500">Modal</h1></div><div class="css-g5y9jx r-1awozwy r-18u37iz r-17s6mgv r-1iusvr4 r-16y2uox r-12vffkv" style="margin-right:0px"></div></div></div></div><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0"><!--$--><div class="css-g5y9jx r-1awozwy r-13awgt0 r-1777fci r-1pcd2l5" style="background-color:rgba(255,255,255,1.00)"><div dir="auto" class="css-146c3p1 r-1ui5ee8 r-vw2c0b r-37tt59" style="color:rgba(17,24,28,1.00)">This is a modal</div><a href="/" dir="auto" role="link" class="css-146c3p1 r-19h5ruw r-1d7mnkm r-1loqt21"><span class="css-1jxf684 r-1v78gzs r-ubezar r-17rnw9f">Go to home screen</span></a></div><!--/$--></div></div></div></div><!--/$--></div></div><script src="/_expo/static/js/web/entry-
|
|
438
|
+
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="icon" href="/favicon.ico" /></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"><!--$--><div style="position:absolute;left:0;right:0;top:0;bottom:0;pointer-events:none;visibility:hidden"></div><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0 r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af" style="background-color:rgba(242,242,242,1.00);display:flex"><div class="css-g5y9jx r-184en5c r-12vffkv"><div class="css-g5y9jx r-12vffkv" style="height:64px"><div class="css-g5y9jx r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af r-12vffkv"><div class="css-g5y9jx r-qklmqi r-13awgt0 r-105ug2t" style="background-color:rgba(255,255,255,1.00);border-bottom-color:rgba(216,216,216,1.00)"></div></div><div class="css-g5y9jx r-633pao" style="height:0px"></div><div class="css-g5y9jx r-1oszu61 r-13awgt0 r-18u37iz r-12vffkv"><div class="css-g5y9jx r-1awozwy r-18u37iz r-1h0z5md r-12vffkv" style="margin-left:0px"></div><div class="css-g5y9jx r-1777fci r-12vffkv" style="max-width:-32px;margin-right:16px;margin-left:16px"><h1 dir="auto" aria-level="1" role="heading" class="css-146c3p1 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a r-1i10wst" style="color:rgba(28,28,30,1.00);font-family:system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-weight:500">Modal</h1></div><div class="css-g5y9jx r-1awozwy r-18u37iz r-17s6mgv r-1iusvr4 r-16y2uox r-12vffkv" style="margin-right:0px"></div></div></div></div><div class="css-g5y9jx r-13awgt0"><div class="css-g5y9jx r-13awgt0"><!--$--><div class="css-g5y9jx r-1awozwy r-13awgt0 r-1777fci r-1pcd2l5" style="background-color:rgba(255,255,255,1.00)"><div dir="auto" class="css-146c3p1 r-1ui5ee8 r-vw2c0b r-37tt59" style="color:rgba(17,24,28,1.00)">This is a modal</div><a href="/" dir="auto" role="link" class="css-146c3p1 r-19h5ruw r-1d7mnkm r-1loqt21"><span class="css-1jxf684 r-1v78gzs r-ubezar r-17rnw9f">Go to home screen</span></a></div><!--/$--></div></div></div></div><!--/$--></div></div><script src="/_expo/static/js/web/entry-e8aa7049f746aaa8f1e865615e248f21.js" defer></script>
|
|
439
439
|
</body></html>
|
package/package.json
CHANGED
|
@@ -51,7 +51,7 @@ workerpal_heartbeat_ms = 0
|
|
|
51
51
|
workerpal_labels = []
|
|
52
52
|
execution_budget_interactive_ms = 600000
|
|
53
53
|
execution_budget_normal_ms = 1500000
|
|
54
|
-
execution_budget_background_ms =
|
|
54
|
+
execution_budget_background_ms = 1200000
|
|
55
55
|
finalization_budget_ms = 120000
|
|
56
56
|
crash_restart_enabled = true
|
|
57
57
|
crash_restart_max_restarts = 3
|
|
@@ -515,7 +515,8 @@
|
|
|
515
515
|
"stream": { "type": "string", "enum": ["stdout", "stderr"] },
|
|
516
516
|
"seq": { "type": "integer", "minimum": 1 },
|
|
517
517
|
"line": { "type": "string" },
|
|
518
|
-
"ts": { "type": "string" }
|
|
518
|
+
"ts": { "type": "string" },
|
|
519
|
+
"phase": { "type": ["string", "null"] }
|
|
519
520
|
},
|
|
520
521
|
"additionalProperties": false
|
|
521
522
|
}
|
|
@@ -1306,7 +1306,7 @@ function loadPushPalsConfig(options = {}) {
|
|
|
1306
1306
|
workerpalLabels: firstNonEmpty(process.env.REMOTEBUDDY_WORKERPAL_LABELS) ? firstNonEmpty(process.env.REMOTEBUDDY_WORKERPAL_LABELS).split(",").map((value) => value.trim()).filter(Boolean) : asStringArray(remoteNode.workerpal_labels),
|
|
1307
1307
|
executionBudgetInteractiveMs: Math.max(60000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_INTERACTIVE_MS") ?? remoteNode.execution_budget_interactive_ms, 300000)),
|
|
1308
1308
|
executionBudgetNormalMs: Math.max(120000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_NORMAL_MS") ?? remoteNode.execution_budget_normal_ms, 900000)),
|
|
1309
|
-
executionBudgetBackgroundMs: Math.max(180000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_BACKGROUND_MS") ?? remoteNode.execution_budget_background_ms,
|
|
1309
|
+
executionBudgetBackgroundMs: Math.max(180000, asInt(parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_BACKGROUND_MS") ?? remoteNode.execution_budget_background_ms, 1200000)),
|
|
1310
1310
|
finalizationBudgetMs: Math.max(30000, asInt(parseIntEnv("REMOTEBUDDY_FINALIZATION_BUDGET_MS") ?? remoteNode.finalization_budget_ms, 120000)),
|
|
1311
1311
|
crashRestartEnabled: parseBoolEnv("REMOTEBUDDY_CRASH_RESTART_ENABLED") ?? asBoolean(remoteNode.crash_restart_enabled, true),
|
|
1312
1312
|
crashRestartMaxRestarts: Math.max(0, asInt(parseIntEnv("REMOTEBUDDY_CRASH_RESTART_MAX_RESTARTS") ?? remoteNode.crash_restart_max_restarts, 3)),
|
|
@@ -1432,10 +1432,15 @@ def _merge_usage_records(first: Any, second: Any) -> Dict[str, Any]:
|
|
|
1432
1432
|
return merged
|
|
1433
1433
|
|
|
1434
1434
|
|
|
1435
|
+
def _is_publishable_changed_path(path: str) -> bool:
|
|
1436
|
+
normalized = str(path or "").replace("\\", "/").lower()
|
|
1437
|
+
return not re.search(r"(^|/)(outputs|node_modules|\.worktrees|\.codex|dist|build|coverage)(/|$)", normalized)
|
|
1438
|
+
|
|
1439
|
+
|
|
1435
1440
|
def _codex_changed_paths(repo: str, baseline_snapshot: List[str]) -> Tuple[List[str], List[str], List[str]]:
|
|
1436
1441
|
changed_paths = summarize_git_changes(repo)
|
|
1437
1442
|
delta = [p for p in changed_paths if p not in baseline_snapshot]
|
|
1438
|
-
effective = delta if delta else changed_paths
|
|
1443
|
+
effective = [p for p in (delta if delta else changed_paths) if _is_publishable_changed_path(p)]
|
|
1439
1444
|
return changed_paths, delta, effective
|
|
1440
1445
|
|
|
1441
1446
|
|
|
@@ -32,6 +32,7 @@ from openai_codex_executor import (
|
|
|
32
32
|
_resolve_reasoning_effort,
|
|
33
33
|
_build_instruction,
|
|
34
34
|
_collect_disallowed_shell_wrapper_rejections,
|
|
35
|
+
_codex_changed_paths,
|
|
35
36
|
_detect_codex_workaround_signal,
|
|
36
37
|
_extract_usage_counts,
|
|
37
38
|
_load_prompt_template,
|
|
@@ -298,6 +299,8 @@ class OpenAICodexRuntimeConfigTests(unittest.TestCase):
|
|
|
298
299
|
task = parse_task_execute_payload(["executor", encoded], logger=Logger("[test]"))
|
|
299
300
|
guidance = "\n".join(task.supplemental_guidance)
|
|
300
301
|
|
|
302
|
+
self.assertIn("Worker speed/convergence contract", guidance)
|
|
303
|
+
self.assertIn("roughly 20 minutes", guidance)
|
|
301
304
|
self.assertIn("Task planning contract from PushPals", guidance)
|
|
302
305
|
self.assertIn("Worker phase contract", guidance)
|
|
303
306
|
self.assertIn("Write globs are relevance hints, not hard limits", guidance)
|
|
@@ -305,6 +308,42 @@ class OpenAICodexRuntimeConfigTests(unittest.TestCase):
|
|
|
305
308
|
self.assertIn("Home shell startup is assertable", guidance)
|
|
306
309
|
self.assertIn("bun run web:e2e", guidance)
|
|
307
310
|
|
|
311
|
+
def test_parse_payload_prefers_helper_tests_for_visual_derivation_tasks(self) -> None:
|
|
312
|
+
with tempfile.TemporaryDirectory(prefix="pushpals-visual-guidance-") as temp_dir:
|
|
313
|
+
repo = Path(temp_dir) / "repo"
|
|
314
|
+
repo.mkdir(parents=True, exist_ok=True)
|
|
315
|
+
payload = {
|
|
316
|
+
"kind": "task.execute",
|
|
317
|
+
"repo": str(repo),
|
|
318
|
+
"params": {
|
|
319
|
+
"instruction": (
|
|
320
|
+
"Improve battlefield readability by making planet ownership rings, "
|
|
321
|
+
"projectile trails, and danger cues clearer."
|
|
322
|
+
),
|
|
323
|
+
"schemaVersion": 2,
|
|
324
|
+
"planning": {
|
|
325
|
+
"intent": "code_change",
|
|
326
|
+
"riskLevel": "medium",
|
|
327
|
+
"queuePriority": "normal",
|
|
328
|
+
"queueWaitBudgetMs": 90_000,
|
|
329
|
+
"executionBudgetMs": 1_800_000,
|
|
330
|
+
"finalizationBudgetMs": 120_000,
|
|
331
|
+
"scope": {"readAnywhere": True, "writeAllowed": True},
|
|
332
|
+
"targetPaths": ["app/game.tsx"],
|
|
333
|
+
"acceptanceCriteria": ["Projectile and ownership readability improve"],
|
|
334
|
+
"validationSteps": ["bun test app/__tests__/battlefieldReadability.test.ts"],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
}
|
|
338
|
+
encoded = base64.b64encode(json.dumps(payload).encode("utf-8")).decode("ascii")
|
|
339
|
+
|
|
340
|
+
task = parse_task_execute_payload(["executor", encoded], logger=Logger("[test]"))
|
|
341
|
+
guidance = "\n".join(task.supplemental_guidance)
|
|
342
|
+
|
|
343
|
+
self.assertIn("Visual/rendering task rule", guidance)
|
|
344
|
+
self.assertIn("prefer pure helper/state/style-prop tests", guidance)
|
|
345
|
+
self.assertIn("full React Native/component render regression", guidance)
|
|
346
|
+
|
|
308
347
|
def test_detects_codex_workaround_signals(self) -> None:
|
|
309
348
|
signal = _detect_codex_workaround_signal(
|
|
310
349
|
"Adapting test to avoid external Codex calls because Codex CLI isn't available in this environment.",
|
|
@@ -571,6 +610,45 @@ class OpenAICodexRuntimeConfigTests(unittest.TestCase):
|
|
|
571
610
|
self.assertIn("src/", str(result.get("stdout") or ""))
|
|
572
611
|
self.assertNotIn("Recovered after Codex attempts", str(result.get("stdout") or ""))
|
|
573
612
|
|
|
613
|
+
def test_codex_changed_paths_filters_dependency_artifacts_from_publishable_delta(self) -> None:
|
|
614
|
+
with tempfile.TemporaryDirectory(prefix="pushpals-codex-artifact-delta-") as temp_dir:
|
|
615
|
+
repo = Path(temp_dir) / "repo"
|
|
616
|
+
repo.mkdir(parents=True, exist_ok=True)
|
|
617
|
+
(repo / "README.md").write_text("# artifact delta test\n", encoding="utf-8")
|
|
618
|
+
subprocess.run(["git", "init"], cwd=repo, check=True, capture_output=True, text=True)
|
|
619
|
+
subprocess.run(
|
|
620
|
+
["git", "config", "user.name", "PushPals Test"],
|
|
621
|
+
cwd=repo,
|
|
622
|
+
check=True,
|
|
623
|
+
capture_output=True,
|
|
624
|
+
text=True,
|
|
625
|
+
)
|
|
626
|
+
subprocess.run(
|
|
627
|
+
["git", "config", "user.email", "pushpals-tests@example.com"],
|
|
628
|
+
cwd=repo,
|
|
629
|
+
check=True,
|
|
630
|
+
capture_output=True,
|
|
631
|
+
text=True,
|
|
632
|
+
)
|
|
633
|
+
subprocess.run(["git", "add", "README.md"], cwd=repo, check=True, capture_output=True, text=True)
|
|
634
|
+
subprocess.run(
|
|
635
|
+
["git", "commit", "-m", "chore: seed artifact test"],
|
|
636
|
+
cwd=repo,
|
|
637
|
+
check=True,
|
|
638
|
+
capture_output=True,
|
|
639
|
+
text=True,
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
(repo / "node_modules").mkdir()
|
|
643
|
+
(repo / "node_modules" / "linked.txt").write_text("artifact\n", encoding="utf-8")
|
|
644
|
+
(repo / "outputs").mkdir()
|
|
645
|
+
(repo / "outputs" / "runtime.log").write_text("artifact\n", encoding="utf-8")
|
|
646
|
+
changed_paths, delta, effective = _codex_changed_paths(str(repo), [])
|
|
647
|
+
|
|
648
|
+
self.assertGreaterEqual(len(changed_paths), 2)
|
|
649
|
+
self.assertGreaterEqual(len(delta), 2)
|
|
650
|
+
self.assertEqual(effective, [])
|
|
651
|
+
|
|
574
652
|
def test_run_codex_task_escalates_wrapper_recovery_and_recovers(self) -> None:
|
|
575
653
|
with tempfile.TemporaryDirectory(prefix="pushpals-codex-wrapper-recovery-") as temp_dir:
|
|
576
654
|
repo = Path(temp_dir) / "repo"
|
|
@@ -63,6 +63,5 @@ export const OPENAI_CODEX_BACKEND: DockerBackendSpec = {
|
|
|
63
63
|
scriptPath: resolve(import.meta.dir, "openai_codex", "openai_codex_executor.py"),
|
|
64
64
|
pythonConfigKey: "openaiCodexPython",
|
|
65
65
|
timeoutConfigKey: "openaiCodexTimeoutMs",
|
|
66
|
-
capTimeoutToExecutionBudget: false,
|
|
67
66
|
}),
|
|
68
67
|
};
|
|
@@ -738,6 +738,72 @@ def _append_list_guidance(lines: List[str], label: str, values: List[str]) -> No
|
|
|
738
738
|
lines.append(f" - {value}")
|
|
739
739
|
|
|
740
740
|
|
|
741
|
+
def _joined_task_text(params: Dict[str, Any]) -> str:
|
|
742
|
+
pieces: List[str] = []
|
|
743
|
+
|
|
744
|
+
def collect(value: Any) -> None:
|
|
745
|
+
if isinstance(value, str):
|
|
746
|
+
pieces.append(value)
|
|
747
|
+
elif isinstance(value, list):
|
|
748
|
+
for item in value:
|
|
749
|
+
collect(item)
|
|
750
|
+
elif isinstance(value, dict):
|
|
751
|
+
for item in value.values():
|
|
752
|
+
collect(item)
|
|
753
|
+
|
|
754
|
+
collect(params.get("instruction"))
|
|
755
|
+
collect(params.get("plannerWorkerInstruction"))
|
|
756
|
+
collect(params.get("qualityRevisionHint"))
|
|
757
|
+
planning = params.get("planning")
|
|
758
|
+
if isinstance(planning, dict):
|
|
759
|
+
collect(planning.get("targetPaths"))
|
|
760
|
+
collect(planning.get("acceptanceCriteria"))
|
|
761
|
+
collect(planning.get("validationSteps"))
|
|
762
|
+
collect(planning.get("requiredValidationSteps"))
|
|
763
|
+
collect(planning.get("discovery"))
|
|
764
|
+
return "\n".join(pieces).lower()
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
def _looks_like_visual_derivation_task(params: Dict[str, Any]) -> bool:
|
|
768
|
+
text = _joined_task_text(params)
|
|
769
|
+
visual_markers = (
|
|
770
|
+
"visual",
|
|
771
|
+
"readability",
|
|
772
|
+
"battlefield",
|
|
773
|
+
"render",
|
|
774
|
+
"rendering",
|
|
775
|
+
"projectile",
|
|
776
|
+
"planet",
|
|
777
|
+
"ship",
|
|
778
|
+
"ring",
|
|
779
|
+
"danger",
|
|
780
|
+
"threat",
|
|
781
|
+
"ownership",
|
|
782
|
+
"dense action",
|
|
783
|
+
"ui surface",
|
|
784
|
+
"style",
|
|
785
|
+
"styles",
|
|
786
|
+
)
|
|
787
|
+
return any(marker in text for marker in visual_markers)
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
def _build_efficiency_guidance(params: Dict[str, Any]) -> str:
|
|
791
|
+
lines: List[str] = [
|
|
792
|
+
"Worker speed/convergence contract from PushPals:",
|
|
793
|
+
"- Target useful completion in roughly 20 minutes for small or medium repo tasks; optimize for the smallest coherent patch over exhaustive exploration.",
|
|
794
|
+
"- Phase soft budgets: discovery <= 5m, editing <= 10m, focused validation <= 5m, final diff review <= 2m. If a phase runs long, narrow scope rather than expanding the harness.",
|
|
795
|
+
"- Test-harness soft budget: if setting up a focused test requires multiple new shared mocks, broad React Native shims, or repeated import fixes, stop building that harness and switch to smaller pure helper/state coverage.",
|
|
796
|
+
]
|
|
797
|
+
if _looks_like_visual_derivation_task(params):
|
|
798
|
+
lines.extend(
|
|
799
|
+
[
|
|
800
|
+
"- Visual/rendering task rule: prefer pure helper/state/style-prop tests for derived visual cues. Use a full React Native/component render regression only if the repo already has a stable harness for that exact surface.",
|
|
801
|
+
"- Full-surface React Native tests are a last resort for visual derivation work; do not spend the job constructing broad mocks just to assert pixels or nested component trees.",
|
|
802
|
+
]
|
|
803
|
+
)
|
|
804
|
+
return "\n".join(lines)
|
|
805
|
+
|
|
806
|
+
|
|
741
807
|
def _build_planning_guidance(params: Dict[str, Any]) -> str:
|
|
742
808
|
planning = params.get("planning")
|
|
743
809
|
if not isinstance(planning, dict):
|
|
@@ -768,6 +834,9 @@ def _build_planning_guidance(params: Dict[str, Any]) -> str:
|
|
|
768
834
|
" - full validation: let PushPals ValidationGate own long required/browser checks unless one local confirmation is explicitly useful."
|
|
769
835
|
)
|
|
770
836
|
lines.append(" - final diff review: remove unrelated churn before returning.")
|
|
837
|
+
lines.append(
|
|
838
|
+
"- Phase soft budget: aim for discovery <= 5m, editing <= 10m, focused validation <= 5m, final diff review <= 2m; if test harness setup starts consuming the budget, reduce to simpler helper/state coverage."
|
|
839
|
+
)
|
|
771
840
|
|
|
772
841
|
scope = planning.get("scope")
|
|
773
842
|
if isinstance(scope, dict):
|
|
@@ -869,6 +938,7 @@ def parse_task_execute_payload(
|
|
|
869
938
|
quality_revision_hint = str(params.get("qualityRevisionHint") or "").strip()
|
|
870
939
|
|
|
871
940
|
supplemental_guidance: List[str] = []
|
|
941
|
+
supplemental_guidance.append(_build_efficiency_guidance(params))
|
|
872
942
|
planning_guidance = _build_planning_guidance(params)
|
|
873
943
|
if planning_guidance:
|
|
874
944
|
supplemental_guidance.append(planning_guidance)
|
|
@@ -136,6 +136,29 @@ export function resolveGenericPythonExecutorTimeoutMs(params: {
|
|
|
136
136
|
return configuredTimeoutMs;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
function toSnakeConfigKey(key: string): string {
|
|
140
|
+
return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function formatGenericPythonExecutorTimeoutDetail(
|
|
144
|
+
config: GenericPythonExecutorConfig,
|
|
145
|
+
configuredTimeoutMs: number,
|
|
146
|
+
executionBudgetMs: number | null,
|
|
147
|
+
timeoutMs: number,
|
|
148
|
+
): string {
|
|
149
|
+
const configPath = `workerpals.${toSnakeConfigKey(config.timeoutConfigKey)}`;
|
|
150
|
+
if (executionBudgetMs == null) {
|
|
151
|
+
return `${configPath}=${configuredTimeoutMs}ms`;
|
|
152
|
+
}
|
|
153
|
+
if (config.capTimeoutToExecutionBudget === false) {
|
|
154
|
+
return `${configPath}=${configuredTimeoutMs}ms; planning executionBudgetMs=${executionBudgetMs}ms ignored by backend opt-out`;
|
|
155
|
+
}
|
|
156
|
+
if (timeoutMs < configuredTimeoutMs) {
|
|
157
|
+
return `${configPath}=${configuredTimeoutMs}ms capped by planning executionBudgetMs=${executionBudgetMs}ms`;
|
|
158
|
+
}
|
|
159
|
+
return `${configPath}=${configuredTimeoutMs}ms within planning executionBudgetMs=${executionBudgetMs}ms`;
|
|
160
|
+
}
|
|
161
|
+
|
|
139
162
|
export function createGenericPythonExecutor(
|
|
140
163
|
config: GenericPythonExecutorConfig,
|
|
141
164
|
): BackendTaskExecutor {
|
|
@@ -172,6 +195,12 @@ export function createGenericPythonExecutor(
|
|
|
172
195
|
executionBudgetMs,
|
|
173
196
|
capTimeoutToExecutionBudget: config.capTimeoutToExecutionBudget,
|
|
174
197
|
});
|
|
198
|
+
const timeoutDetail = formatGenericPythonExecutorTimeoutDetail(
|
|
199
|
+
config,
|
|
200
|
+
configuredTimeoutMs,
|
|
201
|
+
executionBudgetMs,
|
|
202
|
+
timeoutMs,
|
|
203
|
+
);
|
|
175
204
|
const payloadBase64 = Buffer.from(
|
|
176
205
|
JSON.stringify({
|
|
177
206
|
kind,
|
|
@@ -184,7 +213,7 @@ export function createGenericPythonExecutor(
|
|
|
184
213
|
|
|
185
214
|
onLog?.(
|
|
186
215
|
"stdout",
|
|
187
|
-
`[${backendLabel}Executor] Spawning ${backendName} executor (timeout=${timeoutMs}ms)`,
|
|
216
|
+
`[${backendLabel}Executor] Spawning ${backendName} executor (timeout=${timeoutMs}ms; ${timeoutDetail})`,
|
|
188
217
|
);
|
|
189
218
|
|
|
190
219
|
try {
|
|
@@ -207,6 +236,7 @@ export function createGenericPythonExecutor(
|
|
|
207
236
|
});
|
|
208
237
|
|
|
209
238
|
let timedOut = false;
|
|
239
|
+
let hardKillTimer: ReturnType<typeof setTimeout> | null = null;
|
|
210
240
|
const timeoutTimer = setTimeout(() => {
|
|
211
241
|
timedOut = true;
|
|
212
242
|
onLog?.(
|
|
@@ -214,6 +244,13 @@ export function createGenericPythonExecutor(
|
|
|
214
244
|
`[${backendLabel}Executor] Timeout reached after ${timeoutMs}ms; terminating process.`,
|
|
215
245
|
);
|
|
216
246
|
proc.kill();
|
|
247
|
+
hardKillTimer = setTimeout(() => {
|
|
248
|
+
onLog?.(
|
|
249
|
+
"stdout",
|
|
250
|
+
`[${backendLabel}Executor] Process did not exit after graceful timeout termination; forcing kill.`,
|
|
251
|
+
);
|
|
252
|
+
proc.kill("SIGKILL");
|
|
253
|
+
}, 5_000);
|
|
217
254
|
}, timeoutMs);
|
|
218
255
|
|
|
219
256
|
const progressIntervalMs = 15_000;
|
|
@@ -246,6 +283,7 @@ export function createGenericPythonExecutor(
|
|
|
246
283
|
]);
|
|
247
284
|
|
|
248
285
|
clearTimeout(timeoutTimer);
|
|
286
|
+
if (hardKillTimer) clearTimeout(hardKillTimer);
|
|
249
287
|
clearInterval(progressTimer);
|
|
250
288
|
|
|
251
289
|
const stdout = rawStdout ?? "";
|
|
@@ -43,10 +43,10 @@ const WORKERPAL_SANDBOX_COMPONENT_LABEL = "pushpals.component=workerpals-sandbox
|
|
|
43
43
|
const DOCKER_IMAGE_INSPECT_TIMEOUT_MS = 15_000;
|
|
44
44
|
const DOCKER_IMAGE_BUILD_TIMEOUT_MS = 10 * 60_000;
|
|
45
45
|
const DOCKER_IMAGE_PULL_TIMEOUT_MS = 10 * 60_000;
|
|
46
|
-
const BROWSER_VALIDATION_JOB_REPAIR_ATTEMPTS =
|
|
47
|
-
const BROWSER_VALIDATION_JOB_OVERHEAD_MS =
|
|
48
|
-
const BROWSER_VALIDATION_JOB_MIN_TIMEOUT_MS =
|
|
49
|
-
const BROWSER_VALIDATION_JOB_MAX_TIMEOUT_MS =
|
|
46
|
+
const BROWSER_VALIDATION_JOB_REPAIR_ATTEMPTS = 3;
|
|
47
|
+
const BROWSER_VALIDATION_JOB_OVERHEAD_MS = 5 * 60_000;
|
|
48
|
+
const BROWSER_VALIDATION_JOB_MIN_TIMEOUT_MS = 20 * 60_000;
|
|
49
|
+
const BROWSER_VALIDATION_JOB_MAX_TIMEOUT_MS = 45 * 60_000;
|
|
50
50
|
|
|
51
51
|
function parseClampedInt(value: unknown, defaultValue: number, min: number, max: number): number {
|
|
52
52
|
const parsed =
|
|
@@ -303,7 +303,7 @@ export function resolveDockerJobTimeoutMs(
|
|
|
303
303
|
if (!hasBrowserValidationCommand(job)) return baseTimeoutMs;
|
|
304
304
|
|
|
305
305
|
const planning = maybeRecord(job.params.planning);
|
|
306
|
-
const executionBudgetMs = readPositiveNumber(planning?.executionBudgetMs) ??
|
|
306
|
+
const executionBudgetMs = readPositiveNumber(planning?.executionBudgetMs) ?? 1_200_000;
|
|
307
307
|
const finalizationBudgetMs = readPositiveNumber(planning?.finalizationBudgetMs) ?? 120_000;
|
|
308
308
|
const attempts = BROWSER_VALIDATION_JOB_REPAIR_ATTEMPTS + 1; // initial attempt plus repairs
|
|
309
309
|
const estimatedTimeoutMs =
|
|
@@ -312,7 +312,7 @@ export function resolveDockerJobTimeoutMs(
|
|
|
312
312
|
BROWSER_VALIDATION_JOB_MAX_TIMEOUT_MS,
|
|
313
313
|
Math.max(BROWSER_VALIDATION_JOB_MIN_TIMEOUT_MS, estimatedTimeoutMs),
|
|
314
314
|
);
|
|
315
|
-
return Math.max(baseTimeoutMs, boundedTimeoutMs);
|
|
315
|
+
return Math.max(Math.min(baseTimeoutMs, boundedTimeoutMs), BROWSER_VALIDATION_JOB_MIN_TIMEOUT_MS);
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
export class DockerExecutor {
|
|
@@ -1221,7 +1221,8 @@ export class DockerExecutor {
|
|
|
1221
1221
|
});
|
|
1222
1222
|
const timeoutMs = resolveDockerJobTimeoutMs(this.options.timeoutMs, job);
|
|
1223
1223
|
if (timeoutMs !== this.options.timeoutMs) {
|
|
1224
|
-
const
|
|
1224
|
+
const verb = timeoutMs > this.options.timeoutMs ? "Extended" : "Capped";
|
|
1225
|
+
const note = `[DockerExecutor] ${verb} job timeout for browser validation convergence: ${timeoutMs}ms (configured ${this.options.timeoutMs}ms).`;
|
|
1225
1226
|
console.log(note);
|
|
1226
1227
|
onLog?.("stdout", note);
|
|
1227
1228
|
}
|
|
@@ -1246,7 +1247,7 @@ export class DockerExecutor {
|
|
|
1246
1247
|
const timer = setTimeout(() => {
|
|
1247
1248
|
timedOutByDocker = true;
|
|
1248
1249
|
const elapsedMs = Math.max(1, Date.now() - startedAtMs);
|
|
1249
|
-
const timeoutMsg = `[DockerExecutor] Job timeout in warm container after ${elapsedMs}ms (limit ${
|
|
1250
|
+
const timeoutMsg = `[DockerExecutor] Job timeout in warm container after ${elapsedMs}ms (limit ${timeoutMs}ms): ${this.warmContainerName}`;
|
|
1250
1251
|
console.log(timeoutMsg);
|
|
1251
1252
|
onLog?.("stderr", timeoutMsg);
|
|
1252
1253
|
try {
|
|
@@ -176,7 +176,7 @@ export interface QualityGatePolicy {
|
|
|
176
176
|
criticMinScore: number;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
const BROWSER_VALIDATION_MAX_AUTO_REVISIONS =
|
|
179
|
+
const BROWSER_VALIDATION_MAX_AUTO_REVISIONS = 3;
|
|
180
180
|
|
|
181
181
|
export function qualityRevisionLoopUpperBound(policy: {
|
|
182
182
|
maxAutoRevisions: number;
|
|
@@ -378,6 +378,97 @@ function buildDiffBudgetWarning(
|
|
|
378
378
|
.join(", ")}${meaningfulChangedPaths.length > 12 ? ", ..." : ""}`;
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
+
function isNonPublishableArtifactPath(path: string): boolean {
|
|
382
|
+
return /(^|\/)(outputs|node_modules|\.worktrees|\.codex|dist|build|coverage)(\/|$)/i.test(
|
|
383
|
+
path.replace(/\\/g, "/"),
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function publishableChangedPaths(changedPaths: string[]): string[] {
|
|
388
|
+
return changedPaths.filter((path) => !isNonPublishableArtifactPath(path));
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function collectPlanningText(planning: TaskExecutePlanning): string {
|
|
392
|
+
return [
|
|
393
|
+
planning.intent,
|
|
394
|
+
planning.riskLevel,
|
|
395
|
+
...(planning.targetPaths ?? []),
|
|
396
|
+
...(planning.acceptanceCriteria ?? []),
|
|
397
|
+
...(planning.validationSteps ?? []),
|
|
398
|
+
...(planning.requiredValidationSteps ?? []),
|
|
399
|
+
...(planning.discovery?.keywords ?? []),
|
|
400
|
+
...(planning.discovery?.likelyDirs ?? []),
|
|
401
|
+
...(planning.discovery?.ripgrepQueries ?? []),
|
|
402
|
+
]
|
|
403
|
+
.map((part) => String(part ?? ""))
|
|
404
|
+
.join("\n")
|
|
405
|
+
.toLowerCase();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function planningLooksLikeVisualDerivationTask(planning: TaskExecutePlanning): boolean {
|
|
409
|
+
const text = collectPlanningText(planning);
|
|
410
|
+
return /\b(visual|readability|battlefield|render(?:ing)?|projectile|planet|ship|ring|danger|threat|ownership|dense action|style|ui surface)\b/i.test(
|
|
411
|
+
text,
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function buildTestHarnessConvergenceWarning(
|
|
416
|
+
planning: TaskExecutePlanning,
|
|
417
|
+
issues: string[],
|
|
418
|
+
validationRuns: ValidationExecutionResult[],
|
|
419
|
+
): string | null {
|
|
420
|
+
const combined = [
|
|
421
|
+
...issues,
|
|
422
|
+
...validationRuns.flatMap((run) => [run.command, run.stdout, run.stderr]),
|
|
423
|
+
]
|
|
424
|
+
.map((part) => String(part ?? ""))
|
|
425
|
+
.join("\n");
|
|
426
|
+
const hasMockImportFailure =
|
|
427
|
+
/\bCannot find module\b|\bdoes not provide an export\b|\bno exported member\b|\bimport error\b|\bundefined is not a function\b/i.test(
|
|
428
|
+
combined,
|
|
429
|
+
) &&
|
|
430
|
+
/\b(react[- ]native|reactNativeMock|Animated\.View|expo-secure-store|SettingsContext|skin validator|mock|test helper|__mocks__)\b/i.test(
|
|
431
|
+
combined,
|
|
432
|
+
);
|
|
433
|
+
if (!hasMockImportFailure) return null;
|
|
434
|
+
const visualPrefix = planningLooksLikeVisualDerivationTask(planning)
|
|
435
|
+
? " For this visual/rendering task, prefer pure helper/state/style-prop tests over a full React Native surface render."
|
|
436
|
+
: "";
|
|
437
|
+
return (
|
|
438
|
+
"Test harness convergence warning: validation is failing in mock/import setup rather than product behavior." +
|
|
439
|
+
visualPrefix +
|
|
440
|
+
" Do not keep expanding broad shared mocks to rescue an over-scoped component render test. If the repo does not already have stable React Native render-test infrastructure for this surface, replace the full-surface regression with smaller deterministic helper/state coverage and one focused assertion on the behavior-owning API."
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function buildBroadSharedMockWarning(
|
|
445
|
+
planning: TaskExecutePlanning,
|
|
446
|
+
changedPaths: string[],
|
|
447
|
+
): string | null {
|
|
448
|
+
const meaningfulChangedPaths = changedPaths.filter(
|
|
449
|
+
(path) => !/(^|\/)(outputs|node_modules|\.worktrees|dist|build|coverage)(\/|$)/i.test(path),
|
|
450
|
+
);
|
|
451
|
+
const broadMockPaths = meaningfulChangedPaths.filter((path) =>
|
|
452
|
+
/(^|\/)(__mocks__|tests\/.*mock|test.*mock|reactNativeMock|setupTests?|jest\.|vitest\.|mock)(\.|\/|$)/i.test(
|
|
453
|
+
path,
|
|
454
|
+
),
|
|
455
|
+
);
|
|
456
|
+
if (broadMockPaths.length === 0) return null;
|
|
457
|
+
const smallTask =
|
|
458
|
+
planning.riskLevel !== "high" &&
|
|
459
|
+
((planning.targetPaths?.length ?? 0) <= 2 || planning.acceptanceCriteria.length <= 3);
|
|
460
|
+
if (!smallTask && !planningLooksLikeVisualDerivationTask(planning)) return null;
|
|
461
|
+
const explicitlyRequested = /mock|test harness|react native test|component render/i.test(
|
|
462
|
+
collectPlanningText(planning),
|
|
463
|
+
);
|
|
464
|
+
if (explicitlyRequested) return null;
|
|
465
|
+
return `Broad mock warning: this focused task now changes shared mock/test-harness file(s): ${broadMockPaths
|
|
466
|
+
.slice(0, 6)
|
|
467
|
+
.join(", ")}${
|
|
468
|
+
broadMockPaths.length > 6 ? ", ..." : ""
|
|
469
|
+
}. Before continuing, prefer behavior-owned helper/state tests or existing stable render-test infrastructure; do not add broad React Native mocks for a small visual/control change unless the task explicitly requires harness repair.`;
|
|
470
|
+
}
|
|
471
|
+
|
|
381
472
|
const TEST_ASSERTION_BALANCE_ISSUE =
|
|
382
473
|
"Changed test files do not show both positive and negative assertion coverage (expected both).";
|
|
383
474
|
|
|
@@ -3527,6 +3618,22 @@ export function buildQualityRevisionHint(
|
|
|
3527
3618
|
);
|
|
3528
3619
|
const diffBudgetWarning = buildDiffBudgetWarning(planning, changedPaths, focusedBrowserRepair);
|
|
3529
3620
|
if (diffBudgetWarning) lines.push(diffBudgetWarning);
|
|
3621
|
+
const broadSharedMockWarning = buildBroadSharedMockWarning(planning, changedPaths);
|
|
3622
|
+
if (broadSharedMockWarning) lines.push(broadSharedMockWarning);
|
|
3623
|
+
const testHarnessConvergenceWarning = buildTestHarnessConvergenceWarning(
|
|
3624
|
+
planning,
|
|
3625
|
+
issues,
|
|
3626
|
+
validationRuns,
|
|
3627
|
+
);
|
|
3628
|
+
if (testHarnessConvergenceWarning) lines.push(testHarnessConvergenceWarning);
|
|
3629
|
+
if (planningLooksLikeVisualDerivationTask(planning)) {
|
|
3630
|
+
lines.push(
|
|
3631
|
+
"Visual derivation testing rule: prefer pure helper/state/style-prop tests for planet/projectile/ownership/readability cues. Only add a full React Native render regression when this repo already has a stable harness for that exact surface; otherwise keep render-visible behavior covered through the derived inputs that drive it.",
|
|
3632
|
+
);
|
|
3633
|
+
}
|
|
3634
|
+
lines.push(
|
|
3635
|
+
"Phase soft-budget reminder: if discovery, test-harness setup, or validation repair is running long, reduce the approach before spending more time. Small/medium tasks should converge toward a useful patch within roughly 20 minutes.",
|
|
3636
|
+
);
|
|
3530
3637
|
const validationAlreadyPassed =
|
|
3531
3638
|
validationRuns.length > 0 && validationRuns.every((run) => run.ok);
|
|
3532
3639
|
if (validationAlreadyPassed && !focusedBrowserRepair) {
|
|
@@ -6645,6 +6752,53 @@ export async function executeJob(
|
|
|
6645
6752
|
};
|
|
6646
6753
|
}
|
|
6647
6754
|
|
|
6755
|
+
const preQualityStatus = await git(repo, ["status", "--porcelain"]);
|
|
6756
|
+
const preQualityChangedPaths = preQualityStatus.ok
|
|
6757
|
+
? parseChangedPathsFromStatus(preQualityStatus.stdout)
|
|
6758
|
+
: [];
|
|
6759
|
+
const preQualityPublishablePaths = publishableChangedPaths(preQualityChangedPaths);
|
|
6760
|
+
const executorText = `${result.summary ?? ""}\n${result.stdout ?? ""}\n${result.stderr ?? ""}`;
|
|
6761
|
+
const shellWrapperReturn =
|
|
6762
|
+
/shell-wrapper command rejections|command-router shell-wrapper|command policy rejection/i.test(
|
|
6763
|
+
executorText,
|
|
6764
|
+
);
|
|
6765
|
+
if (preQualityChangedPaths.length > 0 && preQualityPublishablePaths.length === 0) {
|
|
6766
|
+
const detail = `Executor changed only non-publishable dependency/runtime artifact path(s): ${preQualityChangedPaths
|
|
6767
|
+
.slice(0, 12)
|
|
6768
|
+
.join(", ")}${preQualityChangedPaths.length > 12 ? ", ..." : ""}.`;
|
|
6769
|
+
onLog?.(
|
|
6770
|
+
"stderr",
|
|
6771
|
+
`[QualityGate] ${detail} Skipping ValidationGate/CriticGate because there is no PR-worthy patch to validate.`,
|
|
6772
|
+
);
|
|
6773
|
+
return {
|
|
6774
|
+
ok: false,
|
|
6775
|
+
summary: "Executor produced no publishable code changes",
|
|
6776
|
+
stdout: result.stdout,
|
|
6777
|
+
stderr: [result.stderr ?? "", detail].filter(Boolean).join("\n"),
|
|
6778
|
+
exitCode: 4,
|
|
6779
|
+
};
|
|
6780
|
+
}
|
|
6781
|
+
if (
|
|
6782
|
+
preQualityPublishablePaths.length === 0 &&
|
|
6783
|
+
(qualityGatePolicy.mode === "review_fix" || shellWrapperReturn)
|
|
6784
|
+
) {
|
|
6785
|
+
const reason =
|
|
6786
|
+
qualityGatePolicy.mode === "review_fix"
|
|
6787
|
+
? "Review-fix executor returned without publishable code changes."
|
|
6788
|
+
: "Codex hit shell-wrapper command rejections without leaving a publishable patch.";
|
|
6789
|
+
onLog?.(
|
|
6790
|
+
"stderr",
|
|
6791
|
+
`[QualityGate] ${reason} Skipping ValidationGate/CriticGate and failing fast.`,
|
|
6792
|
+
);
|
|
6793
|
+
return {
|
|
6794
|
+
ok: false,
|
|
6795
|
+
summary: reason,
|
|
6796
|
+
stdout: result.stdout,
|
|
6797
|
+
stderr: [result.stderr ?? "", reason].filter(Boolean).join("\n"),
|
|
6798
|
+
exitCode: 4,
|
|
6799
|
+
};
|
|
6800
|
+
}
|
|
6801
|
+
|
|
6648
6802
|
const quality = await runDeterministicQualityGate(
|
|
6649
6803
|
repo,
|
|
6650
6804
|
attemptParams,
|
|
@@ -342,6 +342,70 @@ function isNoisyProgressLine(line: string): boolean {
|
|
|
342
342
|
return /^(📦 Installing \[\d+\/\d+\]|🔍 Resolving\.\.\.|🔒 Saving lockfile\.\.\.)$/.test(line);
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
type WorkerJobPhase =
|
|
346
|
+
| "discovering"
|
|
347
|
+
| "editing"
|
|
348
|
+
| "test harness repair"
|
|
349
|
+
| "focused validation"
|
|
350
|
+
| "full validation"
|
|
351
|
+
| "final diff review"
|
|
352
|
+
| "publishing"
|
|
353
|
+
| "quality revision";
|
|
354
|
+
|
|
355
|
+
function inferWorkerJobPhaseFromLogLine(line: string): WorkerJobPhase | null {
|
|
356
|
+
const text = String(line ?? "").trim();
|
|
357
|
+
if (!text) return null;
|
|
358
|
+
if (/Quality gate requested revision|Quality revision required|revision guidance/i.test(text)) {
|
|
359
|
+
return "quality revision";
|
|
360
|
+
}
|
|
361
|
+
if (
|
|
362
|
+
/test harness|React Native package|reactNativeMock|mock helper|mock was missing|expo-secure-store|import error|Cannot find module|does not provide an export|no exported member|Animated\.View|SettingsContext|skin validator/i.test(
|
|
363
|
+
text,
|
|
364
|
+
)
|
|
365
|
+
) {
|
|
366
|
+
return "test harness repair";
|
|
367
|
+
}
|
|
368
|
+
if (
|
|
369
|
+
/focused validation|focused checks|targeted test|focused test|new regression|focused regression|fast checks|rerunning .*regression|node --check/i.test(
|
|
370
|
+
text,
|
|
371
|
+
)
|
|
372
|
+
) {
|
|
373
|
+
return "focused validation";
|
|
374
|
+
}
|
|
375
|
+
if (
|
|
376
|
+
/ValidationGate|required validation|full .*test suite|whole Bun test|repo-level|bun test\b|bunx? tsc|typecheck|type check|bun run lint|web:e2e|browser smoke/i.test(
|
|
377
|
+
text,
|
|
378
|
+
)
|
|
379
|
+
) {
|
|
380
|
+
return "full validation";
|
|
381
|
+
}
|
|
382
|
+
if (/creating commit|Publish blocked|publish-blocked|completion ref|enqueueCompletion/i.test(text)) {
|
|
383
|
+
return "publishing";
|
|
384
|
+
}
|
|
385
|
+
if (
|
|
386
|
+
/final diff|diff review|git diff|git status|whitespace|line-ending|line ending|pruning|remove unrelated|remaining diff|changed files/i.test(
|
|
387
|
+
text,
|
|
388
|
+
)
|
|
389
|
+
) {
|
|
390
|
+
return "final diff review";
|
|
391
|
+
}
|
|
392
|
+
if (
|
|
393
|
+
/editing|patch|implemented|adding|fixing|updating|wiring|in place|changes are in place|making .*change|tightening|restore|normalizing/i.test(
|
|
394
|
+
text,
|
|
395
|
+
)
|
|
396
|
+
) {
|
|
397
|
+
return "editing";
|
|
398
|
+
}
|
|
399
|
+
if (
|
|
400
|
+
/read|inspect|checking|locating|opening|artifact|screenshot|README|context|discover|search|rg |current checkout|worktree/i.test(
|
|
401
|
+
text,
|
|
402
|
+
)
|
|
403
|
+
) {
|
|
404
|
+
return "discovering";
|
|
405
|
+
}
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
|
|
345
409
|
export function shouldEmitDirectSessionJobEvent(options: {
|
|
346
410
|
ok: boolean;
|
|
347
411
|
statusPersistedToServer: boolean;
|
|
@@ -1352,6 +1416,7 @@ async function workerLoop(
|
|
|
1352
1416
|
let lastCleanLog = "";
|
|
1353
1417
|
let lastCleanLogAt = 0;
|
|
1354
1418
|
let lastForwardedJobLogAt = Date.now();
|
|
1419
|
+
let currentJobPhase: WorkerJobPhase | null = null;
|
|
1355
1420
|
|
|
1356
1421
|
const emitJobLog = job.sessionId
|
|
1357
1422
|
? (stream: "stdout" | "stderr", line: string): boolean => {
|
|
@@ -1367,6 +1432,7 @@ async function workerLoop(
|
|
|
1367
1432
|
lastCleanLog = cleaned;
|
|
1368
1433
|
lastCleanLogAt = now;
|
|
1369
1434
|
lastForwardedJobLogAt = now;
|
|
1435
|
+
currentJobPhase = inferWorkerJobPhaseFromLogLine(cleaned) ?? currentJobPhase;
|
|
1370
1436
|
const logTs = new Date(now).toISOString();
|
|
1371
1437
|
|
|
1372
1438
|
const seq = stream === "stdout" ? ++stdoutSeq : ++stderrSeq;
|
|
@@ -1374,7 +1440,14 @@ async function workerLoop(
|
|
|
1374
1440
|
job.sessionId,
|
|
1375
1441
|
{
|
|
1376
1442
|
type: "job_log",
|
|
1377
|
-
payload: {
|
|
1443
|
+
payload: {
|
|
1444
|
+
jobId: job.id,
|
|
1445
|
+
stream,
|
|
1446
|
+
seq,
|
|
1447
|
+
line: cleaned,
|
|
1448
|
+
ts: logTs,
|
|
1449
|
+
phase: currentJobPhase,
|
|
1450
|
+
},
|
|
1378
1451
|
from: `worker:${opts.workerId}`,
|
|
1379
1452
|
},
|
|
1380
1453
|
{ droppable: true },
|
|
@@ -1409,9 +1482,9 @@ async function workerLoop(
|
|
|
1409
1482
|
"stdout",
|
|
1410
1483
|
`[WorkerPals] Job ${job.id} still running after ${formatDurationMs(
|
|
1411
1484
|
now - jobClaimedAtMs,
|
|
1412
|
-
)} (kind=${job.kind}, worker=${opts.workerId},
|
|
1413
|
-
|
|
1414
|
-
)}).`,
|
|
1485
|
+
)} (kind=${job.kind}, worker=${opts.workerId}, phase=${
|
|
1486
|
+
currentJobPhase ?? "unknown"
|
|
1487
|
+
}, quiet_for=${formatDurationMs(quietForMs)}).`,
|
|
1415
1488
|
);
|
|
1416
1489
|
}, jobProgressLogEveryMs)
|
|
1417
1490
|
: null;
|
|
@@ -51,7 +51,7 @@ workerpal_heartbeat_ms = 0
|
|
|
51
51
|
workerpal_labels = []
|
|
52
52
|
execution_budget_interactive_ms = 600000
|
|
53
53
|
execution_budget_normal_ms = 1500000
|
|
54
|
-
execution_budget_background_ms =
|
|
54
|
+
execution_budget_background_ms = 1200000
|
|
55
55
|
finalization_budget_ms = 120000
|
|
56
56
|
crash_restart_enabled = true
|
|
57
57
|
crash_restart_max_restarts = 3
|
|
@@ -515,7 +515,8 @@
|
|
|
515
515
|
"stream": { "type": "string", "enum": ["stdout", "stderr"] },
|
|
516
516
|
"seq": { "type": "integer", "minimum": 1 },
|
|
517
517
|
"line": { "type": "string" },
|
|
518
|
-
"ts": { "type": "string" }
|
|
518
|
+
"ts": { "type": "string" },
|
|
519
|
+
"phase": { "type": ["string", "null"] }
|
|
519
520
|
},
|
|
520
521
|
"additionalProperties": false
|
|
521
522
|
}
|
|
@@ -1619,7 +1619,7 @@ export function loadPushPalsConfig(options: LoadOptions = {}): PushPalsConfig {
|
|
|
1619
1619
|
asInt(
|
|
1620
1620
|
parseIntEnv("REMOTEBUDDY_EXECUTION_BUDGET_BACKGROUND_MS") ??
|
|
1621
1621
|
remoteNode.execution_budget_background_ms,
|
|
1622
|
-
|
|
1622
|
+
1_200_000,
|
|
1623
1623
|
),
|
|
1624
1624
|
),
|
|
1625
1625
|
finalizationBudgetMs: Math.max(
|
|
@@ -515,7 +515,8 @@
|
|
|
515
515
|
"stream": { "type": "string", "enum": ["stdout", "stderr"] },
|
|
516
516
|
"seq": { "type": "integer", "minimum": 1 },
|
|
517
517
|
"line": { "type": "string" },
|
|
518
|
-
"ts": { "type": "string" }
|
|
518
|
+
"ts": { "type": "string" },
|
|
519
|
+
"phase": { "type": ["string", "null"] }
|
|
519
520
|
},
|
|
520
521
|
"additionalProperties": false
|
|
521
522
|
}
|