openfox 0.2.4 → 1.0.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.
Files changed (64) hide show
  1. package/dist/agent-defaults/builder.agent.md +3 -7
  2. package/dist/agent-defaults/code-reviewer.agent.md +1 -2
  3. package/dist/agent-defaults/debugger.agent.md +1 -2
  4. package/dist/agent-defaults/planner.agent.md +2 -9
  5. package/dist/agent-defaults/test-generator.agent.md +1 -1
  6. package/dist/agent-defaults/verifier.agent.md +4 -5
  7. package/dist/ask-3RK5YJZE.js +19 -0
  8. package/dist/auto-compaction-7LNZ5J3W.js +23 -0
  9. package/dist/{branch.api-WDHKZJS6.js → branch.api-XADFZZAA.js} +2 -2
  10. package/dist/chat-handler-T7SLWZ4E.js +201 -0
  11. package/dist/chunk-22CTURMH.js +128 -0
  12. package/dist/chunk-2KSCZSXQ.js +680 -0
  13. package/dist/{chunk-S5NRIWEU.js → chunk-2TBNG7CS.js} +12 -12
  14. package/dist/{chunk-4Z2OZ6NX.js → chunk-3EHGGBWE.js} +29 -2
  15. package/dist/{chunk-GZ7ZVJIW.js → chunk-3UQACISJ.js} +159 -49
  16. package/dist/{chunk-AF7XS4OI.js → chunk-5YQAXUKO.js} +4 -1
  17. package/dist/{chunk-MTX5Y3V3.js → chunk-7IOZFJBW.js} +2 -2
  18. package/dist/chunk-BU2ZYOEA.js +1067 -0
  19. package/dist/chunk-M2C5GEQR.js +137 -0
  20. package/dist/{chunk-U62ZECSQ.js → chunk-PNBH3RAX.js} +2 -2
  21. package/dist/chunk-QDEKU5RL.js +75 -0
  22. package/dist/chunk-QYP5HQV4.js +438 -0
  23. package/dist/{chunk-O4W4555H.js → chunk-RAZQTQK2.js} +1353 -1134
  24. package/dist/chunk-S4QKTRGJ.js +343 -0
  25. package/dist/{chunk-ARFK3RZW.js → chunk-TPT6HP4H.js} +1 -1
  26. package/dist/chunk-TVQOONDR.js +75 -0
  27. package/dist/{chunk-5ZUU23XF.js → chunk-U6BUT37A.js} +286 -33
  28. package/dist/chunk-VZXXJKSQ.js +314 -0
  29. package/dist/{chunk-26NRL3HX.js → chunk-XFXOSPYH.js} +3 -2
  30. package/dist/{chunk-N2XYX4ZA.js → chunk-XKFPU2FA.js} +13 -2
  31. package/dist/{chunk-FUUYYDVG.js → chunk-YB2574C6.js} +2841 -4507
  32. package/dist/cli/dev.js +4 -3
  33. package/dist/cli/index.js +4 -3
  34. package/dist/{config-GIXXE4VK.js → config-GIFCEJDU.js} +11 -6
  35. package/dist/events-G6CKHDNZ.js +114 -0
  36. package/dist/folding-O52L65VN.js +37 -0
  37. package/dist/{init-2EJ5AC7Z.js → init-MKTUIGZU.js} +46 -13
  38. package/dist/orchestrator-UGXX7JRQ.js +39 -0
  39. package/dist/package.json +9 -2
  40. package/dist/{paths-4BPXWB2W.js → paths-MM76AWYB.js} +2 -2
  41. package/dist/processor-KLHKDILM.js +236 -0
  42. package/dist/{project-creator-CWPKRIKI.js → project-creator-KAQXMZCT.js} +9 -8
  43. package/dist/projects-GSMMEVSO.js +19 -0
  44. package/dist/{protocol-BFFz3WM0.d.ts → protocol-BZ6OIASP.d.ts} +71 -50
  45. package/dist/protocol-WQENDK72.js +88 -0
  46. package/dist/{provider-QEVVNYOX.js → provider-4KTWU6IV.js} +41 -9
  47. package/dist/runtime-config-2XJJIMSC.js +9 -0
  48. package/dist/{serve-RYEBLJVN.js → serve-UK6B6G2O.js} +38 -18
  49. package/dist/server/index.d.ts +81 -27
  50. package/dist/server/index.js +19 -11
  51. package/dist/{settings-D5O3TMLD.js → settings-NCLN4JDZ.js} +4 -4
  52. package/dist/shared/index.d.ts +2 -2
  53. package/dist/shared/index.js +1 -1
  54. package/dist/tools-SGBQE736.js +48 -0
  55. package/dist/vision-fallback-63VPBSEN.js +22 -0
  56. package/dist/web/assets/{index-DHmZmhnR.css → index-BsaaC0X0.css} +32 -1
  57. package/dist/web/assets/index-CvO7QkGh.js +141 -0
  58. package/dist/web/index.html +2 -2
  59. package/dist/web/sounds/typing.mp3 +0 -0
  60. package/dist/workflow-defaults/default.workflow.json +1 -1
  61. package/package.json +9 -2
  62. package/dist/chunk-L4XDA3V7.js +0 -218
  63. package/dist/tools-QMIIDJTV.js +0 -48
  64. package/dist/web/assets/index-CAD7Iv_d.js +0 -122
