@open-mercato/cezar 0.9.0-pr646.708 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +1 -17
  2. package/dist/config.d.ts +0 -14
  3. package/dist/config.js +0 -39
  4. package/dist/config.js.map +1 -1
  5. package/dist/core/claude-ui-mapper.d.ts +0 -9
  6. package/dist/core/claude-ui-mapper.js +2 -31
  7. package/dist/core/claude-ui-mapper.js.map +1 -1
  8. package/dist/core/codex-app-server-runner.js +18 -19
  9. package/dist/core/codex-app-server-runner.js.map +1 -1
  10. package/dist/core/opencode-server-runner.js +5 -25
  11. package/dist/core/opencode-server-runner.js.map +1 -1
  12. package/dist/core/tool-display.d.ts +1 -2
  13. package/dist/core/tool-display.js +1 -6
  14. package/dist/core/tool-display.js.map +1 -1
  15. package/dist/index.js +4 -40
  16. package/dist/index.js.map +1 -1
  17. package/dist/runs/auto-name.js +0 -6
  18. package/dist/runs/auto-name.js.map +1 -1
  19. package/dist/runs/store.js +9 -34
  20. package/dist/runs/store.js.map +1 -1
  21. package/dist/server/capabilities.d.ts +0 -6
  22. package/dist/server/capabilities.js +0 -6
  23. package/dist/server/capabilities.js.map +1 -1
  24. package/dist/server/server.d.ts +0 -8
  25. package/dist/server/server.js +7 -146
  26. package/dist/server/server.js.map +1 -1
  27. package/dist/server-install/engine.d.ts +0 -5
  28. package/dist/server-install/engine.js +0 -6
  29. package/dist/server-install/engine.js.map +1 -1
  30. package/dist/server-install/platforms/ubuntu-vps.d.ts +2 -11
  31. package/dist/server-install/platforms/ubuntu-vps.js +10 -123
  32. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -1
  33. package/dist/server-install/types.d.ts +0 -39
  34. package/dist/server-install/types.js +0 -13
  35. package/dist/server-install/types.js.map +1 -1
  36. package/dist/skills-remote.d.ts +0 -11
  37. package/dist/skills-remote.js +2 -31
  38. package/dist/skills-remote.js.map +1 -1
  39. package/dist/skills.d.ts +0 -29
  40. package/dist/skills.js +14 -72
  41. package/dist/skills.js.map +1 -1
  42. package/dist/workflows/run.d.ts +10 -50
  43. package/dist/workflows/run.js +103 -216
  44. package/dist/workflows/run.js.map +1 -1
  45. package/dist/workspace/config.d.ts +0 -30
  46. package/dist/workspace/config.js +0 -5
  47. package/dist/workspace/config.js.map +1 -1
  48. package/dist/workspace/projects-cli.d.ts +0 -2
  49. package/dist/workspace/projects-cli.js +4 -21
  50. package/dist/workspace/projects-cli.js.map +1 -1
  51. package/dist/workspace/projects.d.ts +1 -5
  52. package/dist/workspace/projects.js +8 -5
  53. package/dist/workspace/projects.js.map +1 -1
  54. package/dist/workspace/semaphore.d.ts +2 -53
  55. package/dist/workspace/semaphore.js +5 -93
  56. package/dist/workspace/semaphore.js.map +1 -1
  57. package/package.json +1 -1
  58. package/web/dist/assets/centered-state-zzWBfO_1.js +43 -0
  59. package/web/dist/assets/command-ylf8-fG0.js +1 -0
  60. package/web/dist/assets/compare-variants-BcR3zdtB.js +1 -0
  61. package/web/dist/assets/dialog-BYr_BAil.js +1 -0
  62. package/web/dist/assets/diff-view-DPCR7gon.js +4 -0
  63. package/web/dist/assets/{dist-CqH67S8q.js → dist-Cw_CDvC3.js} +1 -1
  64. package/web/dist/assets/dropdown-menu-C3GD8eLA.js +1 -0
  65. package/web/dist/assets/git-toolbar-CiMaCi03.js +1 -0
  66. package/web/dist/assets/github-BJEZbEOp.js +1 -0
  67. package/web/dist/assets/index-DmW_TYjO.js +16 -0
  68. package/web/dist/assets/index-Qbs-JRWQ.css +2 -0
  69. package/web/dist/assets/loader-circle-CGwIVNTv.js +1 -0
  70. package/web/dist/assets/{project-router-BaWVyqc8.js → project-router-CT8Rt5Eu.js} +1 -1
  71. package/web/dist/assets/prompt-templates-DW7_d8Ys.js +15 -0
  72. package/web/dist/assets/repo-git-BkmyKcvN.js +1 -0
  73. package/web/dist/assets/{run-diff-Cksr4Dk5.js → run-diff-CxIDdRwy.js} +2 -2
  74. package/web/dist/assets/run-header-8nwDIWWO.js +1 -0
  75. package/web/dist/assets/skill-empty-hint-Cl3ESoPu.js +1 -0
  76. package/web/dist/assets/skills-BIpb0mqO.js +1 -0
  77. package/web/dist/assets/{tab-link-vtgjgL_M.js → tab-link-C_bk_Kvn.js} +1 -1
  78. package/web/dist/assets/task-changes-D1bJx2uW.js +1 -0
  79. package/web/dist/assets/task-commits-DlhB21mR.js +1 -0
  80. package/web/dist/assets/task-files-ChJDOFg5.js +2 -0
  81. package/web/dist/assets/task-thread-J7ckxJJh.js +9 -0
  82. package/web/dist/assets/tasks-table--V1pKwuK.js +1 -0
  83. package/web/dist/assets/use-desktop-CuDnWju1.js +3 -0
  84. package/web/dist/assets/workflows-BksgdYAQ.js +11 -0
  85. package/web/dist/assets/x-DgoqYQOJ.js +1 -0
  86. package/web/dist/index.html +12 -6
  87. package/dist/core/v1-text-coalescer.d.ts +0 -36
  88. package/dist/core/v1-text-coalescer.js +0 -72
  89. package/dist/core/v1-text-coalescer.js.map +0 -1
  90. package/web/dist/assets/centered-state-CLmJ67EV.js +0 -43
  91. package/web/dist/assets/commit-list-CSaWuw-x.js +0 -1
  92. package/web/dist/assets/compare-variants-B5BlnpUb.js +0 -1
  93. package/web/dist/assets/diff-view-CYKPGL2w.js +0 -6
  94. package/web/dist/assets/git-toolbar-CDII-3Uv.js +0 -1
  95. package/web/dist/assets/github-C7SNDPf3.js +0 -1
  96. package/web/dist/assets/index-CcfkF2Ey.js +0 -30
  97. package/web/dist/assets/index-DzroxqBG.css +0 -2
  98. package/web/dist/assets/lib-DPEZDBUN.js +0 -1
  99. package/web/dist/assets/repo-git-4l-2tm7d.js +0 -1
  100. package/web/dist/assets/run-header-B3kW2sWC.js +0 -1
  101. package/web/dist/assets/skill-empty-hint-DTUSp6Vl.js +0 -1
  102. package/web/dist/assets/skills-D7hPgl4y.js +0 -1
  103. package/web/dist/assets/task-changes-DvIUGL9a.js +0 -1
  104. package/web/dist/assets/task-commits-QD2JI3zj.js +0 -1
  105. package/web/dist/assets/task-files-BE7JDEwK.js +0 -2
  106. package/web/dist/assets/task-thread-CRjuPhsl.js +0 -9
  107. package/web/dist/assets/textarea-Bj_LCreg.js +0 -1
  108. package/web/dist/assets/use-desktop-4e8LLqMG.js +0 -3
  109. package/web/dist/assets/workflows-bPYx0nbO.js +0 -11
