@zenobius/pi-worktrees 0.1.0 → 0.2.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.
@@ -0,0 +1,62 @@
1
+ import { PiWorktreeConfig, WorktreeSettingsConfig } from './schema.ts';
2
+ export declare function createPiWorktreeConfigService(): Promise<{
3
+ worktrees: Map<string, {
4
+ parentDir?: string | undefined;
5
+ onCreate?: string | string[] | undefined;
6
+ worktreeRoot?: string | undefined;
7
+ }>;
8
+ current: (ctx: {
9
+ cwd: string;
10
+ }) => {
11
+ repo: string | null;
12
+ project: string;
13
+ mainWorktree: string;
14
+ parentDir: string;
15
+ logfile: string;
16
+ matchedPattern: string | null;
17
+ onCreate?: string | string[] | undefined;
18
+ worktreeRoot?: string | undefined;
19
+ };
20
+ save: (data: PiWorktreeConfig) => Promise<void>;
21
+ config: {
22
+ worktrees?: import("typebox").StaticRecord<[], "Encode", {}, {
23
+ worktrees: import("typebox").TOptional<import("typebox").TRecord<"^.*$", import("typebox").TObject<{
24
+ worktreeRoot: import("typebox").TOptional<import("typebox").TString>;
25
+ parentDir: import("typebox").TOptional<import("typebox").TString>;
26
+ onCreate: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TArray<import("typebox").TString>]>>;
27
+ }>>>;
28
+ matchingStrategy: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TLiteral<"fail-on-tie">, import("typebox").TLiteral<"first-wins">, import("typebox").TLiteral<"last-wins">]>>;
29
+ logfile: import("typebox").TOptional<import("typebox").TString>;
30
+ }, "^.*$", import("typebox").TObject<{
31
+ worktreeRoot: import("typebox").TOptional<import("typebox").TString>;
32
+ parentDir: import("typebox").TOptional<import("typebox").TString>;
33
+ onCreate: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TArray<import("typebox").TString>]>>;
34
+ }>> | undefined;
35
+ logfile?: string | undefined;
36
+ matchingStrategy?: "fail-on-tie" | "first-wins" | "last-wins" | undefined;
37
+ };
38
+ ready: Promise<void>;
39
+ set(key: string, value: unknown, target?: "home" | "project"): Promise<void>;
40
+ reload(): Promise<void>;
41
+ events: import("@zenobius/pi-extension-config").ConfigEventEmitter<{
42
+ worktrees?: import("typebox").StaticRecord<[], "Encode", {}, {
43
+ worktrees: import("typebox").TOptional<import("typebox").TRecord<"^.*$", import("typebox").TObject<{
44
+ worktreeRoot: import("typebox").TOptional<import("typebox").TString>;
45
+ parentDir: import("typebox").TOptional<import("typebox").TString>;
46
+ onCreate: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TArray<import("typebox").TString>]>>;
47
+ }>>>;
48
+ matchingStrategy: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TLiteral<"fail-on-tie">, import("typebox").TLiteral<"first-wins">, import("typebox").TLiteral<"last-wins">]>>;
49
+ logfile: import("typebox").TOptional<import("typebox").TString>;
50
+ }, "^.*$", import("typebox").TObject<{
51
+ worktreeRoot: import("typebox").TOptional<import("typebox").TString>;
52
+ parentDir: import("typebox").TOptional<import("typebox").TString>;
53
+ onCreate: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TArray<import("typebox").TString>]>>;
54
+ }>> | undefined;
55
+ logfile?: string | undefined;
56
+ matchingStrategy?: "fail-on-tie" | "first-wins" | "last-wins" | undefined;
57
+ }>;
58
+ }>;
59
+ export declare const DefaultWorktreeSettings: WorktreeSettingsConfig;
60
+ export declare const DefaultLogfileTemplate = "/tmp/pi-worktree-{sessionId}-{name}.log";
61
+ export type PiWorktreeConfigService = Awaited<ReturnType<typeof createPiWorktreeConfigService>>;
62
+ export type PiWorktreeConfiguredWorktreeMap = PiWorktreeConfigService['worktrees'];
@@ -0,0 +1,2 @@
1
+ import { type Migration } from '@zenobius/pi-extension-config';
2
+ export declare const migration: Migration;
@@ -0,0 +1,2 @@
1
+ import { type Migration } from '@zenobius/pi-extension-config';
2
+ export declare const migration: Migration;
@@ -0,0 +1,2 @@
1
+ import { type Migration } from '@zenobius/pi-extension-config';
2
+ export declare const migration: Migration;
@@ -0,0 +1,25 @@
1
+ import { Static } from 'typebox';
2
+ declare const WorktreeSettingsSchema: import("typebox").TObject<{
3
+ worktreeRoot: import("typebox").TOptional<import("typebox").TString>;
4
+ parentDir: import("typebox").TOptional<import("typebox").TString>;
5
+ onCreate: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TArray<import("typebox").TString>]>>;
6
+ }>;
7
+ declare const MatchingStrategySchema: import("typebox").TUnion<[import("typebox").TLiteral<"fail-on-tie">, import("typebox").TLiteral<"first-wins">, import("typebox").TLiteral<"last-wins">]>;
8
+ declare const MatchStrategyResultSchema: import("typebox").TUnion<[import("typebox").TLiteral<"exact">, import("typebox").TLiteral<"unmatched">]>;
9
+ export declare const PiWorktreeConfigSchema: import("typebox").TObject<{
10
+ worktrees: import("typebox").TOptional<import("typebox").TRecord<"^.*$", import("typebox").TObject<{
11
+ worktreeRoot: import("typebox").TOptional<import("typebox").TString>;
12
+ parentDir: import("typebox").TOptional<import("typebox").TString>;
13
+ onCreate: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TArray<import("typebox").TString>]>>;
14
+ }>>>;
15
+ matchingStrategy: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TLiteral<"fail-on-tie">, import("typebox").TLiteral<"first-wins">, import("typebox").TLiteral<"last-wins">]>>;
16
+ logfile: import("typebox").TOptional<import("typebox").TString>;
17
+ }>;
18
+ export type WorktreeSettingsConfig = Static<typeof WorktreeSettingsSchema>;
19
+ export type MatchingStrategy = Static<typeof MatchingStrategySchema>;
20
+ export type MatchingStrategyResult = Static<typeof MatchStrategyResultSchema>;
21
+ export type PiWorktreeConfig = Static<typeof PiWorktreeConfigSchema>;
22
+ export type PiWorktreeRecord = NonNullable<PiWorktreeConfig['worktrees']>;
23
+ export type PiWorktreeLogTemplate = NonNullable<PiWorktreeConfig['logfile']>;
24
+ export declare function getConfiguredWorktreeRoot(settings: WorktreeSettingsConfig): string | undefined;
25
+ export {};
@@ -0,0 +1,83 @@
1
+ import { MatchingStrategy, WorktreeSettingsConfig } from './config/schema.ts';
2
+ import { PiWorktreeConfiguredWorktreeMap } from './config/config.ts';
3
+ export interface WorktreeInfo {
4
+ path: string;
5
+ branch: string;
6
+ head: string;
7
+ isMain: boolean;
8
+ isCurrent: boolean;
9
+ }
10
+ /**
11
+ * Execute a git command and return stdout.
12
+ */
13
+ export declare function git(args: string[], cwd?: string): string;
14
+ /**
15
+ * Get git remote URL for repository.
16
+ */
17
+ export declare function getRemoteUrl(cwd: string, remote?: string): string | null;
18
+ /**
19
+ * Check if we're in a git repository.
20
+ */
21
+ export declare function isGitRepo(cwd: string): boolean;
22
+ /**
23
+ * Get the main worktree path (handles both regular repos and worktrees).
24
+ */
25
+ export declare function getMainWorktreePath(cwd: string): string;
26
+ /**
27
+ * Get the project name from the main worktree path.
28
+ */
29
+ export declare function getProjectName(cwd: string): string;
30
+ /**
31
+ * Check if current directory is a worktree (not the main repo).
32
+ */
33
+ export declare function isWorktree(cwd: string): boolean;
34
+ /**
35
+ * Get current branch name.
36
+ */
37
+ export declare function getCurrentBranch(cwd: string): string;
38
+ /**
39
+ * List all worktrees.
40
+ */
41
+ export declare function listWorktrees(cwd: string): WorktreeInfo[];
42
+ /**
43
+ * Check if a target path is inside the repository root.
44
+ */
45
+ export declare function isPathInsideRepo(repoPath: string, targetPath: string): boolean;
46
+ /**
47
+ * Resolve the parent directory used for worktrees.
48
+ *
49
+ * Attempts to match to a configured repo, or defaults to using current git repos main worktree
50
+ */
51
+ export declare function getWorktreeParentDir(cwd: string, repos: PiWorktreeConfiguredWorktreeMap, matchStrategy?: MatchingStrategy): string;
52
+ /**
53
+ * Ensure worktree dir is excluded from git tracking when it lives inside repo.
54
+ */
55
+ export declare function ensureExcluded(cwd: string, worktreeParentDir: string): void;
56
+ export interface MatchResult {
57
+ settings: WorktreeSettingsConfig;
58
+ matchedPattern: string | null;
59
+ }
60
+ export interface TieConflictError {
61
+ patterns: string[];
62
+ url: string;
63
+ message: string;
64
+ }
65
+ export interface ScoredMatch {
66
+ pattern: string;
67
+ normalizedPattern: string;
68
+ specificity: number;
69
+ }
70
+ export type Result = ({
71
+ type: 'exact';
72
+ } & MatchResult) | ({
73
+ type: 'no-match';
74
+ } & MatchResult) | ({
75
+ type: 'default';
76
+ } & MatchResult) | ({
77
+ type: 'tie-conflict';
78
+ } & TieConflictError) | ({
79
+ type: 'first-wins';
80
+ } & MatchResult) | ({
81
+ type: 'last-wins';
82
+ } & MatchResult);
83
+ export declare function matchRepo(url: string | null, repos: PiWorktreeConfiguredWorktreeMap, matchStrategy?: MatchingStrategy): Result;
@@ -0,0 +1 @@
1
+ export declare function globMatch(input: string, pattern: string): boolean;
@@ -0,0 +1,8 @@
1
+ export interface TemplateContext {
2
+ path: string;
3
+ name: string;
4
+ branch: string;
5
+ project: string;
6
+ mainWorktree: string;
7
+ }
8
+ export declare function expandTemplate(template: string, ctx: TemplateContext): string;
@@ -0,0 +1,15 @@
1
+ import type { ExtensionCommandContext } from '@mariozechner/pi-coding-agent';
2
+ import type { PiWorktreeConfigService } from './services/config/config.ts';
3
+ import { WorktreeSettingsConfig } from './services/config/schema.ts';
4
+ export interface WorktreeCreatedContext {
5
+ path: string;
6
+ name: string;
7
+ branch: string;
8
+ project: string;
9
+ mainWorktree: string;
10
+ }
11
+ export interface CommandDeps {
12
+ settings: WorktreeSettingsConfig;
13
+ configService: PiWorktreeConfigService;
14
+ }
15
+ export type CmdHandler = (...args: [string, ExtensionCommandContext, CommandDeps]) => Promise<void>;
@@ -0,0 +1,21 @@
1
+ import type { Theme } from '@mariozechner/pi-coding-agent';
2
+ export interface TemplateToken {
3
+ token: string;
4
+ value: string;
5
+ source: string;
6
+ }
7
+ type TemplatePreviewTheme = Pick<Theme, 'fg' | 'bold'>;
8
+ interface TemplatePreviewInput {
9
+ cwd: string;
10
+ currentBranch: string;
11
+ parentDirTemplate: string;
12
+ parentDirPreview: string;
13
+ sampleFeatureName: string;
14
+ tokens: TemplateToken[];
15
+ }
16
+ export declare function createTemplatePreviewComponent(input: TemplatePreviewInput, theme: TemplatePreviewTheme, done: () => void): {
17
+ render: (width: number) => string[];
18
+ invalidate: () => void;
19
+ handleInput: (data: string) => void;
20
+ };
21
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenobius/pi-worktrees",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Worktrees extension for Pi Coding Agent",
5
5
  "author": {
6
6
  "name": "Zenobius",
@@ -28,14 +28,19 @@
28
28
  "dist",
29
29
  "README.md"
30
30
  ],
31
+ "pi": {
32
+ "extensions": [
33
+ "./dist/index.js"
34
+ ]
35
+ },
31
36
  "dependencies": {
32
37
  "@mariozechner/pi-coding-agent": "~0.52.9",
33
38
  "@mariozechner/pi-tui": "~0.52.9",
34
- "nconf": "^0.13.0",
39
+ "@zenobius/pi-extension-config": "^0.2.0",
35
40
  "typebox": "^1.0.81"
36
41
  },
37
42
  "devDependencies": {
38
- "@types/nconf": "^0.10.7",
43
+ "@arethetypeswrong/cli": "^0.18.2",
39
44
  "@eslint/js": "^9.39.1",
40
45
  "@types/node": "^20.11.5",
41
46
  "@typescript-eslint/eslint-plugin": "8.47.0",