wepscli 0.1.0 → 0.1.5

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.
Files changed (43) hide show
  1. package/README.md +9 -8
  2. package/dist/WEPSCLI-shell/agent-runtime-events.js +194 -0
  3. package/dist/WEPSCLI-shell/agent-runtime-events.js.map +1 -0
  4. package/dist/WEPSCLI-shell/agent-runtime-helpers.js +117 -0
  5. package/dist/WEPSCLI-shell/agent-runtime-helpers.js.map +1 -0
  6. package/dist/WEPSCLI-shell/agent-runtime-types.js +1 -0
  7. package/dist/WEPSCLI-shell/agent-runtime-types.js.map +1 -0
  8. package/dist/WEPSCLI-shell/agent-runtime.js +42 -294
  9. package/dist/WEPSCLI-shell/agent-runtime.js.map +1 -1
  10. package/dist/WEPSCLI-shell/approval-overlay.js.map +1 -1
  11. package/dist/WEPSCLI-shell/chat-components.js +13 -6
  12. package/dist/WEPSCLI-shell/chat-components.js.map +1 -1
  13. package/dist/WEPSCLI-shell/file-change-preview.js.map +1 -1
  14. package/dist/WEPSCLI-shell/runtime-recovery.js.map +1 -1
  15. package/dist/WEPSCLI-shell/session-consistency.js +9 -0
  16. package/dist/WEPSCLI-shell/session-consistency.js.map +1 -0
  17. package/dist/WEPSCLI-shell/shell-app.js +169 -259
  18. package/dist/WEPSCLI-shell/shell-app.js.map +1 -1
  19. package/dist/WEPSCLI-shell/shell-keyboard.js +135 -0
  20. package/dist/WEPSCLI-shell/shell-keyboard.js.map +1 -0
  21. package/dist/WEPSCLI-shell/shell-modes.js.map +1 -1
  22. package/dist/WEPSCLI-shell/shell-prompt-controller.js +93 -0
  23. package/dist/WEPSCLI-shell/shell-prompt-controller.js.map +1 -0
  24. package/dist/WEPSCLI-shell/shell-status.js +16 -0
  25. package/dist/WEPSCLI-shell/shell-status.js.map +1 -0
  26. package/dist/WEPSCLI-shell/skill-commands.js +7 -0
  27. package/dist/WEPSCLI-shell/skill-commands.js.map +1 -0
  28. package/dist/WEPSCLI-shell/slash-commands.js +68 -7
  29. package/dist/WEPSCLI-shell/slash-commands.js.map +1 -1
  30. package/dist/WEPSCLI-shell/tool-approval.js.map +1 -1
  31. package/dist/WEPSCLI-shell/tool-diff.js.map +1 -1
  32. package/dist/WEPSCLI-shell/tool-file-changes.js.map +1 -1
  33. package/dist/WEPSCLI-shell/tool-message-detail.js.map +1 -1
  34. package/dist/WEPSCLI-shell/tool-messages.js.map +1 -1
  35. package/dist/WEPSCLI-shell/transcript-panel.js.map +1 -1
  36. package/dist/config.js +3 -0
  37. package/dist/config.js.map +1 -1
  38. package/dist/main.js.map +1 -1
  39. package/dist/skills/skill-add-flow.js +88 -0
  40. package/dist/skills/skill-add-flow.js.map +1 -0
  41. package/dist/skills/skill-service.js +123 -0
  42. package/dist/skills/skill-service.js.map +1 -0
  43. package/package.json +28 -24
@@ -1,118 +1,11 @@
1
1
  import { join } from "node:path";
2
2
  import { getAgentDir } from "../config.js";