@@ -14,16 +14,10 @@
14
14
  * `todos.json` (they get `HANDOFF_ONLY_INSTRUCTIONS` and an empty
15
15
  * `CEZ_TODOS_FILE`), the Inbox nav item is gone and the inbox endpoints refuse.
16
16
  * The per-task handoff journal is independent and runs either way.
17
- *
18
- * `singleProject` (spec 2026-07-21-cez-single-project): the workspace is
19
- * deliberately constrained to the launch project when `CEZ_SINGLE_PROJECT=1`.
20
- * Like the other opt-in capabilities, activation is strict: no other spelling
21
- * enables it.
22
17
  */
23
18
  export interface Capabilities {
24
19
  localHandoff: boolean;
25
20
  followups: boolean;
26
- singleProject: boolean;
27
21
  }
28
22
  /** Canonical hostname of an authority: port and IPv6 brackets removed, IPv6
29
23
  * expanded, zone id and FQDN trailing dot dropped, lowercased.
@@ -14,11 +14,6 @@
14
14
  * `todos.json` (they get `HANDOFF_ONLY_INSTRUCTIONS` and an empty
15
15
  * `CEZ_TODOS_FILE`), the Inbox nav item is gone and the inbox endpoints refuse.
16
16
  * The per-task handoff journal is independent and runs either way.
17
- *
18
- * `singleProject` (spec 2026-07-21-cez-single-project): the workspace is
19
- * deliberately constrained to the launch project when `CEZ_SINGLE_PROJECT=1`.
20
- * Like the other opt-in capabilities, activation is strict: no other spelling
21
- * enables it.
22
17
  */
