@agimon-ai/po-git 0.0.0-alpha.7 → 0.0.0-alpha.71
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 +149 -21
- package/README.md +16 -4
- package/dist/apiContracts.cjs +4 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.mjs +4 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/extensions/native.mjs +2163 -534
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +293 -117
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +290 -114
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +1443 -1292
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{worktreeOperations-BSeyxUai.mjs → worktreeOperations-B3E4JY4H.mjs} +258 -85
- package/dist/worktreeOperations-B3E4JY4H.mjs.map +1 -0
- package/dist/{worktreeOperations-DGUbUnYU.cjs → worktreeOperations-CD7s0YnO.cjs} +288 -85
- package/dist/worktreeOperations-CD7s0YnO.cjs.map +1 -0
- package/llms.txt +1 -1
- package/package.json +21 -19
- package/src/prompts/{po-use-git → codemode-how-to-git}/SKILL.md +35 -32
- package/dist/worktreeOperations-BSeyxUai.mjs.map +0 -1
- package/dist/worktreeOperations-DGUbUnYU.cjs.map +0 -1
|
@@ -2,15 +2,16 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_worktreeOperations = require("../worktreeOperations-
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
let node_os = require("node:os");
|
|
9
|
-
node_os = require_worktreeOperations.__toESM(node_os, 1);
|
|
5
|
+
const require_worktreeOperations = require("../worktreeOperations-CD7s0YnO.cjs");
|
|
6
|
+
let node_fs_promises = require("node:fs/promises");
|
|
7
|
+
node_fs_promises = require_worktreeOperations.__toESM(node_fs_promises, 1);
|
|
10
8
|
let node_path = require("node:path");
|
|
11
9
|
node_path = require_worktreeOperations.__toESM(node_path, 1);
|
|
12
|
-
let
|
|
10
|
+
let node_os = require("node:os");
|
|
11
|
+
node_os = require_worktreeOperations.__toESM(node_os, 1);
|
|
12
|
+
let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin");
|
|
13
13
|
let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
|
|
14
|
+
let _agimon_ai_po_core_codemode = require("@agimon-ai/po-core/codemode");
|
|
14
15
|
let _agimon_ai_po_session = require("@agimon-ai/po-session");
|
|
15
16
|
let typebox = require("typebox");
|
|
16
17
|
//#region src/schemas/runWorktreeTool.ts
|
|
@@ -254,7 +255,8 @@ async function executeRunWorktreeTool(params, operations, context, options = {})
|
|
|
254
255
|
content: text(describe(record, context.sessionId), `Session: ${record.sessionId}`, dirtyFiles.length === 0 ? "Clean." : `${String(dirtyFiles.length)} uncommitted file(s): ${dirtyFiles.slice(0, 20).join(", ")}`),
|
|
255
256
|
details: {
|
|
256
257
|
action: params.action,
|
|
257
|
-
records: [record]
|
|
258
|
+
records: [record],
|
|
259
|
+
dirtyFiles
|
|
258
260
|
}
|
|
259
261
|
};
|
|
260
262
|
}
|
|
@@ -278,7 +280,10 @@ async function executeRunWorktreeTool(params, operations, context, options = {})
|
|
|
278
280
|
const waiting = await operations.messages(context, params.id);
|
|
279
281
|
return {
|
|
280
282
|
content: waiting.length === 0 ? text("No messages.") : text(`${String(waiting.length)} message(s):`, ...waiting.map((entry) => `[${entry.sentAt}] ${entry.from}: ${entry.text}`)),
|
|
281
|
-
details: {
|
|
283
|
+
details: {
|
|
284
|
+
action: params.action,
|
|
285
|
+
messages: waiting
|
|
286
|
+
}
|
|
282
287
|
};
|
|
283
288
|
}
|
|
284
289
|
case WORKTREE_ACTIONS.prune: {
|
|
@@ -293,12 +298,172 @@ async function executeRunWorktreeTool(params, operations, context, options = {})
|
|
|
293
298
|
`Untracked directories, left alone: ${plan.untracked.length === 0 ? "none" : plan.untracked.join(", ")}`,
|
|
294
299
|
...plan.keptBranches.length === 0 ? [] : [`Branches kept, they hold commits: ${plan.keptBranches.join(", ")}`]
|
|
295
300
|
]),
|
|
296
|
-
details: {
|
|
301
|
+
details: {
|
|
302
|
+
action: params.action,
|
|
303
|
+
plan
|
|
304
|
+
}
|
|
297
305
|
};
|
|
298
306
|
}
|
|
299
307
|
}
|
|
300
308
|
}
|
|
301
309
|
//#endregion
|
|
310
|
+
//#region src/services/worktreeNamespace/index.ts
|
|
311
|
+
const DECLARATIONS = `type WorktreeStatus = 'spawning' | 'running' | 'closing' | 'orphaned';
|
|
312
|
+
|
|
313
|
+
interface Worktree {
|
|
314
|
+
id: string;
|
|
315
|
+
branch: string;
|
|
316
|
+
baseRef: string;
|
|
317
|
+
/** Absolute path of the checkout, under ~/.po/git/worktrees. */
|
|
318
|
+
path: string;
|
|
319
|
+
repositoryRoot: string;
|
|
320
|
+
/** The session running inside the worktree. */
|
|
321
|
+
sessionId: string;
|
|
322
|
+
parentSessionId?: string;
|
|
323
|
+
status: WorktreeStatus;
|
|
324
|
+
createdAt: string;
|
|
325
|
+
/** How your session relates to it: 'parent' spawned it, 'child' runs inside it, 'other' is neither. */
|
|
326
|
+
relationship: 'parent' | 'child' | 'other';
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
interface WorktreeMessage {
|
|
330
|
+
worktreeId: string;
|
|
331
|
+
fromSessionId: string;
|
|
332
|
+
from: 'parent' | 'child';
|
|
333
|
+
text: string;
|
|
334
|
+
sentAt: string;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
interface PrunePlan {
|
|
338
|
+
remove: Worktree[];
|
|
339
|
+
forget: Worktree[];
|
|
340
|
+
/** Kept because they hold uncommitted work. */
|
|
341
|
+
keptDirty: Worktree[];
|
|
342
|
+
untracked: string[];
|
|
343
|
+
/** Branches kept because they hold commits. */
|
|
344
|
+
keptBranches: string[];
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
declare const worktrees: {
|
|
348
|
+
/** Every worktree for this repository. */
|
|
349
|
+
list(): Promise<Worktree[]>;
|
|
350
|
+
/** One worktree and its uncommitted files. */
|
|
351
|
+
status(id: string): Promise<{ worktree: Worktree; dirtyFiles: string[] }>;
|
|
352
|
+
/**
|
|
353
|
+
* Create a worktree on a new branch and start a Po session in it, nested under this one. baseRef defaults to
|
|
354
|
+
* the current branch's remote-tracking ref, then the remote default branch; name labels it in the rail; task is
|
|
355
|
+
* the new session's first message. Setup can be slow, so give exec a larger timeoutMs.
|
|
356
|
+
*/
|
|
357
|
+
spawn(request: { branch: string; baseRef?: string; name?: string; task?: string }): Promise<Worktree>;
|
|
358
|
+
/** Stop the worktree's session and delete its checkout. Refused on a dirty tree unless force is true. */
|
|
359
|
+
close(id: string, options?: { force?: boolean }): Promise<Worktree>;
|
|
360
|
+
/** Merge the worktree's branch into this checkout. Refused when this checkout is dirty. */
|
|
361
|
+
merge(id: string, options?: { message?: string }): Promise<Worktree>;
|
|
362
|
+
/** Remove orphaned worktrees. With dryRun, only return the plan. */
|
|
363
|
+
prune(options?: { dryRun?: boolean }): Promise<PrunePlan>;
|
|
364
|
+
/**
|
|
365
|
+
* Message the other side of a worktree. Use the record with relationship 'child' to report to your parent,
|
|
366
|
+
* and 'parent' to reach your own children. 'other' records are not communication edges.
|
|
367
|
+
*/
|
|
368
|
+
send(id: string, message: string): Promise<void>;
|
|
369
|
+
/** Messages waiting for you from a worktree. */
|
|
370
|
+
messages(id: string): Promise<WorktreeMessage[]>;
|
|
371
|
+
};`;
|
|
372
|
+
const json = (value) => JSON.parse(JSON.stringify(value));
|
|
373
|
+
/** Git worktrees for code mode: the actions of `run_worktree` as methods, returning records instead of text. */
|
|
374
|
+
function createWorktreeNamespace(options) {
|
|
375
|
+
return {
|
|
376
|
+
name: "worktrees",
|
|
377
|
+
summary: "Git worktrees, each with its own Po session nested under this one: worktrees.list, status, spawn, close, merge, prune, send and messages.",
|
|
378
|
+
declarations: DECLARATIONS,
|
|
379
|
+
bind(run) {
|
|
380
|
+
if (run.sessionId !== options.execution.sessionId) throw new Error("Worktrees namespace belongs to another session.");
|
|
381
|
+
let disposed = false;
|
|
382
|
+
run.onDispose(() => {
|
|
383
|
+
disposed = true;
|
|
384
|
+
});
|
|
385
|
+
const view = (record) => ({
|
|
386
|
+
...record,
|
|
387
|
+
relationship: record.parentSessionId === options.execution.sessionId ? "parent" : record.sessionId === options.execution.sessionId ? "child" : "other"
|
|
388
|
+
});
|
|
389
|
+
/** One `run_worktree` action through the tool's own code, so the tool and the namespace cannot drift. */
|
|
390
|
+
const act = async (name, action, input) => {
|
|
391
|
+
run.signal.throwIfAborted();
|
|
392
|
+
if (disposed) throw new Error("Worktrees namespace run is disposed.");
|
|
393
|
+
options.assertAvailable();
|
|
394
|
+
const params = validateParams({
|
|
395
|
+
action,
|
|
396
|
+
...typeof input === "object" && input !== null ? input : {}
|
|
397
|
+
});
|
|
398
|
+
const context = {
|
|
399
|
+
cwd: options.execution.cwd,
|
|
400
|
+
sessionId: options.execution.sessionId
|
|
401
|
+
};
|
|
402
|
+
const started = Date.now();
|
|
403
|
+
try {
|
|
404
|
+
const result = await executeRunWorktreeTool(params, options.operations, context, { signal: run.signal });
|
|
405
|
+
options.assertAvailable();
|
|
406
|
+
run.record?.({
|
|
407
|
+
name: `worktrees.${name}`,
|
|
408
|
+
tool: RUN_WORKTREE_TOOL_NAME,
|
|
409
|
+
args: params,
|
|
410
|
+
ok: true,
|
|
411
|
+
ms: Date.now() - started,
|
|
412
|
+
result
|
|
413
|
+
});
|
|
414
|
+
return result;
|
|
415
|
+
} catch (error) {
|
|
416
|
+
run.record?.({
|
|
417
|
+
name: `worktrees.${name}`,
|
|
418
|
+
tool: RUN_WORKTREE_TOOL_NAME,
|
|
419
|
+
args: params,
|
|
420
|
+
ok: false,
|
|
421
|
+
ms: Date.now() - started,
|
|
422
|
+
error: error instanceof Error ? error.message : String(error)
|
|
423
|
+
});
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
const record = (result) => view(result.details.records[0]);
|
|
428
|
+
const members = Object.create(null);
|
|
429
|
+
members.list = async () => json((await act("list", "list", {})).details.records.map(view));
|
|
430
|
+
members.status = async (id) => {
|
|
431
|
+
const { details } = await act("status", "status", { id });
|
|
432
|
+
return json({
|
|
433
|
+
worktree: view(details.records[0]),
|
|
434
|
+
dirtyFiles: details.dirtyFiles ?? []
|
|
435
|
+
});
|
|
436
|
+
};
|
|
437
|
+
members.spawn = async (request) => json(record(await act("spawn", "spawn_worktree", request)));
|
|
438
|
+
members.close = async (id, settings) => json(record(await act("close", "close_worktree", {
|
|
439
|
+
...settings,
|
|
440
|
+
id
|
|
441
|
+
})));
|
|
442
|
+
members.merge = async (id, settings) => json(record(await act("merge", "merge", {
|
|
443
|
+
...settings,
|
|
444
|
+
id
|
|
445
|
+
})));
|
|
446
|
+
members.prune = async (settings) => {
|
|
447
|
+
const { plan } = (await act("prune", "prune", settings)).details;
|
|
448
|
+
return json({
|
|
449
|
+
...plan,
|
|
450
|
+
remove: plan.remove.map(view),
|
|
451
|
+
forget: plan.forget.map(view),
|
|
452
|
+
keptDirty: plan.keptDirty.map(view)
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
members.send = async (id, message) => {
|
|
456
|
+
await act("send", "send", {
|
|
457
|
+
id,
|
|
458
|
+
message
|
|
459
|
+
});
|
|
460
|
+
};
|
|
461
|
+
members.messages = async (id) => json((await act("messages", "messages", { id })).details.messages);
|
|
462
|
+
return members;
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
//#endregion
|
|
302
467
|
//#region src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts
|
|
303
468
|
function progressResult(action, label) {
|
|
304
469
|
return {
|
|
@@ -309,9 +474,9 @@ function progressResult(action, label) {
|
|
|
309
474
|
details: { action }
|
|
310
475
|
};
|
|
311
476
|
}
|
|
312
|
-
function createGitSession({ context, host: serverHost }) {
|
|
313
|
-
if (serverHost.context.directEvents === void 0) throw new Error("Git
|
|
314
|
-
if (serverHost.context.sessionId === void 0) throw new Error("Git
|
|
477
|
+
function createGitSession({ context, host: serverHost, agent, signal }) {
|
|
478
|
+
if (serverHost.context.directEvents === void 0) throw new Error("Git server plugin requires the session direct event bus.");
|
|
479
|
+
if (serverHost.context.sessionId === void 0) throw new Error("Git server plugin requires a session identity.");
|
|
315
480
|
const sessionId = serverHost.context.sessionId;
|
|
316
481
|
const directEvents = serverHost.context.directEvents;
|
|
317
482
|
const messageInbox = require_worktreeOperations.createWorktreeMessageInbox(directEvents, sessionId);
|
|
@@ -322,20 +487,12 @@ function createGitSession({ context, host: serverHost }) {
|
|
|
322
487
|
sessionDelivery: () => (0, _agimon_ai_po_session.readPoSessionDelivery)(context)
|
|
323
488
|
});
|
|
324
489
|
const resources = [{
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
attribution: {
|
|
328
|
-
kind: "minor",
|
|
329
|
-
mode: "help"
|
|
330
|
-
}
|
|
331
|
-
},
|
|
332
|
-
name: "po-git",
|
|
333
|
-
kind: "context",
|
|
334
|
-
read: () => (0, _agimon_ai_po_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "llms.txt")
|
|
335
|
-
}, {
|
|
336
|
-
name: "po-use-git",
|
|
490
|
+
name: "codemode-how-to-git",
|
|
491
|
+
description: "Hand a branch of work to a separate session in its own checkout, keeping the current checkout untouched. Use for a long refactor, a risky migration, or parallel features that touch the same files; not for parallel work on one branch.",
|
|
337
492
|
kind: "skill",
|
|
338
|
-
|
|
493
|
+
pinned: true,
|
|
494
|
+
path: (0, _agimon_ai_po_core_serverPlugin.packageResourcePath)(require("url").pathToFileURL(__filename).href, "src/prompts/codemode-how-to-git/SKILL.md"),
|
|
495
|
+
read: () => (0, _agimon_ai_po_core_serverPlugin.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/codemode-how-to-git/SKILL.md")
|
|
339
496
|
}];
|
|
340
497
|
const tool = {
|
|
341
498
|
name: RUN_WORKTREE_TOOL_NAME,
|
|
@@ -355,17 +512,37 @@ function createGitSession({ context, host: serverHost }) {
|
|
|
355
512
|
const changed = (_event, execution) => {
|
|
356
513
|
directEvents.publish(require_worktreeOperations.GIT_SESSION_CHANGED_EVENT, execution.sessionId, { version: 1 });
|
|
357
514
|
};
|
|
515
|
+
const hooks = [{
|
|
516
|
+
event: "tool_execution_end",
|
|
517
|
+
handle: changed
|
|
518
|
+
}, {
|
|
519
|
+
event: "agent_settled",
|
|
520
|
+
handle: changed
|
|
521
|
+
}];
|
|
522
|
+
if (agent) {
|
|
523
|
+
const namespace = createWorktreeNamespace({
|
|
524
|
+
operations,
|
|
525
|
+
execution: agent.context,
|
|
526
|
+
assertAvailable: () => {
|
|
527
|
+
if (signal?.aborted) throw new Error("Git session is unavailable.");
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
context.inject([_agimon_ai_po_core_codemode.PO_CODEMODE_SERVICE], (scoped) => {
|
|
531
|
+
const codemode = (0, _agimon_ai_po_core_codemode.readPoCodemode)(scoped);
|
|
532
|
+
if (!codemode) return void 0;
|
|
533
|
+
const registration = codemode.register("@agimon-ai/po-git", namespace);
|
|
534
|
+
const restriction = agent.registerToolRestriction({ excludedTools: [RUN_WORKTREE_TOOL_NAME] });
|
|
535
|
+
return () => {
|
|
536
|
+
restriction.dispose();
|
|
537
|
+
registration.dispose();
|
|
538
|
+
};
|
|
539
|
+
});
|
|
540
|
+
}
|
|
358
541
|
return {
|
|
359
542
|
value: {
|
|
360
543
|
resources,
|
|
361
544
|
tool,
|
|
362
|
-
hooks
|
|
363
|
-
event: "tool_execution_end",
|
|
364
|
-
handle: changed
|
|
365
|
-
}, {
|
|
366
|
-
event: "agent_settled",
|
|
367
|
-
handle: changed
|
|
368
|
-
}]
|
|
545
|
+
hooks
|
|
369
546
|
},
|
|
370
547
|
onDispose: () => messageInbox.close()
|
|
371
548
|
};
|
|
@@ -476,11 +653,11 @@ const NAME_STATUS = {
|
|
|
476
653
|
T: "modified"
|
|
477
654
|
};
|
|
478
655
|
/** Line count of a small regular file, or undefined when it is binary, large, or not a regular file. */
|
|
479
|
-
function untrackedLines(root, relPath) {
|
|
656
|
+
async function untrackedLines(root, relPath) {
|
|
480
657
|
const absolute = node_path.default.join(root, relPath);
|
|
481
658
|
let stat;
|
|
482
659
|
try {
|
|
483
|
-
stat =
|
|
660
|
+
stat = await node_fs_promises.default.lstat(absolute);
|
|
484
661
|
} catch {
|
|
485
662
|
return;
|
|
486
663
|
}
|
|
@@ -489,7 +666,7 @@ function untrackedLines(root, relPath) {
|
|
|
489
666
|
binary: false
|
|
490
667
|
};
|
|
491
668
|
if (!stat.isFile() || stat.size > MAX_FILE_BYTES) return void 0;
|
|
492
|
-
const content =
|
|
669
|
+
const content = await node_fs_promises.default.readFile(absolute);
|
|
493
670
|
if (content.subarray(0, BINARY_PROBE_BYTES).includes(0)) return {
|
|
494
671
|
lines: 0,
|
|
495
672
|
binary: true
|
|
@@ -612,8 +789,8 @@ function createBranchDiff() {
|
|
|
612
789
|
"--exclude-standard",
|
|
613
790
|
"-z"
|
|
614
791
|
]));
|
|
615
|
-
untracked.
|
|
616
|
-
const counted = index < MAX_UNTRACKED_COUNTED ? untrackedLines(root, relPath) : void 0;
|
|
792
|
+
for (const [index, relPath] of untracked.entries()) {
|
|
793
|
+
const counted = index < MAX_UNTRACKED_COUNTED ? await untrackedLines(root, relPath) : void 0;
|
|
617
794
|
entries.push({
|
|
618
795
|
path: relPath,
|
|
619
796
|
status: "untracked",
|
|
@@ -621,18 +798,20 @@ function createBranchDiff() {
|
|
|
621
798
|
removed: 0,
|
|
622
799
|
...counted?.binary ? { binary: true } : {}
|
|
623
800
|
});
|
|
624
|
-
}
|
|
801
|
+
}
|
|
625
802
|
entries.sort((left, right) => left.path.localeCompare(right.path));
|
|
626
803
|
const conflicts = [...unmerged];
|
|
627
|
-
const
|
|
804
|
+
const rebaseMerge = await readLine$1(root, [
|
|
628
805
|
"rev-parse",
|
|
629
806
|
"--git-path",
|
|
630
807
|
"rebase-merge"
|
|
631
|
-
])
|
|
808
|
+
]);
|
|
809
|
+
const rebaseApply = await readLine$1(root, [
|
|
632
810
|
"rev-parse",
|
|
633
811
|
"--git-path",
|
|
634
812
|
"rebase-apply"
|
|
635
|
-
])
|
|
813
|
+
]);
|
|
814
|
+
const rebasing = (await Promise.all([rebaseMerge, rebaseApply].map(async (gitPath) => gitPath === void 0 ? false : node_fs_promises.default.access(node_path.default.resolve(root, gitPath)).then(() => true, () => false)))).some(Boolean);
|
|
636
815
|
const upstreamRef = branch === void 0 ? void 0 : await upstreamOf(root, branch);
|
|
637
816
|
let upstream;
|
|
638
817
|
if (upstreamRef !== void 0) {
|
|
@@ -677,7 +856,7 @@ function createBranchDiff() {
|
|
|
677
856
|
if (entry === void 0) throw new Error("That path is not in this review.");
|
|
678
857
|
if (entry.status === "untracked") {
|
|
679
858
|
const absolute = node_path.default.join(review.root, entry.path);
|
|
680
|
-
const stat =
|
|
859
|
+
const stat = await node_fs_promises.default.lstat(absolute);
|
|
681
860
|
if (stat.isSymbolicLink()) return {
|
|
682
861
|
path: entry.path,
|
|
683
862
|
hunks: [{
|
|
@@ -685,7 +864,7 @@ function createBranchDiff() {
|
|
|
685
864
|
rows: [{
|
|
686
865
|
marker: "+",
|
|
687
866
|
line: 1,
|
|
688
|
-
content:
|
|
867
|
+
content: await node_fs_promises.default.readlink(absolute)
|
|
689
868
|
}]
|
|
690
869
|
}]
|
|
691
870
|
};
|
|
@@ -694,7 +873,7 @@ function createBranchDiff() {
|
|
|
694
873
|
hunks: [],
|
|
695
874
|
tooLarge: true
|
|
696
875
|
};
|
|
697
|
-
const content =
|
|
876
|
+
const content = await node_fs_promises.default.readFile(absolute);
|
|
698
877
|
if (content.subarray(0, BINARY_PROBE_BYTES).includes(0)) return {
|
|
699
878
|
path: entry.path,
|
|
700
879
|
hunks: [],
|
|
@@ -811,9 +990,9 @@ function isRecord(value) {
|
|
|
811
990
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
812
991
|
}
|
|
813
992
|
/** The workspace key: the canonical root, so a symlinked path and its target share one entry. */
|
|
814
|
-
function workspaceKey(workspaceRoot) {
|
|
993
|
+
async function workspaceKey(workspaceRoot) {
|
|
815
994
|
try {
|
|
816
|
-
return
|
|
995
|
+
return await node_fs_promises.default.realpath(workspaceRoot);
|
|
817
996
|
} catch {
|
|
818
997
|
return node_path.default.resolve(workspaceRoot);
|
|
819
998
|
}
|
|
@@ -862,7 +1041,7 @@ function publicView(config) {
|
|
|
862
1041
|
* the saved one, and only for the same host: a token never follows a host it
|
|
863
1042
|
* was not entered for.
|
|
864
1043
|
*/
|
|
865
|
-
function parseGitAuthSave(request, current, homeDir) {
|
|
1044
|
+
async function parseGitAuthSave(request, current, homeDir) {
|
|
866
1045
|
if (!isRecord(request)) throw require_worktreeOperations.invalidRequest("The git auth request is not an object.", "Send method none, ssh or https.");
|
|
867
1046
|
if (request.method === "none") return { method: "none" };
|
|
868
1047
|
if (request.method === "ssh") {
|
|
@@ -872,7 +1051,7 @@ function parseGitAuthSave(request, current, homeDir) {
|
|
|
872
1051
|
if (!keyPath.startsWith("/") && !keyPath.startsWith("~/")) throw require_worktreeOperations.invalidRequest("The key path is not absolute.", "Give the key as an absolute path or one under ~/.");
|
|
873
1052
|
let isFile = false;
|
|
874
1053
|
try {
|
|
875
|
-
isFile =
|
|
1054
|
+
isFile = (await node_fs_promises.default.stat(expandHome(keyPath, homeDir))).isFile();
|
|
876
1055
|
} catch {
|
|
877
1056
|
isFile = false;
|
|
878
1057
|
}
|
|
@@ -907,16 +1086,16 @@ function parseGitAuthSave(request, current, homeDir) {
|
|
|
907
1086
|
throw require_worktreeOperations.invalidRequest("The git auth method is unknown.", "Send method none, ssh or https.");
|
|
908
1087
|
}
|
|
909
1088
|
/** Tightens a file or folder something left readable by group or others. */
|
|
910
|
-
function tighten(target, mode) {
|
|
1089
|
+
async function tighten(target, mode) {
|
|
911
1090
|
try {
|
|
912
|
-
if ((
|
|
1091
|
+
if (((await node_fs_promises.default.stat(target)).mode & LOOSE_BITS) !== 0) await node_fs_promises.default.chmod(target, mode);
|
|
913
1092
|
} catch {}
|
|
914
1093
|
}
|
|
915
1094
|
function createGitAuthStore(homeDir = node_os.default.homedir()) {
|
|
916
1095
|
const file = require_worktreeOperations.credentialsFile(homeDir);
|
|
917
|
-
const readFile = () => {
|
|
918
|
-
tighten(file, OWNER_ONLY_FILE);
|
|
919
|
-
const raw = require_worktreeOperations.readJson(file);
|
|
1096
|
+
const readFile = async () => {
|
|
1097
|
+
await tighten(file, OWNER_ONLY_FILE);
|
|
1098
|
+
const raw = await require_worktreeOperations.readJson(file);
|
|
920
1099
|
const workspaces = {};
|
|
921
1100
|
if (isRecord(raw) && raw.version === 1 && isRecord(raw.workspaces)) for (const [key, value] of Object.entries(raw.workspaces)) {
|
|
922
1101
|
const config = parseConfig(value);
|
|
@@ -927,28 +1106,28 @@ function createGitAuthStore(homeDir = node_os.default.homedir()) {
|
|
|
927
1106
|
workspaces
|
|
928
1107
|
};
|
|
929
1108
|
};
|
|
930
|
-
const read = (workspaceRoot) => readFile().workspaces[workspaceKey(workspaceRoot)] ?? { method: "none" };
|
|
1109
|
+
const read = async (workspaceRoot) => (await readFile()).workspaces[await workspaceKey(workspaceRoot)] ?? { method: "none" };
|
|
931
1110
|
return {
|
|
932
1111
|
read,
|
|
933
|
-
view: (workspaceRoot) => publicView(read(workspaceRoot)),
|
|
934
|
-
save(workspaceRoot, request) {
|
|
935
|
-
const key = workspaceKey(workspaceRoot);
|
|
936
|
-
const current = readFile();
|
|
937
|
-
const next = parseGitAuthSave(request, current.workspaces[key] ?? { method: "none" }, homeDir);
|
|
1112
|
+
view: async (workspaceRoot) => publicView(await read(workspaceRoot)),
|
|
1113
|
+
async save(workspaceRoot, request) {
|
|
1114
|
+
const key = await workspaceKey(workspaceRoot);
|
|
1115
|
+
const current = await readFile();
|
|
1116
|
+
const next = await parseGitAuthSave(request, current.workspaces[key] ?? { method: "none" }, homeDir);
|
|
938
1117
|
const root = require_worktreeOperations.poGitRoot(homeDir);
|
|
939
|
-
|
|
1118
|
+
await node_fs_promises.default.mkdir(root, {
|
|
940
1119
|
recursive: true,
|
|
941
1120
|
mode: OWNER_ONLY_DIRECTORY
|
|
942
1121
|
});
|
|
943
|
-
|
|
1122
|
+
await node_fs_promises.default.chmod(root, OWNER_ONLY_DIRECTORY);
|
|
944
1123
|
const workspaces = { ...current.workspaces };
|
|
945
1124
|
if (next.method === "none") delete workspaces[key];
|
|
946
1125
|
else workspaces[key] = next;
|
|
947
|
-
require_worktreeOperations.writeJsonAtomic(file, {
|
|
1126
|
+
await require_worktreeOperations.writeJsonAtomic(file, {
|
|
948
1127
|
version: 1,
|
|
949
1128
|
workspaces
|
|
950
1129
|
});
|
|
951
|
-
|
|
1130
|
+
await node_fs_promises.default.chmod(file, OWNER_ONLY_FILE);
|
|
952
1131
|
return publicView(next);
|
|
953
1132
|
}
|
|
954
1133
|
};
|
|
@@ -1194,9 +1373,9 @@ var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)({
|
|
|
1194
1373
|
if (request.method !== "GET" && request.method !== "PUT") return Response.json({ error: "Use GET or PUT." }, { status: 405 });
|
|
1195
1374
|
const root = rootOf(url);
|
|
1196
1375
|
if (root instanceof Response) return root;
|
|
1197
|
-
if (request.method === "GET") return Response.json(gitAuth.view(root));
|
|
1376
|
+
if (request.method === "GET") return Response.json(await gitAuth.view(root));
|
|
1198
1377
|
try {
|
|
1199
|
-
return Response.json(gitAuth.save(root, await request.json().catch(() => void 0)));
|
|
1378
|
+
return Response.json(await gitAuth.save(root, await request.json().catch(() => void 0)));
|
|
1200
1379
|
} catch (error) {
|
|
1201
1380
|
if (error instanceof require_worktreeOperations.PoGitExpectedError && error.code === "invalid_request") {
|
|
1202
1381
|
const text = error.message.replace(/^\[[a-z_]+\] /u, "").replace("\nRecovery: ", " ");
|
|
@@ -1220,7 +1399,7 @@ var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)({
|
|
|
1220
1399
|
if (request.method !== "GET") return Response.json({ error: "Use GET." }, { status: 405 });
|
|
1221
1400
|
let recordedBaseRef;
|
|
1222
1401
|
try {
|
|
1223
|
-
recordedBaseRef = require_worktreeOperations.createWorktreeRegistry(require_worktreeOperations.registryFile(cwd, homeDir)).list().find((record) => record.sessionId === context.sessionId)?.baseRef;
|
|
1402
|
+
recordedBaseRef = (await require_worktreeOperations.createWorktreeRegistry(await require_worktreeOperations.registryFile(cwd, homeDir)).list()).find((record) => record.sessionId === context.sessionId)?.baseRef;
|
|
1224
1403
|
} catch {
|
|
1225
1404
|
recordedBaseRef = void 0;
|
|
1226
1405
|
}
|
|
@@ -1420,7 +1599,7 @@ async function rebasing(root) {
|
|
|
1420
1599
|
"--git-path",
|
|
1421
1600
|
name
|
|
1422
1601
|
]);
|
|
1423
|
-
if (gitPath !== void 0 &&
|
|
1602
|
+
if (gitPath !== void 0 && await node_fs_promises.default.access(node_path.default.resolve(root, gitPath)).then(() => true, () => false)) return true;
|
|
1424
1603
|
}
|
|
1425
1604
|
return false;
|
|
1426
1605
|
}
|
|
@@ -1590,9 +1769,9 @@ const GIT_CHANGES_TYPE = "git_changes";
|
|
|
1590
1769
|
* DESIGN PATTERNS:
|
|
1591
1770
|
* - Apart from the worktrees channel. Worktrees are repository management;
|
|
1592
1771
|
* this is the session's own code change.
|
|
1593
|
-
* - Push, not poll. The session
|
|
1594
|
-
* tool call and settled turn; recounts are coalesced to one in
|
|
1595
|
-
* one rerun, so a burst of tool calls costs at most two.
|
|
1772
|
+
* - Push, not poll. The session's server plugin publishes a "changed" event
|
|
1773
|
+
* after every tool call and settled turn; recounts are coalesced to one in
|
|
1774
|
+
* flight plus one rerun, so a burst of tool calls costs at most two.
|
|
1596
1775
|
* - One sync command per session. A rebase and a push must never overlap.
|
|
1597
1776
|
* - Auth is read fresh for each command from the session's workspace, and goes
|
|
1598
1777
|
* only into that command's git child.
|
|
@@ -1653,9 +1832,9 @@ function createGitChangesChannel(options = {}) {
|
|
|
1653
1832
|
const rerun = /* @__PURE__ */ new Set();
|
|
1654
1833
|
const busy = /* @__PURE__ */ new Set();
|
|
1655
1834
|
/** The base the session's own worktree was created from, when it has one. */
|
|
1656
|
-
const recordedBaseRef = (scope) => {
|
|
1835
|
+
const recordedBaseRef = async (scope) => {
|
|
1657
1836
|
try {
|
|
1658
|
-
return require_worktreeOperations.createWorktreeRegistry(require_worktreeOperations.registryFile(scope.cwd, homeDir)).list().find((record) => record.sessionId === scope.sessionId)?.baseRef;
|
|
1837
|
+
return (await require_worktreeOperations.createWorktreeRegistry(await require_worktreeOperations.registryFile(scope.cwd, homeDir)).list()).find((record) => record.sessionId === scope.sessionId)?.baseRef;
|
|
1659
1838
|
} catch {
|
|
1660
1839
|
return;
|
|
1661
1840
|
}
|
|
@@ -1688,8 +1867,7 @@ function createGitChangesChannel(options = {}) {
|
|
|
1688
1867
|
return;
|
|
1689
1868
|
}
|
|
1690
1869
|
inFlight.add(sessionId);
|
|
1691
|
-
|
|
1692
|
-
diff.review(scope.cwd, base === void 0 ? {} : { recordedBaseRef: base }).then((review) => {
|
|
1870
|
+
recordedBaseRef(scope).then((base) => diff.review(scope.cwd, base === void 0 ? {} : { recordedBaseRef: base })).then((review) => {
|
|
1693
1871
|
if (scopes.has(sessionId)) update(sessionId, { changes: review?.changes });
|
|
1694
1872
|
}).catch((error) => {
|
|
1695
1873
|
host.onNotice(`git diff refresh failed for ${sessionId} (${error instanceof Error ? error.name : "unknown"})`);
|
|
@@ -1698,12 +1876,12 @@ function createGitChangesChannel(options = {}) {
|
|
|
1698
1876
|
if (rerun.delete(sessionId)) refresh(sessionId);
|
|
1699
1877
|
});
|
|
1700
1878
|
};
|
|
1701
|
-
const run = (scope, command) => {
|
|
1879
|
+
const run = async (scope, command) => {
|
|
1702
1880
|
const workspaceRoot = scope.sessionContext?.workspaceRoot ?? scope.cwd;
|
|
1703
|
-
const base = recordedBaseRef(scope);
|
|
1881
|
+
const base = await recordedBaseRef(scope);
|
|
1704
1882
|
const context = {
|
|
1705
1883
|
cwd: scope.cwd,
|
|
1706
|
-
auth: auth.read(workspaceRoot),
|
|
1884
|
+
auth: await auth.read(workspaceRoot),
|
|
1707
1885
|
...base === void 0 ? {} : { recordedBaseRef: base }
|
|
1708
1886
|
};
|
|
1709
1887
|
if (command.action === "pull") return sync.pull(context);
|
|
@@ -1801,9 +1979,9 @@ function payloadOf(state) {
|
|
|
1801
1979
|
};
|
|
1802
1980
|
}
|
|
1803
1981
|
/** Worktrees visible to this session, using the hub's live session table for ownership. */
|
|
1804
|
-
function viewsFor(scope, deps) {
|
|
1982
|
+
async function viewsFor(scope, deps) {
|
|
1805
1983
|
try {
|
|
1806
|
-
return require_worktreeOperations.createWorktreeRegistry(require_worktreeOperations.registryFile(scope.cwd, deps.homeDir)).list().flatMap((record) => {
|
|
1984
|
+
return (await require_worktreeOperations.createWorktreeRegistry(await require_worktreeOperations.registryFile(scope.cwd, deps.homeDir)).list()).flatMap((record) => {
|
|
1807
1985
|
if (record.parentSessionId === void 0 && record.sessionId !== scope.sessionId) return [];
|
|
1808
1986
|
const owned = record.parentSessionId === void 0 || record.parentSessionId === scope.sessionId;
|
|
1809
1987
|
const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId);
|
|
@@ -1828,11 +2006,15 @@ function sameList(left, right) {
|
|
|
1828
2006
|
return other !== void 0 && entry.id === other.id && entry.branch === other.branch && entry.sessionId === other.sessionId && entry.orphaned === other.orphaned && entry.unowned === other.unowned;
|
|
1829
2007
|
});
|
|
1830
2008
|
}
|
|
1831
|
-
function errorTargetFor(command) {
|
|
1832
|
-
|
|
2009
|
+
function errorTargetFor(command, error) {
|
|
2010
|
+
if (command.action === "close") return {
|
|
1833
2011
|
action: "close",
|
|
1834
2012
|
id: command.id
|
|
1835
2013
|
};
|
|
2014
|
+
return error instanceof require_worktreeOperations.PoGitExpectedError && error.code === "rift_missing" ? {
|
|
2015
|
+
action: "create",
|
|
2016
|
+
riftMissing: true
|
|
2017
|
+
} : { action: "create" };
|
|
1836
2018
|
}
|
|
1837
2019
|
/** A command the page sent, or undefined when the frame was not one. */
|
|
1838
2020
|
function parseCommand(payload) {
|
|
@@ -1860,11 +2042,15 @@ function parseCommand(payload) {
|
|
|
1860
2042
|
/**
|
|
1861
2043
|
* What the reader is told when a command fails.
|
|
1862
2044
|
*
|
|
1863
|
-
* An expected failure explains itself
|
|
1864
|
-
*
|
|
2045
|
+
* An expected failure explains itself, minus the `[code]` tag and recovery line
|
|
2046
|
+
* written for the agent's tool result. A dirty close is said in the person's
|
|
2047
|
+
* terms, because its message tells the agent to pass `force`. Anything else is
|
|
2048
|
+
* summarised, never echoed: a git error can carry a remote URL with a token in it.
|
|
1865
2049
|
*/
|
|
1866
2050
|
function failureText(error) {
|
|
1867
|
-
|
|
2051
|
+
if (!(error instanceof require_worktreeOperations.PoGitExpectedError)) return "The worktree operation failed.";
|
|
2052
|
+
if (error.code === "worktree_dirty") return "The worktree has uncommitted changes.";
|
|
2053
|
+
return error.message.replace(/^\[[a-z_]+\] /u, "").split("\nRecovery:")[0] ?? error.message;
|
|
1868
2054
|
}
|
|
1869
2055
|
/** Starts one direct-event subscription per managed session. */
|
|
1870
2056
|
function createWorktreesChannel(options = {}) {
|
|
@@ -1917,10 +2103,13 @@ function createWorktreesChannel(options = {}) {
|
|
|
1917
2103
|
return generation;
|
|
1918
2104
|
};
|
|
1919
2105
|
/** Republishes a session, skipping a frame that would say nothing new. */
|
|
1920
|
-
const publish = (scope, force) => {
|
|
2106
|
+
const publish = async (scope, force) => {
|
|
2107
|
+
const generation = generations.get(scope.sessionId);
|
|
2108
|
+
const worktreeViews = await viewsFor(scope, views);
|
|
2109
|
+
if (generation === void 0 || generations.get(scope.sessionId) !== generation) return;
|
|
1921
2110
|
const previous = latest.get(scope.sessionId);
|
|
1922
2111
|
const next = {
|
|
1923
|
-
worktrees:
|
|
2112
|
+
worktrees: worktreeViews,
|
|
1924
2113
|
pending: previous?.pending,
|
|
1925
2114
|
error: previous?.error,
|
|
1926
2115
|
errorTarget: previous?.errorTarget
|
|
@@ -1932,7 +2121,7 @@ function createWorktreesChannel(options = {}) {
|
|
|
1932
2121
|
const mark = (scope, pending, error, errorTarget) => {
|
|
1933
2122
|
const previous = latest.get(scope.sessionId);
|
|
1934
2123
|
latest.set(scope.sessionId, {
|
|
1935
|
-
worktrees: previous?.worktrees ??
|
|
2124
|
+
worktrees: previous?.worktrees ?? [],
|
|
1936
2125
|
pending,
|
|
1937
2126
|
error,
|
|
1938
2127
|
errorTarget
|
|
@@ -1972,15 +2161,15 @@ function createWorktreesChannel(options = {}) {
|
|
|
1972
2161
|
sessionAdded(scope) {
|
|
1973
2162
|
newGeneration(scope.sessionId);
|
|
1974
2163
|
publish(scope, false);
|
|
1975
|
-
const unsubscribe = host.directEvents.subscribe(require_worktreeOperations.GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {
|
|
2164
|
+
const unsubscribe = host.directEvents.subscribe(require_worktreeOperations.GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, async (payload) => {
|
|
1976
2165
|
if (!require_worktreeOperations.isWorktreeLifecycleEvent(payload)) return;
|
|
1977
2166
|
let sameRepository = false;
|
|
1978
2167
|
try {
|
|
1979
|
-
sameRepository = require_worktreeOperations.registryFile(scope.cwd, options.homeDir) === require_worktreeOperations.registryFile(payload.repositoryRoot, options.homeDir);
|
|
2168
|
+
sameRepository = await require_worktreeOperations.registryFile(scope.cwd, options.homeDir) === await require_worktreeOperations.registryFile(payload.repositoryRoot, options.homeDir);
|
|
1980
2169
|
} catch {
|
|
1981
2170
|
sameRepository = false;
|
|
1982
2171
|
}
|
|
1983
|
-
if (sameRepository) publish(scope, false);
|
|
2172
|
+
if (sameRepository) await publish(scope, false);
|
|
1984
2173
|
});
|
|
1985
2174
|
subscriptions.set(scope.sessionId, unsubscribe);
|
|
1986
2175
|
},
|
|
@@ -2013,7 +2202,7 @@ function createWorktreesChannel(options = {}) {
|
|
|
2013
2202
|
}).catch((error) => {
|
|
2014
2203
|
if (generations.get(scope.sessionId) !== generation) return;
|
|
2015
2204
|
host.onNotice(`worktree command failed for ${scope.sessionId} (${failureText(error)})`);
|
|
2016
|
-
mark(scope, void 0, failureText(error), errorTargetFor(command));
|
|
2205
|
+
mark(scope, void 0, failureText(error), errorTargetFor(command, error));
|
|
2017
2206
|
}).finally(() => {
|
|
2018
2207
|
if (generations.get(scope.sessionId) === generation) busy.delete(scope.sessionId);
|
|
2019
2208
|
});
|
|
@@ -2035,20 +2224,8 @@ var agent_settled_server_default = (0, _agimon_ai_po_core_extensionFile.defineHo
|
|
|
2035
2224
|
//#region src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts
|
|
2036
2225
|
var tool_execution_end_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)((context) => context.root.hooks[0]);
|
|
2037
2226
|
//#endregion
|
|
2038
|
-
//#region src/extensions/workspaces/sessions/(backend)/resource/_lib/poGit.server.ts
|
|
2039
|
-
var poGit_server_default$1 = (context) => context.root.resources[0];
|
|
2040
|
-
//#endregion
|
|
2041
|
-
//#region src/extensions/workspaces/sessions/(backend)/resource/poGit.server.ts
|
|
2042
|
-
var poGit_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)(poGit_server_default$1);
|
|
2043
|
-
//#endregion
|
|
2044
|
-
//#region src/extensions/workspaces/sessions/(backend)/resource/_lib/poGitReadme.server.ts
|
|
2045
|
-
var poGitReadme_server_default$1 = (context) => context.root.resources[2];
|
|
2046
|
-
//#endregion
|
|
2047
|
-
//#region src/extensions/workspaces/sessions/(backend)/resource/poGitReadme.server.ts
|
|
2048
|
-
var poGitReadme_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)(poGitReadme_server_default$1);
|
|
2049
|
-
//#endregion
|
|
2050
2227
|
//#region src/extensions/workspaces/sessions/(backend)/resource/_lib/poUseGit.server.ts
|
|
2051
|
-
var poUseGit_server_default$1 = (context) => context.root.resources[
|
|
2228
|
+
var poUseGit_server_default$1 = (context) => context.root.resources[0];
|
|
2052
2229
|
//#endregion
|
|
2053
2230
|
//#region src/extensions/workspaces/sessions/(backend)/resource/poUseGit.server.ts
|
|
2054
2231
|
var poUseGit_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)(poUseGit_server_default$1);
|
|
@@ -2058,19 +2235,22 @@ var runWorktree_server_default = (0, _agimon_ai_po_core_extensionFile.defineServ
|
|
|
2058
2235
|
//#endregion
|
|
2059
2236
|
//#region generated/server.ts
|
|
2060
2237
|
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
2238
|
+
/* v8 ignore next -- generated normalization branch */
|
|
2239
|
+
const defined = (values) => values.filter((value) => value !== void 0);
|
|
2061
2240
|
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
2062
2241
|
...identity,
|
|
2063
2242
|
...value
|
|
2064
2243
|
};
|
|
2065
|
-
const
|
|
2244
|
+
const serverPlugin = (0, _agimon_ai_po_core_serverPlugin.defineServerPlugin)({
|
|
2066
2245
|
name: "@agimon-ai/po-git",
|
|
2067
|
-
providerOverrides: (0,
|
|
2246
|
+
providerOverrides: (0, _agimon_ai_po_core_serverPlugin.composeServerProviderOverrides)(root_server_default),
|
|
2247
|
+
injects: (0, _agimon_ai_po_core_extensionFile.composeRootInjects)({ session: [root_server_default] }),
|
|
2068
2248
|
global: (context) => ({
|
|
2069
2249
|
get api() {
|
|
2070
2250
|
return [at(route_server_default, context)];
|
|
2071
2251
|
},
|
|
2072
2252
|
get channels() {
|
|
2073
|
-
return [() => via({ frameType: "git_changes" }, git_changes_server_default
|
|
2253
|
+
return [() => via({ frameType: "git_changes" }, at(git_changes_server_default, context)), () => via({ frameType: "git_worktrees" }, at(git_worktrees_server_default, context))];
|
|
2074
2254
|
}
|
|
2075
2255
|
}),
|
|
2076
2256
|
workspace: (context) => ({
|
|
@@ -2078,11 +2258,11 @@ const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
|
|
|
2078
2258
|
return [at(route_server_default, context)];
|
|
2079
2259
|
},
|
|
2080
2260
|
get channels() {
|
|
2081
|
-
return [() => via({ frameType: "git_changes" }, git_changes_server_default
|
|
2261
|
+
return defined([context.hosted("global") ? void 0 : () => via({ frameType: "git_changes" }, at(git_changes_server_default, context)), context.hosted("global") ? void 0 : () => via({ frameType: "git_worktrees" }, at(git_worktrees_server_default, context))]);
|
|
2082
2262
|
}
|
|
2083
2263
|
}),
|
|
2084
2264
|
session: async (context) => {
|
|
2085
|
-
const scopeSession = await root_server_default
|
|
2265
|
+
const scopeSession = await context.scopeRoot("session", root_server_default, context);
|
|
2086
2266
|
const contextSession = {
|
|
2087
2267
|
...context,
|
|
2088
2268
|
root: scopeSession.value
|
|
@@ -2093,17 +2273,13 @@ const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
|
|
|
2093
2273
|
return [at(route_server_default, context)];
|
|
2094
2274
|
},
|
|
2095
2275
|
get channels() {
|
|
2096
|
-
return [() => via({ frameType: "git_changes" }, git_changes_server_default
|
|
2276
|
+
return defined([context.hosted("global") ? void 0 : () => via({ frameType: "git_changes" }, at(git_changes_server_default, context)), context.hosted("global") ? void 0 : () => via({ frameType: "git_worktrees" }, at(git_worktrees_server_default, context))]);
|
|
2097
2277
|
},
|
|
2098
2278
|
get hooks() {
|
|
2099
2279
|
return [via({ event: "agent_settled" }, at(agent_settled_server_default, contextSession)), via({ event: "tool_execution_end" }, at(tool_execution_end_server_default, contextSession))];
|
|
2100
2280
|
},
|
|
2101
2281
|
get resources() {
|
|
2102
|
-
return [
|
|
2103
|
-
at(poGit_server_default, contextSession),
|
|
2104
|
-
at(poGitReadme_server_default, contextSession),
|
|
2105
|
-
at(poUseGit_server_default, contextSession)
|
|
2106
|
-
];
|
|
2282
|
+
return [at(poUseGit_server_default, contextSession)];
|
|
2107
2283
|
},
|
|
2108
2284
|
get tools() {
|
|
2109
2285
|
return [via({ name: "run_worktree" }, at(runWorktree_server_default, contextSession))];
|
|
@@ -2116,7 +2292,7 @@ const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
|
|
|
2116
2292
|
}
|
|
2117
2293
|
});
|
|
2118
2294
|
//#endregion
|
|
2119
|
-
exports.default =
|
|
2120
|
-
exports.
|
|
2295
|
+
exports.default = serverPlugin;
|
|
2296
|
+
exports.serverPlugin = serverPlugin;
|
|
2121
2297
|
|
|
2122
2298
|
//# sourceMappingURL=server.cjs.map
|