@@ -4,23 +4,19 @@ name: Builder
4
4
  description: Implements the task by writing code and completing criteria
5
5
  subagent: false
6
6
  color: '#3b82f6'
7
- tools:
7
+ allowedTools:
8
8
  - read_file
9
- - glob
10
- - grep
11
9
  - web_fetch
12
10
  - write_file
13
11
  - edit_file
14
12
  - run_command
15
13
  - ask_user
16
- - complete_criterion
17
- - get_criteria
18
- - todo_write
14
+ - criterion:complete,get
15
+ - todo:list,add,write,update,remove
19
16
  - call_sub_agent
20
17
  - load_skill
21
18
  - dev_server
22
19
  - step_done
23
- - return_value
24
20
  ---
25
21
 
26
22
  # Build Mode
@@ -4,9 +4,8 @@ name: Code Reviewer
4
4
  description: Review code changes for quality, bugs, and best practices
5
5
  subagent: true
6
6
  color: '#3b82f6'
7
- tools:
7
+ allowedTools:
8
8
  - read_file
9
- - grep
10
9
  - web_fetch
11
10
  ---
12
11
 
@@ -4,10 +4,9 @@ name: Debugger
4
4
  description: Analyze errors and suggest fixes
5
5
  subagent: true
6
6
  color: '#f97316'
7
- tools:
7
+ allowedTools:
8
8
  - read_file
9
9
  - run_command
10
- - grep
11
10
  - web_fetch
12
11
  ---
13
12
 
@@ -4,20 +4,13 @@ name: Planner
4
4
  description: Explores the codebase and defines criteria for the task
5
5
  subagent: false
6
6
  color: '#a855f7'
7
- tools:
7
+ allowedTools:
8
8
  - read_file
9
- - glob
10
- - grep
11
9
  - web_fetch
12
10
  - run_command
13
- - git
14
- - get_criteria
15
- - add_criterion
16
- - update_criterion
17
- - remove_criterion
11
+ - criterion:add,get,update,remove
18
12
  - call_sub_agent
19
13
  - load_skill
20
- - return_value
21
14
  ---
22
15
 
23
16
  # Plan Mode
@@ -4,7 +4,7 @@ name: Test Generator
4
4
  description: Generate tests for implemented features
5
5
  subagent: true
6
6
  color: '#f59e0b'
7
- tools:
7
+ allowedTools:
8
8
  - read_file
9
9
  - write_file
10
10
  - run_command
@@ -4,11 +4,10 @@ name: Verifier
4
4
  description: Verifies completed criteria against actual code changes
5
5
  subagent: true
6
6
  color: '#22c55e'
7
- tools:
7
+ allowedTools:
8
8
  - read_file