23
18
  import { followupsEnabled } from '../handoff.js';
24
19
  /** Every IPv4 address in 127.0.0.0/8, anchored. Anchoring is load-bearing: a
@@ -120,7 +115,6 @@ export function resolveCapabilities(env = process.env, bindHost) {
120
115
  // Deliberately not re-derived here: RunManager enforces the same predicate,
121
116
  // and two spellings of "is the inbox on" would eventually disagree.
122
117
  followups: followupsEnabled(env),
123
- singleProject: env.CEZ_SINGLE_PROJECT === '1',
124
118
  };
125
119
  }
126
120
  //# sourceMappingURL=capabilities.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/server/capabilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/server/capabilities.ts"],"names":[],"mappings":"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"}
@@ -114,14 +114,6 @@ export interface RemoveProjectResponse {
114
114
  removed: true;
115
115
  id: string;
116
116
  }
117
- /** `PATCH /api/projects/:projectId` (spec 2026-07-22-per-project-concurrency)
118
- * — sets or clears a project's per-project `maxParallel`. The entry carries
119
- * the same `status`/`branch` probe `GET /api/projects` attaches, so the
120
- * cockpit sees one project shape. `null` in the request clears the override
121
- * back to "inherit the workspace cap". */
122
- export interface UpdateProjectResponse {
123
- project: ProjectListEntry;
124
- }
125
117
  /** `GET/PUT /api/workspace/config` (multi-project spec, step 2.7) — the
126
118
  * settings slice of `~/.cezar/config.json`: global knobs ONLY, never the
127
119
  * project registry (that is `GET /api/projects`' job). */
@@ -16,7 +16,7 @@ import { WORKFLOWS_DIR, loadWorkflows } from '../workflows/load.js';
16
16
  import { QUICK_TASK_WORKFLOW, normalizeWorkflowDoc, skillStackOf, skillsToSteps, stepsIssue, workflowFileSchema, workflowStepSchema, } from '../workflows/types.js';
17
17
  import { planChain, slugify } from '../planner.js';
18
18
  import { discoverSkills } from '../skills.js';
19
- import { getTeamSkillsCached, refreshTeamSkills, waitForTeamSkills } from '../skills-remote.js';
19
+ import { refreshTeamSkills, waitForTeamSkills } from '../skills-remote.js';
20
20
  import { appendHandoffHeartbeat, handoffProgressExcerpt, readHandoff } from '../handoff.js';