3
- import { createCompactingRuntimeState, createErrorRuntimeState, createIdleRuntimeState, createInterruptedRuntimeState, createRetryingRuntimeState, createRunningRuntimeState } from "./runtime-status.js";
3
+ import { handleAgentSessionEvent } from "./agent-runtime-events.js";
4
+ import { cancellationToolOutput, createMessageId, extractAssistantReasoning, extractAssistantVisibleText, extractUserText, formatCompactionResultMessage, formatRuntimeError, formatTime, getRuntimeSessionDir, installBeforeToolCallHook, loadCodingAgentRuntime, toModelDefinition } from "./agent-runtime-helpers.js";
5
+ import { createCompactingRuntimeState, createErrorRuntimeState, createIdleRuntimeState, createInterruptedRuntimeState, createRunningRuntimeState } from "./runtime-status.js";
4
6
  import { getRuntimeRecoveryHint } from "./runtime-recovery.js";
5
7
  import { createToolApprovalRequest, toolApprovalDecisionReason } from "./tool-approval.js";
6
8
  import { createToolMessageState, updateToolMessageState } from "./tool-messages.js";
7
- let codingAgentRuntimePromise;
8
- async function loadCodingAgentRuntime() {
9
- if (!codingAgentRuntimePromise) {
10
- codingAgentRuntimePromise = import("@mariozechner/pi-coding-agent").then(module => module);
11
- }
12
- return codingAgentRuntimePromise;
13
- }
14
- function formatTime(timestamp) {
15
- return new Date(timestamp ?? Date.now()).toLocaleTimeString("en-US", {
16
- hour: "2-digit",
17
- minute: "2-digit"
18
- });
19
- }
20
- function createMessageId(record, role) {
21
- record.sequence += 1;
22
- return `runtime:${role}:${record.sequence}`;
23
- }
24
- function guessReasoningSupport(modelId) {
25
- const value = modelId.toLowerCase();
26
- return ["gpt-5", "gpt-4.1", "o1", "o3", "o4", "claude-3-7", "claude-sonnet-4", "claude-opus-4", "gemini-2.5", "reasoner", "thinking"].some(token => value.includes(token));
27
- }
28
- function extractTextBlocks(content) {
29
- return content.map(item => {
30
- if (item.type === "text" && typeof item.text === "string") {
31
- return item.text;
32
- }
33
- if (item.type === "image") {
34
- return "[image]";
35
- }
36
- if (item.type === "thinking" && typeof item.thinking === "string") {
37
- return item.thinking;
38
- }
39
- return "";
40
- }).filter(Boolean).join("\n\n");
41
- }
42
- function extractUserText(message) {
43
- if (typeof message.content === "string") {
44
- return message.content;
45
- }
46
- return extractTextBlocks(message.content);
47
- }
48
- function extractAssistantVisibleText(message) {
49
- const text = extractTextBlocks(message.content.filter(item => item.type === "text").map(item => ({
50
- type: item.type,
51
- text: item.text
52
- })));
53
- if (text) {
54
- return text;
55
- }
56
- if (message.errorMessage) {
57
- return message.errorMessage;
58
- }
59
- return "";
60
- }
61
- function extractAssistantReasoning(message) {
62
- return extractTextBlocks(message.content.filter(item => item.type === "thinking").map(item => ({
63
- type: item.type,
64
- thinking: item.thinking
65
- })));
66
- }
67
- function formatRuntimeError(error) {
68
- return error instanceof Error ? error.message : String(error);
69
- }
70
- function formatCompactionResultMessage(result) {
71
- if (typeof result.tokensBefore === "number" && Number.isFinite(result.tokensBefore)) {
72
- return `Context compacted from ${result.tokensBefore.toLocaleString("en-US")} tokens.`;
73
- }
74
- return "Context compacted.";
75
- }
76
- function cancellationToolOutput(reason) {
77
- return {
78
- content: [{
79
- type: "text",
80
- text: reason
81
- }]
82
- };
83
- }
84
- function toModelDefinition(model) {
85
- return {
86
- id: model.id,
87
- name: model.name,
88
- reasoning: guessReasoningSupport(model.id),
89
- input: ["text", "image"],
90
- cost: {
91
- input: 0,
92
- output: 0,
93
- cacheRead: 0,
94
- cacheWrite: 0
95
- },
96
- contextWindow: 128_000,
97
- maxTokens: 16_384
98
- };
99
- }
100
- function getRuntimeSessionDir(cwd, agentDir) {
101
- const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
102
- return join(agentDir, "sessions", safePath);
103
- }
104
- function installBeforeToolCallHook(session, handler) {
105
- if (typeof session.addBeforeToolCall === "function") {
106
- return session.addBeforeToolCall(handler);
107
- }
108
- if (typeof session.agent?.setBeforeToolCall === "function") {
109
- session.agent.setBeforeToolCall(handler);
110
- return () => {
111
- session.agent.setBeforeToolCall?.(undefined);
112
- };
113
- }
114
- throw new Error("The installed pi-coding-agent runtime does not expose a before-tool-call hook API.");
115
- }
116
9
  export class WepsAgentRuntime {
117
10
  records = new Map();
118
11
  pending = new Map();
@@ -209,6 +102,31 @@ export class WepsAgentRuntime {
209
102
  this.applyRecoveryState(sessionId, record, message, "Selection failed - ready");
210
103
  }
211
104
  }