9
9
  - run_command
10
- - pass_criterion
11
- - fail_criterion
10
+ - criterion:pass,fail
12
11
  - web_fetch
13
12
  ---
14
13
 
@@ -28,8 +27,8 @@ For each criterion marked [NEEDS VERIFICATION]:
28
27
  4. Run tests or commands only if applicable to the criterion
29
28
 
30
29
  Then call:
31
- - `pass_criterion` if the criterion is satisfied
32
- - `fail_criterion` if it is NOT satisfied (explain why clearly)
30
+ - `criterion` with action "pass" if the criterion is satisfied
31
+ - `criterion` with action "fail" if it is NOT satisfied (explain why clearly)
33
32
 
34
33
  ## IMPORTANT
35
34
  - Start by analyzing what each criterion actually requires
@@ -0,0 +1,19 @@
1
+ import {
2
+ AskUserInterrupt,
3
+ askUserTool,
4
+ awaitAnswer,
5
+ cancelQuestion,
6
+ cancelQuestionsForSession,
7
+ hasPendingQuestion,
8
+ provideAnswer
9
+ } from "./chunk-22CTURMH.js";
10
+ export {
11
+ AskUserInterrupt,
12
+ askUserTool,
13
+ awaitAnswer,
14
+ cancelQuestion,
15
+ cancelQuestionsForSession,
16
+ hasPendingQuestion,
17
+ provideAnswer
18
+ };
19
+ //# sourceMappingURL=ask-3RK5YJZE.js.map
@@ -0,0 +1,23 @@
1
+ import {
2
+ maybeAutoCompactContext,
3
+ performManualContextCompaction,
4
+ resolveCompactionStatsIdentity
5
+ } from "./chunk-YB2574C6.js";
6
+ import "./chunk-BU2ZYOEA.js";
7
+ import "./chunk-2KSCZSXQ.js";
8
+ import "./chunk-S4QKTRGJ.js";
9
+ import "./chunk-22CTURMH.js";
10
+ import "./chunk-7IOZFJBW.js";
11
+ import "./chunk-XKFPU2FA.js";
12
+ import "./chunk-3EHGGBWE.js";
13
+ import "./chunk-TPT6HP4H.js";
14
+ import "./chunk-TVQOONDR.js";
15
+ import "./chunk-XFXOSPYH.js";
16
+ import "./chunk-5YQAXUKO.js";
17
+ import "./chunk-PNBH3RAX.js";
18
+ export {
19
+ maybeAutoCompactContext,
20
+ performManualContextCompaction,
21
+ resolveCompactionStatsIdentity
22
+ };
23
+ //# sourceMappingURL=auto-compaction-7LNZ5J3W.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-U62ZECSQ.js";
3
+ } from "./chunk-PNBH3RAX.js";
4
4
 
5
5
  // src/server/branch.api.ts
6
6
  import { spawn } from "child_process";
