fix(triage): enforce per-project maxConcurrent limit on triage
The triage processor was only checking the global semaphore, not the per-project maxConcurrent setting. Now it counts all active agents (in-progress + specifying) and respects Math.min(perProjectAvailable, semaphoreAvailable) before starting new triage tasks. This matches the scheduler's concurrency enforcement and prevents triage from consuming all available slots on startup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,22 @@ describe("PWA configuration", () => {
|
||||
expect(cssContent).toMatch(/@media\s*\(\s*display-mode:\s*standalone\s*\)\s*\{[^}]*#root\s*\{[^}]*env\(safe-area-inset-bottom,\s*0px\)/);
|
||||
});
|
||||
|
||||
it("CSS includes --standalone-bottom-gap token with 8px value in standalone mode", () => {
|
||||
const cssContent = readFileSync(resolve(__dirname, "../styles.css"), "utf8");
|
||||
|
||||
// Token definition in :root
|
||||
expect(cssContent).toContain("--standalone-bottom-gap: 0px");
|
||||
// Token override in standalone mode sets 8px gap
|
||||
expect(cssContent).toMatch(/--standalone-bottom-gap:\s*8px/);
|
||||
});
|
||||
|
||||
it("CSS uses additive bottom spacing in standalone mode (safe-area + gap)", () => {
|
||||
const cssContent = readFileSync(resolve(__dirname, "../styles.css"), "utf8");
|
||||
|
||||
// #root should use var(--standalone-bottom-gap) in a calc expression for additive spacing
|
||||
expect(cssContent).toContain("var(--standalone-bottom-gap))");
|
||||
});
|
||||
|
||||
it("service worker contains lifecycle handlers and versioned cache name", () => {
|
||||
const swSource = readFileSync(resolve(__dirname, "../public/sw.js"), "utf8");
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
--executor-footer-height: 0px;
|
||||
--executor-footer-height-mobile: 0px;
|
||||
|
||||
/* PWA standalone mode bottom gap (FN-1626): extra breathing room for iOS home indicator */
|
||||
--standalone-bottom-gap: 0px;
|
||||
|
||||
/* Shadow tokens */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
@@ -6371,8 +6374,12 @@ body {
|
||||
|
||||
@media (display-mode: standalone) {
|
||||
#root {
|
||||
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||
/* FN-1626: additive bottom spacing = safe-area inset + 8px home bar gap */
|
||||
padding-bottom: calc(env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap));
|
||||
}
|
||||
|
||||
/* PWA standalone mode: 8px extra breathing room for iOS home indicator */
|
||||
--standalone-bottom-gap: 8px;
|
||||
}
|
||||
|
||||
/* === Mobile Responsive Overrides ===
|
||||
@@ -18791,7 +18798,7 @@ html .column.drag-over * {
|
||||
font-size: 11px;
|
||||
height: 32px;
|
||||
overflow: hidden;
|
||||
bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px));
|
||||
bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap));
|
||||
}
|
||||
|
||||
.executor-status-bar__segment {
|
||||
@@ -26614,12 +26621,12 @@ html .column.drag-over * {
|
||||
|
||||
/* Content padding: mobile nav only (no footer) */
|
||||
.project-content--with-mobile-nav:not(.project-content--with-footer) {
|
||||
padding-bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px));
|
||||
padding-bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap));
|
||||
}
|
||||
|
||||
/* Content padding: both mobile nav AND footer */
|
||||
.project-content--with-footer.project-content--with-mobile-nav {
|
||||
padding-bottom: calc(32px + var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px));
|
||||
padding-bottom: calc(32px + var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user