@saadnvd1/agent-os 0.3.467 → 0.3.470
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/README.md +28 -1
- package/app/api/projects/clone/route.ts +4 -2
- package/app/api/projects/init/route.test.ts +46 -0
- package/app/api/projects/init/route.ts +24 -4
- package/components/CommandPalette/CommandPalette.tsx +3 -1
- package/components/CommandPalette/useAppCommands.ts +10 -0
- package/components/Projects/AddProject/AddProjectDialog.tsx +25 -5
- package/components/Projects/AddProject/CloneForm.tsx +3 -1
- package/components/Projects/AddProject/FolderForm.tsx +98 -4
- package/components/Projects/AddProject/NameForm.tsx +3 -1
- package/components/Projects/AddProject/WorkspacePick.tsx +56 -0
- package/components/Projects/AddProject/useAddExistingProject.ts +58 -0
- package/components/SessionList/WorkspaceSwitcher.tsx +10 -0
- package/components/SessionList/useDoneAction.ts +2 -1
- package/data/projects/add.ts +23 -3
- package/lib/chat/driver.ts +8 -0
- package/lib/chat/drivers/claude-approvals.ts +40 -0
- package/lib/chat/drivers/claude.ts +7 -10
- package/lib/chat/worker/extras.ts +1 -0
- package/lib/chat/worker/host.ts +4 -0
- package/lib/done/index.ts +1 -8
- package/lib/done/plan.ts +13 -2
- package/lib/done/worktree.ts +55 -33
- package/lib/orchestrator/add-project.ts +35 -0
- package/lib/orchestrator/brief.ts +3 -2
- package/lib/orchestrator/diff.ts +5 -1
- package/lib/orchestrator/serve.ts +6 -0
- package/lib/orchestrator/tool-names.ts +13 -6
- package/lib/orchestrator/tool-schemas.ts +15 -0
- package/lib/orchestrator/tools.ts +2 -0
- package/lib/orchestrator/worker.ts +4 -1
- package/lib/orchestrator/write-guard.ts +295 -0
- package/lib/project-add/index.ts +133 -14
- package/lib/project-add/name.ts +1 -0
- package/lib/secret-paths.ts +9 -0
- package/lib/tasks/finish.ts +8 -2
- package/lib/worktree-removal.ts +115 -0
- package/lib/worktrees.ts +30 -27
- package/package.json +1 -1
- package/stores/addProject.ts +12 -3
package/lib/worktrees.ts
CHANGED
|
@@ -14,6 +14,14 @@ import {
|
|
|
14
14
|
} from "./git";
|
|
15
15
|
import { installWorktreeHooks } from "./worktree-hooks";
|
|
16
16
|
import { gitResult, isGitError, worktreeList } from "./git-exec";
|
|
17
|
+
import {
|
|
18
|
+
markRemoving,
|
|
19
|
+
removalKey,
|
|
20
|
+
removalRunning,
|
|
21
|
+
removalSettled,
|
|
22
|
+
removals,
|
|
23
|
+
unmarkRemoving,
|
|
24
|
+
} from "./worktree-removal";
|
|
17
25
|
|
|
18
26
|
const git = (cwd: string, args: string[], timeout: number) =>
|
|
19
27
|
gitResult(cwd, args, { timeout });
|
|
@@ -252,28 +260,10 @@ async function undoFailedAdd(
|
|
|
252
260
|
await quiet(["branch", "-D", "--", branch]);
|
|
253
261
|
}
|
|
254
262
|
|
|
255
|
-
// Removals in progress, by path, with the branch each one's worktree was
|
|
256
|
-
// on. `git worktree remove` takes seconds on a tree with cloned
|
|
257
|
-
// dependencies, and a tree read halfway through looks like every file it
|
|
258
|
-
// already deleted is an uncommitted change.
|
|
259
|
-
const removing = new Map<
|
|
260
|
-
string,
|
|
261
|
-
{ done: Promise<void>; branch: Promise<string | null> }
|
|
262
|
-
>();
|
|
263
|
-
|
|
264
|
-
const removalKey = (p: string) => path.resolve(resolvePath(p));
|
|
265
|
-
|
|
266
|
-
// Resolves once no removal of this worktree is running.
|
|
267
|
-
export async function removalSettled(worktreePath: string): Promise<void> {
|
|
268
|
-
await removing.get(removalKey(worktreePath))?.done.catch(() => {});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
export const removalRunning = (worktreePath: string) =>
|
|
272
|
-
removing.has(removalKey(worktreePath));
|
|
273
|
-
|
|
274
263
|
/**
|
|
275
264
|
* Delete a worktree and optionally its branch. A second call while one is
|
|
276
|
-
* running joins it, and still deletes the branch when it asks to
|
|
265
|
+
* running joins it, and still deletes the branch when it asks to; one
|
|
266
|
+
* another process is running is waited for first.
|
|
277
267
|
*/
|
|
278
268
|
export function deleteWorktree(
|
|
279
269
|
worktreePath: string,
|
|
@@ -282,22 +272,35 @@ export function deleteWorktree(
|
|
|
282
272
|
): Promise<void> {
|
|
283
273
|
const key = removalKey(worktreePath);
|
|
284
274
|
const repo = resolvePath(projectPath);
|
|
285
|
-
const running =
|
|
275
|
+
const running = removals.get(key);
|
|
286
276
|
if (running)
|
|
287
277
|
return deleteBranch
|
|
288
278
|
? running.done.then(async () => dropBranch(repo, await running.branch))
|
|
289
279
|
: running.done;
|
|
280
|
+
// One another process is running goes first, and keeps its own marker.
|
|
281
|
+
const foreign = removalRunning(key)
|
|
282
|
+
? removalSettled(key, undefined, { foreignOnly: true })
|
|
283
|
+
: null;
|
|
290
284
|
// Read before anything is removed.
|
|
291
|
-
const branch =
|
|
292
|
-
|
|
293
|
-
(
|
|
294
|
-
|
|
285
|
+
const branch = (async () => {
|
|
286
|
+
await foreign;
|
|
287
|
+
return git(key, ["rev-parse", "--abbrev-ref", "HEAD"], 5000).then(
|
|
288
|
+
({ stdout }) => stdout.trim() || null,
|
|
289
|
+
() => null
|
|
290
|
+
);
|
|
291
|
+
})();
|
|
292
|
+
let marker: string | null = null;
|
|
295
293
|
const done = (async () => {
|
|
296
294
|
await branch;
|
|
295
|
+
// Before anything is removed, so no reader catches it half-deleted.
|
|
296
|
+
marker = markRemoving(key);
|
|
297
297
|
await removeWorktree(key, repo);
|
|
298
298
|
if (deleteBranch) await dropBranch(repo, await branch);
|
|
299
|
-
})().finally(() =>
|
|
300
|
-
|
|
299
|
+
})().finally(() => {
|
|
300
|
+
removals.delete(key);
|
|
301
|
+
if (marker) unmarkRemoving(key, marker);
|
|
302
|
+
});
|
|
303
|
+
removals.set(key, { done, branch });
|
|
301
304
|
return done;
|
|
302
305
|
}
|
|
303
306
|
|
package/package.json
CHANGED
package/stores/addProject.ts
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import { proxy } from "valtio";
|
|
2
|
+
import { sidebarUi } from "./sidebarUi";
|
|
2
3
|
|
|
3
4
|
export type AddProjectKind = "folder" | "clone" | "name";
|
|
4
5
|
|
|
5
|
-
// The add-project form on show, once a machine and a way are picked.
|
|
6
|
+
// The add-project form on show, once a machine and a way are picked. It
|
|
7
|
+
// adds to the workspace the sidebar is on, changeable in the form.
|
|
6
8
|
export const addProjectUi = proxy<{
|
|
7
|
-
open: {
|
|
9
|
+
open: {
|
|
10
|
+
kind: AddProjectKind;
|
|
11
|
+
hostId: string;
|
|
12
|
+
workspaceId: string | null;
|
|
13
|
+
} | null;
|
|
8
14
|
}>({ open: null });
|
|
9
15
|
|
|
10
16
|
export const addProjectActions = {
|
|
11
17
|
show: (kind: AddProjectKind, hostId: string) => {
|
|
12
|
-
addProjectUi.open = { kind, hostId };
|
|
18
|
+
addProjectUi.open = { kind, hostId, workspaceId: sidebarUi.workspaceId };
|
|
19
|
+
},
|
|
20
|
+
setWorkspace: (workspaceId: string | null) => {
|
|
21
|
+
if (addProjectUi.open) addProjectUi.open.workspaceId = workspaceId;
|
|
13
22
|
},
|
|
14
23
|
close: () => {
|
|
15
24
|
addProjectUi.open = null;
|