@ilya-lesikov/pi-pi 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/3p/pi-ask-user/index.ts +1835 -0
- package/3p/pi-ask-user/package.json +50 -0
- package/3p/pi-ask-user/single-select-layout.ts +203 -0
- package/3p/pi-lsp/extensions/lsp/client.ts +542 -0
- package/3p/pi-lsp/extensions/lsp/config.ts +135 -0
- package/3p/pi-lsp/extensions/lsp/effects/command.ts +42 -0
- package/3p/pi-lsp/extensions/lsp/effects/filesystem.ts +50 -0
- package/3p/pi-lsp/extensions/lsp/effects/runtime.ts +21 -0
- package/3p/pi-lsp/extensions/lsp/errors.ts +113 -0
- package/3p/pi-lsp/extensions/lsp/formatting.ts +315 -0
- package/3p/pi-lsp/extensions/lsp/index.ts +231 -0
- package/3p/pi-lsp/extensions/lsp/protocol.ts +209 -0
- package/3p/pi-lsp/extensions/lsp/retry.ts +39 -0
- package/3p/pi-lsp/extensions/lsp/tools/programs.ts +293 -0
- package/3p/pi-lsp/extensions/lsp/tools.ts +89 -0
- package/3p/pi-lsp/extensions/lsp/types.ts +243 -0
- package/3p/pi-lsp/package.json +54 -0
- package/3p/pi-plannotator/AGENTS.md +583 -0
- package/3p/pi-plannotator/apps/pi-extension/README.md +228 -0
- package/3p/pi-plannotator/apps/pi-extension/assistant-message.ts +128 -0
- package/3p/pi-plannotator/apps/pi-extension/config.test.ts +166 -0
- package/3p/pi-plannotator/apps/pi-extension/config.ts +318 -0
- package/3p/pi-plannotator/apps/pi-extension/current-pi-session.ts +147 -0
- package/3p/pi-plannotator/apps/pi-extension/index.ts +1279 -0
- package/3p/pi-plannotator/apps/pi-extension/package.json +56 -0
- package/3p/pi-plannotator/apps/pi-extension/plannotator-browser.test.ts +13 -0
- package/3p/pi-plannotator/apps/pi-extension/plannotator-browser.ts +616 -0
- package/3p/pi-plannotator/apps/pi-extension/plannotator-events.ts +342 -0
- package/3p/pi-plannotator/apps/pi-extension/plannotator.json +12 -0
- package/3p/pi-plannotator/apps/pi-extension/server/agent-jobs.ts +515 -0
- package/3p/pi-plannotator/apps/pi-extension/server/ai-runtime.ts +169 -0
- package/3p/pi-plannotator/apps/pi-extension/server/annotations.ts +85 -0
- package/3p/pi-plannotator/apps/pi-extension/server/external-annotations.ts +189 -0
- package/3p/pi-plannotator/apps/pi-extension/server/handlers.ts +210 -0
- package/3p/pi-plannotator/apps/pi-extension/server/helpers.ts +78 -0
- package/3p/pi-plannotator/apps/pi-extension/server/ide.ts +46 -0
- package/3p/pi-plannotator/apps/pi-extension/server/integrations.ts +195 -0
- package/3p/pi-plannotator/apps/pi-extension/server/network.test.ts +158 -0
- package/3p/pi-plannotator/apps/pi-extension/server/network.ts +268 -0
- package/3p/pi-plannotator/apps/pi-extension/server/pr.ts +126 -0
- package/3p/pi-plannotator/apps/pi-extension/server/project.ts +64 -0
- package/3p/pi-plannotator/apps/pi-extension/server/reference.ts +362 -0
- package/3p/pi-plannotator/apps/pi-extension/server/serverAnnotate.ts +199 -0
- package/3p/pi-plannotator/apps/pi-extension/server/serverPlan.ts +505 -0
- package/3p/pi-plannotator/apps/pi-extension/server/serverReview.ts +1229 -0
- package/3p/pi-plannotator/apps/pi-extension/server/vcs.ts +121 -0
- package/3p/pi-plannotator/apps/pi-extension/server.test.ts +966 -0
- package/3p/pi-plannotator/apps/pi-extension/server.ts +44 -0
- package/3p/pi-plannotator/apps/pi-extension/tool-scope.test.ts +88 -0
- package/3p/pi-plannotator/apps/pi-extension/tool-scope.ts +39 -0
- package/3p/pi-plannotator/apps/pi-extension/tsconfig.json +16 -0
- package/3p/pi-plannotator/apps/pi-extension/vendor.sh +48 -0
- package/3p/pi-plannotator/package.json +53 -0
- package/3p/pi-plannotator/packages/ai/ai.test.ts +1407 -0
- package/3p/pi-plannotator/packages/ai/base-session.ts +94 -0
- package/3p/pi-plannotator/packages/ai/context.ts +250 -0
- package/3p/pi-plannotator/packages/ai/endpoints.ts +326 -0
- package/3p/pi-plannotator/packages/ai/index.ts +105 -0
- package/3p/pi-plannotator/packages/ai/package.json +21 -0
- package/3p/pi-plannotator/packages/ai/provider.ts +103 -0
- package/3p/pi-plannotator/packages/ai/providers/claude-agent-sdk.ts +447 -0
- package/3p/pi-plannotator/packages/ai/providers/codex-sdk.ts +430 -0
- package/3p/pi-plannotator/packages/ai/providers/command-path.ts +115 -0
- package/3p/pi-plannotator/packages/ai/providers/opencode-sdk.ts +546 -0
- package/3p/pi-plannotator/packages/ai/providers/pi-events.ts +110 -0
- package/3p/pi-plannotator/packages/ai/providers/pi-sdk-node.ts +425 -0
- package/3p/pi-plannotator/packages/ai/providers/pi-sdk.ts +469 -0
- package/3p/pi-plannotator/packages/ai/session-manager.ts +195 -0
- package/3p/pi-plannotator/packages/ai/tsconfig.json +15 -0
- package/3p/pi-plannotator/packages/ai/types.ts +379 -0
- package/3p/pi-plannotator/packages/server/agent-jobs.ts +538 -0
- package/3p/pi-plannotator/packages/server/agent-review-message.test.ts +135 -0
- package/3p/pi-plannotator/packages/server/agent-review-message.ts +243 -0
- package/3p/pi-plannotator/packages/server/ai-runtime.ts +108 -0
- package/3p/pi-plannotator/packages/server/annotate.ts +401 -0
- package/3p/pi-plannotator/packages/server/browser.test.ts +87 -0
- package/3p/pi-plannotator/packages/server/browser.ts +245 -0
- package/3p/pi-plannotator/packages/server/claude-review.ts +352 -0
- package/3p/pi-plannotator/packages/server/code-nav.ts +73 -0
- package/3p/pi-plannotator/packages/server/codex-review-schema.json +41 -0
- package/3p/pi-plannotator/packages/server/codex-review.ts +330 -0
- package/3p/pi-plannotator/packages/server/config.ts +8 -0
- package/3p/pi-plannotator/packages/server/draft.ts +1 -0
- package/3p/pi-plannotator/packages/server/editor-annotations.ts +76 -0
- package/3p/pi-plannotator/packages/server/external-annotations.test.ts +18 -0
- package/3p/pi-plannotator/packages/server/external-annotations.ts +207 -0
- package/3p/pi-plannotator/packages/server/git.ts +141 -0
- package/3p/pi-plannotator/packages/server/goal-setup.test.ts +55 -0
- package/3p/pi-plannotator/packages/server/goal-setup.ts +248 -0
- package/3p/pi-plannotator/packages/server/ide.ts +43 -0
- package/3p/pi-plannotator/packages/server/image.test.ts +63 -0
- package/3p/pi-plannotator/packages/server/image.ts +66 -0
- package/3p/pi-plannotator/packages/server/index.ts +648 -0
- package/3p/pi-plannotator/packages/server/integrations.test.ts +172 -0
- package/3p/pi-plannotator/packages/server/integrations.ts +214 -0
- package/3p/pi-plannotator/packages/server/jj.test.ts +69 -0
- package/3p/pi-plannotator/packages/server/jj.ts +86 -0
- package/3p/pi-plannotator/packages/server/p4.ts +417 -0
- package/3p/pi-plannotator/packages/server/package.json +40 -0
- package/3p/pi-plannotator/packages/server/path-utils.ts +18 -0
- package/3p/pi-plannotator/packages/server/pr.ts +146 -0
- package/3p/pi-plannotator/packages/server/project.test.ts +115 -0
- package/3p/pi-plannotator/packages/server/project.ts +45 -0
- package/3p/pi-plannotator/packages/server/reference-handlers.ts +404 -0
- package/3p/pi-plannotator/packages/server/remote.test.ts +150 -0
- package/3p/pi-plannotator/packages/server/remote.ts +74 -0
- package/3p/pi-plannotator/packages/server/repo.ts +80 -0
- package/3p/pi-plannotator/packages/server/resolve-file.test.ts +310 -0
- package/3p/pi-plannotator/packages/server/review-workspace.test.ts +1032 -0
- package/3p/pi-plannotator/packages/server/review-workspace.ts +48 -0
- package/3p/pi-plannotator/packages/server/review.ts +1318 -0
- package/3p/pi-plannotator/packages/server/sessions.ts +111 -0
- package/3p/pi-plannotator/packages/server/share-url.ts +53 -0
- package/3p/pi-plannotator/packages/server/shared-handlers.test.ts +43 -0
- package/3p/pi-plannotator/packages/server/shared-handlers.ts +177 -0
- package/3p/pi-plannotator/packages/server/storage.test.ts +176 -0
- package/3p/pi-plannotator/packages/server/storage.ts +17 -0
- package/3p/pi-plannotator/packages/server/tour/tour-review.test.ts +146 -0
- package/3p/pi-plannotator/packages/server/tour/tour-review.ts +604 -0
- package/3p/pi-plannotator/packages/server/tsconfig.json +15 -0
- package/3p/pi-plannotator/packages/server/vcs.test.ts +48 -0
- package/3p/pi-plannotator/packages/server/vcs.ts +80 -0
- package/3p/pi-plannotator/packages/shared/agent-jobs.ts +132 -0
- package/3p/pi-plannotator/packages/shared/agents.ts +53 -0
- package/3p/pi-plannotator/packages/shared/annotate-args.test.ts +386 -0
- package/3p/pi-plannotator/packages/shared/annotate-args.ts +107 -0
- package/3p/pi-plannotator/packages/shared/at-reference.test.ts +99 -0
- package/3p/pi-plannotator/packages/shared/at-reference.ts +52 -0
- package/3p/pi-plannotator/packages/shared/checklist.ts +52 -0
- package/3p/pi-plannotator/packages/shared/code-file.test.ts +112 -0
- package/3p/pi-plannotator/packages/shared/code-file.ts +41 -0
- package/3p/pi-plannotator/packages/shared/code-nav.test.ts +515 -0
- package/3p/pi-plannotator/packages/shared/code-nav.ts +436 -0
- package/3p/pi-plannotator/packages/shared/compress.ts +51 -0
- package/3p/pi-plannotator/packages/shared/config.ts +262 -0
- package/3p/pi-plannotator/packages/shared/crypto.test.ts +172 -0
- package/3p/pi-plannotator/packages/shared/crypto.ts +97 -0
- package/3p/pi-plannotator/packages/shared/data-dir.ts +42 -0
- package/3p/pi-plannotator/packages/shared/diff-paths.test.ts +30 -0
- package/3p/pi-plannotator/packages/shared/diff-paths.ts +137 -0
- package/3p/pi-plannotator/packages/shared/draft.ts +64 -0
- package/3p/pi-plannotator/packages/shared/external-annotation.ts +397 -0
- package/3p/pi-plannotator/packages/shared/extract-code-paths.test.ts +59 -0
- package/3p/pi-plannotator/packages/shared/extract-code-paths.ts +66 -0
- package/3p/pi-plannotator/packages/shared/favicon.ts +5 -0
- package/3p/pi-plannotator/packages/shared/feedback-templates.test.ts +65 -0
- package/3p/pi-plannotator/packages/shared/feedback-templates.ts +29 -0
- package/3p/pi-plannotator/packages/shared/goal-setup.test.ts +231 -0
- package/3p/pi-plannotator/packages/shared/goal-setup.ts +336 -0
- package/3p/pi-plannotator/packages/shared/html-to-markdown.test.ts +62 -0
- package/3p/pi-plannotator/packages/shared/html-to-markdown.ts +32 -0
- package/3p/pi-plannotator/packages/shared/improvement-hooks.test.ts +135 -0
- package/3p/pi-plannotator/packages/shared/improvement-hooks.ts +115 -0
- package/3p/pi-plannotator/packages/shared/integrations-common.ts +243 -0
- package/3p/pi-plannotator/packages/shared/jj-core.test.ts +236 -0
- package/3p/pi-plannotator/packages/shared/jj-core.ts +433 -0
- package/3p/pi-plannotator/packages/shared/package.json +55 -0
- package/3p/pi-plannotator/packages/shared/pfm-reminder.test.ts +88 -0
- package/3p/pi-plannotator/packages/shared/pfm-reminder.ts +80 -0
- package/3p/pi-plannotator/packages/shared/pr-github.ts +661 -0
- package/3p/pi-plannotator/packages/shared/pr-gitlab.test.ts +202 -0
- package/3p/pi-plannotator/packages/shared/pr-gitlab.ts +620 -0
- package/3p/pi-plannotator/packages/shared/pr-provider.test.ts +266 -0
- package/3p/pi-plannotator/packages/shared/pr-provider.ts +123 -0
- package/3p/pi-plannotator/packages/shared/pr-stack.test.ts +104 -0
- package/3p/pi-plannotator/packages/shared/pr-stack.ts +194 -0
- package/3p/pi-plannotator/packages/shared/pr-types.ts +326 -0
- package/3p/pi-plannotator/packages/shared/project.ts +71 -0
- package/3p/pi-plannotator/packages/shared/prompts-integration.test.ts +421 -0
- package/3p/pi-plannotator/packages/shared/prompts.test.ts +504 -0
- package/3p/pi-plannotator/packages/shared/prompts.ts +247 -0
- package/3p/pi-plannotator/packages/shared/reference-common.ts +87 -0
- package/3p/pi-plannotator/packages/shared/repo.ts +71 -0
- package/3p/pi-plannotator/packages/shared/resolve-file.test.ts +113 -0
- package/3p/pi-plannotator/packages/shared/resolve-file.ts +509 -0
- package/3p/pi-plannotator/packages/shared/review-args.test.ts +64 -0
- package/3p/pi-plannotator/packages/shared/review-args.ts +85 -0
- package/3p/pi-plannotator/packages/shared/review-core.test.ts +286 -0
- package/3p/pi-plannotator/packages/shared/review-core.ts +895 -0
- package/3p/pi-plannotator/packages/shared/review-workspace-node.ts +230 -0
- package/3p/pi-plannotator/packages/shared/review-workspace.ts +436 -0
- package/3p/pi-plannotator/packages/shared/semantic-diff-types.ts +76 -0
- package/3p/pi-plannotator/packages/shared/semantic-diff.test.ts +322 -0
- package/3p/pi-plannotator/packages/shared/semantic-diff.ts +520 -0
- package/3p/pi-plannotator/packages/shared/storage.ts +378 -0
- package/3p/pi-plannotator/packages/shared/tour.ts +61 -0
- package/3p/pi-plannotator/packages/shared/tsconfig.json +15 -0
- package/3p/pi-plannotator/packages/shared/types.ts +29 -0
- package/3p/pi-plannotator/packages/shared/url-to-markdown.test.ts +177 -0
- package/3p/pi-plannotator/packages/shared/url-to-markdown.ts +351 -0
- package/3p/pi-plannotator/packages/shared/vcs-core.test.ts +332 -0
- package/3p/pi-plannotator/packages/shared/vcs-core.ts +482 -0
- package/3p/pi-plannotator/packages/shared/worktree-pool.test.ts +162 -0
- package/3p/pi-plannotator/packages/shared/worktree-pool.ts +103 -0
- package/3p/pi-plannotator/packages/shared/worktree.ts +119 -0
- package/3p/pi-subagents/package.json +50 -0
- package/3p/pi-subagents/src/agent-manager.ts +413 -0
- package/3p/pi-subagents/src/agent-runner.ts +502 -0
- package/3p/pi-subagents/src/agent-types.ts +248 -0
- package/3p/pi-subagents/src/context.ts +58 -0
- package/3p/pi-subagents/src/cross-extension-rpc.ts +135 -0
- package/3p/pi-subagents/src/custom-agents.ts +137 -0
- package/3p/pi-subagents/src/default-agents.ts +144 -0
- package/3p/pi-subagents/src/env.ts +33 -0
- package/3p/pi-subagents/src/group-join.ts +141 -0
- package/3p/pi-subagents/src/index.ts +1811 -0
- package/3p/pi-subagents/src/invocation-config.ts +40 -0
- package/3p/pi-subagents/src/memory.ts +165 -0
- package/3p/pi-subagents/src/model-resolver.ts +81 -0
- package/3p/pi-subagents/src/output-file.ts +77 -0
- package/3p/pi-subagents/src/prompts.ts +85 -0
- package/3p/pi-subagents/src/skill-loader.ts +79 -0
- package/3p/pi-subagents/src/types.ts +111 -0
- package/3p/pi-subagents/src/ui/agent-widget.ts +496 -0
- package/3p/pi-subagents/src/ui/conversation-viewer.ts +250 -0
- package/3p/pi-subagents/src/worktree.ts +162 -0
- package/3p/pi-tasks/package.json +52 -0
- package/3p/pi-tasks/src/auto-clear.ts +91 -0
- package/3p/pi-tasks/src/index.ts +1150 -0
- package/3p/pi-tasks/src/process-tracker.ts +140 -0
- package/3p/pi-tasks/src/reminder-cadence.ts +90 -0
- package/3p/pi-tasks/src/task-store.ts +324 -0
- package/3p/pi-tasks/src/tasks-config.ts +27 -0
- package/3p/pi-tasks/src/types.ts +40 -0
- package/3p/pi-tasks/src/ui/settings-menu.ts +152 -0
- package/3p/pi-tasks/src/ui/task-widget.ts +296 -0
- package/AGENTS.md +28 -0
- package/LICENSE +201 -0
- package/extensions/orchestrator/agents/brainstorm-reviewer.ts +77 -0
- package/extensions/orchestrator/agents/code-reviewer.ts +89 -0
- package/extensions/orchestrator/agents/explore.ts +33 -0
- package/extensions/orchestrator/agents/librarian.ts +43 -0
- package/extensions/orchestrator/agents/plan-reviewer.ts +75 -0
- package/extensions/orchestrator/agents/planner.ts +61 -0
- package/extensions/orchestrator/agents/registry.ts +156 -0
- package/extensions/orchestrator/agents/task.ts +50 -0
- package/extensions/orchestrator/agents/tool-routing.ts +84 -0
- package/extensions/orchestrator/ast-search.ts +85 -0
- package/extensions/orchestrator/cbm.ts +330 -0
- package/extensions/orchestrator/command-handlers.test.ts +163 -0
- package/extensions/orchestrator/command-handlers.ts +116 -0
- package/extensions/orchestrator/commands.test.ts +81 -0
- package/extensions/orchestrator/commands.ts +75 -0
- package/extensions/orchestrator/config.test.ts +221 -0
- package/extensions/orchestrator/config.ts +230 -0
- package/extensions/orchestrator/context.test.ts +293 -0
- package/extensions/orchestrator/context.ts +206 -0
- package/extensions/orchestrator/event-handlers.test.ts +190 -0
- package/extensions/orchestrator/event-handlers.ts +1416 -0
- package/extensions/orchestrator/exa.ts +104 -0
- package/extensions/orchestrator/flant-infra.ts +486 -0
- package/extensions/orchestrator/index.ts +80 -0
- package/extensions/orchestrator/integration.test.ts +1214 -0
- package/extensions/orchestrator/orchestrator.test.ts +252 -0
- package/extensions/orchestrator/orchestrator.ts +538 -0
- package/extensions/orchestrator/phases/brainstorm.test.ts +15 -0
- package/extensions/orchestrator/phases/brainstorm.ts +273 -0
- package/extensions/orchestrator/phases/implementation.ts +40 -0
- package/extensions/orchestrator/phases/machine.test.ts +293 -0
- package/extensions/orchestrator/phases/machine.ts +209 -0
- package/extensions/orchestrator/phases/planning.ts +255 -0
- package/extensions/orchestrator/phases/review.ts +193 -0
- package/extensions/orchestrator/plannotator.ts +56 -0
- package/extensions/orchestrator/pp-menu.ts +866 -0
- package/extensions/orchestrator/state.test.ts +343 -0
- package/extensions/orchestrator/state.ts +237 -0
- package/extensions/orchestrator/validate-artifacts.test.ts +88 -0
- package/extensions/orchestrator/validate-artifacts.ts +272 -0
- package/extensions/orchestrator/vendor.d.ts +26 -0
- package/package.json +73 -0
- package/scripts/postinstall.sh +18 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe PR/MR types and pure helpers.
|
|
3
|
+
*
|
|
4
|
+
* Split out from pr-provider.ts so the review UI can import types,
|
|
5
|
+
* label helpers, and URL parsing without dragging the GitHub/GitLab
|
|
6
|
+
* server implementations (and their Node-only dependencies) through
|
|
7
|
+
* the browser bundle. pr-provider.ts re-exports nothing from here;
|
|
8
|
+
* server-side dispatch lives there.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// --- Runtime Types ---
|
|
12
|
+
|
|
13
|
+
export interface CommandResult {
|
|
14
|
+
stdout: string;
|
|
15
|
+
stderr: string;
|
|
16
|
+
exitCode: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PRRuntime {
|
|
20
|
+
runCommand: (
|
|
21
|
+
cmd: string,
|
|
22
|
+
args: string[],
|
|
23
|
+
) => Promise<CommandResult>;
|
|
24
|
+
runCommandWithInput?: (
|
|
25
|
+
cmd: string,
|
|
26
|
+
args: string[],
|
|
27
|
+
input: string,
|
|
28
|
+
) => Promise<CommandResult>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// --- Platform Types ---
|
|
32
|
+
|
|
33
|
+
export type Platform = "github" | "gitlab";
|
|
34
|
+
|
|
35
|
+
/** GitHub PR reference */
|
|
36
|
+
export interface GithubPRRef {
|
|
37
|
+
platform: "github";
|
|
38
|
+
host: string;
|
|
39
|
+
owner: string;
|
|
40
|
+
repo: string;
|
|
41
|
+
number: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** GitLab MR reference */
|
|
45
|
+
export interface GitlabMRRef {
|
|
46
|
+
platform: "gitlab";
|
|
47
|
+
host: string;
|
|
48
|
+
projectPath: string;
|
|
49
|
+
iid: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Discriminated union — auto-detected from URL */
|
|
53
|
+
export type PRRef = GithubPRRef | GitlabMRRef;
|
|
54
|
+
|
|
55
|
+
/** GitHub PR metadata */
|
|
56
|
+
export interface GithubPRMetadata {
|
|
57
|
+
platform: "github";
|
|
58
|
+
host: string;
|
|
59
|
+
owner: string;
|
|
60
|
+
repo: string;
|
|
61
|
+
number: number;
|
|
62
|
+
/** GraphQL node ID for the PR — used for markFileAsViewed mutations */
|
|
63
|
+
prNodeId?: string;
|
|
64
|
+
title: string;
|
|
65
|
+
author: string;
|
|
66
|
+
baseBranch: string;
|
|
67
|
+
headBranch: string;
|
|
68
|
+
/** Repository default branch, used to infer whether this PR targets another PR branch. */
|
|
69
|
+
defaultBranch?: string;
|
|
70
|
+
baseSha: string;
|
|
71
|
+
headSha: string;
|
|
72
|
+
/** Merge-base SHA — the common ancestor commit used to compute the PR diff. Differs from baseSha when the base branch has moved. */
|
|
73
|
+
mergeBaseSha?: string;
|
|
74
|
+
url: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** GitLab MR metadata */
|
|
78
|
+
export interface GitlabMRMetadata {
|
|
79
|
+
platform: "gitlab";
|
|
80
|
+
host: string;
|
|
81
|
+
projectPath: string;
|
|
82
|
+
iid: number;
|
|
83
|
+
title: string;
|
|
84
|
+
author: string;
|
|
85
|
+
baseBranch: string;
|
|
86
|
+
headBranch: string;
|
|
87
|
+
/** Project default branch, used to infer whether this MR targets another MR branch. */
|
|
88
|
+
defaultBranch?: string;
|
|
89
|
+
baseSha: string;
|
|
90
|
+
headSha: string;
|
|
91
|
+
/** Merge-base SHA — the common ancestor commit used to compute the MR diff. */
|
|
92
|
+
mergeBaseSha?: string;
|
|
93
|
+
url: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Discriminated union — downstream gets type narrowing for free */
|
|
97
|
+
export type PRMetadata = GithubPRMetadata | GitlabMRMetadata;
|
|
98
|
+
|
|
99
|
+
// --- PR Context Types (platform-agnostic) ---
|
|
100
|
+
|
|
101
|
+
export interface PRComment {
|
|
102
|
+
id: string;
|
|
103
|
+
author: string;
|
|
104
|
+
body: string;
|
|
105
|
+
createdAt: string;
|
|
106
|
+
url: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface PRReview {
|
|
110
|
+
id: string;
|
|
111
|
+
author: string;
|
|
112
|
+
state: string;
|
|
113
|
+
body: string;
|
|
114
|
+
submittedAt: string;
|
|
115
|
+
url?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface PRCheck {
|
|
119
|
+
name: string;
|
|
120
|
+
status: string;
|
|
121
|
+
conclusion: string | null;
|
|
122
|
+
workflowName: string;
|
|
123
|
+
detailsUrl: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface PRLinkedIssue {
|
|
127
|
+
number: number;
|
|
128
|
+
url: string;
|
|
129
|
+
repo: string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface PRThreadComment {
|
|
133
|
+
id: string;
|
|
134
|
+
author: string;
|
|
135
|
+
body: string;
|
|
136
|
+
createdAt: string;
|
|
137
|
+
url: string;
|
|
138
|
+
diffHunk?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface PRReviewThread {
|
|
142
|
+
id: string;
|
|
143
|
+
isResolved: boolean;
|
|
144
|
+
isOutdated: boolean;
|
|
145
|
+
path: string;
|
|
146
|
+
line: number | null;
|
|
147
|
+
startLine: number | null;
|
|
148
|
+
diffSide: 'LEFT' | 'RIGHT' | null;
|
|
149
|
+
comments: PRThreadComment[];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface PRContext {
|
|
153
|
+
body: string;
|
|
154
|
+
state: string;
|
|
155
|
+
isDraft: boolean;
|
|
156
|
+
labels: Array<{ name: string; color: string }>;
|
|
157
|
+
reviewDecision: string;
|
|
158
|
+
mergeable: string;
|
|
159
|
+
mergeStateStatus: string;
|
|
160
|
+
comments: PRComment[];
|
|
161
|
+
reviews: PRReview[];
|
|
162
|
+
reviewThreads: PRReviewThread[];
|
|
163
|
+
checks: PRCheck[];
|
|
164
|
+
linkedIssues: PRLinkedIssue[];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface PRReviewFileComment {
|
|
168
|
+
path: string;
|
|
169
|
+
line: number;
|
|
170
|
+
side: "LEFT" | "RIGHT";
|
|
171
|
+
body: string;
|
|
172
|
+
start_line?: number;
|
|
173
|
+
start_side?: "LEFT" | "RIGHT";
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export type PRDiffScope = "layer" | "full-stack";
|
|
177
|
+
|
|
178
|
+
export interface PRDiffScopeOption {
|
|
179
|
+
id: PRDiffScope;
|
|
180
|
+
label: string;
|
|
181
|
+
description: string;
|
|
182
|
+
enabled: boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface PRStackInfo {
|
|
186
|
+
isStacked: boolean;
|
|
187
|
+
baseBranch: string;
|
|
188
|
+
defaultBranch?: string;
|
|
189
|
+
label: string;
|
|
190
|
+
source: "branch-inferred" | "tree-discovered" | "github-native" | "gitlab-native" | "graphite" | "ghstack";
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface PRStackNode {
|
|
194
|
+
branch: string;
|
|
195
|
+
number?: number;
|
|
196
|
+
title?: string;
|
|
197
|
+
url?: string;
|
|
198
|
+
isCurrent: boolean;
|
|
199
|
+
isDefaultBranch: boolean;
|
|
200
|
+
state?: 'open' | 'merged' | 'closed';
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface PRStackTree {
|
|
204
|
+
nodes: PRStackNode[];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface PRListItem {
|
|
208
|
+
id: string;
|
|
209
|
+
number: number;
|
|
210
|
+
title: string;
|
|
211
|
+
author: string;
|
|
212
|
+
url: string;
|
|
213
|
+
baseBranch: string;
|
|
214
|
+
state: 'open' | 'closed' | 'merged';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// --- Label Helpers ---
|
|
218
|
+
// Accept either PRRef or PRMetadata (both have `platform` discriminant)
|
|
219
|
+
|
|
220
|
+
type HasPlatform = PRRef | PRMetadata;
|
|
221
|
+
|
|
222
|
+
/** "GitHub" or "GitLab" */
|
|
223
|
+
export function getPlatformLabel(m: HasPlatform): string {
|
|
224
|
+
return m.platform === "github" ? "GitHub" : "GitLab";
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** "PR" or "MR" */
|
|
228
|
+
export function getMRLabel(m: HasPlatform): string {
|
|
229
|
+
return m.platform === "github" ? "PR" : "MR";
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** "#123" or "!42" */
|
|
233
|
+
export function getMRNumberLabel(m: HasPlatform): string {
|
|
234
|
+
if (m.platform === "github") return `#${m.number}`;
|
|
235
|
+
return `!${m.iid}`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** "owner/repo" or "group/project" */
|
|
239
|
+
export function getDisplayRepo(m: HasPlatform): string {
|
|
240
|
+
if (m.platform === "github") return `${m.owner}/${m.repo}`;
|
|
241
|
+
return m.projectPath;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** Reconstruct a PRRef from metadata */
|
|
245
|
+
export function prRefFromMetadata(m: PRMetadata): PRRef {
|
|
246
|
+
if (m.platform === "github") {
|
|
247
|
+
return { platform: "github", host: m.host, owner: m.owner, repo: m.repo, number: m.number };
|
|
248
|
+
}
|
|
249
|
+
return { platform: "gitlab", host: m.host, projectPath: m.projectPath, iid: m.iid };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function isSameProject(a: PRRef, b: PRRef): boolean {
|
|
253
|
+
if (a.platform !== b.platform) return false;
|
|
254
|
+
if (a.platform === "github" && b.platform === "github") {
|
|
255
|
+
return a.host === b.host && a.owner === b.owner && a.repo === b.repo;
|
|
256
|
+
}
|
|
257
|
+
if (a.platform === "gitlab" && b.platform === "gitlab") {
|
|
258
|
+
return a.host === b.host && a.projectPath === b.projectPath;
|
|
259
|
+
}
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** CLI tool name for the platform */
|
|
264
|
+
export function getCliName(ref: PRRef): string {
|
|
265
|
+
return ref.platform === "github" ? "gh" : "glab";
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Install URL for the platform CLI */
|
|
269
|
+
export function getCliInstallUrl(ref: PRRef): string {
|
|
270
|
+
return ref.platform === "github"
|
|
271
|
+
? "https://cli.github.com"
|
|
272
|
+
: "https://gitlab.com/gitlab-org/cli";
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** Encode a file path for use in platform API URLs */
|
|
276
|
+
export function encodeApiFilePath(filePath: string): string {
|
|
277
|
+
return encodeURIComponent(filePath);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// --- URL Parsing ---
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Parse a PR/MR URL into its components. Auto-detects platform.
|
|
284
|
+
*
|
|
285
|
+
* Handles:
|
|
286
|
+
* - GitHub: https://github.com/owner/repo/pull/123[/files|/commits]
|
|
287
|
+
* - GitHub Enterprise: https://ghe.company.com/owner/repo/pull/123
|
|
288
|
+
* - GitLab: https://gitlab.com/group/subgroup/project/-/merge_requests/42[/diffs]
|
|
289
|
+
* - Self-hosted GitLab: https://gitlab.mycompany.com/group/project/-/merge_requests/42
|
|
290
|
+
*
|
|
291
|
+
* GitLab is checked first because `/-/merge_requests/` is unambiguous,
|
|
292
|
+
* while `/pull/` could theoretically appear on any host.
|
|
293
|
+
*/
|
|
294
|
+
export function parsePRUrl(url: string): PRRef | null {
|
|
295
|
+
if (!url) return null;
|
|
296
|
+
|
|
297
|
+
// GitLab: https://{host}/{projectPath}/-/merge_requests/{iid}[/...]
|
|
298
|
+
// Checked first — `/-/merge_requests/` is the most specific pattern.
|
|
299
|
+
const glMatch = url.match(
|
|
300
|
+
/^https?:\/\/([^/]+)\/(.+?)\/-\/merge_requests\/(\d+)/,
|
|
301
|
+
);
|
|
302
|
+
if (glMatch) {
|
|
303
|
+
return {
|
|
304
|
+
platform: "gitlab",
|
|
305
|
+
host: glMatch[1],
|
|
306
|
+
projectPath: glMatch[2],
|
|
307
|
+
iid: parseInt(glMatch[3], 10),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// GitHub (including GHE): https://{host}/{owner}/{repo}/pull/{number}[/...]
|
|
312
|
+
const ghMatch = url.match(
|
|
313
|
+
/^https?:\/\/([^/]+)\/([^/]+)\/([^/]+)\/pull\/(\d+)/,
|
|
314
|
+
);
|
|
315
|
+
if (ghMatch) {
|
|
316
|
+
return {
|
|
317
|
+
platform: "github",
|
|
318
|
+
host: ghMatch[1],
|
|
319
|
+
owner: ghMatch[2],
|
|
320
|
+
repo: ghMatch[3],
|
|
321
|
+
number: parseInt(ghMatch[4], 10),
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Utility — Pure Functions
|
|
3
|
+
*
|
|
4
|
+
* String sanitization and path extraction helpers.
|
|
5
|
+
* Runtime-agnostic: no Bun or Node-specific APIs.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sanitize a string for use as a tag
|
|
10
|
+
* - lowercase
|
|
11
|
+
* - replace spaces/underscores with hyphens
|
|
12
|
+
* - remove special characters
|
|
13
|
+
* - trim to reasonable length
|
|
14
|
+
*/
|
|
15
|
+
export function sanitizeTag(name: string): string | null {
|
|
16
|
+
if (!name || typeof name !== "string") return null;
|
|
17
|
+
|
|
18
|
+
const sanitized = name
|
|
19
|
+
.toLowerCase()
|
|
20
|
+
.trim()
|
|
21
|
+
.replace(/[\s_]+/g, "-") // spaces/underscores -> hyphens
|
|
22
|
+
.replace(/[^a-z0-9-]/g, "") // remove special chars
|
|
23
|
+
.replace(/-+/g, "-") // collapse multiple hyphens
|
|
24
|
+
.replace(/^-|-$/g, "") // trim leading/trailing hyphens
|
|
25
|
+
.slice(0, 30); // max 30 chars
|
|
26
|
+
|
|
27
|
+
return sanitized.length >= 2 ? sanitized : null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Extract repo name from a git root path
|
|
32
|
+
*/
|
|
33
|
+
export function extractRepoName(gitRootPath: string): string | null {
|
|
34
|
+
if (!gitRootPath || typeof gitRootPath !== "string") return null;
|
|
35
|
+
|
|
36
|
+
const trimmed = gitRootPath.trim().replace(/\/+$/, ""); // remove trailing slashes
|
|
37
|
+
const parts = trimmed.split("/");
|
|
38
|
+
const name = parts[parts.length - 1];
|
|
39
|
+
|
|
40
|
+
return sanitizeTag(name);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extract directory name from a path
|
|
45
|
+
*/
|
|
46
|
+
export function extractDirName(path: string): string | null {
|
|
47
|
+
if (!path || typeof path !== "string") return null;
|
|
48
|
+
|
|
49
|
+
const trimmed = path.trim().replace(/\/+$/, "");
|
|
50
|
+
if (trimmed === "" || trimmed === "/") return null;
|
|
51
|
+
|
|
52
|
+
const parts = trimmed.split("/");
|
|
53
|
+
const name = parts[parts.length - 1];
|
|
54
|
+
|
|
55
|
+
// Skip generic names
|
|
56
|
+
const skipNames = new Set(["home", "users", "user", "root", "tmp", "var"]);
|
|
57
|
+
if (skipNames.has(name.toLowerCase())) return null;
|
|
58
|
+
|
|
59
|
+
return sanitizeTag(name);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Extract hostname from a URL string, or return the original string on failure.
|
|
64
|
+
*/
|
|
65
|
+
export function hostnameOrFallback(url: string): string {
|
|
66
|
+
try {
|
|
67
|
+
return new URL(url).hostname;
|
|
68
|
+
} catch {
|
|
69
|
+
return url;
|
|
70
|
+
}
|
|
71
|
+
}
|