whipped 0.1.1 → 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.
- package/README.md +1 -1
- package/dist/cli.js +39 -19
- package/dist/web-ui/assets/{index-rpsRpaUU.js → index-Ce4HDOh7.js} +1664 -1598
- package/dist/web-ui/index.html +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -194,7 +194,7 @@ Whipped can start a [Cloudflare Tunnel](https://developers.cloudflare.com/cloudf
|
|
|
194
194
|
|
|
195
195
|
A standalone Chrome/Chromium extension for capturing UI context off any web page. Click the toolbar icon to enter select mode, then click any element to capture its React component and source location. It builds a ready-to-paste **YAML prompt** for your AI coding agent — no server connection required.
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
Install from the [Chrome Web Store](https://chromewebstore.google.com/detail/codkafoociihebdklkpfjjoacenkkhci?utm_source=item-share-cb), or build from source at [github.com/nxnom/whipped-extension](https://github.com/nxnom/whipped-extension).
|
|
198
198
|
|
|
199
199
|
### Visual comments
|
|
200
200
|
|
package/dist/cli.js
CHANGED
|
@@ -18966,6 +18966,7 @@ function isCommandAvailable(args) {
|
|
|
18966
18966
|
stdio: ["ignore", "pipe", "ignore"],
|
|
18967
18967
|
timeout: 5e3
|
|
18968
18968
|
});
|
|
18969
|
+
if (result.error) return result.error.code !== "ENOENT";
|
|
18969
18970
|
return result.status === 0 || result.status === null;
|
|
18970
18971
|
}
|
|
18971
18972
|
function getAvailableAgents() {
|
|
@@ -22530,10 +22531,11 @@ ${devSystemPromptResult.text}`;
|
|
|
22530
22531
|
const conflictGitInstructions = conflictProjectConfig.gitInstructions?.trim() || DEFAULT_GIT_INSTRUCTIONS;
|
|
22531
22532
|
let outputBuffer = "";
|
|
22532
22533
|
let hookHandled = false;
|
|
22534
|
+
const conflictSystemPrompt = buildConflictResolutionSystemPrompt(card, conflictedFiles, conflictGitInstructions);
|
|
22533
22535
|
if (defaultAgent === "opencode") {
|
|
22534
22536
|
const mcpSpec = buildWhippedMcpServerSpec(getMcpServerPath(), this.options.serverUrl, workspaceId);
|
|
22535
22537
|
await writeOpencodeFiles(streamId, getServerPort(this.options.serverUrl), mcpSpec, {
|
|
22536
|
-
appendSystemPrompt:
|
|
22538
|
+
appendSystemPrompt: conflictSystemPrompt
|
|
22537
22539
|
}).catch(() => {
|
|
22538
22540
|
});
|
|
22539
22541
|
} else if (defaultAgent === "cursor") {
|
|
@@ -22543,7 +22545,7 @@ ${devSystemPromptResult.text}`;
|
|
|
22543
22545
|
}
|
|
22544
22546
|
const proc = spawnAgent({
|
|
22545
22547
|
agentId: defaultAgent,
|
|
22546
|
-
prompt:
|
|
22548
|
+
prompt: buildTaskPrompt(),
|
|
22547
22549
|
cwd: mergeWorktreePath,
|
|
22548
22550
|
hookSettingsPath: defaultAgent === "claude" ? CLAUDE_TASK_SETTINGS_PATH : void 0,
|
|
22549
22551
|
hookServerPort: defaultAgent === "codex" ? getServerPort(this.options.serverUrl) : void 0,
|
|
@@ -22552,7 +22554,7 @@ ${devSystemPromptResult.text}`;
|
|
|
22552
22554
|
...defaultAgent === "opencode" ? { [OPENCODE_CONFIG_DIR_ENV]: getOpencodeConfigDir(streamId) } : {},
|
|
22553
22555
|
...defaultAgent === "cursor" ? { [CURSOR_CONFIG_DIR_ENV]: getCursorConfigDir(streamId) } : {}
|
|
22554
22556
|
},
|
|
22555
|
-
appendSystemPrompt: defaultAgent !== "opencode" ?
|
|
22557
|
+
appendSystemPrompt: defaultAgent !== "opencode" ? conflictSystemPrompt : void 0,
|
|
22556
22558
|
onOutput: (data) => {
|
|
22557
22559
|
outputBuffer += data;
|
|
22558
22560
|
stateHub.broadcastTerminalOutput(workspaceId, streamId, data);
|
|
@@ -22714,27 +22716,27 @@ ${secretsSection}` : ""}${systemPrompt?.trim() ? `
|
|
|
22714
22716
|
|
|
22715
22717
|
${systemPrompt.trim()}` : ""}`;
|
|
22716
22718
|
}
|
|
22717
|
-
|
|
22719
|
+
function buildConflictResolutionSystemPrompt(card, conflictedFiles, gitInstructions) {
|
|
22720
|
+
return `You are a merge conflict resolution agent. Your only job is to resolve git merge conflicts.
|
|
22718
22721
|
|
|
22719
22722
|
Rules:
|
|
22720
22723
|
- Only edit files to remove conflict markers (<<<<<<< ======= >>>>>>>)
|
|
22721
22724
|
- Preserve the intent of BOTH sides where possible; when in doubt keep the incoming (task) changes
|
|
22722
22725
|
- Never refactor, rename, or change logic beyond resolving the conflict markers
|
|
22723
|
-
- Exit when done
|
|
22724
|
-
|
|
22725
|
-
|
|
22726
|
+
- Exit when done
|
|
22727
|
+
|
|
22728
|
+
## Task being merged
|
|
22726
22729
|
|
|
22727
|
-
Task being merged:
|
|
22728
22730
|
${card.description?.trim() ?? ""}
|
|
22729
22731
|
|
|
22730
|
-
Conflicted files
|
|
22732
|
+
## Conflicted files
|
|
22733
|
+
|
|
22731
22734
|
${conflictedFiles.map((f2) => `- ${f2}`).join("\n")}
|
|
22732
22735
|
|
|
22733
|
-
Resolve each conflict, preserving the task's intent. Then stage and commit
|
|
22734
|
-
the resolution. Write the commit message following the project's git
|
|
22735
|
-
conventions below \u2014 do not use a hard-coded template.
|
|
22736
|
+
Resolve each conflict, preserving the task's intent. Then stage and commit the resolution. Write the commit message following the project's git conventions below \u2014 do not use a hard-coded template.
|
|
22736
22737
|
|
|
22737
22738
|
## Git conventions
|
|
22739
|
+
|
|
22738
22740
|
${gitInstructions}`;
|
|
22739
22741
|
}
|
|
22740
22742
|
function buildTaskPrompt() {
|
|
@@ -26831,8 +26833,8 @@ import { z as z9 } from "zod";
|
|
|
26831
26833
|
// src/api/services/projects-service.ts
|
|
26832
26834
|
init_runtime_config();
|
|
26833
26835
|
init_api_contract();
|
|
26834
|
-
init_logger();
|
|
26835
26836
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
26837
|
+
init_logger();
|
|
26836
26838
|
|
|
26837
26839
|
// src/state/projects-layout.ts
|
|
26838
26840
|
init_db();
|
|
@@ -26888,14 +26890,31 @@ var saveProjectsLayoutData = (layout) => {
|
|
|
26888
26890
|
return { ok: true };
|
|
26889
26891
|
};
|
|
26890
26892
|
var checkProjectPath = async (repoPath) => {
|
|
26891
|
-
if (!repoPath.trim())
|
|
26893
|
+
if (!repoPath.trim())
|
|
26894
|
+
return { valid: false, isGitRepo: false, error: null, name: null, branch: null, remote: null, branches: [] };
|
|
26892
26895
|
const { statSync: statSync2 } = await import("node:fs");
|
|
26893
26896
|
try {
|
|
26894
26897
|
const stat2 = statSync2(repoPath);
|
|
26895
26898
|
if (!stat2.isDirectory())
|
|
26896
|
-
return {
|
|
26899
|
+
return {
|
|
26900
|
+
valid: false,
|
|
26901
|
+
isGitRepo: false,
|
|
26902
|
+
error: "Not a directory",
|
|
26903
|
+
name: null,
|
|
26904
|
+
branch: null,
|
|
26905
|
+
remote: null,
|
|
26906
|
+
branches: []
|
|
26907
|
+
};
|
|
26897
26908
|
} catch {
|
|
26898
|
-
return {
|
|
26909
|
+
return {
|
|
26910
|
+
valid: false,
|
|
26911
|
+
isGitRepo: false,
|
|
26912
|
+
error: "Path does not exist",
|
|
26913
|
+
name: null,
|
|
26914
|
+
branch: null,
|
|
26915
|
+
remote: null,
|
|
26916
|
+
branches: []
|
|
26917
|
+
};
|
|
26899
26918
|
}
|
|
26900
26919
|
const r = spawnSync9("git", ["rev-parse", "--git-dir"], {
|
|
26901
26920
|
cwd: repoPath,
|
|
@@ -26910,7 +26929,8 @@ var checkProjectPath = async (repoPath) => {
|
|
|
26910
26929
|
error: "Not a git repository",
|
|
26911
26930
|
name: null,
|
|
26912
26931
|
branch: null,
|
|
26913
|
-
remote: null
|
|
26932
|
+
remote: null,
|
|
26933
|
+
branches: []
|
|
26914
26934
|
};
|
|
26915
26935
|
const branchR = spawnSync9("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
26916
26936
|
cwd: repoPath,
|
|
@@ -26926,7 +26946,7 @@ var checkProjectPath = async (repoPath) => {
|
|
|
26926
26946
|
const branch = branchR.status === 0 ? branchR.stdout.trim() : null;
|
|
26927
26947
|
const rawRemote = remoteR.status === 0 ? remoteR.stdout.trim() : null;
|
|
26928
26948
|
const remote = rawRemote ? rawRemote.replace(/^https?:\/\//, "").replace(/^git@([^:]+):/, "$1/").replace(/\.git$/, "") : null;
|
|
26929
|
-
return { valid: true, isGitRepo: true, error: null, name, branch, remote };
|
|
26949
|
+
return { valid: true, isGitRepo: true, error: null, name, branch, remote, branches: listLocalBranches(repoPath) };
|
|
26930
26950
|
};
|
|
26931
26951
|
var addProject = async (repoPath, initialConfig) => {
|
|
26932
26952
|
const { statSync: statSync2 } = await import("node:fs");
|
|
@@ -28545,7 +28565,7 @@ process.on("uncaughtException", (err) => {
|
|
|
28545
28565
|
if (err.code === "EPIPE" || err.code === "ECONNRESET") return;
|
|
28546
28566
|
throw err;
|
|
28547
28567
|
});
|
|
28548
|
-
var VERSION9 = true ? "0.
|
|
28568
|
+
var VERSION9 = true ? "0.2.0" : "0.0.0-dev";
|
|
28549
28569
|
async function isPortAvailable(port, host) {
|
|
28550
28570
|
return new Promise((resolve5) => {
|
|
28551
28571
|
const probe = createServer2();
|