@open-mercato/cezar 0.9.2 → 0.9.3
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/LICENSE +21 -0
- package/README.md +4 -2
- package/dist/contract/health.d.ts +2 -0
- package/dist/contract/index.js +23 -10
- package/dist/git-diff-base.d.ts +51 -26
- package/dist/git-diff-base.js +163 -37
- package/dist/git-diff-base.js.map +1 -1
- package/dist/git-worktree.d.ts +15 -6
- package/dist/git-worktree.js +10 -3
- package/dist/git-worktree.js.map +1 -1
- package/dist/server/capabilities.d.ts +15 -1
- package/dist/server/capabilities.js +16 -1
- package/dist/server/capabilities.js.map +1 -1
- package/dist/server/git-changes.d.ts +7 -5
- package/dist/server/git-changes.js +15 -10
- package/dist/server/git-changes.js.map +1 -1
- package/dist/server/server.d.ts +59 -58
- package/dist/server/server.js +54 -3
- package/dist/server/server.js.map +1 -1
- package/dist/workflows/run.d.ts +27 -7
- package/dist/workflows/run.js +106 -43
- package/dist/workflows/run.js.map +1 -1
- package/dist/workspace/config.d.ts +8 -0
- package/dist/workspace/config.js +29 -2
- package/dist/workspace/config.js.map +1 -1
- package/dist/workspace/semaphore.d.ts +7 -1
- package/dist/workspace/semaphore.js +10 -4
- package/dist/workspace/semaphore.js.map +1 -1
- package/dist/workspace/ui-state.d.ts +3 -2
- package/dist/workspace/ui-state.js +3 -2
- package/dist/workspace/ui-state.js.map +1 -1
- package/package.json +3 -3
- package/web/dist/assets/{alert-dialog-ghffK6g9.js → alert-dialog-V9cigyAO.js} +1 -1
- package/web/dist/assets/arrow-down-DflHdNlN.js +1 -0
- package/web/dist/assets/arrow-left-IIL4uR-C.js +1 -0
- package/web/dist/assets/centered-state-BkAJVLJE.js +43 -0
- package/web/dist/assets/chevron-right-CxAoD1eD.js +1 -0
- package/web/dist/assets/circle-check-CdwcIbkx.js +1 -0
- package/web/dist/assets/{circle-x-C3EFZ3xf.js → circle-x-Cnc43xJ2.js} +1 -1
- package/web/dist/assets/{collapsible-B0JVzd0B.js → collapsible-BlF-7CeC.js} +1 -1
- package/web/dist/assets/{commit-list-wm6DPHNs.js → commit-list-D2mKElUx.js} +1 -1
- package/web/dist/assets/{compare-variants-DbdP4Y5T.js → compare-variants-CFBY16Rc.js} +1 -1
- package/web/dist/assets/{diff-Bizc96qe.js → diff-DE6u5dTe.js} +2 -2
- package/web/dist/assets/{diff-stat-Dyfg3ltF.js → diff-stat-B1j6L7C6.js} +1 -1
- package/web/dist/assets/{diff-view-CG8ek6tC.js → diff-view-Gb2kk3Le.js} +1 -1
- package/web/dist/assets/{dropdown-menu-C1Dlf35P.js → dropdown-menu-Ns-rY6sm.js} +1 -1
- package/web/dist/assets/editable-title-BGuiDxFT.js +1 -0
- package/web/dist/assets/{ellipsis-vertical-DpGTRqC2.js → ellipsis-vertical-BbxtXb6s.js} +1 -1
- package/web/dist/assets/{file-DlUGpUlb.js → file-j5O4NryU.js} +1 -1
- package/web/dist/assets/{folder-BAY6Vddy.js → folder-w9Lwj9x9.js} +1 -1
- package/web/dist/assets/{git-pull-request-agOG0iGM.js → git-pull-request-DlSop3Ch.js} +1 -1
- package/web/dist/assets/{git-toolbar-DGiNMmtY.js → git-toolbar-BdJ8XSxI.js} +1 -1
- package/web/dist/assets/github-CCLn2OAU.js +1 -0
- package/web/dist/assets/{image-preview-BWGk5fPX.js → image-preview-CcFdkZXW.js} +1 -1
- package/web/dist/assets/index-BmHHLbwc.js +6 -0
- package/web/dist/assets/index-u8OAnq0r.css +2 -0
- package/web/dist/assets/{markdown-BGBOGCA_.js → markdown-q9lm7kQ2.js} +1 -1
- package/web/dist/assets/{new-task-form-BpAw_Dks.js → new-task-form-BuYxAWN7.js} +1 -1
- package/web/dist/assets/{pill-Dvs-P0xy.js → pill-t97MvPW_.js} +1 -1
- package/web/dist/assets/{project-router-Cx8NPoqn.js → project-router-DudOmkHf.js} +1 -1
- package/web/dist/assets/{prompt-templates-CSBYBR1I.js → prompt-templates-C5iO3Lda.js} +1 -1
- package/web/dist/assets/{refresh-cw-BoGdAykg.js → refresh-cw-_C2EGJK5.js} +1 -1
- package/web/dist/assets/{repo-git-PmX-BNMo.js → repo-git-DqQzj33d.js} +1 -1
- package/web/dist/assets/{run-diff-EcOkf3ti.js → run-diff-BLoKEnTx.js} +1 -1
- package/web/dist/assets/run-header-Dho4eurS.js +1 -0
- package/web/dist/assets/{search-x-X3EpVhgs.js → search-x-BgxaJgro.js} +1 -1
- package/web/dist/assets/{skill-empty-hint-CZLALx6l.js → skill-empty-hint-D5MOmycv.js} +1 -1
- package/web/dist/assets/skills-B5g064CC.js +1 -0
- package/web/dist/assets/{sparkles-Dt4q7pbG.js → sparkles-ANSka5bH.js} +1 -1
- package/web/dist/assets/{square-terminal-hwBL8XsC.js → square-terminal-qojq20cH.js} +1 -1
- package/web/dist/assets/{tab-link-DIlR5T07.js → tab-link-CIcwFJtC.js} +1 -1
- package/web/dist/assets/task-changes-yRfsEsnh.js +1 -0
- package/web/dist/assets/{task-commits-BTTA5k5T.js → task-commits-yXmDrCoE.js} +1 -1
- package/web/dist/assets/{task-files-Da8_4C9g.js → task-files-BDRmCCPN.js} +2 -2
- package/web/dist/assets/task-thread-C9AnIz4Z.js +9 -0
- package/web/dist/assets/{textarea-CUdokhkv.js → textarea-DVO7pg8Y.js} +1 -1
- package/web/dist/assets/{thread-loading-B8q8ukXJ.js → thread-loading-DJDl701Z.js} +1 -1
- package/web/dist/assets/{trash-2-DhVIdWv8.js → trash-2-DKcnmg6e.js} +1 -1
- package/web/dist/assets/{triangle-alert-XYT0DGCI.js → triangle-alert-CPUEVSZ3.js} +1 -1
- package/web/dist/assets/{upload-BKjN59-1.js → upload-D5Jrq7QK.js} +1 -1
- package/web/dist/assets/{use-desktop-Bf5LS_P4.js → use-desktop-CXae6uyk.js} +1 -1
- package/web/dist/assets/{use-submit-shortcut-CzVyoAMd.js → use-submit-shortcut-RKJLKdsW.js} +1 -1
- package/web/dist/assets/{utils-DsLuRXwV.js → utils-Wtkd5E6j.js} +1 -1
- package/web/dist/assets/{workflows-o2QU_pvU.js → workflows-CGyTdyds.js} +3 -3
- package/web/dist/assets/{zoomable-image-7WyUiaVD.js → zoomable-image-hcqwUIlQ.js} +1 -1
- package/web/dist/index.html +22 -22
- package/web/dist/assets/arrow-down-Cz8qb71e.js +0 -1
- package/web/dist/assets/arrow-left-wcYKQXI_.js +0 -1
- package/web/dist/assets/centered-state-ZtnFHA-n.js +0 -43
- package/web/dist/assets/chevron-right-G4caF2QV.js +0 -1
- package/web/dist/assets/circle-check--KvBxXWp.js +0 -1
- package/web/dist/assets/editable-title-5rC_QRBZ.js +0 -1
- package/web/dist/assets/github-Vp7lxYGQ.js +0 -1
- package/web/dist/assets/index-DSxyJpuK.css +0 -2
- package/web/dist/assets/index-DiawI6RX.js +0 -6
- package/web/dist/assets/run-header-BGiv6_qX.js +0 -1
- package/web/dist/assets/skills-CC91ouGH.js +0 -1
- package/web/dist/assets/task-changes-XkHDxzQA.js +0 -1
- package/web/dist/assets/task-thread-DoNXUsHr.js +0 -9
package/dist/server/server.js
CHANGED
|
@@ -146,6 +146,8 @@ export function projectRouteManifest(app) {
|
|
|
146
146
|
}
|
|
147
147
|
/** 409 body for the inbox mutators while the follow-up inbox is off (#471). */
|
|
148
148
|
const FOLLOWUPS_OFF = 'the follow-up inbox is disabled — set CEZ_FOLLOWUPS=1 to enable it';
|
|
149
|
+
/** 409 body for every automations route while GitHub automations are off (#801). */
|
|
150
|
+
const AUTOMATIONS_OFF = 'GitHub automations are disabled — set CEZ_AUTOMATIONS=1 to enable them';
|
|
149
151
|
/**
|
|
150
152
|
* The in-process bus for workspace-level SSE events. The registry-mutating
|
|
151
153
|
* routes (`POST /api/projects` — step 4.2, emits `project-added` for a
|
|
@@ -312,6 +314,12 @@ const workspaceUiStateSchema = z
|
|
|
312
314
|
appearance: appearanceSchema.optional(),
|
|
313
315
|
notifications: z.object({ enabled: z.boolean().optional() }).passthrough().optional(),
|
|
314
316
|
dismissedProviderAuthFailures: providerAuthDismissalsSchema.optional(),
|
|
317
|
+
// LEGACY, like `sidebar` below: both moved into the browser's own
|
|
318
|
+
// localStorage (packages/web/src/lib/{last-location,sidebar-collapse}.ts),
|
|
319
|
+
// because one workspace-wide answer meant the last client to navigate — a
|
|
320
|
+
// phone, a second window — decided where every other client's next launch
|
|
321
|
+
// landed, and whose sidebar groups were shut. Kept named and bounded here
|
|
322
|
+
// so a cockpit from before that change still round-trips and validates.
|
|
315
323
|
lastLocation: z
|
|
316
324
|
.object({
|
|
317
325
|
projectId: z.string().min(1).max(64),
|
|
@@ -2014,12 +2022,35 @@ export function createApp(deps) {
|
|
|
2014
2022
|
return c.json(await planChain(repoRoot, parsed.data.task));
|
|
2015
2023
|
});
|
|
2016
2024
|
const manualChecks = new Map();
|
|
2025
|
+
/**
|
|
2026
|
+
* The automations gate (#801): with `CEZ_AUTOMATIONS` unset, every route of the feature
|
|
2027
|
+
* answers 409 before touching a store, a lease or GitHub.
|
|
2028
|
+
*
|
|
2029
|
+
* Written as MIDDLEWARE rather than a line in each handler so the family cannot drift: a route
|
|
2030
|
+
* added to either chain below inherits the gate from its path, where a per-handler check is one
|
|
2031
|
+
* omission away from an ungated endpoint.
|
|
2032
|
+
*
|
|
2033
|
+
* Registered against EXPLICIT paths, never `use('*')`. Both chains are mounted with
|
|
2034
|
+
* `.route('/', …)` alongside a dozen unrelated sub-apps, and `route()` re-registers a sub-app's
|
|
2035
|
+
* middleware under the mount prefix — so a `'*'` here would gate the entire `/api/v1` surface,
|
|
2036
|
+
* including `/health`. The two-line pairing (`/automations` and `/automations/*`) is what makes
|
|
2037
|
+
* a path match both the collection and everything under it.
|
|
2038
|
+
*/
|
|
2039
|
+
const requireAutomations = async (c, next) => {
|
|
2040
|
+
if (!capabilities().automations)
|
|
2041
|
+
return c.json({ error: AUTOMATIONS_OFF }, 409);
|
|
2042
|
+
await next();
|
|
2043
|
+
};
|
|
2017
2044
|
// ---- chained family: GitHub automations (project-scoped) ----
|
|
2018
2045
|
// Every handler below reads `c.get('project')` — the definitions, their runtime state and the
|
|
2019
2046
|
// execution log are per-project files — so the family is project-scoped and mounted with the
|
|
2020
2047
|
// rest of the mirrored table. The one exception is the manual-check read, which touches no
|
|
2021
2048
|
// project at all; it is its own workspace-level family below.
|
|
2022
2049
|
const automationsRoutes = new Hono()
|
|
2050
|
+
.use('/automations', requireAutomations)
|
|
2051
|
+
.use('/automations/*', requireAutomations)
|
|
2052
|
+
.use('/automation-log', requireAutomations)
|
|
2053
|
+
.use('/automation-log/*', requireAutomations)
|
|
2023
2054
|
.get('/automations', async (c) => {
|
|
2024
2055
|
const { root, automationStore } = c.get('project');
|
|
2025
2056
|
const forge = resolveForge(await getRepoInfo(root));
|
|
@@ -2243,6 +2274,7 @@ export function createApp(deps) {
|
|
|
2243
2274
|
// above, keyed by an unguessable id that the project-scoped POST hands back. Mounting it under
|
|
2244
2275
|
// `/api/v1/p/:projectId` too would be a second spelling of a lookup that consults no project.
|
|
2245
2276
|
const automationChecksRoutes = new Hono()
|
|
2277
|
+
.use('/automation-checks/*', requireAutomations)
|
|
2246
2278
|
.get('/automation-checks/:checkId', (c) => {
|
|
2247
2279
|
const check = manualChecks.get(c.req.param('checkId'));
|
|
2248
2280
|
return check ? c.json(check) : c.json({ error: 'not found' }, 404);
|
|
@@ -2750,6 +2782,8 @@ export function createApp(deps) {
|
|
|
2750
2782
|
return c.json({ error: NO_WORKTREE }, 409);
|
|
2751
2783
|
const result = await collectChanges(workingDirectory, run.baseBranch ?? 'HEAD', {
|
|
2752
2784
|
taskBranch: run.branch,
|
|
2785
|
+
// Anchors a repointed worktree at the branch as this run found it (#751).
|
|
2786
|
+
runStartedAt: run.startedAt,
|
|
2753
2787
|
// A read-only GET against the user's real checkout must never modify its index.
|
|
2754
2788
|
intentToAdd: run.worktreePath ? undefined : false,
|
|
2755
2789
|
});
|
|
@@ -3870,6 +3904,11 @@ export function startServer(deps, port) {
|
|
|
3870
3904
|
semaphore: deps.semaphore,
|
|
3871
3905
|
automationStore: (projectId, root) => automationCoordinator.store(projectId, root),
|
|
3872
3906
|
});
|
|
3907
|
+
// #801: GitHub automations are opt-in. Off, the flag must remove the BEHAVIOR and not merely
|
|
3908
|
+
// the UI — no scheduler, no GitHub polling, no launched runs — so every entry point into the
|
|
3909
|
+
// workspace scheduler below is gated on it. Read per call rather than captured, for the same
|
|
3910
|
+
// reason `capabilities()` is inside `createApp`: tests flip the variable between apps.
|
|
3911
|
+
const automationsEnabled = () => resolveCapabilities(process.env, deps.bindHost).automations;
|
|
3873
3912
|
let rescheduleAutomations = () => { };
|
|
3874
3913
|
const app = createApp({
|
|
3875
3914
|
...deps,
|
|
@@ -3922,7 +3961,14 @@ export function startServer(deps, port) {
|
|
|
3922
3961
|
};
|
|
3923
3962
|
},
|
|
3924
3963
|
});
|
|
3925
|
-
|
|
3964
|
+
// The scheduler is inert until `start()` anyway (it constructs `stopped`), but the gate is
|
|
3965
|
+
// stated here rather than inherited from that detail: a definition saved while the flag is off
|
|
3966
|
+
// must not even ask the coordinator to refresh.
|
|
3967
|
+
rescheduleAutomations = () => {
|
|
3968
|
+
if (!automationsEnabled())
|
|
3969
|
+
return;
|
|
3970
|
+
void automationScheduler.reschedule();
|
|
3971
|
+
};
|
|
3926
3972
|
const unsubscribe = workspaceEvents.on((event, data) => {
|
|
3927
3973
|
if (event === 'project-added') {
|
|
3928
3974
|
const project = data.project;
|
|
@@ -3932,7 +3978,7 @@ export function startServer(deps, port) {
|
|
|
3932
3978
|
const parsed = parseRemote(info?.remote ?? '');
|
|
3933
3979
|
if (parsed?.host === 'github.com')
|
|
3934
3980
|
automationProjects.set(project.id, { root: project.root, owner: parsed.owner, repo: parsed.repo });
|
|
3935
|
-
return
|
|
3981
|
+
return rescheduleAutomations();
|
|
3936
3982
|
});
|
|
3937
3983
|
}
|
|
3938
3984
|
}
|
|
@@ -3943,7 +3989,7 @@ export function startServer(deps, port) {
|
|
|
3943
3989
|
if (typeof id === 'string') {
|
|
3944
3990
|
automationCoordinator.remove(id);
|
|
3945
3991
|
automationProjects.delete(id);
|
|
3946
|
-
|
|
3992
|
+
rescheduleAutomations();
|
|
3947
3993
|
}
|
|
3948
3994
|
}
|
|
3949
3995
|
});
|
|
@@ -3952,6 +3998,11 @@ export function startServer(deps, port) {
|
|
|
3952
3998
|
const all = projects.some((project) => project.root === deps.repoRoot)
|
|
3953
3999
|
? projects : [{ id: deps.bootProjectId ?? 'default', root: deps.repoRoot, status: 'ok' }, ...projects];
|
|
3954
4000
|
coordinator.start(all);
|
|
4001
|
+
// #801: with automations off there is nothing to warm — no remote to resolve, no receipts
|
|
4002
|
+
// to reconcile, and above all no scheduler to start. The skills-update coordinator above is
|
|
4003
|
+
// a separate feature and starts either way.
|
|
4004
|
+
if (!automationsEnabled())
|
|
4005
|
+
return;
|
|
3955
4006
|
void Promise.all(all.map(async (project) => {
|
|
3956
4007
|
const parsed = parseRemote((await getRepoInfo(project.root))?.remote ?? '');
|
|
3957
4008
|
if (parsed?.host === 'github.com')
|