opencode2-cow-worktree 0.1.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.
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/package.json +44 -0
- package/src/capability.ts +140 -0
- package/src/clone.ts +126 -0
- package/src/config.ts +92 -0
- package/src/device.ts +98 -0
- package/src/dirty.ts +54 -0
- package/src/entry-kind.ts +36 -0
- package/src/hooks.ts +216 -0
- package/src/index.ts +1 -0
- package/src/mechanism.ts +9 -0
- package/src/platform-darwin-ffi.ts +142 -0
- package/src/platform-darwin.ts +104 -0
- package/src/platform.ts +71 -0
- package/src/plugin.ts +249 -0
- package/src/removal.ts +306 -0
- package/src/strategy.ts +125 -0
- package/src/tool.ts +482 -0
- package/src/uncommitted.ts +84 -0
- package/strategy-badge.ts +28 -0
- package/tui.tsx +47 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The badge decision for a worktree inventory, kept a pure function so it can
|
|
3
|
+
* be tested without a TUI or a live server.
|
|
4
|
+
*
|
|
5
|
+
* Returns the literal `"cow"` when the inventory records `directory` — under
|
|
6
|
+
* the same directory-identity rule the tool's attach flow applies, basename
|
|
7
|
+
* narrowing then exact match then realpath with lexical fallback — with the
|
|
8
|
+
* `cow` strategy id. Everything else — no match, an empty inventory, a `git`
|
|
9
|
+
* entry, an entry with no strategy — yields `undefined`, which the caller
|
|
10
|
+
* renders as nothing.
|
|
11
|
+
*
|
|
12
|
+
* The shared matcher (`inventoryEntryFor` in `src/tool.ts`) is the point: the
|
|
13
|
+
* inventory may record the same directory through a different spelling (a
|
|
14
|
+
* symlinked ancestor, a `..` segment), and an exact-string badge would go dark
|
|
15
|
+
* for a location the tool happily attaches to. The row type is the upstream
|
|
16
|
+
* `WorktreeInventoryEntry` rather than a local lookalike, so a schema change
|
|
17
|
+
* surfaces here at compile time.
|
|
18
|
+
*/
|
|
19
|
+
import { inventoryEntryFor } from "./src/tool";
|
|
20
|
+
import type { WorktreeInventoryEntry } from "./types/opencode2-worktree";
|
|
21
|
+
|
|
22
|
+
export async function strategyBadge(
|
|
23
|
+
entries: readonly WorktreeInventoryEntry[],
|
|
24
|
+
directory: string,
|
|
25
|
+
): Promise<"cow" | undefined> {
|
|
26
|
+
const match = await inventoryEntryFor(entries, directory);
|
|
27
|
+
return match?.strategy === "cow" ? "cow" : undefined;
|
|
28
|
+
}
|
package/tui.tsx
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Plugin } from "@opencode/plugin/tui";
|
|
2
|
+
import type { PluginContext } from "@opencode/plugin/tui";
|
|
3
|
+
import { strategyBadge } from "./strategy-badge";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `cow` sidebar badge.
|
|
7
|
+
*
|
|
8
|
+
* opencode2's TUI runtime loads this module and provides `@opencode/plugin/tui`
|
|
9
|
+
* and `solid-js` by specifier rewrite — they are not installable dependencies.
|
|
10
|
+
*
|
|
11
|
+
* The value is resolved BEFORE the slot is registered, so the render is a plain
|
|
12
|
+
* constant read. A slot claim is rendered through opencode2's `provide()`,
|
|
13
|
+
* which calls the render function once, untracked and outside any reactive
|
|
14
|
+
* owner: a signal or `<Show>` read inside that render is captured at its
|
|
15
|
+
* initial value and never updates. Resolving first and registering after avoids
|
|
16
|
+
* reactivity in the render entirely.
|
|
17
|
+
*
|
|
18
|
+
* The trade-off: the badge reflects the location at load time. A session that
|
|
19
|
+
* moves between the project root and a worktree mid-session will not re-resolve
|
|
20
|
+
* until the plugin reloads. That is the price of a render that cannot update,
|
|
21
|
+
* and it is the correct call for a decoration that must never break the footer.
|
|
22
|
+
*/
|
|
23
|
+
export default Plugin.define({
|
|
24
|
+
id: "opencode2-cow-worktree-tui",
|
|
25
|
+
async setup(context) {
|
|
26
|
+
const isCow = await resolveIsCow(context).catch(() => false);
|
|
27
|
+
context.ui.slot({
|
|
28
|
+
append: "sidebar.footer",
|
|
29
|
+
render: () => (isCow ? <Badge context={context} /> : null),
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
async function resolveIsCow(context: PluginContext): Promise<boolean> {
|
|
35
|
+
const directory = context.location?.directory;
|
|
36
|
+
if (!directory) return false;
|
|
37
|
+
const entries = await context.client.worktree.list({ location: { directory } });
|
|
38
|
+
return (await strategyBadge(entries, directory)) === "cow";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function Badge(props: { readonly context: PluginContext }) {
|
|
42
|
+
return (
|
|
43
|
+
<box flexShrink={0}>
|
|
44
|
+
<text fg={props.context.theme.text.subdued}> cow</text>
|
|
45
|
+
</box>
|
|
46
|
+
);
|
|
47
|
+
}
|