MCPcopy
hub / github.com/garrytan/gstack / decideSourceRemove

Function decideSourceRemove

lib/gbrain-guards.ts:232–269  ·  view source on GitHub ↗
(
  sourceId: string,
  env: NodeJS.ProcessEnv = process.env,
  opts: DecideRemoveOpts = {},
)

Source from the content-addressed store, hash-verified

230}
231
232export function decideSourceRemove(
233 sourceId: string,
234 env: NodeJS.ProcessEnv = process.env,
235 opts: DecideRemoveOpts = {},
236): RemoveDecision {
237 const keepStorage = opts.keepStorage ?? gbrainSupportsKeepStorage(env);
238 const extra = keepStorage ? ["--keep-storage"] : [];
239
240 let rows: GbrainSourceRow[];
241 try {
242 rows = (opts.fetchRows ?? fetchSources)(env);
243 } catch {
244 return { allow: false, extraArgs: [], reason: "could not read sources list; refusing remove (fail closed)" };
245 }
246
247 const row = rows.find((r) => r.id === sourceId);
248 if (!row) return { allow: true, extraArgs: extra, reason: "source absent (no-op)" };
249
250 const remoteUrl = row.config?.remote_url;
251 const userManaged =
252 !!remoteUrl && !!row.local_path && !clonesDirs(env).some((d) => isInside(row.local_path!, d));
253
254 if (userManaged) {
255 if (keepStorage) {
256 return { allow: true, extraArgs: ["--keep-storage"], reason: "user-managed; --keep-storage protects files" };
257 }
258 return {
259 allow: false,
260 extraArgs: [],
261 reason:
262 `refusing remove of user-managed source "${sourceId}" (remote_url set, local_path ` +
263 `${row.local_path} outside gbrain clones) — this gbrain has no --keep-storage to ` +
264 `protect the working tree. Upgrade gbrain or remove the source manually.`,
265 };
266 }
267
268 return { allow: true, extraArgs: extra, reason: "gbrain-managed or path-managed without remote_url" };
269}
270
271export interface SyncDecision {
272 allow: boolean;

Callers 2

safeSourcesRemoveFunction · 0.90

Calls 3

clonesDirsFunction · 0.85
isInsideFunction · 0.85

Tested by

no test coverage detected