@pageops/sdk 0.1.38 → 0.1.39

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/dist/client.d.ts CHANGED
@@ -9,6 +9,7 @@ export declare class PageOpsClient {
9
9
  listMessages(threadId: string): Promise<ConversationMessage[]>;
10
10
  getAgentRun(runId: string): Promise<AgentRunHistory>;
11
11
  listSources(): Promise<SourceSnapshot[]>;
12
+ deleteSource(sourceSnapshotId: string): Promise<{ status: string; warning?: string | null }>;
12
13
  uploadSource(file: File, metadata: SourceUploadMetadata): Promise<SourceSnapshot>;
13
14
  streamQuestion(threadId: string, question: string, userRole: string, signal?: AbortSignal): Promise<Response>;
14
15
  private request;
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ declare class PageOpsSDKController {
23
23
  private sourceUploadError;
24
24
  private sourceLoadError;
25
25
  private sourceUploading;
26
+ private deletingSourceId;
26
27
  private sourceRefreshTimer;
27
28
  private developerAccess;
28
29
  private streaming;
@@ -68,6 +69,7 @@ declare class PageOpsSDKController {
68
69
  private selectThread;
69
70
  private deleteConversation;
70
71
  private uploadSource;
72
+ private deleteSourceSnapshot;
71
73
  private ask;
72
74
  private cancelActiveAnswer;
73
75
  private handleStreamEvent;
@@ -140,3 +140,43 @@
140
140
  .po-message.user > div {
141
141
  margin-top: 1px;
142
142
  }
143
+
144
+ .po-source-item-head {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: space-between;
148
+ gap: 8px;
149
+ min-width: 0;
150
+ }
151
+
152
+ .po-source-item-head strong {
153
+ min-width: 0;
154
+ }
155
+
156
+ .po-source-delete {
157
+ display: grid;
158
+ width: 28px;
159
+ height: 28px;
160
+ flex: 0 0 auto;
161
+ place-items: center;
162
+ border: 0;
163
+ border-radius: 6px;
164
+ background: transparent;
165
+ color: #64748b;
166
+ }
167
+
168
+ .po-source-delete:hover,
169
+ .po-source-delete:focus-visible {
170
+ background: #fee2e2;
171
+ color: #b91c1c;
172
+ }
173
+
174
+ .po-source-delete:focus-visible {
175
+ outline: 2px solid #b91c1c;
176
+ outline-offset: 1px;
177
+ }
178
+
179
+ .po-source-delete:disabled {
180
+ cursor: not-allowed;
181
+ opacity: .4;
182
+ }
@@ -49,6 +49,11 @@ class K {
49
49
  async listSources() {
50
50
  return (await this.request(`/sources?project_id=${encodeURIComponent(this.options.appId)}`)).sources;
51
51
  }
52
+ async deleteSource(e) {
53
+ return this.request(`/sources/${encodeURIComponent(e)}?project_id=${encodeURIComponent(this.options.appId)}`, {
54
+ method: "DELETE"
55
+ });
56
+ }
52
57
  uploadSource(e, t) {
53
58
  if (e.size && e.size > UPLOAD_MAX_BYTES) throw new Error("源码包超过 500M,请压缩后重新上传。");
54
59
  const s = new FormData();
@@ -205,6 +210,7 @@ class V {
205
210
  i(this, "sourceUploadError", "");
206
211
  i(this, "sourceLoadError", "");
207
212
  i(this, "sourceUploading", !1);
213
+ i(this, "deletingSourceId", "");
208
214
  i(this, "sourceRefreshTimer", null);
209
215
  i(this, "developerAccess", !1);
210
216
  i(this, "streaming", "");
@@ -233,7 +239,7 @@ class V {
233
239
  }
234
240
  unmount() {
235
241
  var e;
236
- this.cleanupFloatingLauncher(), this.stopSourceRefresh(), this.cancelActiveAnswer(!1), this.resetAnswerState(), (e = this.root) == null || e.remove(), this.root = null, this.panel = null, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.conversations = [], this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
242
+ this.cleanupFloatingLauncher(), this.stopSourceRefresh(), this.cancelActiveAnswer(!1), this.resetAnswerState(), (e = this.root) == null || e.remove(), this.root = null, this.panel = null, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.conversations = [], this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.deletingSourceId = "", this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
237
243
  }
238
244
  open() {
239
245
  this.root && (this.cleanupFloatingLauncher(), this.root.innerHTML = "", this.panel = document.createElement("div"), this.panel.className = "po-panel", this.root.appendChild(this.panel), this.loadDeveloperAccess(), this.loadSources(), this.loadConversations(), this.renderPanel());
@@ -437,6 +443,28 @@ class V {
437
443
  }
438
444
  }
439
445
  }
446
+ async deleteSourceSnapshot(e) {
447
+ if (!this.client || this.asking || this.sourceUploading || this.deletingSourceId) return;
448
+ const id = this.sourceSnapshotValue(e);
449
+ const selected = this.selectedSourceSnapshot();
450
+ if (!id || e.in_use_reason || selected && this.sourceSnapshotValue(selected) === id) return;
451
+ const name = e.filename || `代码包 ${id}`;
452
+ if (!window.confirm(`确定删除历史代码包“${name}”吗?代码索引和存储文件将一并清理,此操作无法撤销。`)) return;
453
+ this.deletingSourceId = id;
454
+ this.sourceUploadError = "";
455
+ this.renderPanel();
456
+ try {
457
+ const result = await this.client.deleteSource(id);
458
+ this.sourceSnapshots = this.sourceSnapshots.filter((item) => this.sourceSnapshotValue(item) !== id);
459
+ this.sourceUploadError = result.warning || "";
460
+ await this.loadSources();
461
+ } catch (error) {
462
+ this.sourceUploadError = error instanceof Error ? error.message : "删除代码包失败";
463
+ } finally {
464
+ this.deletingSourceId = "";
465
+ this.renderPanel();
466
+ }
467
+ }
440
468
  async ask(e) {
441
469
  if (!this.client || this.asking) return;
442
470
  const t = this.questionUnavailableReason();
@@ -692,7 +720,11 @@ class V {
692
720
  renderSourceItem(e) {
693
721
  var w, b, S, $, E, A, T;
694
722
  const t = e.filename || "未命名代码包", s = e.created_at ? O(e.created_at) : "刚刚上传", r = G(e.archive_bytes || e.total_bytes || 0), n = String((b = (w = e.metadata) == null ? void 0 : w.analysis_status) != null ? b : "unknown"), c = typeof ((S = e.metadata) == null ? void 0 : S.tag) == "string" ? e.metadata.tag : "", p = typeof (($ = e.metadata) == null ? void 0 : $.branch) == "string" ? e.metadata.branch : "", m = c ? `Tag: ${c}` : p ? `Branch: ${p}` : "未记录代码引用", g = typeof ((E = e.metadata) == null ? void 0 : E.remark) == "string" && e.metadata.remark ? e.metadata.remark : "无备注", o = typeof ((A = e.metadata) == null ? void 0 : A.uploader) == "string" ? e.metadata.uploader : "未知用户", y = (T = { pending: "项目记忆等待更新", running: "项目记忆更新中", ready: "项目记忆已就绪", failed: "项目记忆更新失败" }[n]) != null ? T : "项目记忆状态未知";
695
- return `<article class="po-source-item ${this.selectedSourceSnapshotId != null && this.sourceSnapshotValue(e) === String(this.selectedSourceSnapshotId) || this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "selected" : ""}"><strong>${l(t)}</strong><span>${l(m)}</span><span>备注:${l(g)}</span><span>上传人:${l(o)} · ${l(s)} · ${l(r)}</span><span>${l(y)} · 当前问答${this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "默认" : ""}引用</span></article>`;
723
+ const id = this.sourceSnapshotValue(e), selected = this.selectedSourceSnapshot(), current = selected && this.sourceSnapshotValue(selected) === id;
724
+ const reason = current ? "当前问答引用" : e.in_use_reason === "default" ? "默认问答引用" : e.in_use_reason === "conversation" ? "已有会话引用" : "";
725
+ const deleting = this.deletingSourceId === id;
726
+ const action = reason ? "" : `<button class="po-source-delete" type="button" data-delete-source="${l(id)}" aria-label="删除代码包:${l(t)}" title="删除代码包" ${this.asking || this.sourceUploading || this.deletingSourceId ? "disabled" : ""}><span class="po-trash-icon" aria-hidden="true"></span></button>`;
727
+ return `<article class="po-source-item ${current ? "selected" : ""}"><div class="po-source-item-head"><strong title="${l(t)}">${l(t)}</strong>${action}</div><span>${l(m)}</span><span>备注:${l(g)}</span><span>上传人:${l(o)} · ${l(s)} · ${l(r)}</span><span>${l(y)}${reason ? ` · ${reason},不可删除` : deleting ? " · 正在删除" : ""}</span></article>`;
696
728
  }
697
729
  renderThinkingProcess() {
698
730
  if (!this.asking && !this.thoughts.length && !this.runLoading && !this.runLoadError) return "";
@@ -769,6 +801,12 @@ class V {
769
801
  const d = h;
770
802
  d.key === "Enter" && !d.shiftKey && (d.preventDefault(), (f = (u = this.panel) == null ? void 0 : u.querySelector("form")) == null || f.requestSubmit());
771
803
  });
804
+ this.panel.querySelectorAll("[data-delete-source]").forEach((button) => {
805
+ button.addEventListener("click", () => {
806
+ const snapshot = this.sourceSnapshots.find((item) => this.sourceSnapshotValue(item) === button.dataset.deleteSource);
807
+ if (snapshot) this.deleteSourceSnapshot(snapshot);
808
+ });
809
+ });
772
810
  }
773
811
  }
774
812
  function l(a) {
@@ -49,6 +49,11 @@ class K {
49
49
  async listSources() {
50
50
  return (await this.request(`/sources?project_id=${encodeURIComponent(this.options.appId)}`)).sources;
51
51
  }
52
+ async deleteSource(e) {
53
+ return this.request(`/sources/${encodeURIComponent(e)}?project_id=${encodeURIComponent(this.options.appId)}`, {
54
+ method: "DELETE"
55
+ });
56
+ }
52
57
  uploadSource(e, t) {
53
58
  if (e.size && e.size > UPLOAD_MAX_BYTES) throw new Error("源码包超过 500M,请压缩后重新上传。");
54
59
  const s = new FormData();
@@ -205,6 +210,7 @@ class V {
205
210
  i(this, "sourceUploadError", "");
206
211
  i(this, "sourceLoadError", "");
207
212
  i(this, "sourceUploading", !1);
213
+ i(this, "deletingSourceId", "");
208
214
  i(this, "sourceRefreshTimer", null);
209
215
  i(this, "developerAccess", !1);
210
216
  i(this, "streaming", "");
@@ -233,7 +239,7 @@ class V {
233
239
  }
234
240
  unmount() {
235
241
  var e;
236
- this.cleanupFloatingLauncher(), this.stopSourceRefresh(), this.cancelActiveAnswer(!1), this.resetAnswerState(), (e = this.root) == null || e.remove(), this.root = null, this.panel = null, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.conversations = [], this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
242
+ this.cleanupFloatingLauncher(), this.stopSourceRefresh(), this.cancelActiveAnswer(!1), this.resetAnswerState(), (e = this.root) == null || e.remove(), this.root = null, this.panel = null, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.conversations = [], this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.deletingSourceId = "", this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
237
243
  }
238
244
  open() {
239
245
  this.root && (this.cleanupFloatingLauncher(), this.root.innerHTML = "", this.panel = document.createElement("div"), this.panel.className = "po-panel", this.root.appendChild(this.panel), this.loadDeveloperAccess(), this.loadSources(), this.loadConversations(), this.renderPanel());
@@ -437,6 +443,28 @@ class V {
437
443
  }
438
444
  }
439
445
  }
446
+ async deleteSourceSnapshot(e) {
447
+ if (!this.client || this.asking || this.sourceUploading || this.deletingSourceId) return;
448
+ const id = this.sourceSnapshotValue(e);
449
+ const selected = this.selectedSourceSnapshot();
450
+ if (!id || e.in_use_reason || selected && this.sourceSnapshotValue(selected) === id) return;
451
+ const name = e.filename || `代码包 ${id}`;
452
+ if (!window.confirm(`确定删除历史代码包“${name}”吗?代码索引和存储文件将一并清理,此操作无法撤销。`)) return;
453
+ this.deletingSourceId = id;
454
+ this.sourceUploadError = "";
455
+ this.renderPanel();
456
+ try {
457
+ const result = await this.client.deleteSource(id);
458
+ this.sourceSnapshots = this.sourceSnapshots.filter((item) => this.sourceSnapshotValue(item) !== id);
459
+ this.sourceUploadError = result.warning || "";
460
+ await this.loadSources();
461
+ } catch (error) {
462
+ this.sourceUploadError = error instanceof Error ? error.message : "删除代码包失败";
463
+ } finally {
464
+ this.deletingSourceId = "";
465
+ this.renderPanel();
466
+ }
467
+ }
440
468
  async ask(e) {
441
469
  if (!this.client || this.asking) return;
442
470
  const t = this.questionUnavailableReason();
@@ -692,7 +720,11 @@ class V {
692
720
  renderSourceItem(e) {
693
721
  var w, b, S, $, E, A, T;
694
722
  const t = e.filename || "未命名代码包", s = e.created_at ? O(e.created_at) : "刚刚上传", r = G(e.archive_bytes || e.total_bytes || 0), n = String((b = (w = e.metadata) == null ? void 0 : w.analysis_status) != null ? b : "unknown"), c = typeof ((S = e.metadata) == null ? void 0 : S.tag) == "string" ? e.metadata.tag : "", p = typeof (($ = e.metadata) == null ? void 0 : $.branch) == "string" ? e.metadata.branch : "", m = c ? `Tag: ${c}` : p ? `Branch: ${p}` : "未记录代码引用", g = typeof ((E = e.metadata) == null ? void 0 : E.remark) == "string" && e.metadata.remark ? e.metadata.remark : "无备注", o = typeof ((A = e.metadata) == null ? void 0 : A.uploader) == "string" ? e.metadata.uploader : "未知用户", y = (T = { pending: "项目记忆等待更新", running: "项目记忆更新中", ready: "项目记忆已就绪", failed: "项目记忆更新失败" }[n]) != null ? T : "项目记忆状态未知";
695
- return `<article class="po-source-item ${this.selectedSourceSnapshotId != null && this.sourceSnapshotValue(e) === String(this.selectedSourceSnapshotId) || this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "selected" : ""}"><strong>${l(t)}</strong><span>${l(m)}</span><span>备注:${l(g)}</span><span>上传人:${l(o)} · ${l(s)} · ${l(r)}</span><span>${l(y)} · 当前问答${this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "默认" : ""}引用</span></article>`;
723
+ const id = this.sourceSnapshotValue(e), selected = this.selectedSourceSnapshot(), current = selected && this.sourceSnapshotValue(selected) === id;
724
+ const reason = current ? "当前问答引用" : e.in_use_reason === "default" ? "默认问答引用" : e.in_use_reason === "conversation" ? "已有会话引用" : "";
725
+ const deleting = this.deletingSourceId === id;
726
+ const action = reason ? "" : `<button class="po-source-delete" type="button" data-delete-source="${l(id)}" aria-label="删除代码包:${l(t)}" title="删除代码包" ${this.asking || this.sourceUploading || this.deletingSourceId ? "disabled" : ""}><span class="po-trash-icon" aria-hidden="true"></span></button>`;
727
+ return `<article class="po-source-item ${current ? "selected" : ""}"><div class="po-source-item-head"><strong title="${l(t)}">${l(t)}</strong>${action}</div><span>${l(m)}</span><span>备注:${l(g)}</span><span>上传人:${l(o)} · ${l(s)} · ${l(r)}</span><span>${l(y)}${reason ? ` · ${reason},不可删除` : deleting ? " · 正在删除" : ""}</span></article>`;
696
728
  }
697
729
  renderThinkingProcess() {
698
730
  if (!this.asking && !this.thoughts.length && !this.runLoading && !this.runLoadError) return "";
@@ -769,6 +801,12 @@ class V {
769
801
  const d = h;
770
802
  d.key === "Enter" && !d.shiftKey && (d.preventDefault(), (f = (u = this.panel) == null ? void 0 : u.querySelector("form")) == null || f.requestSubmit());
771
803
  });
804
+ this.panel.querySelectorAll("[data-delete-source]").forEach((button) => {
805
+ button.addEventListener("click", () => {
806
+ const snapshot = this.sourceSnapshots.find((item) => this.sourceSnapshotValue(item) === button.dataset.deleteSource);
807
+ if (snapshot) this.deleteSourceSnapshot(snapshot);
808
+ });
809
+ });
772
810
  }
773
811
  }
774
812
  function l(a) {
package/dist/types.d.ts CHANGED
@@ -90,6 +90,7 @@ export interface SourceSnapshot {
90
90
  filename?: string | null;
91
91
  archive_bytes?: number;
92
92
  status: string;
93
+ in_use_reason?: 'default' | 'conversation' | null;
93
94
  message?: string | null;
94
95
  file_count: number;
95
96
  total_bytes?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageops/sdk",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "PageOps embeddable frontend SDK",
5
5
  "type": "module",
6
6
  "main": "dist/pageops-sdk.umd.cjs",