@@ -45,4 +45,4 @@ function getGitBranch(cwd) {
45
45
  export {
46
46
  getCurrentBranch
47
47
  };
48
- //# sourceMappingURL=branch.api-WDHKZJS6.js.map
48
+ //# sourceMappingURL=branch.api-XADFZZAA.js.map
@@ -0,0 +1,201 @@
1
+ import {
2
+ runChatTurn
3
+ } from "./chunk-VZXXJKSQ.js";
4
+ import "./chunk-YB2574C6.js";
5
+ import {
6
+ generateSessionName,
7
+ needsNameGeneration
8
+ } from "./chunk-QDEKU5RL.js";
9
+ import {
10
+ getEventStore,
11
+ updateSessionMetadata
12
+ } from "./chunk-BU2ZYOEA.js";
13
+ import {
14
+ buildMessagesFromStoredEvents,
15
+ foldPendingConfirmations
16
+ } from "./chunk-2KSCZSXQ.js";
17
+ import {
18
+ createChatMessageMessage,
19
+ createContextStateMessage,
20
+ createPhaseChangedMessage,
21
+ createSessionRunningMessage,
22
+ createSessionStateMessage
23
+ } from "./chunk-S4QKTRGJ.js";
24
+ import "./chunk-22CTURMH.js";
25
+ import "./chunk-7IOZFJBW.js";
26
+ import "./chunk-XKFPU2FA.js";
27
+ import "./chunk-3EHGGBWE.js";
28
+ import "./chunk-TPT6HP4H.js";
29
+ import "./chunk-TVQOONDR.js";
30
+ import "./chunk-XFXOSPYH.js";
31
+ import "./chunk-5YQAXUKO.js";
32
+ import {
33
+ logger
34
+ } from "./chunk-PNBH3RAX.js";
35
+
36
+ // src/server/session/chat-handler.ts
37
+ var activeAgents = /* @__PURE__ */ new Map();
38
+ async function startChatSession(sessionId, content, deps, options) {
39
+ const { sessionManager, llmClient, statsIdentity, broadcastForSession } = deps;
40
+ const session = sessionManager.getSession(sessionId);
41
+ if (!session) {
42
+ throw new Error("Session not found");
43
+ }
44
+ const eventStore = getEventStore();
45
+ if (session.isRunning) {
46
+ throw new Error("Session is already running");
47
+ }
48
+ if (session.phase === "blocked") {
49
+ sessionManager.setPhase(sessionId, "build");
50
+ sessionManager.resetAllCriteriaAttempts(sessionId);
51
+ broadcastForSession(sessionId, createPhaseChangedMessage("build"));
52
+ }
53
+ const controller = new AbortController();
54
+ const existingController = activeAgents.get(sessionId);
55
+ if (existingController) {
56
+ existingController.abort();
57
+ }
58
+ activeAgents.set(sessionId, controller);
59
+ sessionManager.setRunning(sessionId, true);
60
+ broadcastForSession(sessionId, createSessionRunningMessage(true));
61
+ try {
62
+ const { maybeAutoCompactContext } = await import("./auto-compaction-7LNZ5J3W.js");
63
+ await maybeAutoCompactContext({
64
+ sessionManager,
65
+ sessionId,
66
+ llmClient,
67
+ statsIdentity,
68
+ signal: controller.signal
69
+ });
70
+ if (controller.signal.aborted) {
71
+ return;
72
+ }
73
+ const userMessage = sessionManager.addMessage(sessionId, {
74
+ role: "user",
75
+ content,
76
+ ...options?.attachments && { attachments: options.attachments },
77
+ ...options?.messageKind && { messageKind: options.messageKind },
78
+ ...options?.isSystemGenerated && { isSystemGenerated: options.isSystemGenerated }
79
+ });
80
+ broadcastForSession(sessionId, createChatMessageMessage(userMessage));
81
+ const messageCount = getSessionMessageCount(sessionId);
82
+ const currentSession = sessionManager.getSession(sessionId);
83
+ logger.debug("Session name generation check", {
84
+ sessionId,
85
+ title: currentSession?.metadata.title,
86
+ messageCount,
87
+ needsGeneration: currentSession ? needsNameGeneration(currentSession.metadata.title, messageCount) : false
88
+ });
89
+ if (currentSession && needsNameGeneration(currentSession.metadata.title, messageCount)) {
90
+ generateSessionName({
91
+ userMessage: content,
92
+ llmClient,
93
+ signal: controller.signal
94
+ }).then((result) => {
95
+ logger.debug("Session name generation result", {
96
+ sessionId,
97
+ success: result.success,
98
+ name: result.name,
99
+ error: result.error
100
+ });
101
+ if (result.success && result.name) {
102
+ updateSessionMetadata(sessionId, { title: result.name });
103
+ eventStore.append(sessionId, {
104
+ type: "session.name_generated",
105
+ data: { name: result.name }
106
+ });
107
+ const updatedSession = sessionManager.getSession(sessionId);
108
+ if (updatedSession) {
109
+ const events = eventStore.getEvents(sessionId);
110
+ const messages = buildMessagesFromStoredEvents(events);
111
+ const pendingConfirmations = foldPendingConfirmations(events);
112
+ broadcastForSession(sessionId, createSessionStateMessage(updatedSession, messages, pendingConfirmations));
113
+ }
114
+ }
115
+ }).catch((error) => {
116
+ logger.error("Session name generation failed", {
117
+ sessionId,
118
+ error: error instanceof Error ? error.message : String(error)
119
+ });
120
+ });
121
+ }
122
+ startTurnWithCompletionChain(sessionId, controller, deps);
123
+ } catch (error) {
124
+ if (activeAgents.get(sessionId) === controller) {
125
+ activeAgents.delete(sessionId);
126
+ }
127
+ sessionManager.setRunning(sessionId, false);
128
+ broadcastForSession(sessionId, createSessionRunningMessage(false));
129
+ const contextState = sessionManager.getContextState(sessionId);
130
+ broadcastForSession(sessionId, createContextStateMessage(contextState));
131
+ throw error;
132
+ }
133
+ }
134
+ function getSessionMessageCount(sessionId) {
135
+ const eventStore = getEventStore();
136
+ const events = eventStore.getEvents(sessionId);
137
+ let count = 0;
138
+ for (const event of events) {
139
+ if (event.type === "message.start") {
140
+ const data = event.data;
141
+ if (data.role === "user") {
142
+ count++;
143
+ }
144
+ }
145
+ }
146
+ return count;
147
+ }
148
+ function startTurnWithCompletionChain(sessionId, controller, deps) {
149
+ const { sessionManager, llmClient, statsIdentity, broadcastForSession } = deps;
150
+ runChatTurn({
151
+ sessionManager,
152
+ sessionId,
153
+ llmClient,
154
+ statsIdentity,
155
+ signal: controller.signal,
156
+ onMessage: (msg) => broadcastForSession(sessionId, msg)
157
+ }).catch((error) => {
158
+ if (error instanceof Error && error.message === "Aborted") {
159
+ return;
160
+ }
161
+ }).finally(() => {
162
+ if (activeAgents.get(sessionId) !== controller) {
163
+ return;
164
+ }
165
+ activeAgents.delete(sessionId);
166
+ const completionMsgs = sessionManager.drainCompletionMessages(sessionId);
167
+ const next = completionMsgs[0];
168
+ if (next) {
169
+ for (const remaining of completionMsgs.slice(1)) {
170
+ sessionManager.queueMessage(sessionId, "completion", remaining.content, remaining.attachments);
171
+ }
172
+ const userMessage = sessionManager.addMessage(sessionId, {
173
+ role: "user",
174
+ content: next.content,
175
+ ...next.attachments ? { attachments: next.attachments } : {}
176
+ });
177
+ broadcastForSession(sessionId, createChatMessageMessage(userMessage));
178
+ const newController = new AbortController();
179
+ activeAgents.set(sessionId, newController);
180
+ startTurnWithCompletionChain(sessionId, newController, deps);
181
+ return;
182
+ }
183
+ sessionManager.clearMessageQueue(sessionId);
184
+ sessionManager.setRunning(sessionId, false);
185
+ const contextState = sessionManager.getContextState(sessionId);
186
+ broadcastForSession(sessionId, createContextStateMessage(contextState));
187
+ });
188
+ }
189
+ function stopSessionExecution(sessionId, sessionManager) {
190
+ const controller = activeAgents.get(sessionId);
191
+ if (controller) {
192
+ activeAgents.delete(sessionId);
193
+ controller.abort();
194
+ }
195
+ sessionManager.setRunning(sessionId, false);
196
+ }
197
+ export {
198
+ startChatSession,
199
+ stopSessionExecution
200
+ };
201
+ //# sourceMappingURL=chat-handler-T7SLWZ4E.js.map
@@ -0,0 +1,128 @@
1
+ // src/server/utils/async.ts
2
+ function createDeferred() {
3
+ let resolve;
4
+ let reject;
5
+ const promise = new Promise((res, rej) => {
6
+ resolve = res;
7
+ reject = rej;
8
+ });
9
+ return { promise, resolve, reject };
10
+ }
11
+ var EventEmitter = class {
12
+ listeners = /* @__PURE__ */ new Map();
13
+ on(event, listener) {
14
+ if (!this.listeners.has(event)) {
15
+ this.listeners.set(event, /* @__PURE__ */ new Set());
16
+ }
17
+ const listeners = this.listeners.get(event);
18
+ listeners.add(listener);
19
+ return () => {
20
+ listeners.delete(listener);
21
+ };
22
+ }
23
+ emit(event, ...args) {
24
+ const listeners = this.listeners.get(event);
25
+ if (listeners) {
26
+ for (const listener of listeners) {
27
+ listener(...args);
28
+ }
29
+ }
30
+ }
31
+ removeAllListeners() {
32
+ this.listeners.clear();
33
+ }
34
+ };
35
+
36
+ // src/server/tools/ask.ts
37
+ var pendingQuestions = /* @__PURE__ */ new Map();
38
+ var askUserTool = {
39
+ name: "ask_user",
40
+ definition: {
41
+ type: "function",
42
+ function: {
43
+ name: "ask_user",
44
+ description: "Pause execution and ask the user a question. Use this when you need clarification or user input before proceeding.",
45
+ parameters: {
46
+ type: "object",
47
+ properties: {
48
+ question: {
49
+ type: "string",
50
+ description: "The question to ask the user"
51
+ }
52
+ },
53
+ required: ["question"]
54
+ }
55
+ }
56
+ },
57
+ async execute(args, context) {
58
+ const question = args["question"];
59
+ const callId = crypto.randomUUID();
60
+ const deferred = createDeferred();
61
+ void deferred.promise.catch(() => {
62
+ });
63
+ pendingQuestions.set(callId, {
64
+ promise: deferred.promise,
65
+ resolve: deferred.resolve,
66
+ reject: deferred.reject,
67
+ sessionId: context.sessionId
68
+ });
69
+ throw new AskUserInterrupt(callId, question);
70
+ }
71
+ };
72
+ var AskUserInterrupt = class extends Error {
73
+ constructor(callId, question) {
74
+ super("Ask user interrupt");
75
+ this.callId = callId;
76
+ this.question = question;
77
+ this.name = "AskUserInterrupt";
78
+ }
79
+ };
80
+ function provideAnswer(callId, answer) {
81
+ const pending = pendingQuestions.get(callId);
82
+ if (!pending) {
83
+ return false;
84
+ }
85
+ pending.resolve(answer);
86
+ pendingQuestions.delete(callId);
87
+ return true;
88
+ }
89
+ function cancelQuestion(callId, reason) {
90
+ const pending = pendingQuestions.get(callId);
91
+ if (!pending) {
92
+ return false;
93
+ }
94
+ pending.reject(new Error(reason));
95
+ pendingQuestions.delete(callId);
96
+ return true;
97
+ }
98
+ function cancelQuestionsForSession(sessionId, reason) {
99
+ let cancelledCount = 0;
100
+ for (const [callId, pending] of pendingQuestions.entries()) {
101
+ if (pending.sessionId !== sessionId) {
102
+ continue;
103
+ }
104
+ pending.reject(new Error(reason));
105
+ pendingQuestions.delete(callId);
106
+ cancelledCount += 1;
107
+ }
108
+ return cancelledCount;
109
+ }
110
+ function hasPendingQuestion(callId) {
111
+ return pendingQuestions.has(callId);
112
+ }
113
+ function awaitAnswer(callId) {
114
+ const pending = pendingQuestions.get(callId);
115
+ return pending?.promise ?? null;
116
+ }
117
+
118
+ export {
119
+ EventEmitter,
120
+ askUserTool,
121
+ AskUserInterrupt,
122
+ provideAnswer,
123
+ cancelQuestion,
124
+ cancelQuestionsForSession,
125
+ hasPendingQuestion,
126
+ awaitAnswer
127
+ };
128
+ //# sourceMappingURL=chunk-22CTURMH.js.map