21
21
  import { markStarted, onTodosChanged, readTodos, removeTodo, todoTaskText } from '../todos.js';
22
22
  import { isV2WireEventType } from '../runs/ui-event-sink.js';
@@ -24,7 +24,7 @@ import { removeWorktree, worktreeDiff, worktreeDiffStat, worktreeSizeBytes } fro
24
24
  import { isReclaimable, reclaimWorktrees } from '../runs/retention.js';
25
25
  import { getBranches, getCommit, getDiff, getLog, getRepoInfo, getStatus } from './git.js';
26
26
  import { collectChanges, collectCommitChanges, collectRunCommits, commitAll, createOrSwitchBranch, imageMimeType, isOsOpenableImage, pushCurrentBranch, readWorktreePath, } from './git-changes.js';
27
- import { gatedSkillsRepos, loadConfig, resolveWorktreeRetention } from '../config.js';
27
+ import { loadConfig, resolveWorktreeRetention } from '../config.js';
28
28
  import { findConfigFile } from '../agent-config/catalog.js';
29
29
  import { readConfigFile, writeConfigFile } from '../agent-config/files.js';
30
30
  import { listAgentConfig } from '../agent-config/service.js';
@@ -236,18 +236,6 @@ const workspaceUiStateSchema = z
236
236
  })
237
237
  .passthrough()
238
238
  .optional(),
239
- // The user's curated selection of default (vendor) skills — `open-mercato/skills` — so the
240
- // catalog is no longer forced in full. GLOBAL (here, not per-repo) because "which skills I
241
- // want" describes the person, not a checkout, and must not depend on where cezar was launched
242
- // (multi-project workspace). Tri-state, enforced in `discoverSkills`: an ABSENT key means "not
243
- // curated" and every default skill still shows (opt-out default — no silent break on upgrade);
244
- // a PRESENT array (even `[]`) shows only those names. Bounded like the `skillUsage` map: the
245
- // file is GET/PUT wholesale, so an unbounded array is an unbounded write. Names match
246
- // `lastTask.ref` (`.min(1).max(200)`). The client PUTs the whole array (shallow top-level merge).
247
- importedSkills: z
248
- .array(z.string().min(1).max(200))
249
- .max(SKILL_USAGE_MAX_ENTRIES)
250
- .optional(),
251
239
  })
252
240
  .passthrough();
253
241
  const uiStateSchema = z
@@ -315,9 +303,6 @@ const uiStateSchema = z
315
303
  .optional(),
316
304
  // Skills promo banner (#391): set once the cockpit banner is dismissed, never unset.
317
305
  // Server-persisted (not a cookie) so the "shown once" promise holds across browsers.
318
- // Retained for backward compatibility — the banner is gone, replaced by the workspace-level
319
- // `importedSkills` curation (see `workspaceUiStateSchema`); `.passthrough()` would preserve
320
- // the key regardless, but keep it typed.
321
306
  dismissedSkillsBanner: z.boolean().optional(),
322
307
  })
323
308
  .passthrough();