105
+ async reload(sessionId, selection, binding = {}) {
106
+ const record = await this.ensureSession(sessionId, selection, binding);
107
+ const reloadableSession = record.session;
108
+ if (typeof reloadableSession.reload !== "function") {
109
+ this.appendSystemMessage(sessionId, record, "Resource reload is not available in the current runtime.");
110
+ this.setRuntimeState(sessionId, record, createErrorRuntimeState("Reload unavailable - ready"));
111
+ return false;
112
+ }
113
+ record.activePrompts += 1;
114
+ this.setRuntimeState(sessionId, record, createRunningRuntimeState("Reloading resources"));
115
+ try {
116
+ await this.applySelection(record, selection);
117
+ await reloadableSession.reload();
118
+ this.setRuntimeState(sessionId, record, createIdleRuntimeState());
119
+ return true;
120
+ } catch (error) {
121
+ const message = formatRuntimeError(error);
122
+ this.appendSystemMessage(sessionId, record, `Reload failed: ${message}`);
123
+ this.applyRecoveryState(sessionId, record, message, "Reload failed - ready");
124
+ return false;
125
+ } finally {
126
+ record.activePrompts = Math.max(0, record.activePrompts - 1);
127
+ this.resetRuntimeStateAfterActivity(sessionId, record);
128
+ }
129
+ }
212
130
  setMode(mode) {
213
131
  this.currentMode = mode;
214
132
  }
@@ -284,7 +202,9 @@ export class WepsAgentRuntime {
284
202
  switchSession: async () => ({
285
203
  cancelled: true
286
204
  }),
287
- reload: async () => {}
205
+ reload: async () => {
206
+ await session.reload?.();
207
+ }
288
208
  },
289
209
  onError: error => {
290
210
  const record = this.records.get(sessionId);
@@ -637,188 +557,16 @@ export class WepsAgentRuntime {
637
557
  };
638
558
  }
