pi-harness-runtime 0.10.0 → 0.10.2
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/CHANGELOG.md +22 -0
- package/README.md +122 -0
- package/harness/e2e/minimax-quota-scraper.ts +4 -4
- package/harness/e2e/openai-quota-scraper.ts +13 -8
- package/index.ts +93 -2
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/dist/src/copy-sync.d.ts +27 -0
- package/packages/clipboard/dist/src/copy-sync.d.ts.map +1 -0
- package/packages/clipboard/dist/src/copy-sync.js +170 -0
- package/packages/clipboard/dist/src/copy-sync.js.map +1 -0
- package/packages/clipboard/dist/src/gist-relay.d.ts +48 -0
- package/packages/clipboard/dist/src/gist-relay.d.ts.map +1 -0
- package/packages/clipboard/dist/src/gist-relay.js +186 -0
- package/packages/clipboard/dist/src/gist-relay.js.map +1 -0
- package/packages/clipboard/dist/src/github-login.d.ts +16 -0
- package/packages/clipboard/dist/src/github-login.d.ts.map +1 -0
- package/packages/clipboard/dist/src/github-login.js +69 -0
- package/packages/clipboard/dist/src/github-login.js.map +1 -0
- package/packages/clipboard/dist/src/index.d.ts +2 -0
- package/packages/clipboard/dist/src/index.d.ts.map +1 -1
- package/packages/clipboard/dist/src/index.js +2 -1
- package/packages/clipboard/dist/src/index.js.map +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard/src/copy-sync.ts +201 -0
- package/packages/clipboard/src/gist-relay.ts +240 -0
- package/packages/clipboard/src/github-login.ts +107 -0
- package/packages/clipboard/src/index.ts +2 -0
- package/packages/clipboard/test/mojibake.test.mjs +143 -0
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +22 -0
- package/packages/todo-bd-sync/src/detector.ts +150 -0
- package/packages/todo-bd-sync/src/extension.ts +84 -0
- package/packages/todo-bd-sync/src/index.ts +401 -0
- package/packages/todo-bd-sync/src/sync.ts +322 -0
- package/packages/todo-bd-sync/src/todo-reminder.ts +418 -0
- package/packages/todo-bd-sync/src/types.ts +137 -0
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy + Sync — Ctrl+Shift+C shortcut for clipboard sync
|
|
3
|
+
*
|
|
4
|
+
* Registers a keyboard shortcut that:
|
|
5
|
+
* 1. Reads selected text from clipboard (Xvfb/X11 on headless server)
|
|
6
|
+
* 2. Writes to bridge file for terminal paste
|
|
7
|
+
* 3. POSTs to GitHub Gist for cross-device sync
|
|
8
|
+
*
|
|
9
|
+
* Only fires on explicit Ctrl+Shift+C — NOT on auto-select/highlight.
|
|
10
|
+
*/
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { homedir } from "node:os";
|
|
15
|
+
import { postToGist, isConfigured as isGistConfigured } from "./gist-relay.js";
|
|
16
|
+
// ─── Bridge file path ─────────────────────────────────────────────────────────
|
|
17
|
+
const BRIDGE_FILE = join(homedir(), ".herdr-clipboard");
|
|
18
|
+
const XCLIP_WRAPPER = join(homedir(), ".local", "bin", "xclip");
|
|
19
|
+
// ─── Mojibake detection & repair ──────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Detect UTF-8 mojibake (double-encoding: UTF-8 → Latin-1 → UTF-8).
|
|
22
|
+
*
|
|
23
|
+
* The pattern:
|
|
24
|
+
* - UTF-8 box-drawing chars (e2 xx xx) get Latin-1 decoded to "âÄx" chars
|
|
25
|
+
* - When those Latin-1 chars are re-encoded as UTF-8:
|
|
26
|
+
* - "â" (c3 a2) = UTF-8 Latin small Letter A with Circumflex
|
|
27
|
+
* - "Ä" (c2 94) = UTF-8 Latin Capital Letter A with Diaeresis
|
|
28
|
+
* - "Œ" (c2 8c) = UTF-8 Latin Capital Ligature OE
|
|
29
|
+
* - So raw UTF-8 box-drawing chars e2 94 8c become "âÄŒ" (c3 a2 c2 94 c2 8c)
|
|
30
|
+
* when misdecoded as Latin-1 then re-encoded.
|
|
31
|
+
*
|
|
32
|
+
* Detection heuristic: "â" or "Ã" followed by another non-ASCII char or
|
|
33
|
+
* box-drawing surrogate pairs. These sequences are almost always mojibake.
|
|
34
|
+
*/
|
|
35
|
+
function isMojibake(text) {
|
|
36
|
+
// "â" = \u00e2, "Ã" = \u00c3 — common Latin-1 surrogates in mojibake
|
|
37
|
+
// Check for these appearing before other non-ASCII chars (box-drawing etc.)
|
|
38
|
+
const moji = /[\u00e2\u00c2\u00e3\u00c3][\u0080-\u00ff]/;
|
|
39
|
+
return moji.test(text);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Repair UTF-8 mojibake: UTF-8 bytes interpreted as Latin-1 → re-interpret as UTF-8.
|
|
43
|
+
*
|
|
44
|
+
* Safe because:
|
|
45
|
+
* 1. isMojibake() already confirmed the string has the characteristic pattern
|
|
46
|
+
* 2. We only apply Buffer.from(str, "latin1") to the affected substrings
|
|
47
|
+
* 3. Plain ASCII and correctly-encoded UTF-8 pass through unchanged
|
|
48
|
+
* (Buffer.from("hello", "latin1").toString("utf8") === "hello")
|
|
49
|
+
* 4. Thai/other CJK scripts don't have the "â"+"Ä" surrogate pattern
|
|
50
|
+
*
|
|
51
|
+
* @param text - possibly-mojibaked string
|
|
52
|
+
* @returns repaired UTF-8 string
|
|
53
|
+
*/
|
|
54
|
+
function repairMojibake(text) {
|
|
55
|
+
if (!isMojibake(text))
|
|
56
|
+
return text;
|
|
57
|
+
try {
|
|
58
|
+
// Encode the JavaScript string back to its byte representation using
|
|
59
|
+
// Latin-1 (which is byte-identity for all code points 0-255), then
|
|
60
|
+
// decode those bytes as UTF-8. This reverses the double-encoding.
|
|
61
|
+
return Buffer.from(text, "latin1").toString("utf8");
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// If encoding fails for any reason, return original
|
|
65
|
+
return text;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// ─── Read from Xvfb clipboard ─────────────────────────────────────────────────
|
|
69
|
+
function readFromClipboard() {
|
|
70
|
+
// Try Xvfb xclip first (our headless clipboard)
|
|
71
|
+
try {
|
|
72
|
+
const content = execSync(`"${XCLIP_WRAPPER}" -selection clipboard -o 2>/dev/null || DISPLAY=:99 xclip -selection clipboard -o 2>/dev/null || true`, { encoding: "utf8", timeout: 2000 })
|
|
73
|
+
.trim()
|
|
74
|
+
// Repair mojibake that xclip or Xvfb might have introduced
|
|
75
|
+
.replace(/\r\n/g, "\n");
|
|
76
|
+
if (content)
|
|
77
|
+
return repairMojibake(content);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Fall through
|
|
81
|
+
}
|
|
82
|
+
// Fallback: read bridge file directly
|
|
83
|
+
try {
|
|
84
|
+
if (existsSync(BRIDGE_FILE)) {
|
|
85
|
+
const content = readFileSync(BRIDGE_FILE, "utf8").trim();
|
|
86
|
+
if (content)
|
|
87
|
+
return repairMojibake(content);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// fall through
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
// ─── Write to bridge file ─────────────────────────────────────────────────────
|
|
96
|
+
function writeToBridge(text) {
|
|
97
|
+
try {
|
|
98
|
+
// Write raw UTF-8 bytes — no transformation needed.
|
|
99
|
+
// UTF-8 strings in Node.js write correctly with writeFileSync(file, "utf8").
|
|
100
|
+
writeFileSync(BRIDGE_FILE, text, "utf8");
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// ignore
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ─── Write to Xvfb clipboard ──────────────────────────────────────────────────
|
|
107
|
+
function writeToXvfb(text) {
|
|
108
|
+
try {
|
|
109
|
+
// Pass raw bytes via Buffer to avoid any implicit encoding conversion.
|
|
110
|
+
// This ensures UTF-8 multi-byte sequences are sent as-is to xclip.
|
|
111
|
+
execSync(`"${XCLIP_WRAPPER}" -selection clipboard -in`, {
|
|
112
|
+
input: Buffer.from(text, "utf8"),
|
|
113
|
+
timeout: 5000,
|
|
114
|
+
});
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ─── Main: copy + sync ───────────────────────────────────────────────────────
|
|
122
|
+
/**
|
|
123
|
+
* Read selected text, write to bridge, sync to Gist.
|
|
124
|
+
* Called by the Ctrl+Shift+C shortcut handler.
|
|
125
|
+
*/
|
|
126
|
+
export async function copyAndSync(ctx) {
|
|
127
|
+
const text = readFromClipboard();
|
|
128
|
+
if (!text) {
|
|
129
|
+
ctx.ui.notify("No clipboard content. Make sure text is selected in the terminal.", "warning");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
// Write to bridge file (for terminal paste)
|
|
133
|
+
writeToBridge(text);
|
|
134
|
+
// Write to Xvfb clipboard (for Ctrl+Shift+V paste in terminal)
|
|
135
|
+
const xvfbOk = writeToXvfb(text);
|
|
136
|
+
// Sync to GitHub Gist (for cross-device clipboard)
|
|
137
|
+
if (isGistConfigured()) {
|
|
138
|
+
const gistOk = await postToGist(text);
|
|
139
|
+
if (gistOk) {
|
|
140
|
+
ctx.ui.notify(`Synced ${text.length} chars to Gist ✓`, "info");
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
ctx.ui.notify(`Copied ${text.length} chars (Gist sync failed)`, "warning");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (xvfbOk) {
|
|
147
|
+
ctx.ui.notify(`Copied ${text.length} chars to clipboard`, "info");
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
ctx.ui.notify(`Copied ${text.length} chars (terminal paste may not work on headless server)`, "warning");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Register Ctrl+Shift+C as the copy+sync shortcut.
|
|
155
|
+
* The Key.ctrlShift("c") syntax comes from @earendil-works/pi-tui.
|
|
156
|
+
*/
|
|
157
|
+
export function registerCopySyncShortcut(pi, Key) {
|
|
158
|
+
try {
|
|
159
|
+
pi.registerShortcut(Key.ctrlShift("c"), {
|
|
160
|
+
description: "Copy to clipboard + sync to GitHub Gist",
|
|
161
|
+
handler: async (rawCtx) => {
|
|
162
|
+
await copyAndSync(rawCtx);
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
console.error("[copy-sync] Failed to register shortcut:", err);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=copy-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy-sync.js","sourceRoot":"","sources":["../../src/copy-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gist Relay — GitHub Gist clipboard sync
|
|
3
|
+
*
|
|
4
|
+
* Stores clipboard content in a secret Gist, accessible from any device.
|
|
5
|
+
* - POST: Upload clipboard content to Gist
|
|
6
|
+
* - GET: Download latest clipboard content from Gist
|
|
7
|
+
*
|
|
8
|
+
* Security: Uses secret Gist (only accessible via API token)
|
|
9
|
+
*/
|
|
10
|
+
interface GistConfig {
|
|
11
|
+
token: string;
|
|
12
|
+
gistId: string;
|
|
13
|
+
gistUrl: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if Gist relay is configured
|
|
17
|
+
*/
|
|
18
|
+
export declare function isConfigured(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Get stored GitHub token
|
|
21
|
+
*/
|
|
22
|
+
export declare function getToken(): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Store GitHub token and Gist ID after initial setup
|
|
25
|
+
*/
|
|
26
|
+
export declare function saveCredentials(token: string, gistId: string, gistUrl: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Create a new secret Gist and return its ID
|
|
29
|
+
*/
|
|
30
|
+
export declare function createGist(token: string, content: string): Promise<GistConfig | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Update existing Gist with new clipboard content
|
|
33
|
+
*/
|
|
34
|
+
export declare function updateGist(content: string): Promise<boolean>;
|
|
35
|
+
/**
|
|
36
|
+
* Fetch current clipboard content from Gist
|
|
37
|
+
*/
|
|
38
|
+
export declare function fetchFromGist(): Promise<string | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Post clipboard content to Gist. Creates Gist on first call, updates on subsequent calls.
|
|
41
|
+
*/
|
|
42
|
+
export declare function postToGist(content: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Delete stored Gist config (for reset)
|
|
45
|
+
*/
|
|
46
|
+
export declare function clearConfig(): void;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=gist-relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gist-relay.d.ts","sourceRoot":"","sources":["../../src/gist-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,UAAU,UAAU;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AA+BD;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAExC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACb,IAAI,CAEN;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAyC5B;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA4ClE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2B5D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBlE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAOlC"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gist Relay — GitHub Gist clipboard sync
|
|
3
|
+
*
|
|
4
|
+
* Stores clipboard content in a secret Gist, accessible from any device.
|
|
5
|
+
* - POST: Upload clipboard content to Gist
|
|
6
|
+
* - GET: Download latest clipboard content from Gist
|
|
7
|
+
*
|
|
8
|
+
* Security: Uses secret Gist (only accessible via API token)
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
const HARNESS_DIR = join(homedir(), ".pi-harness-runtime");
|
|
14
|
+
const CONFIG_FILE = join(HARNESS_DIR, "gist-config.json");
|
|
15
|
+
// ─── Config ──────────────────────────────────────────────────────────────
|
|
16
|
+
function loadConfig() {
|
|
17
|
+
try {
|
|
18
|
+
if (!existsSync(CONFIG_FILE))
|
|
19
|
+
return null;
|
|
20
|
+
const raw = readFileSync(CONFIG_FILE, "utf8");
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveConfig(config) {
|
|
28
|
+
mkdirSync(HARNESS_DIR, { recursive: true });
|
|
29
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), "utf8");
|
|
30
|
+
}
|
|
31
|
+
// ─── API ────────────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Check if Gist relay is configured
|
|
34
|
+
*/
|
|
35
|
+
export function isConfigured() {
|
|
36
|
+
return loadConfig() !== null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get stored GitHub token
|
|
40
|
+
*/
|
|
41
|
+
export function getToken() {
|
|
42
|
+
return loadConfig()?.token ?? null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Store GitHub token and Gist ID after initial setup
|
|
46
|
+
*/
|
|
47
|
+
export function saveCredentials(token, gistId, gistUrl) {
|
|
48
|
+
saveConfig({ token, gistId, gistUrl });
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a new secret Gist and return its ID
|
|
52
|
+
*/
|
|
53
|
+
export async function createGist(token, content) {
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch("https://api.github.com/gists", {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: {
|
|
58
|
+
Authorization: `Bearer ${token}`,
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
Accept: "application/vnd.github+json",
|
|
61
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
62
|
+
},
|
|
63
|
+
body: JSON.stringify({
|
|
64
|
+
description: "pi-harness-runtime clipboard sync",
|
|
65
|
+
public: false,
|
|
66
|
+
files: {
|
|
67
|
+
"clipboard.txt": {
|
|
68
|
+
content: content || "(empty)",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const error = await response.text();
|
|
75
|
+
console.error(`[gist-relay] Failed to create Gist: ${response.status} ${error}`);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const gist = (await response.json());
|
|
79
|
+
const config = {
|
|
80
|
+
token,
|
|
81
|
+
gistId: gist.id,
|
|
82
|
+
gistUrl: gist.html_url,
|
|
83
|
+
};
|
|
84
|
+
saveConfig(config);
|
|
85
|
+
return config;
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
console.error("[gist-relay] Failed to create Gist:", err);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Update existing Gist with new clipboard content
|
|
94
|
+
*/
|
|
95
|
+
export async function updateGist(content) {
|
|
96
|
+
const config = loadConfig();
|
|
97
|
+
if (!config) {
|
|
98
|
+
console.error("[gist-relay] Not configured. Run 'bun run gist-auth' first.");
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const response = await fetch(`https://api.github.com/gists/${config.gistId}`, {
|
|
103
|
+
method: "PATCH",
|
|
104
|
+
headers: {
|
|
105
|
+
Authorization: `Bearer ${config.token}`,
|
|
106
|
+
"Content-Type": "application/json",
|
|
107
|
+
Accept: "application/vnd.github+json",
|
|
108
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
109
|
+
},
|
|
110
|
+
body: JSON.stringify({
|
|
111
|
+
description: "pi-harness-runtime clipboard sync",
|
|
112
|
+
files: {
|
|
113
|
+
"clipboard.txt": {
|
|
114
|
+
content: content,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const error = await response.text();
|
|
121
|
+
console.error(`[gist-relay] Failed to update Gist: ${response.status} ${error}`);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
console.error("[gist-relay] Failed to update Gist:", err);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetch current clipboard content from Gist
|
|
133
|
+
*/
|
|
134
|
+
export async function fetchFromGist() {
|
|
135
|
+
const config = loadConfig();
|
|
136
|
+
if (!config) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const response = await fetch(`https://api.github.com/gists/${config.gistId}`, {
|
|
141
|
+
headers: {
|
|
142
|
+
Authorization: `Bearer ${config.token}`,
|
|
143
|
+
Accept: "application/vnd.github+json",
|
|
144
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const gist = (await response.json());
|
|
151
|
+
return gist.files["clipboard.txt"]?.content ?? null;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Post clipboard content to Gist. Creates Gist on first call, updates on subsequent calls.
|
|
159
|
+
*/
|
|
160
|
+
export async function postToGist(content) {
|
|
161
|
+
const config = loadConfig();
|
|
162
|
+
if (!config) {
|
|
163
|
+
// First time — need token
|
|
164
|
+
console.error("[gist-relay] Not configured. Run 'bun run gist-auth' first.");
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
// Update existing Gist
|
|
168
|
+
const ok = await updateGist(content);
|
|
169
|
+
if (ok) {
|
|
170
|
+
console.error(`[gist-relay] Synced ${content.length} chars to Gist`);
|
|
171
|
+
}
|
|
172
|
+
return ok;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Delete stored Gist config (for reset)
|
|
176
|
+
*/
|
|
177
|
+
export function clearConfig() {
|
|
178
|
+
try {
|
|
179
|
+
const { unlinkSync } = require("node:fs");
|
|
180
|
+
unlinkSync(CONFIG_FILE);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// ignore
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=gist-relay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gist-relay.js","sourceRoot":"","sources":["../../src/gist-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC,CAAC;AAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;AAkB1D,4EAA4E;AAE5E,SAAS,UAAU;IAClB,IAAI,CAAC;QACJ,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,SAAS,UAAU,CAAC,MAAkB;IACrC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACrE,CAAC;AAED,2EAA2E;AAE3E;;GAEG;AACH,MAAM,UAAU,YAAY;IAC3B,OAAO,UAAU,EAAE,KAAK,IAAI,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACvB,OAAO,UAAU,EAAE,EAAE,KAAK,IAAI,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC9B,KAAa,EACb,MAAc,EACd,OAAe;IAEf,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,KAAa,EACb,OAAe;IAEf,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,8BAA8B,EAAE;YAC5D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACR,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,6BAA6B;gBACrC,sBAAsB,EAAE,YAAY;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACpB,WAAW,EAAE,mCAAmC;gBAChD,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE;oBACN,eAAe,EAAE;wBAChB,OAAO,EAAE,OAAO,IAAI,SAAS;qBAC7B;iBACD;aACD,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,CACZ,uCAAuC,QAAQ,CAAC,MAAM,IAAI,KAAK,EAAE,CACjE,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiB,CAAC;QACrD,MAAM,MAAM,GAAe;YAC1B,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,QAAQ;SACtB,CAAC;QACF,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,MAAM,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACZ,6DAA6D,CAC7D,CAAC;QACF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC3B,gCAAgC,MAAM,CAAC,MAAM,EAAE,EAC/C;YACC,MAAM,EAAE,OAAO;YACf,OAAO,EAAE;gBACR,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE;gBACvC,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,6BAA6B;gBACrC,sBAAsB,EAAE,YAAY;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACpB,WAAW,EAAE,mCAAmC;gBAChD,KAAK,EAAE;oBACN,eAAe,EAAE;wBAChB,OAAO,EAAE,OAAO;qBAChB;iBACD;aACD,CAAC;SACF,CACD,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,CACZ,uCAAuC,QAAQ,CAAC,MAAM,IAAI,KAAK,EAAE,CACjE,CAAC;YACF,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;QAC1D,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC3B,gCAAgC,MAAM,CAAC,MAAM,EAAE,EAC/C;YACC,OAAO,EAAE;gBACR,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE;gBACvC,MAAM,EAAE,6BAA6B;gBACrC,sBAAsB,EAAE,YAAY;aACpC;SACD,CACD,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiB,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,0BAA0B;QAC1B,OAAO,CAAC,KAAK,CACZ,6DAA6D,CAC7D,CAAC;QACF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,uBAAuB;IACvB,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,uBAAuB,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IAC1B,IAAI,CAAC;QACJ,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,UAAU,CAAC,WAAW,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,SAAS;IACV,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Login — /github-login slash command
|
|
3
|
+
*
|
|
4
|
+
* Registers the /github-login command that prompts for GitHub PAT
|
|
5
|
+
* and creates a secret Gist for clipboard sync.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Register /github-login command in pi-coding-agent
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerGithubLoginCommand(pi: {
|
|
11
|
+
registerCommand: (name: string, options: {
|
|
12
|
+
description: string;
|
|
13
|
+
handler: (args: string, ctx: unknown) => Promise<void>;
|
|
14
|
+
}) => void;
|
|
15
|
+
}): void;
|
|
16
|
+
//# sourceMappingURL=github-login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-login.d.ts","sourceRoot":"","sources":["../../src/github-login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,EAAE;IAC9C,eAAe,EAAE,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACR,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACvD,KACG,IAAI,CAAC;CACV,GAAG,IAAI,CAsFP"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Login — /github-login slash command
|
|
3
|
+
*
|
|
4
|
+
* Registers the /github-login command that prompts for GitHub PAT
|
|
5
|
+
* and creates a secret Gist for clipboard sync.
|
|
6
|
+
*/
|
|
7
|
+
import { createGist, isConfigured } from "./gist-relay.js";
|
|
8
|
+
/**
|
|
9
|
+
* Register /github-login command in pi-coding-agent
|
|
10
|
+
*/
|
|
11
|
+
export function registerGithubLoginCommand(pi) {
|
|
12
|
+
pi.registerCommand("github-login", {
|
|
13
|
+
description: "Connect GitHub Gist for clipboard sync across devices",
|
|
14
|
+
handler: async (_args, rawCtx) => {
|
|
15
|
+
const ctx = rawCtx;
|
|
16
|
+
// Check if already configured
|
|
17
|
+
if (isConfigured()) {
|
|
18
|
+
const reset = await ctx.ui.confirm("GitHub Gist already configured", "Reset and reconfigure?");
|
|
19
|
+
if (!reset) {
|
|
20
|
+
ctx.ui.notify("Cancelled.", "info");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
ctx.ui.notify("Setting up GitHub Gist clipboard sync...", "info");
|
|
25
|
+
// Step 1: Ask user to create PAT
|
|
26
|
+
const instructions = [
|
|
27
|
+
"",
|
|
28
|
+
"Create a GitHub Personal Access Token:",
|
|
29
|
+
" 1. Go to https://github.com/settings/tokens",
|
|
30
|
+
" 2. Generate new token (classic)",
|
|
31
|
+
" 3. Select scope: gist",
|
|
32
|
+
" 4. Copy the token",
|
|
33
|
+
"",
|
|
34
|
+
].join("\n");
|
|
35
|
+
ctx.ui.notify(instructions, "info");
|
|
36
|
+
// Step 2: Prompt for PAT
|
|
37
|
+
const token = await ctx.ui.input("GitHub Personal Access Token", "ghp_xxxxxxxxxxxxxxxxxxxx");
|
|
38
|
+
if (!token?.trim()) {
|
|
39
|
+
ctx.ui.notify("No token provided. Cancelled.", "warning");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Step 3: Create Gist
|
|
43
|
+
ctx.ui.notify("Creating secret Gist...", "info");
|
|
44
|
+
const testContent = [
|
|
45
|
+
"pi-harness-runtime clipboard sync",
|
|
46
|
+
`Connected at: ${new Date().toISOString()}`,
|
|
47
|
+
"",
|
|
48
|
+
"This Gist stores clipboard content for cross-device sync.",
|
|
49
|
+
"Polling script: see scripts/gist-poll.sh",
|
|
50
|
+
].join("\n");
|
|
51
|
+
const result = await createGist(token.trim(), testContent);
|
|
52
|
+
if (result) {
|
|
53
|
+
ctx.ui.notify([
|
|
54
|
+
"✅ GitHub Gist clipboard sync configured!",
|
|
55
|
+
"",
|
|
56
|
+
` Gist: ${result.gistUrl}`,
|
|
57
|
+
"",
|
|
58
|
+
" Polling script: scripts/gist-poll.sh",
|
|
59
|
+
" Run: bun scripts/gist-auth-poll.ts on client devices",
|
|
60
|
+
"",
|
|
61
|
+
].join("\n"), "info");
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
ctx.ui.notify("❌ Failed to create Gist. Check your PAT and try again.", "error");
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=github-login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-login.js","sourceRoot":"","sources":["../../src/github-login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,EAQ1C;IACA,EAAE,CAAC,eAAe,CAAC,cAAc,EAAE;QAClC,WAAW,EAAE,uDAAuD;QACpE,OAAO,EAAE,KAAK,EAAE,KAAa,EAAE,MAAe,EAAE,EAAE;YACjD,MAAM,GAAG,GAAG,MASX,CAAC;YACF,8BAA8B;YAC9B,IAAI,YAAY,EAAE,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CACjC,gCAAgC,EAChC,wBAAwB,CACxB,CAAC;gBACF,IAAI,CAAC,KAAK,EAAE,CAAC;oBACZ,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;oBACpC,OAAO;gBACR,CAAC;YACF,CAAC;YAED,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,0CAA0C,EAAE,MAAM,CAAC,CAAC;YAElE,iCAAiC;YACjC,MAAM,YAAY,GAAG;gBACpB,EAAE;gBACF,wCAAwC;gBACxC,+CAA+C;gBAC/C,mCAAmC;gBACnC,yBAAyB;gBACzB,qBAAqB;gBACrB,EAAE;aACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAEpC,yBAAyB;YACzB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,CAC/B,8BAA8B,EAC9B,0BAA0B,CAC1B,CAAC;YAEF,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;gBACpB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,+BAA+B,EAAE,SAAS,CAAC,CAAC;gBAC1D,OAAO;YACR,CAAC;YAED,sBAAsB;YACtB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAC;YAEjD,MAAM,WAAW,GAAG;gBACnB,mCAAmC;gBACnC,iBAAiB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;gBAC3C,EAAE;gBACF,2DAA2D;gBAC3D,0CAA0C;aAC1C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;YAE3D,IAAI,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,EAAE,CAAC,MAAM,CACZ;oBACC,0CAA0C;oBAC1C,EAAE;oBACF,YAAY,MAAM,CAAC,OAAO,EAAE;oBAC5B,EAAE;oBACF,yCAAyC;oBACzC,yDAAyD;oBACzD,EAAE;iBACF,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ,MAAM,CACN,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,GAAG,CAAC,EAAE,CAAC,MAAM,CACZ,wDAAwD,EACxD,OAAO,CACP,CAAC;YACH,CAAC;QACF,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrE,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC"}
|