opendoor-plugin 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.
- package/README.md +1 -0
- package/dist/browser/pi-web-plugin.js +60 -27
- package/dist/package.json +4 -2
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -271,6 +271,7 @@ bottom:
|
|
|
271
271
|
```sh
|
|
272
272
|
npm install # install dependencies
|
|
273
273
|
npm test # vitest (unit tests under src/**/*.test.ts)
|
|
274
|
+
npm run test:coverage # v8 coverage report
|
|
274
275
|
npm run typecheck # tsc --noEmit (strict)
|
|
275
276
|
npm run build # esbuild: dist/browser/pi-web-plugin.js + dist/server-plugin.js
|
|
276
277
|
# (+ verbatim package.json manifest copy into dist/)
|
|
@@ -7568,9 +7568,32 @@ var panelStyles = i`
|
|
|
7568
7568
|
background: var(--pi-selection-bg);
|
|
7569
7569
|
}
|
|
7570
7570
|
|
|
7571
|
+
/* The per-link trash can (pointer-only, see {@link renderLinkOut}):
|
|
7572
|
+
right-aligned in the flex row, mirroring .doorstop-item-add. */
|
|
7573
|
+
.doorstop-link-remove {
|
|
7574
|
+
display: inline-flex;
|
|
7575
|
+
align-items: center;
|
|
7576
|
+
align-self: center;
|
|
7577
|
+
flex: 0 0 auto;
|
|
7578
|
+
margin-left: auto;
|
|
7579
|
+
color: var(--pi-muted);
|
|
7580
|
+
cursor: pointer;
|
|
7581
|
+
}
|
|
7582
|
+
|
|
7583
|
+
.doorstop-link-remove:hover {
|
|
7584
|
+
color: var(--pi-text);
|
|
7585
|
+
}
|
|
7586
|
+
|
|
7571
7587
|
.doorstop-fingerprint {
|
|
7572
7588
|
color: var(--pi-muted);
|
|
7573
7589
|
font-size: 11px;
|
|
7590
|
+
/* The link row wraps, which could push the trash can onto a second
|
|
7591
|
+
line on narrow panes. Let the fingerprint shrink and ellipsize
|
|
7592
|
+
instead (min-width: 0 lifts the flex min-content floor). */
|
|
7593
|
+
min-width: 0;
|
|
7594
|
+
overflow: hidden;
|
|
7595
|
+
text-overflow: ellipsis;
|
|
7596
|
+
white-space: nowrap;
|
|
7574
7597
|
}
|
|
7575
7598
|
|
|
7576
7599
|
.doorstop-attributes {
|
|
@@ -7688,7 +7711,7 @@ var panelStyles = i`
|
|
|
7688
7711
|
.doorstop-menu-items {
|
|
7689
7712
|
position: absolute;
|
|
7690
7713
|
right: 0;
|
|
7691
|
-
|
|
7714
|
+
bottom: calc(100% + 4px);
|
|
7692
7715
|
z-index: 3;
|
|
7693
7716
|
min-width: 180px;
|
|
7694
7717
|
display: grid;
|
|
@@ -7943,6 +7966,7 @@ var publishIconSvg = w`<svg width="14" height="14" viewBox="0 0 24 24" fill="non
|
|
|
7943
7966
|
var gitStageIconSvg = w`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M8 12h8"/><path d="M12 8v8"/></svg>`;
|
|
7944
7967
|
var gitUnstageIconSvg = w`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M8 12h8"/></svg>`;
|
|
7945
7968
|
var gitCommitIconSvg = w`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>`;
|
|
7969
|
+
var trashIconSvg = w`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M10 11v6"/><path d="M14 11v6"/></svg>`;
|
|
7946
7970
|
|
|
7947
7971
|
// src/doorstop-prompts.ts
|
|
7948
7972
|
function andJoin(values) {
|
|
@@ -8717,9 +8741,9 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8717
8741
|
<div class="doorstop-state-chip-row">
|
|
8718
8742
|
${item.stateKeys.map((key) => this.renderStateChip(key))}
|
|
8719
8743
|
</div>
|
|
8720
|
-
${this.renderChangesSinceReview(item)}
|
|
8721
8744
|
<h4 class="doorstop-section-title">Text</h4>
|
|
8722
8745
|
<p class=${item.text === "" ? "doorstop-text doorstop-text-empty" : "doorstop-text"}>${item.text === "" ? "empty" : item.text}</p>
|
|
8746
|
+
${this.renderChangesSinceReview(item)}
|
|
8723
8747
|
<h4 class="doorstop-section-title">Parent links</h4>
|
|
8724
8748
|
${this.renderLinksOut(item, result.index)}
|
|
8725
8749
|
<h4 class="doorstop-section-title">Child links</h4>
|
|
@@ -8781,11 +8805,22 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8781
8805
|
if (item.links.length === 0) return b2`<p class="doorstop-muted">No parent links.</p>`;
|
|
8782
8806
|
return b2`
|
|
8783
8807
|
<div class="doorstop-links" aria-label="Parent links">
|
|
8784
|
-
${item.links.map((link) => this.renderLinkOut(link, index))}
|
|
8808
|
+
${item.links.map((link) => this.renderLinkOut(item, link, index))}
|
|
8785
8809
|
</div>
|
|
8786
8810
|
`;
|
|
8787
8811
|
}
|
|
8788
|
-
renderLinkOut(link, index) {
|
|
8812
|
+
renderLinkOut(item, link, index) {
|
|
8813
|
+
const remove = b2`
|
|
8814
|
+
<span
|
|
8815
|
+
class="doorstop-link-remove"
|
|
8816
|
+
aria-hidden="true"
|
|
8817
|
+
title=${`doorstop unlink ${item.uid} ${link.uid}`}
|
|
8818
|
+
@click=${(event) => {
|
|
8819
|
+
event.stopPropagation();
|
|
8820
|
+
this.unlinkLink(item, link.uid);
|
|
8821
|
+
}}
|
|
8822
|
+
>${trashIconSvg}</span>
|
|
8823
|
+
`;
|
|
8789
8824
|
const target = index.byUid.get(link.uid);
|
|
8790
8825
|
if (target === void 0) {
|
|
8791
8826
|
return b2`
|
|
@@ -8793,6 +8828,7 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8793
8828
|
<code>${link.uid}</code>
|
|
8794
8829
|
<span class="doorstop-chip doorstop-chip-danger">unknown</span>
|
|
8795
8830
|
<span class="doorstop-fingerprint">not in the index — ${link.fingerprint === null ? "no recorded fingerprint" : `recorded ${shortFingerprint(link.fingerprint)}`}</span>
|
|
8831
|
+
${remove}
|
|
8796
8832
|
</div>
|
|
8797
8833
|
`;
|
|
8798
8834
|
}
|
|
@@ -8811,6 +8847,7 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8811
8847
|
<code>${link.uid}</code>
|
|
8812
8848
|
<span class=${suspect ? "doorstop-chip doorstop-chip-danger" : "doorstop-chip doorstop-chip-ok"}>${suspect ? "suspect" : "ok"}</span>
|
|
8813
8849
|
<span class="doorstop-fingerprint">recorded ${shortFingerprint(link.fingerprint)} · current ${shortFingerprint(current)}</span>
|
|
8850
|
+
${remove}
|
|
8814
8851
|
</button>
|
|
8815
8852
|
`;
|
|
8816
8853
|
}
|
|
@@ -8869,7 +8906,7 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8869
8906
|
@click=${() => {
|
|
8870
8907
|
this.reviewItem(item);
|
|
8871
8908
|
}}
|
|
8872
|
-
>
|
|
8909
|
+
>Approve</button>
|
|
8873
8910
|
<button
|
|
8874
8911
|
type="button"
|
|
8875
8912
|
class="doorstop-clear"
|
|
@@ -8879,15 +8916,6 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8879
8916
|
this.clearSuspects(item, suspectUids);
|
|
8880
8917
|
}}
|
|
8881
8918
|
>Clear suspect links</button>
|
|
8882
|
-
<button
|
|
8883
|
-
type="button"
|
|
8884
|
-
class="doorstop-edit"
|
|
8885
|
-
?disabled=${this.runInProgress !== void 0}
|
|
8886
|
-
title=${`Open ${item.uid} in the editor`}
|
|
8887
|
-
@click=${() => {
|
|
8888
|
-
this.editItem(item);
|
|
8889
|
-
}}
|
|
8890
|
-
>Edit</button>
|
|
8891
8919
|
${gitStatus === void 0 ? A : b2`<button
|
|
8892
8920
|
type="button"
|
|
8893
8921
|
class="doorstop-item-stage"
|
|
@@ -8906,19 +8934,6 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8906
8934
|
this.unstageItem(item);
|
|
8907
8935
|
}}
|
|
8908
8936
|
>${gitUnstageIconSvg}Unstage</button>`}
|
|
8909
|
-
<div class="doorstop-op">
|
|
8910
|
-
<input
|
|
8911
|
-
type="text"
|
|
8912
|
-
class="doorstop-target-input"
|
|
8913
|
-
data-op="unlink"
|
|
8914
|
-
placeholder="parent UID"
|
|
8915
|
-
${n5(this.unlinkInputRef)}
|
|
8916
|
-
@keydown=${this.onTargetKeydown}
|
|
8917
|
-
/>
|
|
8918
|
-
<button type="button" class="doorstop-unlink" title=${`doorstop unlink ${item.uid} <target>`} ?disabled=${this.runInProgress !== void 0} @click=${() => {
|
|
8919
|
-
this.runTargetOp("unlink", this.unlinkInputRef, item);
|
|
8920
|
-
}}>Unlink</button>
|
|
8921
|
-
</div>
|
|
8922
8937
|
<div class="doorstop-op">
|
|
8923
8938
|
<input
|
|
8924
8939
|
type="text"
|
|
@@ -8999,6 +9014,24 @@ function defineDoorstopPanelBodyElement() {
|
|
|
8999
9014
|
if (controller === void 0 || controller.runInProgress !== void 0) return;
|
|
9000
9015
|
void controller.runGitUnstage([item.path], `Git: unstage ${item.uid}`);
|
|
9001
9016
|
}
|
|
9017
|
+
/** Unlink one parent from one item — the same `unlink` run the palette's
|
|
9018
|
+
* free-text Unlink button dispatches, but with the target sourced from
|
|
9019
|
+
* the index (`link.uid`) instead of an input. The guard mirrors
|
|
9020
|
+
* {@link stageItem}: a run already in flight must never be overlapped.
|
|
9021
|
+
* There is no `targetError` interaction: an index-sourced UID cannot
|
|
9022
|
+
* fail the free-text validation, and `parseDoorstopRunRequest`
|
|
9023
|
+
* re-validates server-side. */
|
|
9024
|
+
unlinkLink(item, target) {
|
|
9025
|
+
const controller = this.controller;
|
|
9026
|
+
if (controller === void 0 || controller.runInProgress !== void 0) return;
|
|
9027
|
+
this.runDoorstop(
|
|
9028
|
+
"unlink",
|
|
9029
|
+
`Doorstop: unlink ${item.uid}`,
|
|
9030
|
+
{ op: "unlink", uid: item.uid, target },
|
|
9031
|
+
`doorstop unlink ${item.uid} ${target}`,
|
|
9032
|
+
false
|
|
9033
|
+
);
|
|
9034
|
+
}
|
|
9002
9035
|
/**
|
|
9003
9036
|
* The browser must never send an empty commit message: the server
|
|
9004
9037
|
* rejects it, and git with an empty `-m` would hang the exec until the
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opendoor-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Opendoor — a pi-web browser plugin that surfaces Doorstop requirements stored in the workspace: the document tree, per-item state (reviewed/unreviewed changes, suspect links), validation findings, and one-click doorstop CLI actions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"build": "node scripts/build-plugin.mjs",
|
|
34
34
|
"dev": "node scripts/build-plugin.mjs --watch",
|
|
35
35
|
"test": "vitest run",
|
|
36
|
+
"test:coverage": "vitest run --coverage",
|
|
36
37
|
"typecheck": "tsc --noEmit"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
@@ -42,10 +43,11 @@
|
|
|
42
43
|
"@jmfederico/pi-web": "^1.202608.2",
|
|
43
44
|
"@types/js-yaml": "^4.0.9",
|
|
44
45
|
"@types/node": "^24.0.0",
|
|
46
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
45
47
|
"esbuild": "^0.27.7",
|
|
48
|
+
"happy-dom": "^20.11.1",
|
|
46
49
|
"js-yaml": "^4.3.2",
|
|
47
50
|
"lit": "^3.3.3",
|
|
48
|
-
"happy-dom": "^20.11.1",
|
|
49
51
|
"typescript": "^6.0.3",
|
|
50
52
|
"vitest": "^4.1.10"
|
|
51
53
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opendoor-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Opendoor — a pi-web browser plugin that surfaces Doorstop requirements stored in the workspace: the document tree, per-item state (reviewed/unreviewed changes, suspect links), validation findings, and one-click doorstop CLI actions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"build": "node scripts/build-plugin.mjs",
|
|
34
34
|
"dev": "node scripts/build-plugin.mjs --watch",
|
|
35
35
|
"test": "vitest run",
|
|
36
|
+
"test:coverage": "vitest run --coverage",
|
|
36
37
|
"typecheck": "tsc --noEmit"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
@@ -42,10 +43,11 @@
|
|
|
42
43
|
"@jmfederico/pi-web": "^1.202608.2",
|
|
43
44
|
"@types/js-yaml": "^4.0.9",
|
|
44
45
|
"@types/node": "^24.0.0",
|
|
46
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
45
47
|
"esbuild": "^0.27.7",
|
|
48
|
+
"happy-dom": "^20.11.1",
|
|
46
49
|
"js-yaml": "^4.3.2",
|
|
47
50
|
"lit": "^3.3.3",
|
|
48
|
-
"happy-dom": "^20.11.1",
|
|
49
51
|
"typescript": "^6.0.3",
|
|
50
52
|
"vitest": "^4.1.10"
|
|
51
53
|
}
|