639
559
  handleSessionEvent(sessionId, record, event) {
640
- switch (event.type) {
641
- case "message_start":
642
- if (event.message.role === "user") {
643
- const text = extractUserText(event.message);
644
- if (text) {
645
- this.callbacks.appendMessage(sessionId, {
646
- id: createMessageId(record, "user"),
647
- role: "user",
648
- content: text,
649
- time: formatTime(event.message.timestamp)
650
- });
651
- }
652
- return;
653
- }
654
- if (event.message.role === "assistant") {
655
- record.streamingAssistantMessageId = undefined;
656
- record.streamingReasoningMessageId = undefined;
657
- }
658
- return;
659
- case "message_update":
660
- if (event.assistantMessageEvent.type === "thinking_delta") {
661
- if (!record.streamingReasoningMessageId) {
662
- record.streamingReasoningMessageId = record.streamingAssistantMessageId ? this.insertReasoningMessageBefore(sessionId, record, record.streamingAssistantMessageId, event.assistantMessageEvent.delta) : (() => {
663
- const id = createMessageId(record, "assistant");
664
- this.callbacks.appendMessage(sessionId, {
665
- id,
666
- role: "assistant",
667
- content: event.assistantMessageEvent.delta,
668
- time: formatTime(),
669
- kind: "reasoning",
670
- collapsible: true,
671
- expanded: false
672
- });
673
- return id;
674
- })();
675
- return;
676
- }
677
- this.callbacks.patchMessage(sessionId, record.streamingReasoningMessageId, {
678
- appendContent: event.assistantMessageEvent.delta
679
- });
680
- return;
681
- }
682
- if (event.assistantMessageEvent.type === "text_delta" && record.streamingAssistantMessageId) {
683
- this.callbacks.patchMessage(sessionId, record.streamingAssistantMessageId, {
684
- appendContent: event.assistantMessageEvent.delta
685
- });
686
- return;
687
- }
688
- if (event.assistantMessageEvent.type === "text_delta") {
689
- const messageId = createMessageId(record, "assistant");
690
- record.streamingAssistantMessageId = messageId;
691
- this.callbacks.appendMessage(sessionId, {
692
- id: messageId,
693
- role: "assistant",
694
- content: event.assistantMessageEvent.delta,
695
- time: formatTime()
696
- });
697
- }
698
- return;
699
- case "message_end":
700
- if (event.message.role === "assistant") {
701
- const finalMessage = event.message;
702
- const content = extractAssistantVisibleText(finalMessage);
703
- const reasoning = extractAssistantReasoning(finalMessage);
704
- const messageId = record.streamingAssistantMessageId;
705
- const reasoningMessageId = record.streamingReasoningMessageId;
706
- record.streamingAssistantMessageId = undefined;
707
- record.streamingReasoningMessageId = undefined;
708
- if (messageId) {
709
- this.callbacks.patchMessage(sessionId, messageId, {
710
- content,
711
- time: formatTime(finalMessage.timestamp)
712
- });
713
- } else if (content) {
714
- this.callbacks.appendMessage(sessionId, {
715
- id: createMessageId(record, "assistant"),
716
- role: "assistant",
717
- content,
718
- time: formatTime(finalMessage.timestamp)
719
- });
720
- }
721
- if (reasoning) {
722
- if (reasoningMessageId) {
723
- this.callbacks.patchMessage(sessionId, reasoningMessageId, {
724
- content: reasoning,
725
- time: formatTime(finalMessage.timestamp)
726
- });
727
- } else if (messageId) {
728
- this.insertReasoningMessageBefore(sessionId, record, messageId, reasoning);
729
- } else {
730
- this.appendReasoningMessage(sessionId, record, reasoning);
731
- }
732
- }
733
- if (finalMessage.stopReason === "aborted") {
734
- this.setRuntimeState(sessionId, record, createInterruptedRuntimeState("Interrupted - ready", "The current request was cancelled."));
735
- } else if (finalMessage.stopReason === "error" && finalMessage.errorMessage) {
736
- this.applyRecoveryState(sessionId, record, finalMessage.errorMessage, "Request failed - ready");
737
- }
738
- }
739
- return;
740
- case "tool_execution_start":
741
- {
742
- const tool = createToolMessageState(event.toolCallId, event.toolName, event.args);
743
- const messageId = this.appendToolMessage(sessionId, record, tool);
744
- record.toolMessageIds.set(event.toolCallId, messageId);
745
- record.toolStates.set(event.toolCallId, tool);
746
- return;
747
- }
748
- case "tool_execution_update":
749
- {
750
- const messageId = record.toolMessageIds.get(event.toolCallId);
751
- const tool = record.toolStates.get(event.toolCallId);
752
- if (!messageId || !tool) {
753
- return;
754
- }
755
- const nextTool = updateToolMessageState(tool, {
756
- args: event.args,
757
- output: event.partialResult
758
- });
759
- record.toolStates.set(event.toolCallId, nextTool);
760
- this.callbacks.patchMessage(sessionId, messageId, {
761
- tool: nextTool
762
- });
763
- return;
764
- }
765
- case "tool_execution_end":
766
- {
767
- const messageId = record.toolMessageIds.get(event.toolCallId);
768
- const tool = record.toolStates.get(event.toolCallId);
769
- record.toolMessageIds.delete(event.toolCallId);
770
- record.toolStates.delete(event.toolCallId);
771
- const nextTool = updateToolMessageState(tool ?? createToolMessageState(event.toolCallId, event.toolName, undefined), {
772
- status: event.isError ? "failed" : "completed",
773
- output: event.result
774
- });
775
- if (messageId) {
776
- this.callbacks.patchMessage(sessionId, messageId, {
777
- tool: nextTool,
778
- time: formatTime()
779
- });
780
- return;
781
- }
782
- this.appendToolMessage(sessionId, record, nextTool);
783
- return;
784
- }
785
- case "auto_compaction_start":
786
- this.setRuntimeState(sessionId, record, createCompactingRuntimeState(event.reason === "overflow" ? "Compacting after overflow" : "Compacting context"));
787
- this.appendSystemMessage(sessionId, record, "Compacting context...");
788
- return;
789
- case "auto_compaction_end":
790
- if (event.errorMessage) {
791
- this.applyRecoveryState(sessionId, record, event.errorMessage, "Compaction failed - ready");
792
- } else if (event.aborted) {
793
- this.setRuntimeState(sessionId, record, createInterruptedRuntimeState("Compaction cancelled - ready", "You can continue with a new prompt."));
794
- } else if (event.willRetry) {
795
- this.setRuntimeState(sessionId, record, createRetryingRuntimeState("Retrying after compaction"));
796
- } else if (record.activePrompts > 0) {
797
- this.setRuntimeState(sessionId, record, createRunningRuntimeState());
798
- }
799
- this.appendSystemMessage(sessionId, record, event.errorMessage ? `Compaction failed: ${event.errorMessage}` : event.aborted ? "Compaction aborted." : event.result ? "Context compacted." : "Compaction skipped.");
800
- return;
801
- case "auto_retry_start":
802
- this.setRuntimeState(sessionId, record, createRetryingRuntimeState(`Retrying (${event.attempt}/${event.maxAttempts})`, event.errorMessage));
803
- this.appendSystemMessage(sessionId, record, `Retrying request (${event.attempt}/${event.maxAttempts}) after error: ${event.errorMessage}`);
804
- return;
805
- case "auto_retry_end":
806
- if (!event.success) {
807
- const finalError = event.finalError ?? "Retry cancelled";
808
- this.setRuntimeState(sessionId, record, finalError.toLowerCase().includes("cancel") ? createInterruptedRuntimeState("Retry cancelled - ready", finalError) : createErrorRuntimeState("Retry failed - ready", finalError));
809
- this.appendSystemMessage(sessionId, record, `Retry failed: ${finalError}`);
810
- if (!finalError.toLowerCase().includes("cancel")) {
811
- const hint = getRuntimeRecoveryHint(finalError);
812
- if (hint?.nextStep) {
813
- this.appendSystemMessage(sessionId, record, hint.nextStep);
814
- }
815
- }
816
- } else if (record.activePrompts > 0) {
817
- this.setRuntimeState(sessionId, record, createRunningRuntimeState());
818
- }
819
- return;
820
- default:
821
- return;
822
- }
560
+ handleAgentSessionEvent(event, {
561
+ sessionId,
562
+ record,
563
+ callbacks: this.callbacks,
564
+ appendToolMessage: tool => this.appendToolMessage(sessionId, record, tool),
565
+ appendReasoningMessage: content => this.appendReasoningMessage(sessionId, record, content),
566
+ insertReasoningMessageBefore: (beforeMessageId, content) => this.insertReasoningMessageBefore(sessionId, record, beforeMessageId, content),
567
+ appendSystemMessage: content => this.appendSystemMessage(sessionId, record, content),
568
+ applyRecoveryState: (message, fallbackLabel) => this.applyRecoveryState(sessionId, record, message, fallbackLabel),
569
+ setRuntimeState: state => this.setRuntimeState(sessionId, record, state)
570
+ });
823
571
  }
824
572
  }