pinprompt 0.0.1-alpha.0 → 0.0.1-alpha.1
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 +17 -12
- package/dist/client.js +57 -15
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# pinprompt
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/pinprompt)
|
|
4
|
+
[](https://www.npmjs.com/package/pinprompt)
|
|
5
|
+
[](https://github.com/ueqeb/pinprompt/actions/workflows/ci.yml)
|
|
6
|
+
[](https://socket.dev/npm/package/pinprompt)
|
|
7
|
+

|
|
8
|
+
[](LICENSE)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
**Stop describing where to change, waiting for your AI to find it, and paying for the search.**
|
|
11
|
+
|
|
12
|
+
Click elements in your SvelteKit app; pinprompt puts their exact source location in your prompt.
|
|
13
|
+
|
|
14
|
+

|
|
6
15
|
|
|
7
16
|
```
|
|
8
17
|
move [click] above [click]
|
|
@@ -22,15 +31,11 @@ move [1] above [2]
|
|
|
22
31
|
|
|
23
32
|
## Why
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
**For your AI**
|
|
31
|
-
- Goes straight to `file:line` instead of searching the codebase.
|
|
32
|
-
- Fewer turns, fewer tokens, fewer edits to the wrong element.
|
|
33
|
-
- Compact on purpose: no framework internals, no whole files pulled into context.
|
|
34
|
+
| Pain | With pinprompt |
|
|
35
|
+
|---|---|
|
|
36
|
+
| Describing exactly where to change | Click it. The prompt gets `file:line`, the component and which loop item |
|
|
37
|
+
| Waiting while the AI searches | It goes straight to the line: **2.4× faster** |
|
|
38
|
+
| Paying for that search | Fewer turns and tokens: **39% cheaper** |
|
|
34
39
|
|
|
35
40
|
## Benchmark
|
|
36
41
|
|
|
@@ -65,7 +70,7 @@ Start your dev server, then:
|
|
|
65
70
|
| **Alt+P** | open the prompt bar |
|
|
66
71
|
| click | reference an element |
|
|
67
72
|
| **↑ / ↓** | widen to the parent element / narrow back |
|
|
68
|
-
| **Enter** | copy the prompt |
|
|
73
|
+
| **Enter** | copy the prompt (it stays shown: copy all again, or select just a part) |
|
|
69
74
|
| **Esc** | close (your draft is kept) |
|
|
70
75
|
|
|
71
76
|
## Feedback wanted
|
package/dist/client.js
CHANGED
|
@@ -2853,6 +2853,49 @@ var all_registered_events = /* @__PURE__ */ new Set();
|
|
|
2853
2853
|
var root_event_handles = /* @__PURE__ */ new Set();
|
|
2854
2854
|
/**
|
|
2855
2855
|
* @param {string} event_name
|
|
2856
|
+
* @param {EventTarget} dom
|
|
2857
|
+
* @param {EventListener} [handler]
|
|
2858
|
+
* @param {AddEventListenerOptions} [options]
|
|
2859
|
+
*/
|
|
2860
|
+
function create_event(event_name, dom, handler, options = {}) {
|
|
2861
|
+
/**
|
|
2862
|
+
* @this {EventTarget}
|
|
2863
|
+
*/
|
|
2864
|
+
function target_handler(event) {
|
|
2865
|
+
if (!options.capture) handle_event_propagation.call(dom, event);
|
|
2866
|
+
if (!event.cancelBubble) return without_reactive_context(() => {
|
|
2867
|
+
return handler?.call(this, event);
|
|
2868
|
+
});
|
|
2869
|
+
}
|
|
2870
|
+
if (event_name.startsWith("pointer") || event_name.startsWith("touch") || event_name === "wheel") {
|
|
2871
|
+
target_handler.__removed = false;
|
|
2872
|
+
queue_micro_task(() => {
|
|
2873
|
+
if (!target_handler.__removed) dom.addEventListener(event_name, target_handler, options);
|
|
2874
|
+
});
|
|
2875
|
+
} else dom.addEventListener(event_name, target_handler, options);
|
|
2876
|
+
return target_handler;
|
|
2877
|
+
}
|
|
2878
|
+
/**
|
|
2879
|
+
* @param {string} event_name
|
|
2880
|
+
* @param {Element} dom
|
|
2881
|
+
* @param {EventListener} [handler]
|
|
2882
|
+
* @param {boolean} [capture]
|
|
2883
|
+
* @param {boolean} [passive]
|
|
2884
|
+
* @returns {void}
|
|
2885
|
+
*/
|
|
2886
|
+
function event(event_name, dom, handler, capture, passive) {
|
|
2887
|
+
var options = {
|
|
2888
|
+
capture,
|
|
2889
|
+
passive
|
|
2890
|
+
};
|
|
2891
|
+
var target_handler = create_event(event_name, dom, handler, options);
|
|
2892
|
+
if (dom === document.body || dom === window || dom === document || dom instanceof HTMLMediaElement) teardown(() => {
|
|
2893
|
+
target_handler.__removed = true;
|
|
2894
|
+
dom.removeEventListener(event_name, target_handler, options);
|
|
2895
|
+
});
|
|
2896
|
+
}
|
|
2897
|
+
/**
|
|
2898
|
+
* @param {string} event_name
|
|
2856
2899
|
* @param {Element} element
|
|
2857
2900
|
* @param {EventListener} [handler]
|
|
2858
2901
|
* @returns {void}
|
|
@@ -4662,13 +4705,13 @@ var root = /* @__PURE__ */ from_html(`<div class="box picked svelte-4537t3"><spa
|
|
|
4662
4705
|
var root_1 = /* @__PURE__ */ from_html(`<div class="box hover svelte-4537t3"><span class="tag svelte-4537t3"> </span></div>`);
|
|
4663
4706
|
var root_2 = /* @__PURE__ */ from_html(`<li class="svelte-4537t3"><b class="svelte-4537t3"> </b> </li>`);
|
|
4664
4707
|
var root_3 = /* @__PURE__ */ from_html(`<ul class="refs svelte-4537t3"></ul>`);
|
|
4665
|
-
var root_4 = /* @__PURE__ */ from_html(`<
|
|
4708
|
+
var root_4 = /* @__PURE__ */ from_html(`<pre class="output svelte-4537t3" tabindex="-1"> </pre> <div class="hint svelte-4537t3"><span class="svelte-4537t3"><span> </span> · select to copy part · Esc dismiss</span> <span class="actions svelte-4537t3"><button class="copy svelte-4537t3">Copy all</button> <button class="dismiss svelte-4537t3" title="Dismiss">✕</button></span></div>`, 1);
|
|
4666
4709
|
var root_5 = /* @__PURE__ */ from_html(`<textarea rows="2" placeholder="Type what you want, click elements to reference them…" class="svelte-4537t3"></textarea> <div class="hint svelte-4537t3"><span class="svelte-4537t3">Click to reference · ↑↓ parent/child · Enter copy · Esc close</span> <span class="svelte-4537t3"> </span></div>`, 1);
|
|
4667
4710
|
var root_6 = /* @__PURE__ */ from_html(`<!> <!> <div class="bar svelte-4537t3"><!> <!></div>`, 1);
|
|
4668
4711
|
var root_7 = /* @__PURE__ */ from_html(`<button class="launcher svelte-4537t3" title="pinprompt (Alt+P)">pinprompt</button>`);
|
|
4669
4712
|
var $$css = {
|
|
4670
4713
|
hash: "svelte-4537t3",
|
|
4671
|
-
code: ".svelte-4537t3 {box-sizing:border-box;}.box.svelte-4537t3 {position:fixed;z-index:2147483646;pointer-events:none;border-radius:3px;}.hover.svelte-4537t3 {outline:2px dashed #3b82f6;background:rgb(59 130 246 / 0.08);}.picked.svelte-4537t3 {outline:2px solid var(--c);}.tag.svelte-4537t3 {position:absolute;left:-2px;bottom:100%;padding:1px 6px;border-radius:3px 3px 0 0;background:var(--c, #3b82f6);color:#fff;font:600 11px/1.5 ui-monospace, monospace;white-space:nowrap;}.bar.svelte-4537t3 {position:fixed;z-index:2147483647;left:50%;bottom:16px;width:min(640px, calc(100vw - 32px));transform:translateX(-50%);padding:8px;border-radius:10px;background:#18181b;color:#fafafa;box-shadow:0 8px 30px rgb(0 0 0 / 0.35);font:13px/1.4 system-ui, sans-serif;}.refs.svelte-4537t3 {display:flex;flex-wrap:wrap;gap:4px;margin:0 0 6px;padding:0;list-style:none;}.refs.svelte-4537t3 li:where(.svelte-4537t3) {padding:1px 6px;border-left:3px solid var(--c);border-radius:3px;background:#27272a;font-size:12px;}textarea.svelte-4537t3 {display:block;width:100%;resize:none;padding:6px 8px;border:1px solid #3f3f46;border-radius:6px;background:#09090b;color:inherit;font:14px/1.4 ui-monospace, monospace;outline:none;}textarea.svelte-4537t3:focus {border-color:#3b82f6;}.hint.svelte-4537t3 {display:flex;justify-content:space-between;margin-top:4px;color:#a1a1aa;font-size:11px;}.status.svelte-4537t3 {color:#4ade80;}.status.failed.svelte-4537t3 {color:#f87171;}.output.svelte-4537t3 {
|
|
4714
|
+
code: ".svelte-4537t3 {box-sizing:border-box;}.box.svelte-4537t3 {position:fixed;z-index:2147483646;pointer-events:none;border-radius:3px;}.hover.svelte-4537t3 {outline:2px dashed #3b82f6;background:rgb(59 130 246 / 0.08);}.picked.svelte-4537t3 {outline:2px solid var(--c);}.tag.svelte-4537t3 {position:absolute;left:-2px;bottom:100%;padding:1px 6px;border-radius:3px 3px 0 0;background:var(--c, #3b82f6);color:#fff;font:600 11px/1.5 ui-monospace, monospace;white-space:nowrap;}.bar.svelte-4537t3 {position:fixed;z-index:2147483647;left:50%;bottom:16px;width:min(640px, calc(100vw - 32px));transform:translateX(-50%);padding:8px;border-radius:10px;background:#18181b;color:#fafafa;box-shadow:0 8px 30px rgb(0 0 0 / 0.35);font:13px/1.4 system-ui, sans-serif;}.refs.svelte-4537t3 {display:flex;flex-wrap:wrap;gap:4px;margin:0 0 6px;padding:0;list-style:none;}.refs.svelte-4537t3 li:where(.svelte-4537t3) {padding:1px 6px;border-left:3px solid var(--c);border-radius:3px;background:#27272a;font-size:12px;}textarea.svelte-4537t3 {display:block;width:100%;resize:none;padding:6px 8px;border:1px solid #3f3f46;border-radius:6px;background:#09090b;color:inherit;font:14px/1.4 ui-monospace, monospace;outline:none;}textarea.svelte-4537t3:focus {border-color:#3b82f6;}.hint.svelte-4537t3 {display:flex;justify-content:space-between;margin-top:4px;color:#a1a1aa;font-size:11px;}.status.svelte-4537t3 {color:#4ade80;}.status.failed.svelte-4537t3 {color:#f87171;}.output.svelte-4537t3 {max-height:40vh;overflow:auto;margin:0;padding:6px 8px;border:1px solid #3f3f46;border-radius:6px;background:#09090b;font:12px/1.45 ui-monospace, monospace;white-space:pre-wrap;word-break:break-word;user-select:text;cursor:text;outline:none;}.actions.svelte-4537t3 {display:flex;gap:6px;align-items:center;}.copy.svelte-4537t3 {padding:1px 8px;border:1px solid #3f3f46;border-radius:4px;background:#27272a;color:#fafafa;font:inherit;cursor:pointer;}.copy.svelte-4537t3:hover,\n .copy.svelte-4537t3:focus-visible {border-color:#3b82f6;outline:none;}.dismiss.svelte-4537t3 {padding:0 4px;border:0;background:none;color:inherit;font:inherit;cursor:pointer;}.dismiss.svelte-4537t3:hover {color:#fafafa;}.launcher.svelte-4537t3 {position:fixed;z-index:2147483647;right:12px;bottom:12px;padding:4px 10px;border:0;border-radius:6px;background:#18181b;color:#fafafa;font:12px/1.4 system-ui, sans-serif;cursor:pointer;opacity:0.6;}.launcher.svelte-4537t3:hover {opacity:1;}"
|
|
4672
4715
|
};
|
|
4673
4716
|
function Overlay($$anchor, $$props) {
|
|
4674
4717
|
push($$props, true);
|
|
@@ -4711,6 +4754,9 @@ function Overlay($$anchor, $$props) {
|
|
|
4711
4754
|
if (e.altKey && !e.ctrlKey && !e.metaKey && e.code === "KeyP") {
|
|
4712
4755
|
e.preventDefault();
|
|
4713
4756
|
toggle();
|
|
4757
|
+
} else if (e.key === "Escape" && get(output) && e.composedPath().includes($$props.host)) {
|
|
4758
|
+
e.preventDefault();
|
|
4759
|
+
dismiss();
|
|
4714
4760
|
}
|
|
4715
4761
|
};
|
|
4716
4762
|
window.addEventListener("keydown", onKey, true);
|
|
@@ -4789,12 +4835,6 @@ function Overlay($$anchor, $$props) {
|
|
|
4789
4835
|
set(output, "");
|
|
4790
4836
|
set(status, "");
|
|
4791
4837
|
}
|
|
4792
|
-
function onResultKeydown(e) {
|
|
4793
|
-
if (e.key === "Escape") {
|
|
4794
|
-
e.preventDefault();
|
|
4795
|
-
dismiss();
|
|
4796
|
-
}
|
|
4797
|
-
}
|
|
4798
4838
|
function onKeydown(e) {
|
|
4799
4839
|
if (e.isComposing || e.keyCode === 229) return;
|
|
4800
4840
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
@@ -4890,26 +4930,28 @@ function Overlay($$anchor, $$props) {
|
|
|
4890
4930
|
var node_5 = sibling(node_4, 2);
|
|
4891
4931
|
var consequent_3 = ($$anchor) => {
|
|
4892
4932
|
var fragment_3 = root_4();
|
|
4893
|
-
var
|
|
4894
|
-
var text_5 = only_child(
|
|
4895
|
-
|
|
4896
|
-
bind_this(button, ($$value) => set(result, $$value), () => get(result));
|
|
4897
|
-
var div_3 = sibling(button, 2);
|
|
4933
|
+
var pre = first_child(fragment_3);
|
|
4934
|
+
var text_5 = only_child(pre, true);
|
|
4935
|
+
var div_3 = sibling(pre, 2);
|
|
4898
4936
|
var span_2 = child(div_3);
|
|
4899
4937
|
var span_3 = child(span_2);
|
|
4900
4938
|
let classes;
|
|
4901
4939
|
var text_6 = only_child(span_3, true);
|
|
4902
4940
|
next();
|
|
4903
4941
|
reset(span_2);
|
|
4904
|
-
var
|
|
4942
|
+
var span_4 = sibling(span_2, 2);
|
|
4943
|
+
var button = child(span_4);
|
|
4944
|
+
bind_this(button, ($$value) => set(result, $$value), () => get(result));
|
|
4945
|
+
var button_1 = sibling(button, 2);
|
|
4946
|
+
reset(span_4);
|
|
4905
4947
|
reset(div_3);
|
|
4906
4948
|
template_effect(() => {
|
|
4907
4949
|
set_text(text_5, get(output));
|
|
4908
4950
|
classes = set_class(span_3, 1, "status svelte-4537t3", null, classes, { failed: get(failed) });
|
|
4909
4951
|
set_text(text_6, get(status) || "Copied");
|
|
4910
4952
|
});
|
|
4953
|
+
event("copy", pre, () => (set(status, "Copied selection"), set(failed, false)));
|
|
4911
4954
|
delegated("click", button, copy);
|
|
4912
|
-
delegated("keydown", button, onResultKeydown);
|
|
4913
4955
|
delegated("click", button_1, dismiss);
|
|
4914
4956
|
append($$anchor, fragment_3);
|
|
4915
4957
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinprompt",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.1-alpha.1",
|
|
4
|
+
"description": "Click your SvelteKit UI to tell your AI exactly where to change. Less describing, waiting and paying.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|
|
7
7
|
"sveltekit",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": ">=18"
|
|
29
29
|
},
|
|
30
|
+
"packageManager": "pnpm@12.9.1",
|
|
30
31
|
"files": [
|
|
31
32
|
"dist"
|
|
32
33
|
],
|