@@ -382,12 +367,9 @@ function foldedLength(task, stack) {
382
367
  // "Continue"/"Send back" body (spec 003 / #401): every field optional, so an empty POST reopens
383
368
  // the last session on the run's current backend (backward compat). A runner/model override lets
384
369
  // the follow-up composer choose which engine handles the continuation. `text` stays bounded like
385
- // the live-session message `text` (#429), and `images` like a live-session message's — the
386
- // follow-up composer is a full composer, so a screenshot pasted into it must reach the reopened
387
- // session rather than being silently dropped.
370
+ // the live-session message `text` (#429).
388
371
  const continueSchema = z.object({
389
372
  text: z.string().max(100_000, 'text must be at most 100000 characters').optional(),
390
- images: z.array(imageInputSchema).max(4).optional(),
391
373
  runner: z.enum(['claude', 'codex', 'opencode']).optional(),
392
374
  model: z.string().max(200).optional(),
393
375
  });
@@ -511,18 +493,14 @@ export function createApp(deps) {
511
493
  const workspaceSummary = async () => {
512
494
  try {
513
495
  const registry = (await loadWorkspaceConfig()).projects;
514
- const bootProject = await resolveBootProject(registry);
515
- const visible = capabilities().singleProject
516
- ? registry.filter((project) => project.id === bootProject)
517
- : registry;
518
496
  return {
519
497
  // Explicit picks, not a spread: the registry schema passes unknown
520
498
  // keys through, and `root` must never ride along onto health.
521
- projects: visible.map((p) => ({
499
+ projects: registry.map((p) => ({
522
500
  id: p.id,
523
501
  name: p.name || basename(p.root),
524
502
  })),
525
- bootProject,
503
+ bootProject: await resolveBootProject(registry),
526
504
  };
527
505
  }
528
506
  catch {
@@ -532,7 +510,6 @@ export function createApp(deps) {
532
510
  // Hosted-mode gate (spec §"Deployment modes") — read per request so
533
511
  // CEZ_REMOTE flips take effect live (and tests can toggle it).
534
512
  const capabilities = () => resolveCapabilities(process.env, bindHost);
535
- const singleProjectRefusal = (action) => ({ error: `single-project mode is enabled; ${action} is disabled` });
536
513
  // Inbox live updates (spec 007). Opt-in (#471): no capability, no watcher —
537
514
  // and since step 2.3 the per-dataDir watch is created lazily by the first
538
515
  // SSE subscription (and torn down with the last), nothing to start here.
@@ -553,15 +530,7 @@ export function createApp(deps) {
553
530
  };
554
531
  // Non-boot projects build lazily on first scoped request; their managers
555
532
  // count against the same workspace semaphore as the boot manager (step 2.5).
556
- const contexts = deps.contexts ?? new ProjectContexts({
557
- listProjects: async () => {
558
- const selector = capabilities().singleProject
559
- ? { projectId: await resolveBootProject() }
560
- : undefined;
561
- return listProjects(selector);
562
- },
563
- semaphore: deps.semaphore,
564
- });
533
+ const contexts = deps.contexts ?? new ProjectContexts({ listProjects, semaphore: deps.semaphore });
565
534
  // Workspace-level SSE bus (step 2.8) — the registry mutators and the
566
535
  // checkout flow (Phase 4) emit here; /api/workspace/events relays.
567
536
  const workspaceEvents = deps.workspaceEvents ?? new WorkspaceEventBus();
@@ -843,10 +812,7 @@ export function createApp(deps) {
843
812
  let projectsDir = defaultWorkspaceConfig().projectsDir;
844
813
  try {
845
814
  projectsDir = (await loadWorkspaceConfig()).projectsDir;
846
- const selector = capabilities().singleProject
847
- ? { projectId: await resolveBootProject() }
848
- : undefined;
849
- projects = await listProjects(selector);
815
+ projects = await listProjects();
850
816
  }
851
817
  catch {
852
818
  // unreadable workspace — degrade to the empty registry + defaults
@@ -872,9 +838,6 @@ export function createApp(deps) {
872
838
  * Returns the status + body for the caller to answer with.
873
839
  */
874
840
  const registerFolder = async (spelled, source) => {
875
- if (capabilities().singleProject) {
876
- return { status: 409, body: singleProjectRefusal('adding projects') };
877
- }
878
841
  // `~` is expanded for the same reason `/api/fs/browse` expands it: the
879
842
  // dialog hands back absolute paths, but a hand-written body (curl, a
880
843
  // future CLI) spells home the way a shell does.
@@ -1020,9 +983,6 @@ export function createApp(deps) {
1020
983
  return ctx.store.listRuns().filter((run) => ACTIVE_RUN_STATUSES.has(run.status)).length;
1021
984
  };
1022
985
  app.delete('/api/projects/:projectId', async (c) => {
1023
- if (capabilities().singleProject) {
1024
- return c.json(singleProjectRefusal('removing projects'), 409);
1025
- }
1026
986
  const raw = c.req.param('projectId');
1027
987
  // Same gate the scoped-route resolver applies, and the same 404 wording —
1028
988
  // a malformed id is an unknown project, not a validation essay.
@@ -1078,78 +1038,6 @@ export function createApp(deps) {
1078
1038
  const body = { removed: true, id };
1079
1039
  return c.json(body);
1080
1040
  });
1081
- // Edit one field of an existing registry entry (spec
1082
- // 2026-07-22-per-project-concurrency): the per-project concurrency ceiling.
1083
- // A PATCH (not PUT) because it touches a single field, and a distinct route
1084
- // from POST (register-a-folder) to keep register vs. edit semantics clear.
1085
- // `maxParallel: null` clears the override back to "inherit the workspace
1086
- // cap". Bounds mirror `workspaceProjectSchema` (config.ts) exactly, so a
1087
- // value this route accepts can never be degraded away by the next load's
1088
- // `.catch`.
1089
- const updateProjectSchema = z.object({
1090
- maxParallel: z.number().int().min(1).max(16).nullable(),
1091
- });
1092
- app.patch('/api/projects/:projectId', async (c) => {
1093
- if (capabilities().singleProject) {
1094
- return c.json(singleProjectRefusal('editing projects'), 409);
1095
- }
1096
- const raw = c.req.param('projectId');
1097
- // Same gate + 404 wording as DELETE: a malformed id is an unknown project.
1098
- if (!projectIdSchema.safeParse(raw).success) {
1099
- return c.json({ error: `unknown project: ${raw}` }, 404);
1100
- }
1101
- const parsed = updateProjectSchema.safeParse(await c.req.json().catch(() => null));
1102
- if (!parsed.success) {
1103
- return c.json({ error: parsed.error.issues.map((i) => i.message).join('; ') }, 400);
1104
- }
1105
- // `default` is the boot alias the cockpit is allowed to use everywhere else.
1106
- const id = raw === 'default' ? await resolveBootProject() : raw;
1107
- const { maxParallel } = parsed.data;
1108
- // Read-first (mirroring DELETE, server.ts:1252-1258): a well-formed but
1109
- // unknown id must 404 WITHOUT rewriting the config — otherwise it would both
1110
- // do a needless full-config tmp+rename and, on a read-only home, surface the
1111
- // write failure as a 500 where the honest answer is 404.
1112
- let known = false;
1113
- try {
1114
- known = (await loadWorkspaceConfig()).projects.some((p) => p.id === id);
1115
- }
1116
- catch {
1117
- // unreadable workspace — treat as unknown; the read-only case answers 404,
1118
- // not a 500 the caller cannot act on (same reasoning as DELETE).
1119
- }
1120
- if (!known)
1121
- return c.json({ error: `unknown project: ${id}` }, 404);
1122
- let updated;
1123
- try {
1124
- await mergeWriteWorkspaceConfig((config) => {
1125
- const entry = config.projects.find((p) => p.id === id);
1126
- if (!entry)
1127
- return; // lost a race with a concurrent remove — answered below
1128
- // null clears the override; a number sets it. Mutated in place so
1129
- // `.passthrough()` keys on the entry survive.
1130
- if (maxParallel === null)
1131
- delete entry.maxParallel;
1132
- else
1133
- entry.maxParallel = maxParallel;
1134
- updated = entry;
1135
- });
1136
- }
1137
- catch (err) {
1138
- // e.g. a read-only home — nothing was persisted (atomic tmp+rename).
1139
- return c.json({ error: err instanceof Error ? err.message : String(err) }, 500);
1140
- }
1141
- // Raced with a concurrent removal between the read and the write.
1142
- if (!updated)
1143
- return c.json({ error: `unknown project: ${id}` }, 404);
1144
- // The new ceiling takes effect WITHOUT a restart: refresh the shared
1145
- // semaphore's snapshot and pump every manager — the same live-apply hook
1146
- // `PUT /api/workspace/config` fires for a workspace-cap change.
1147
- await deps.semaphore?.refresh();
1148
- const body = {
1149
- project: { ...updated, ...(await probeProjectStatus(updated.root)) },
1150
- };
1151
- return c.json(body);
1152
- });
1153
1041
  // ---- GUI clone (multi-project spec, step 4.3) ----------------------------
1154
1042
  // "Add project → Clone from GitHub": clone into the checkout root, then
1155
1043
  // register the result through `registerFolder` above (same guards, same
@@ -1167,9 +1055,6 @@ export function createApp(deps) {
1167
1055
  checkoutId: z.string().trim().max(128).optional(),
1168
1056
  });
1169
1057
  app.post('/api/projects/checkout', async (c) => {
1170
- if (capabilities().singleProject) {
1171
- return c.json(singleProjectRefusal('adding projects'), 409);
1172
- }
1173
1058
  const parsed = checkoutSchema.safeParse(await c.req.json().catch(() => null));
1174
1059
  if (!parsed.success)
1175
1060
  return c.json({ error: 'url must be a GitHub repository' }, 400);
@@ -1320,9 +1205,6 @@ export function createApp(deps) {
1320
1205
  // it is realpath-based. The independently configured browse root is read per
1321
1206
  // request, so a successful settings save applies without a restart.
1322
1207
  app.get('/api/fs/browse', async (c) => {
1323
- if (capabilities().singleProject) {
1324
- return c.json(singleProjectRefusal('folder browsing'), 409);
1325
- }
1326
1208
  const root = resolveBrowseRoot(await workspaceBrowseRoot());
1327
1209
  const result = await browseDirectory({
1328
1210
  root,
@@ -1345,23 +1227,6 @@ export function createApp(deps) {
1345
1227
  await waitForTeamSkills(repoRoot);
1346
1228
  return c.json(await discoverSkills(repoRoot));
1347
1229
  });
1348
- // The opt-in catalog for the "Import skills" panel: every skill a default
1349
- // (vendor) repo offers — `open-mercato/skills` — regardless of import state,
1350
- // so the panel can present them all with a per-skill toggle. Empty once a repo
1351
- // configures its own `skillsRepos` (nothing is gated then). `wait=1` lets the
1352
- // panel wait out a cold team-skill cache, same as `GET /skills` (spec 005).
1353
- api.get('/skills/importable', async (c) => {
1354
- const repoRoot = c.get('project').root;
1355
- const gated = await gatedSkillsRepos(repoRoot);
1356
- if (gated.size === 0)
1357
- return c.json([]);
1358
- if (c.req.query('wait') === '1')
1359
- await waitForTeamSkills(repoRoot);
1360
- const importable = getTeamSkillsCached(repoRoot)
1361
- .filter((skill) => skill.team && gated.has(skill.team.repo))
1362
- .map((skill) => ({ name: skill.name, description: skill.description }));
1363
- return c.json(importable);
1364
- });
1365
1230
  // ---- GUI prefs (ui-state.json) --------------------------------------------
1366
1231
  // The read path is shared with the CLI (`src/ui-state.ts`) so `cezar serve` can honour a
1367
1232
  // preference set here — #391's dismissed skills banner — from one notion of the file.
@@ -1883,10 +1748,6 @@ export function createApp(deps) {
1883
1748
  }
1884
1749
  const result = manager.continueRun(id, {
1885
1750
  text: parsed.data.text,
1886
- images: parsed.data.images?.map((img) => ({
1887
- type: 'image',
1888
- source: { type: 'base64', media_type: img.mediaType, data: img.data },
1889
- })),
1890
1751
  runner: parsed.data.runner,
1891
1752
  model: parsed.data.model,
1892
1753
  });