@aiden-ade/sandbox-agent 0.1.45 → 0.1.46
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/index.cjs +805 -268
- package/package.json +1 -1
- package/dist/__tests__/cli-executable.test.d.ts +0 -2
- package/dist/__tests__/cli-executable.test.d.ts.map +0 -1
- package/dist/__tests__/cli-executable.test.js +0 -83
- package/dist/__tests__/cli-executable.test.js.map +0 -1
- package/dist/__tests__/cli-help.test.d.ts +0 -2
- package/dist/__tests__/cli-help.test.d.ts.map +0 -1
- package/dist/__tests__/cli-help.test.js +0 -33
- package/dist/__tests__/cli-help.test.js.map +0 -1
- package/dist/__tests__/core-agent-workflow-context.test.d.ts +0 -2
- package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +0 -1
- package/dist/__tests__/core-agent-workflow-context.test.js +0 -50
- package/dist/__tests__/core-agent-workflow-context.test.js.map +0 -1
- package/dist/__tests__/daemon-socket.integration.test.d.ts +0 -2
- package/dist/__tests__/daemon-socket.integration.test.d.ts.map +0 -1
- package/dist/__tests__/daemon-socket.integration.test.js +0 -156
- package/dist/__tests__/daemon-socket.integration.test.js.map +0 -1
- package/dist/__tests__/daemon.test.d.ts +0 -2
- package/dist/__tests__/daemon.test.d.ts.map +0 -1
- package/dist/__tests__/daemon.test.js +0 -1014
- package/dist/__tests__/daemon.test.js.map +0 -1
- package/dist/__tests__/generated-images.test.d.ts +0 -2
- package/dist/__tests__/generated-images.test.d.ts.map +0 -1
- package/dist/__tests__/generated-images.test.js +0 -50
- package/dist/__tests__/generated-images.test.js.map +0 -1
- package/dist/__tests__/sandbox-workflow-context.test.d.ts +0 -2
- package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +0 -1
- package/dist/__tests__/sandbox-workflow-context.test.js +0 -66
- package/dist/__tests__/sandbox-workflow-context.test.js.map +0 -1
- package/dist/aiden-system-prompt.d.ts +0 -6
- package/dist/aiden-system-prompt.d.ts.map +0 -1
- package/dist/aiden-system-prompt.js +0 -6
- package/dist/aiden-system-prompt.js.map +0 -1
- package/dist/cli-executable.d.ts +0 -58
- package/dist/cli-executable.d.ts.map +0 -1
- package/dist/cli-executable.js +0 -301
- package/dist/cli-executable.js.map +0 -1
- package/dist/cli-help.d.ts +0 -7
- package/dist/cli-help.d.ts.map +0 -1
- package/dist/cli-help.js +0 -45
- package/dist/cli-help.js.map +0 -1
- package/dist/core-agent.d.ts +0 -37
- package/dist/core-agent.d.ts.map +0 -1
- package/dist/core-agent.js +0 -337
- package/dist/core-agent.js.map +0 -1
- package/dist/daemon.d.ts +0 -46
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -876
- package/dist/daemon.js.map +0 -1
- package/dist/generated-images.d.ts +0 -4
- package/dist/generated-images.d.ts.map +0 -1
- package/dist/generated-images.js +0 -142
- package/dist/generated-images.js.map +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -118
- package/dist/index.js.map +0 -1
- package/dist/runtime-backends.d.ts +0 -2
- package/dist/runtime-backends.d.ts.map +0 -1
- package/dist/runtime-backends.js +0 -2
- package/dist/runtime-backends.js.map +0 -1
- package/dist/sandbox.d.ts +0 -31
- package/dist/sandbox.d.ts.map +0 -1
- package/dist/sandbox.js +0 -215
- package/dist/sandbox.js.map +0 -1
- package/dist/types.d.ts +0 -6
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -6
- package/dist/types.js.map +0 -1
- package/dist/updater.d.ts +0 -15
- package/dist/updater.d.ts.map +0 -1
- package/dist/updater.js +0 -50
- package/dist/updater.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -2
- package/dist/version.js.map +0 -1
- package/dist/web-presenter.d.ts +0 -36
- package/dist/web-presenter.d.ts.map +0 -1
- package/dist/web-presenter.js +0 -125
- package/dist/web-presenter.js.map +0 -1
- package/dist/ws-client.d.ts +0 -114
- package/dist/ws-client.d.ts.map +0 -1
- package/dist/ws-client.js +0 -97
- package/dist/ws-client.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -13851,63 +13851,21 @@ var import_path = require("path");
|
|
|
13851
13851
|
// ../shared/dist/agent/agent-definitions.js
|
|
13852
13852
|
var COORDINATOR_PROMPT = `## You are the Orchestrator
|
|
13853
13853
|
|
|
13854
|
-
You are the **Orchestrator** for this task. When asked "who are you?", "what agent are you?", "are you the coordinator?", "are you the orchestrator?", or anything similar \u2014 identify yourself plainly as the Orchestrator for this task. Do not say "I'm Alan" alone; say "I'm the Orchestrator
|
|
13854
|
+
You are the **Orchestrator** for this task. When asked "who are you?", "what agent are you?", "are you the coordinator?", "are you the orchestrator?", or anything similar \u2014 identify yourself plainly as the Orchestrator for this task. Do not say "I'm Alan" alone; say "I'm the Orchestrator for this task."
|
|
13855
13855
|
|
|
13856
|
-
Your primary job is orchestration: understand
|
|
13856
|
+
Your primary job is orchestration: understand task state, choose the next unit of work, and decide whether to act directly or delegate to a specialist.
|
|
13857
13857
|
|
|
13858
|
-
You may inspect, edit, run commands, create artifacts, and use MCP tools when
|
|
13858
|
+
You are coordination-first and not read-only. You may inspect, edit, run commands, create artifacts, and use MCP tools when direct action is the smallest coherent path.
|
|
13859
13859
|
|
|
13860
|
-
##
|
|
13861
|
-
|
|
13862
|
-
Use these tools, in roughly this order of frequency:
|
|
13863
|
-
1. \`delegate_task_session\` \u2014 route work to a specialist, reusing active matching workers by default
|
|
13864
|
-
2. \`list_task_events\` / \`add_task_event\` \u2014 use only for high-signal human-visible events: durable decisions, learnings, checkpoints, and outcomes that change future work
|
|
13865
|
-
3. \`list_agent_memory\` / \`add_agent_memory\` \u2014 use only when synthesized context will help future agents; do not store raw files inspected, commands run, or tool outputs
|
|
13866
|
-
4. \`list_subtasks\` / \`create_subtask\` / \`update_subtask\` \u2014 keep task breakdown current
|
|
13867
|
-
5. \`get_session_context\` \u2014 check what a worker accomplished
|
|
13868
|
-
6. \`update_task\` \u2014 keep status, priority, labels current
|
|
13869
|
-
7. \`send_session_message\` / \`start_task_session\` \u2014 continue a specific session or force a new session only when needed
|
|
13870
|
-
8. \`list_sessions\` / \`search\` / \`search_code_context\` / \`Read\` / \`Glob\` / \`Grep\` \u2014 situational awareness (\`search_code_context\` before grep for codebase discovery or implementation-answer questions; read exact cited files before claiming behavior)
|
|
13871
|
-
9. \`get_task_memory\` / \`update_task_memory\` \u2014 compatibility memory tools for older task summaries and session outcomes
|
|
13872
|
-
10. \`create_plan\` \u2014 document implementation plans and durable specs as artifacts
|
|
13873
|
-
11. \`add_task_comment\` \u2014 human-facing collaboration: answer questions, post explicit status updates, escalate blockers, or leave comments the user asked you to post. Do not use comments as running notes or memory.
|
|
13874
|
-
|
|
13875
|
-
## How to scale work
|
|
13876
|
-
|
|
13877
|
-
Match session count to actual complexity \u2014 do not over-delegate:
|
|
13878
|
-
- **Single session** (1 agent, focused scope): most tasks \u2014 a bug fix, a single feature, a review
|
|
13879
|
-
- **2\u20133 sessions** (parallel or sequential): a feature that touches API + UI independently, or implementation followed by verification
|
|
13880
|
-
- **4+ sessions**: only when subtasks are clearly independent and coordination value exceeds overhead
|
|
13881
|
-
|
|
13882
|
-
A two-line change does not need its own session. A well-scoped subtask can often be one session.
|
|
13883
|
-
|
|
13884
|
-
## How to choose an agent when delegating
|
|
13885
|
-
|
|
13886
|
-
- **Implementor** \u2014 any implementation task, broad or narrow: features, fixes, data, API, UI, tests
|
|
13887
|
-
- **Designer** \u2014 interaction, layout, accessibility, visual clarity
|
|
13888
|
-
- **PM Agent** \u2014 product questions, requirements, scope definition, PRD creation
|
|
13889
|
-
- **General Agent** \u2014 only when no specialist fits
|
|
13890
|
-
|
|
13891
|
-
## How to delegate
|
|
13892
|
-
|
|
13893
|
-
Before creating any worker, check task memory and active sessions for a matching agent/workstream. Reuse the owning worker with \`delegate_task_session\` unless \`force_new\` is explicit or the workstream is intentionally independent.
|
|
13894
|
-
|
|
13895
|
-
Every \`delegate_task_session\` message must include all four of these:
|
|
13896
|
-
1. **Objective** \u2014 what to do, in one clear sentence
|
|
13897
|
-
2. **Relevant context** \u2014 which files, APIs, or prior session results matter
|
|
13898
|
-
3. **Constraints** \u2014 what not to change, patterns to match, things already tried
|
|
13899
|
-
4. **Definition of done** \u2014 what the output should look like when finished
|
|
13900
|
-
|
|
13901
|
-
Write it like a senior engineer's handoff note, not a vague request.
|
|
13902
|
-
|
|
13903
|
-
## Your workflow
|
|
13860
|
+
## How to work
|
|
13904
13861
|
|
|
13905
|
-
1. Read the task,
|
|
13906
|
-
2.
|
|
13907
|
-
3.
|
|
13908
|
-
4.
|
|
13862
|
+
1. Read the task, subtasks, recent sessions, and durable decisions before acting.
|
|
13863
|
+
2. Act directly for focused work. Delegate via \`delegate_task_session\` when a specialist or parallel worker is genuinely useful; prefer reusing an active matching worker over starting a new one. Use \`start_task_session\` only when a fresh session is explicitly required.
|
|
13864
|
+
3. Break down wide work into subtasks only when the split clarifies ownership or dependencies.
|
|
13865
|
+
4. Use \`get_session_context\` to integrate worker results. Log only durable decisions, blockers, validation outcomes, and changed assumptions with \`add_task_event\` or \`add_agent_memory\`.
|
|
13866
|
+
5. Change task status, priority, or labels only when the user explicitly asks or a task lifecycle instruction authorizes it.
|
|
13909
13867
|
|
|
13910
|
-
|
|
13868
|
+
Delegation notes must include objective, relevant context, constraints, and definition of done.
|
|
13911
13869
|
|
|
13912
13870
|
${TASK_CREATE_FIND_BEFORE_CREATE_INSTRUCTIONS}`;
|
|
13913
13871
|
var PM_PROMPT = `## You are the PM Agent
|
|
@@ -13916,78 +13874,23 @@ You are the **PM Agent** (Product Manager) for this task. When identifying yours
|
|
|
13916
13874
|
|
|
13917
13875
|
Your job is product thinking, not implementation. You own requirements, scope, and prioritization. You do not write code or edit files.
|
|
13918
13876
|
|
|
13919
|
-
##
|
|
13920
|
-
|
|
13921
|
-
You MUST NOT call these tools:
|
|
13922
|
-
- \`Edit\`, \`Write\`, \`MultiEdit\`, \`NotebookEdit\` \u2014 any file modification
|
|
13923
|
-
- \`Bash\` for state-mutating commands
|
|
13924
|
-
|
|
13925
|
-
You MUST NOT call \`start_task_session\` before you have written a plan or requirements document. Delegate only after scope is defined.
|
|
13926
|
-
|
|
13927
|
-
Read-only inspection is fine when you need to understand what exists.
|
|
13928
|
-
|
|
13929
|
-
## Your primary tools
|
|
13930
|
-
|
|
13931
|
-
Use these tools, in roughly this order of frequency:
|
|
13932
|
-
1. \`create_plan\` / \`create_document_artifact\` \u2014 write requirements, PRDs, or specs first
|
|
13933
|
-
2. \`create_subtask\` / \`update_subtask\` / \`list_subtasks\` \u2014 break work into ordered, dependency-aware units
|
|
13934
|
-
3. \`start_task_session\` \u2014 delegate to a specialist once scope is defined
|
|
13935
|
-
4. \`get_session_context\` / \`list_sessions\` \u2014 track progress
|
|
13936
|
-
5. \`update_task\` \u2014 keep status and priority current
|
|
13937
|
-
6. \`list_task_events\` / \`add_task_event\` \u2014 persist only high-signal human-readable decisions, learnings, checkpoints, and outcomes in the Agent Log
|
|
13938
|
-
7. \`list_agent_memory\` / \`add_agent_memory\` \u2014 persist only synthesized agent-only context that future agents need
|
|
13939
|
-
8. \`add_task_comment\` \u2014 human-facing collaboration: answer questions, post explicit status updates, escalate blockers, or leave comments the user asked you to post. Do not use comments as running notes or memory.
|
|
13940
|
-
|
|
13941
|
-
## How to think like a PM
|
|
13942
|
-
|
|
13943
|
-
- **Challenge scope creep** \u2014 if a request expands beyond the task objective, name it and decide explicitly
|
|
13944
|
-
- **One question at a time** \u2014 never ask a list of questions; identify the single most ambiguity-reducing question
|
|
13945
|
-
- **Prioritize by dependency** \u2014 order subtasks so nothing blocks unnecessarily
|
|
13946
|
-
- **Define done clearly** \u2014 every subtask must have an unambiguous completion criterion
|
|
13947
|
-
- **Surface risk early** \u2014 flag unknowns before delegating, not after a session fails
|
|
13948
|
-
|
|
13949
|
-
## How to choose an agent when delegating
|
|
13950
|
-
|
|
13951
|
-
- **Implementor** \u2014 any code change: features, fixes, data, API, UI, tests
|
|
13952
|
-
- **Designer** \u2014 interaction, layout, accessibility, visual design
|
|
13953
|
-
- **Orchestrator** \u2014 multi-agent orchestration where the work is complex enough to need coordination
|
|
13954
|
-
- **General Agent** \u2014 research, investigation, or work that doesn't fit a specialist
|
|
13955
|
-
|
|
13956
|
-
## How to write a kickoff message
|
|
13957
|
-
|
|
13958
|
-
Every \`start_task_session\` message must include all four of these:
|
|
13959
|
-
1. **Objective** \u2014 what to do, in one clear sentence
|
|
13960
|
-
2. **Relevant context** \u2014 which files, APIs, or prior session results matter
|
|
13961
|
-
3. **Constraints** \u2014 what not to change, patterns to match, things already tried
|
|
13962
|
-
4. **Definition of done** \u2014 what the output should look like when finished
|
|
13877
|
+
## How to work
|
|
13963
13878
|
|
|
13964
|
-
|
|
13879
|
+
1. Inspect existing task, product, code, and session context before asking questions.
|
|
13880
|
+
2. Ask one ambiguity-reducing question at a time.
|
|
13881
|
+
3. Write requirements, PRDs, plans, or task breakdowns as structured artifacts when task context exists.
|
|
13882
|
+
4. Challenge scope creep and define clear acceptance criteria before delegation.
|
|
13883
|
+
5. Delegate only after scope is defined. A kickoff must include objective, context, constraints, and definition of done.
|
|
13884
|
+
6. Log only durable product decisions or risks. Change task status, priority, or labels only when explicitly asked.
|
|
13965
13885
|
|
|
13966
|
-
|
|
13967
|
-
2. If scope is ambiguous, ask the one question that resolves the most uncertainty.
|
|
13968
|
-
3. Write requirements or a plan artifact before any delegation.
|
|
13969
|
-
4. Break work into subtasks ordered by dependency. Delegate one at a time unless subtasks are truly independent.
|
|
13970
|
-
5. Track results and update task status as work completes.`;
|
|
13886
|
+
Read-only inspection is fine. Do not edit files or run state-mutating commands.`;
|
|
13971
13887
|
var GENERAL_PROMPT = `## You are the General Agent
|
|
13972
13888
|
|
|
13973
|
-
You are a flexible general-purpose agent
|
|
13974
|
-
|
|
13975
|
-
Your name is Alan, General Agent.
|
|
13976
|
-
|
|
13977
|
-
Clarify the goal only when required, inspect the relevant context first, then complete the requested work directly. For codebase discovery or implementation-answer questions, use \`search_code_context\` before grep and read exact cited files before claiming behavior. Keep changes focused, avoid unrelated refactors, and validate the result before reporting back.
|
|
13978
|
-
|
|
13979
|
-
Non-trivial implementations include tests. Break and plan before building when scope is wide.
|
|
13889
|
+
You are Alan, General Agent: a flexible general-purpose agent profile for work that does not need a specialist.
|
|
13980
13890
|
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
## When done, report
|
|
13986
|
-
|
|
13987
|
-
- What you did (1\u20132 sentences)
|
|
13988
|
-
- Files changed, if any
|
|
13989
|
-
- How you validated the result
|
|
13990
|
-
- Any residual risk or open question`;
|
|
13891
|
+
Clarify only when required, inspect relevant context first, then act directly.
|
|
13892
|
+
For codebase discovery or implementation-answer questions, use \`search_code_context\` before grep and read exact cited files before claiming behavior.
|
|
13893
|
+
Keep changes focused and validate the result before reporting back.`;
|
|
13991
13894
|
var BUDDY_PROMPT = `## You are Buddy
|
|
13992
13895
|
|
|
13993
13896
|
You are **Buddy** (an Alan agent profile) for direct team chat. When identifying yourself, say "I'm Buddy, the direct chat agent in Alan."
|
|
@@ -14003,13 +13906,6 @@ Your job is to be the user's always-available teammate: answer questions, inspec
|
|
|
14003
13906
|
5. For implementation work, make the smallest coherent change and validate it.
|
|
14004
13907
|
6. For plans, PRDs, reviews, and test reports, use structured Alan artifacts when task context exists.
|
|
14005
13908
|
|
|
14006
|
-
## Primary tools (code discovery)
|
|
14007
|
-
|
|
14008
|
-
- \`mcp__alan__search_code_context\` / \`search_code_context\` \u2014 find where code lives or how behavior is implemented (**use this first**)
|
|
14009
|
-
- \`mcp__alan__code_context_status\` \u2014 confirm the team index is ready
|
|
14010
|
-
- \`Read\`, \`Grep\` \u2014 only after you have paths from the index, or for line-level edits in known files; read exact cited files before answering exact questions
|
|
14011
|
-
- Do **not** run repo-wide \`grep\` / \`rg\` / Bash find for "where is X" or "how does this work" questions when MCP code-context tools are available
|
|
14012
|
-
|
|
14013
13909
|
## Rules
|
|
14014
13910
|
|
|
14015
13911
|
- Do not pretend every chat is attached to a task. If no task context exists, treat it as team-level chat.
|
|
@@ -14043,8 +13939,6 @@ var IMPLEMENTOR_PROMPT = `## You are the Implementor Agent
|
|
|
14043
13939
|
|
|
14044
13940
|
You are a senior implementation agent responsible for end-to-end code delivery. When identifying yourself, say "I'm the Implementor Agent (an Alan agent profile)."
|
|
14045
13941
|
|
|
14046
|
-
Workflow: Listen \u2192 Understand \u2192 Break down \u2192 Plan \u2192 Build \u2192 Test \u2192 Ship.
|
|
14047
|
-
|
|
14048
13942
|
## How to approach the work
|
|
14049
13943
|
|
|
14050
13944
|
1. Read the kickoff message fully. Identify the exact scope \u2014 do not expand it.
|
|
@@ -14052,19 +13946,12 @@ Workflow: Listen \u2192 Understand \u2192 Break down \u2192 Plan \u2192 Build \u
|
|
|
14052
13946
|
3. Implement the smallest coherent path that satisfies the objective. Tests ship with code when the change is non-trivial.
|
|
14053
13947
|
4. Validate the specific behavior you changed before reporting back.
|
|
14054
13948
|
|
|
14055
|
-
## Primary tools
|
|
14056
|
-
|
|
14057
|
-
- \`mcp__alan__search_code_context\` / \`search_code_context\` \u2014 find where code lives or how behavior is implemented (use BEFORE grep for discovery and implementation-answer questions)
|
|
14058
|
-
- \`Read\`, \`Glob\`, \`Grep\` \u2014 read exact cited files or narrow search after you have paths from the index
|
|
14059
|
-
- \`Edit\`, \`Write\` \u2014 make changes; prefer \`Edit\` over \`Write\` for existing files
|
|
14060
|
-
- \`Bash\` \u2014 run type-checks, tests, and read-only commands; never skip validation
|
|
14061
|
-
- \`get_session_context\` \u2014 check what prior sessions already did before redoing work
|
|
14062
|
-
|
|
14063
13949
|
## Rules
|
|
14064
13950
|
|
|
13951
|
+
- For codebase discovery or implementation-answer questions, use \`search_code_context\` before grep and read exact cited files before claiming behavior.
|
|
14065
13952
|
- Match existing patterns. Do not introduce new abstractions unless the current implementation cannot work.
|
|
14066
13953
|
- Keep the write set narrow. A bug fix does not need surrounding cleanup.
|
|
14067
|
-
-
|
|
13954
|
+
- Run the narrowest meaningful validation after changes. If validation cannot run, say exactly why.
|
|
14068
13955
|
- Do not redesign scope. If the task is ambiguous, ask one targeted question before implementing.
|
|
14069
13956
|
|
|
14070
13957
|
## When done, report
|
|
@@ -14077,35 +13964,24 @@ var DESIGNER_PROMPT = `## You are the Designer Agent
|
|
|
14077
13964
|
|
|
14078
13965
|
You are a product UI designer and frontend interaction specialist. When identifying yourself, say "I'm the Designer Agent (an Alan agent profile)."
|
|
14079
13966
|
|
|
14080
|
-
## Taste Skill (premium frontends)
|
|
14081
|
-
|
|
14082
|
-
For landing pages, marketing sites, portfolios, or visual redesigns outside the core product shell, read and follow the \`design-taste-frontend\` skill in \`.agents/skills/\` before writing UI. Related vendored skills: \`redesign-existing-projects\` (existing codebases), \`minimalist-ui\`, \`high-end-visual-design\`, \`industrial-brutalist-ui\`. Sync from upstream with \`scripts/sync-taste-skills.sh\`.
|
|
14083
|
-
|
|
14084
13967
|
## How to approach the work
|
|
14085
13968
|
|
|
14086
13969
|
1. Think from the user's task flow before touching layout. What is the user trying to do?
|
|
14087
13970
|
2. Read the existing component patterns before writing new ones. Match what's already there.
|
|
14088
13971
|
3. Improve clarity, hierarchy, and consistency \u2014 not decoration.
|
|
14089
|
-
4.
|
|
13972
|
+
4. For landing pages, marketing sites, portfolios, or visual redesigns outside the core product shell, read and follow the \`design-taste-frontend\` skill in \`.agents/skills/\` before writing UI.
|
|
13973
|
+
5. If implementation is required, keep it tightly scoped to the UI change and validate the rendered screen state.
|
|
14090
13974
|
|
|
14091
13975
|
## Design principles
|
|
14092
13976
|
|
|
14093
13977
|
- **Useful over decorative** \u2014 every element should serve a user goal
|
|
14094
|
-
- **Consistent** \u2014 match
|
|
13978
|
+
- **Consistent** \u2014 match existing components and design-system tokens
|
|
14095
13979
|
- **Accessible** \u2014 keyboard-navigable, sufficient contrast, meaningful labels
|
|
14096
|
-
- **Responsive** \u2014
|
|
14097
|
-
|
|
14098
|
-
## Primary tools
|
|
14099
|
-
|
|
14100
|
-
- \`Read\`, \`Glob\`, \`Grep\` \u2014 read existing components and design tokens before making changes
|
|
14101
|
-
- \`Edit\` \u2014 make focused UI changes; avoid touching non-UI logic unless it blocks the design
|
|
14102
|
-
- \`Bash\` \u2014 run type-checks after changes; inspect the browser console if needed
|
|
14103
|
-
- \`get_session_context\` \u2014 check what prior sessions already built before duplicating work
|
|
13980
|
+
- **Responsive** \u2014 design for realistic desktop and mobile states
|
|
14104
13981
|
|
|
14105
13982
|
## Rules
|
|
14106
13983
|
|
|
14107
|
-
-
|
|
14108
|
-
- Never write raw \`<button>\`, \`<input>\`, \`<select>\` \u2014 use UI primitives
|
|
13984
|
+
- Use UI primitives where available; raw controls are acceptable only when no project primitive fits.
|
|
14109
13985
|
- Keep changes focused on the UI layer; do not refactor business logic as a side effect
|
|
14110
13986
|
- Validate the specific screen state you changed before reporting back
|
|
14111
13987
|
|
|
@@ -14134,7 +14010,7 @@ var BUILTIN_AGENT_DEFINITIONS = [
|
|
|
14134
14010
|
{
|
|
14135
14011
|
id: "general",
|
|
14136
14012
|
name: "General Agent",
|
|
14137
|
-
description: "Flexible agent
|
|
14013
|
+
description: "Flexible general-purpose agent",
|
|
14138
14014
|
iconKey: "bot",
|
|
14139
14015
|
defaultMode: "agent",
|
|
14140
14016
|
capabilities: {
|
|
@@ -14479,38 +14355,27 @@ function alanMcpConfigFilesForBackend(backendKind, mcpServers, home) {
|
|
|
14479
14355
|
var SESSION_RESUME_FAILED_MESSAGE = "Session resume failed. The previous session may have expired or is no longer available. Please start a new session.";
|
|
14480
14356
|
|
|
14481
14357
|
// ../shared/dist/agent/system-prompt.js
|
|
14482
|
-
var ALAN_IDENTITY_PROMPT = `You are Alan, the software factory agent. Alan ships software end to end
|
|
14358
|
+
var ALAN_IDENTITY_PROMPT = `You are Alan, the software factory agent. Alan ships software end to end: plan, write, review, test, deploy.
|
|
14483
14359
|
|
|
14484
14360
|
## How Alan is structured
|
|
14485
14361
|
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14490
|
-
\u2502 \u251C\u2500\u2500 Conversations \u2192 Messages
|
|
14491
|
-
\u2502 \u2514\u2500\u2500 Artifacts (plans, test reports, document artifacts)
|
|
14492
|
-
\u251C\u2500\u2500 Documents (standalone pages \u2014 PRDs, specs, wikis)
|
|
14493
|
-
\u2502 \u2514\u2500\u2500 Artifacts
|
|
14494
|
-
\u2514\u2500\u2500 Whiteboard (beta)
|
|
14495
|
-
\`\`\`
|
|
14496
|
-
|
|
14497
|
-
- **Document vs Artifact**: Document = standalone page in a team. Artifact = output from work on a task + conversation, tied to that context. Belongs to a task \u2192 artifact. Doesn't \u2192 document.
|
|
14498
|
-
- **IDs are not interchangeable**: teamId, taskId, conversationId identify different things. Substituting one for another orphans records. Use the IDs the system provides; never invent or guess.
|
|
14362
|
+
- Team contains tasks, documents, and the whiteboard.
|
|
14363
|
+
- Tasks contain subtasks, conversations, messages, and task-bound artifacts.
|
|
14364
|
+
- Documents are standalone pages. Artifacts are outputs tied to task/conversation work.
|
|
14365
|
+
- IDs are not interchangeable: teamId, taskId, conversationId, documentId, and artifactId identify different records. Use provided IDs; never invent or guess.
|
|
14499
14366
|
|
|
14500
14367
|
## Universal teammate principles
|
|
14501
14368
|
|
|
14502
14369
|
- Listen first. Don't jump to solutions. One question at a time, not a list.
|
|
14503
|
-
- Scan available context
|
|
14504
|
-
- Challenge
|
|
14505
|
-
- Human leads
|
|
14506
|
-
- Own mistakes. Wrong ID, jumped too fast \u2014 say so and fix it.
|
|
14507
|
-
- Think visually. Mermaid over paragraphs for architecture, flows, state, and schema.
|
|
14370
|
+
- Scan available context before asking questions you can answer yourself.
|
|
14371
|
+
- Challenge wrong assumptions before acting.
|
|
14372
|
+
- Human leads. Act on reversible steps; propose before consequential decisions.
|
|
14508
14373
|
|
|
14509
14374
|
## Task Logging
|
|
14510
14375
|
|
|
14511
|
-
For non-trivial tasks, log high-signal events
|
|
14376
|
+
For non-trivial tasks, log high-signal events: decisions, changed assumptions, validation results, known-good IDs, blockers, risks, and direction changes. Do not log routine commands or file reads.
|
|
14512
14377
|
|
|
14513
|
-
The
|
|
14378
|
+
The selected agent profile below defines the role-specific behavior.`;
|
|
14514
14379
|
function buildAlanTeamScopePrompt(teamId) {
|
|
14515
14380
|
return [
|
|
14516
14381
|
`You are operating within team \`${teamId}\`.`,
|
|
@@ -14550,15 +14415,7 @@ var PLAN_MODE_PROMPT = [
|
|
|
14550
14415
|
"Do not make code changes or execute write operations in plan mode.",
|
|
14551
14416
|
"Write the plan in natural markdown. Use whatever structure best communicates the work clearly.",
|
|
14552
14417
|
"Include dependencies, ordering, risks, key files/functions, and decision points where relevant.",
|
|
14553
|
-
"When
|
|
14554
|
-
"Pass title, content, summary, taskId, and conversationId. Include teamId too when available.",
|
|
14555
|
-
"If create_plan fails, retry it. Do not finish plan mode until the plan is persisted successfully.",
|
|
14556
|
-
"After create_plan succeeds, present the plan title and artifact link to the user for approval."
|
|
14557
|
-
].join("\n");
|
|
14558
|
-
var TEST_MODE_PROMPT = [
|
|
14559
|
-
"You are in test mode. Verify the implemented feature carefully.",
|
|
14560
|
-
"Prefer browser-based validation when available.",
|
|
14561
|
-
"Persist the outcome as a structured test report artifact with create_test_report instead of leaving it only in chat."
|
|
14418
|
+
"When task artifact tools and known task/conversation IDs are available, persist the plan as an Alan artifact."
|
|
14562
14419
|
].join("\n");
|
|
14563
14420
|
var ASK_MODE_PROMPT = "You are in ask mode. Stay read-only and explain the code, architecture, or behavior clearly without changing files.";
|
|
14564
14421
|
var REVIEW_MODE_PROMPT = "You are in review mode. Inspect the relevant changes, find real issues, and summarize risks and regressions precisely.";
|
|
@@ -14566,8 +14423,6 @@ function getAlanModePrompt(mode) {
|
|
|
14566
14423
|
switch (mode) {
|
|
14567
14424
|
case "plan":
|
|
14568
14425
|
return PLAN_MODE_PROMPT;
|
|
14569
|
-
case "test":
|
|
14570
|
-
return TEST_MODE_PROMPT;
|
|
14571
14426
|
case "ask":
|
|
14572
14427
|
return ASK_MODE_PROMPT;
|
|
14573
14428
|
case "review":
|
|
@@ -15142,10 +14997,10 @@ var CLAUDE_CLI_PICKER_FALLBACK_MODELS = [
|
|
|
15142
14997
|
slugModel("claude_cli", "claude-opus-4-8", "Opus 4.8", ["200k", "1m"])
|
|
15143
14998
|
];
|
|
15144
14999
|
var CODEX_APP_SERVER_PICKER_FALLBACK_MODELS = [
|
|
15145
|
-
slugModel("codex_app_server", "", "
|
|
15000
|
+
slugModel("codex_app_server", "gpt-5.6-sol", "GPT-5.6 Sol"),
|
|
15001
|
+
slugModel("codex_app_server", "gpt-5.6-terra", "GPT-5.6 Terra"),
|
|
15002
|
+
slugModel("codex_app_server", "gpt-5.6-luna", "GPT-5.6 Luna"),
|
|
15146
15003
|
slugModel("codex_app_server", "gpt-5.5", "GPT-5.5", ["1m"]),
|
|
15147
|
-
slugModel("codex_app_server", "gpt-5.4-mini", "GPT-5.4 Mini"),
|
|
15148
|
-
slugModel("codex_app_server", "gpt-5.3-codex", "GPT-5.3 Codex"),
|
|
15149
15004
|
slugModel("codex_app_server", "gpt-5.3-codex-spark", "GPT-5.3 Codex Spark")
|
|
15150
15005
|
];
|
|
15151
15006
|
var ANTIGRAVITY_CLI_PICKER_FALLBACK_MODELS = [
|
|
@@ -15285,14 +15140,17 @@ var import_path5 = require("path");
|
|
|
15285
15140
|
var import_fs6 = require("fs");
|
|
15286
15141
|
var import_os6 = require("os");
|
|
15287
15142
|
var import_path6 = require("path");
|
|
15288
|
-
var import_readline2 = require("readline");
|
|
15289
|
-
var import_url2 = require("url");
|
|
15290
15143
|
var import_fs7 = require("fs");
|
|
15291
15144
|
var import_os7 = require("os");
|
|
15292
15145
|
var import_path7 = require("path");
|
|
15293
|
-
var
|
|
15146
|
+
var import_readline2 = require("readline");
|
|
15147
|
+
var import_url2 = require("url");
|
|
15294
15148
|
var import_fs8 = require("fs");
|
|
15149
|
+
var import_os8 = require("os");
|
|
15295
15150
|
var import_path8 = require("path");
|
|
15151
|
+
var import_crypto3 = require("crypto");
|
|
15152
|
+
var import_fs9 = require("fs");
|
|
15153
|
+
var import_path9 = require("path");
|
|
15296
15154
|
var MANAGED_ALAN_MCP_SERVER_NAMES = [
|
|
15297
15155
|
"alan",
|
|
15298
15156
|
"alan-prod",
|
|
@@ -16354,6 +16212,10 @@ function createGenericCliBackend(options) {
|
|
|
16354
16212
|
}
|
|
16355
16213
|
} finally {
|
|
16356
16214
|
if (startupTimer) clearTimeout(startupTimer);
|
|
16215
|
+
if (state.providerTranscriptPollTimer) {
|
|
16216
|
+
clearInterval(state.providerTranscriptPollTimer);
|
|
16217
|
+
state.providerTranscriptPollTimer = void 0;
|
|
16218
|
+
}
|
|
16357
16219
|
stdoutRl.close();
|
|
16358
16220
|
stderrRl.close();
|
|
16359
16221
|
logUnhandledStructuredEventSummary(options.kind, state);
|
|
@@ -17299,16 +17161,26 @@ function handleClaudeStructuredEvent(parsed, context, state) {
|
|
|
17299
17161
|
if (typeof block !== "object" || block === null || !("type" in block)) continue;
|
|
17300
17162
|
if (block.type === "text" && typeof block.text === "string") {
|
|
17301
17163
|
const text = block.text;
|
|
17302
|
-
state.summary += `${text}
|
|
17164
|
+
if (!parentToolUseId) state.summary += `${text}
|
|
17303
17165
|
`;
|
|
17304
|
-
|
|
17305
|
-
${text}` : text
|
|
17166
|
+
const streamedText = previousBlockWasText ? `
|
|
17167
|
+
${text}` : text;
|
|
17168
|
+
if (parentToolUseId) {
|
|
17169
|
+
void presenter.onAssistantText(streamedText, parentToolUseId);
|
|
17170
|
+
} else {
|
|
17171
|
+
void presenter.onAssistantText(streamedText);
|
|
17172
|
+
}
|
|
17306
17173
|
previousBlockWasText = true;
|
|
17307
17174
|
continue;
|
|
17308
17175
|
}
|
|
17309
17176
|
if (block.type === "thinking" && typeof block.thinking === "string") {
|
|
17310
17177
|
previousBlockWasText = false;
|
|
17311
|
-
|
|
17178
|
+
const thinking = block.thinking;
|
|
17179
|
+
if (parentToolUseId) {
|
|
17180
|
+
void presenter.onThinking(thinking, parentToolUseId);
|
|
17181
|
+
} else {
|
|
17182
|
+
void presenter.onThinking(thinking);
|
|
17183
|
+
}
|
|
17312
17184
|
continue;
|
|
17313
17185
|
}
|
|
17314
17186
|
if (block.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string") {
|
|
@@ -17686,7 +17558,7 @@ function isSyntheticUserRolloutMessage(payload) {
|
|
|
17686
17558
|
const text = extractRolloutMessageText(payload).trimStart();
|
|
17687
17559
|
if (!text) return false;
|
|
17688
17560
|
const lower = text.toLowerCase();
|
|
17689
|
-
return lower.startsWith("<environment_context") || lower.startsWith("<user_instructions") || // Auto-compaction bridge summaries are tagged in the rollout content.
|
|
17561
|
+
return lower.startsWith("<environment_context") || lower.startsWith("<user_instructions") || lower.startsWith("<recommended_plugins") || lower.startsWith("<subagent_notification") || // Auto-compaction bridge summaries are tagged in the rollout content.
|
|
17690
17562
|
lower.startsWith("<compact") || lower.startsWith("[compact");
|
|
17691
17563
|
}
|
|
17692
17564
|
function latestUserMessageLineIndex(lines) {
|
|
@@ -17702,6 +17574,253 @@ function latestUserMessageLineIndex(lines) {
|
|
|
17702
17574
|
}
|
|
17703
17575
|
return latestIndex;
|
|
17704
17576
|
}
|
|
17577
|
+
function firstUserMessageLineIndex(lines) {
|
|
17578
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
17579
|
+
const line = lines[index];
|
|
17580
|
+
if (!line) continue;
|
|
17581
|
+
const entry = parseJsonObject(line);
|
|
17582
|
+
const payload = asRecord(entry?.payload);
|
|
17583
|
+
if (payload?.type === "message" && payload.role === "user" && !isSyntheticUserRolloutMessage(payload)) {
|
|
17584
|
+
return index;
|
|
17585
|
+
}
|
|
17586
|
+
}
|
|
17587
|
+
return -1;
|
|
17588
|
+
}
|
|
17589
|
+
function asRecord(value2) {
|
|
17590
|
+
return value2 && typeof value2 === "object" ? value2 : null;
|
|
17591
|
+
}
|
|
17592
|
+
function rolloutTextContent(content) {
|
|
17593
|
+
if (typeof content === "string") return content;
|
|
17594
|
+
if (!Array.isArray(content)) return "";
|
|
17595
|
+
return content.flatMap((block) => {
|
|
17596
|
+
const record = asRecord(block);
|
|
17597
|
+
const text = record?.text;
|
|
17598
|
+
return typeof text === "string" ? [text] : [];
|
|
17599
|
+
}).join("");
|
|
17600
|
+
}
|
|
17601
|
+
function rolloutToolOutputText(output) {
|
|
17602
|
+
if (typeof output === "string") return output;
|
|
17603
|
+
const text = rolloutTextContent(output);
|
|
17604
|
+
if (text) return text;
|
|
17605
|
+
try {
|
|
17606
|
+
return JSON.stringify(output ?? "", null, 2);
|
|
17607
|
+
} catch {
|
|
17608
|
+
return String(output ?? "");
|
|
17609
|
+
}
|
|
17610
|
+
}
|
|
17611
|
+
function rolloutFunctionToolName(payload) {
|
|
17612
|
+
const name = typeof payload.name === "string" ? payload.name : "Codex Tool";
|
|
17613
|
+
const namespace = typeof payload.namespace === "string" ? payload.namespace : "";
|
|
17614
|
+
if (namespace.startsWith("mcp__")) {
|
|
17615
|
+
return `${namespace.replace(/_+$/, "")}__${name}`;
|
|
17616
|
+
}
|
|
17617
|
+
if (name === "exec" || name === "exec_command") return "Bash";
|
|
17618
|
+
return name;
|
|
17619
|
+
}
|
|
17620
|
+
function collectCodexWorkerReplays(lines, state) {
|
|
17621
|
+
const spawnByCallId = /* @__PURE__ */ new Map();
|
|
17622
|
+
const workersByThreadId = /* @__PURE__ */ new Map();
|
|
17623
|
+
for (const line of lines) {
|
|
17624
|
+
const entry = parseJsonObject(line);
|
|
17625
|
+
const payload = asRecord(entry?.payload);
|
|
17626
|
+
if (!payload) continue;
|
|
17627
|
+
if (entry?.type === "response_item" && payload.type === "function_call" && payload.name === "spawn_agent") {
|
|
17628
|
+
const namespace = typeof payload.namespace === "string" ? payload.namespace : "";
|
|
17629
|
+
if (namespace !== "collaboration" && namespace !== "multi_agent_v1") continue;
|
|
17630
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17631
|
+
if (!callId) continue;
|
|
17632
|
+
const args = asRecord(parseMaybeJson(payload.arguments));
|
|
17633
|
+
const taskName = typeof args?.task_name === "string" ? args.task_name : "";
|
|
17634
|
+
const message = typeof args?.message === "string" ? args.message : "";
|
|
17635
|
+
spawnByCallId.set(callId, {
|
|
17636
|
+
launcherId: callId,
|
|
17637
|
+
description: taskName || (message ? message.split(/\r?\n/, 1)[0] : void 0)
|
|
17638
|
+
});
|
|
17639
|
+
continue;
|
|
17640
|
+
}
|
|
17641
|
+
if (entry?.type === "response_item" && payload.type === "function_call_output") {
|
|
17642
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17643
|
+
const spawn32 = spawnByCallId.get(callId);
|
|
17644
|
+
if (!spawn32) continue;
|
|
17645
|
+
const output = asRecord(parseMaybeJson(payload.output));
|
|
17646
|
+
const threadId = typeof output?.agent_id === "string" ? output.agent_id : "";
|
|
17647
|
+
if (!threadId) continue;
|
|
17648
|
+
const nickname = typeof output?.nickname === "string" ? output.nickname : void 0;
|
|
17649
|
+
workersByThreadId.set(threadId, { ...spawn32, threadId, nickname });
|
|
17650
|
+
continue;
|
|
17651
|
+
}
|
|
17652
|
+
if (entry?.type === "event_msg" && payload.type === "sub_agent_activity" && payload.kind === "started") {
|
|
17653
|
+
const threadId = typeof payload.agent_thread_id === "string" ? payload.agent_thread_id : "";
|
|
17654
|
+
const launcherId = typeof payload.event_id === "string" ? payload.event_id : "";
|
|
17655
|
+
if (!threadId || !launcherId) continue;
|
|
17656
|
+
const agentPath = typeof payload.agent_path === "string" ? payload.agent_path : void 0;
|
|
17657
|
+
const spawn32 = spawnByCallId.get(launcherId);
|
|
17658
|
+
workersByThreadId.set(threadId, {
|
|
17659
|
+
launcherId,
|
|
17660
|
+
threadId,
|
|
17661
|
+
agentPath,
|
|
17662
|
+
description: spawn32?.description
|
|
17663
|
+
});
|
|
17664
|
+
}
|
|
17665
|
+
}
|
|
17666
|
+
for (const [threadId, launcherId] of state.backgroundToolIdByTaskId ?? []) {
|
|
17667
|
+
if (!workersByThreadId.has(threadId)) {
|
|
17668
|
+
workersByThreadId.set(threadId, { threadId, launcherId });
|
|
17669
|
+
}
|
|
17670
|
+
}
|
|
17671
|
+
for (const [threadId, launcherId] of state.codexWorkerToolIdByThreadId ?? []) {
|
|
17672
|
+
const existing = workersByThreadId.get(threadId);
|
|
17673
|
+
workersByThreadId.set(threadId, {
|
|
17674
|
+
...existing,
|
|
17675
|
+
threadId,
|
|
17676
|
+
launcherId
|
|
17677
|
+
});
|
|
17678
|
+
}
|
|
17679
|
+
return [...workersByThreadId.values()];
|
|
17680
|
+
}
|
|
17681
|
+
function replayCodexWorkerTranscript(context, worker, codexHome, state) {
|
|
17682
|
+
const logPath = state.codexWorkerSessionLogPathByThreadId?.get(worker.threadId) ?? findCodexSessionLog(worker.threadId, codexHome);
|
|
17683
|
+
if (!logPath) return "";
|
|
17684
|
+
if (!state.codexWorkerSessionLogPathByThreadId)
|
|
17685
|
+
state.codexWorkerSessionLogPathByThreadId = /* @__PURE__ */ new Map();
|
|
17686
|
+
state.codexWorkerSessionLogPathByThreadId.set(worker.threadId, logPath);
|
|
17687
|
+
const allLines = (0, import_fs5.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
17688
|
+
const firstUserLineIndex = firstUserMessageLineIndex(allLines);
|
|
17689
|
+
const lines = firstUserLineIndex >= 0 ? allLines.slice(firstUserLineIndex + 1) : allLines;
|
|
17690
|
+
const emittedToolNames = /* @__PURE__ */ new Map();
|
|
17691
|
+
const replayedLineCount = state.codexWorkerReplayLineCountByThreadId?.get(worker.threadId) ?? 0;
|
|
17692
|
+
let finalText = state.codexWorkerFinalTextByThreadId?.get(worker.threadId) ?? "";
|
|
17693
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
17694
|
+
const line = lines[index];
|
|
17695
|
+
if (!line) continue;
|
|
17696
|
+
const entry = parseJsonObject(line);
|
|
17697
|
+
if (entry?.type !== "response_item") continue;
|
|
17698
|
+
const payload = asRecord(entry.payload);
|
|
17699
|
+
if (!payload) continue;
|
|
17700
|
+
if (payload.type === "message" && payload.role === "assistant") {
|
|
17701
|
+
const text = rolloutTextContent(payload.content);
|
|
17702
|
+
if (!text) continue;
|
|
17703
|
+
finalText = text;
|
|
17704
|
+
if (index >= replayedLineCount) {
|
|
17705
|
+
void context.presenter.onAssistantText(text, worker.launcherId);
|
|
17706
|
+
}
|
|
17707
|
+
continue;
|
|
17708
|
+
}
|
|
17709
|
+
if (payload.type === "function_call") {
|
|
17710
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17711
|
+
if (!callId) continue;
|
|
17712
|
+
const toolName = rolloutFunctionToolName(payload);
|
|
17713
|
+
emittedToolNames.set(callId, toolName);
|
|
17714
|
+
if (index >= replayedLineCount) {
|
|
17715
|
+
void context.presenter.onToolUse(
|
|
17716
|
+
toolName,
|
|
17717
|
+
parseMaybeJson(payload.arguments),
|
|
17718
|
+
callId,
|
|
17719
|
+
worker.launcherId
|
|
17720
|
+
);
|
|
17721
|
+
}
|
|
17722
|
+
continue;
|
|
17723
|
+
}
|
|
17724
|
+
if (payload.type === "custom_tool_call") {
|
|
17725
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17726
|
+
if (!callId) continue;
|
|
17727
|
+
const toolName = rolloutFunctionToolName(payload);
|
|
17728
|
+
emittedToolNames.set(callId, toolName);
|
|
17729
|
+
if (index >= replayedLineCount) {
|
|
17730
|
+
void context.presenter.onToolUse(
|
|
17731
|
+
toolName,
|
|
17732
|
+
{ code: payload.input ?? "" },
|
|
17733
|
+
callId,
|
|
17734
|
+
worker.launcherId
|
|
17735
|
+
);
|
|
17736
|
+
}
|
|
17737
|
+
continue;
|
|
17738
|
+
}
|
|
17739
|
+
if (payload.type === "tool_search_call") {
|
|
17740
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17741
|
+
if (!callId) continue;
|
|
17742
|
+
emittedToolNames.set(callId, "tool_search");
|
|
17743
|
+
if (index >= replayedLineCount) {
|
|
17744
|
+
void context.presenter.onToolUse(
|
|
17745
|
+
"tool_search",
|
|
17746
|
+
payload.arguments ?? {},
|
|
17747
|
+
callId,
|
|
17748
|
+
worker.launcherId
|
|
17749
|
+
);
|
|
17750
|
+
}
|
|
17751
|
+
continue;
|
|
17752
|
+
}
|
|
17753
|
+
if (payload.type === "function_call_output" || payload.type === "custom_tool_call_output") {
|
|
17754
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17755
|
+
const toolName = emittedToolNames.get(callId);
|
|
17756
|
+
if (!callId || !toolName || index < replayedLineCount) continue;
|
|
17757
|
+
let output = rolloutToolOutputText(payload.output);
|
|
17758
|
+
if (toolName.startsWith("mcp__")) {
|
|
17759
|
+
try {
|
|
17760
|
+
output = normalizeCodexMcpToolResult(payload.output);
|
|
17761
|
+
} catch {
|
|
17762
|
+
}
|
|
17763
|
+
}
|
|
17764
|
+
void context.presenter.onToolResult?.(callId, output, void 0, worker.launcherId);
|
|
17765
|
+
continue;
|
|
17766
|
+
}
|
|
17767
|
+
if (payload.type === "tool_search_output") {
|
|
17768
|
+
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
17769
|
+
if (!callId || !emittedToolNames.has(callId) || index < replayedLineCount) continue;
|
|
17770
|
+
void context.presenter.onToolResult?.(
|
|
17771
|
+
callId,
|
|
17772
|
+
JSON.stringify(payload.tools ?? [], null, 2),
|
|
17773
|
+
void 0,
|
|
17774
|
+
worker.launcherId
|
|
17775
|
+
);
|
|
17776
|
+
}
|
|
17777
|
+
}
|
|
17778
|
+
if (!state.codexWorkerReplayLineCountByThreadId)
|
|
17779
|
+
state.codexWorkerReplayLineCountByThreadId = /* @__PURE__ */ new Map();
|
|
17780
|
+
state.codexWorkerReplayLineCountByThreadId.set(worker.threadId, lines.length);
|
|
17781
|
+
if (!state.codexWorkerFinalTextByThreadId) state.codexWorkerFinalTextByThreadId = /* @__PURE__ */ new Map();
|
|
17782
|
+
if (finalText) state.codexWorkerFinalTextByThreadId.set(worker.threadId, finalText);
|
|
17783
|
+
return finalText;
|
|
17784
|
+
}
|
|
17785
|
+
function syncCodexWorkerEventsFromSessionLog(context, state) {
|
|
17786
|
+
const runtimeSessionId = state.runtimeSessionId;
|
|
17787
|
+
if (!runtimeSessionId) return [];
|
|
17788
|
+
const codexHome = resolveCodexHome(context.env);
|
|
17789
|
+
const logPath = state.codexSessionLogPath ?? findCodexSessionLog(runtimeSessionId, codexHome);
|
|
17790
|
+
if (!logPath) return [];
|
|
17791
|
+
state.codexSessionLogPath = logPath;
|
|
17792
|
+
const allLines = (0, import_fs5.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
17793
|
+
const latestUserLineIndex = latestUserMessageLineIndex(allLines);
|
|
17794
|
+
const lines = latestUserLineIndex >= 0 ? allLines.slice(latestUserLineIndex + 1) : allLines;
|
|
17795
|
+
const workers = collectCodexWorkerReplays(lines, state);
|
|
17796
|
+
for (const worker of workers) {
|
|
17797
|
+
const launcherWasStreamed = state.codexStreamedToolIds?.has(worker.launcherId) === true;
|
|
17798
|
+
if (!launcherWasStreamed) {
|
|
17799
|
+
const workerName = worker.nickname || worker.agentPath?.slice(worker.agentPath.lastIndexOf("/") + 1) || "codex-worker";
|
|
17800
|
+
void context.presenter.onToolUse(
|
|
17801
|
+
"Agent",
|
|
17802
|
+
{
|
|
17803
|
+
subagent_type: workerName,
|
|
17804
|
+
description: worker.description || worker.agentPath || "Codex background worker",
|
|
17805
|
+
agent_thread_id: worker.threadId
|
|
17806
|
+
},
|
|
17807
|
+
worker.launcherId
|
|
17808
|
+
);
|
|
17809
|
+
if (!state.codexStreamedToolIds) state.codexStreamedToolIds = /* @__PURE__ */ new Set();
|
|
17810
|
+
state.codexStreamedToolIds.add(worker.launcherId);
|
|
17811
|
+
if (!state.codexRecoveredLauncherIds) state.codexRecoveredLauncherIds = /* @__PURE__ */ new Set();
|
|
17812
|
+
state.codexRecoveredLauncherIds.add(worker.launcherId);
|
|
17813
|
+
}
|
|
17814
|
+
if (!state.codexWorkerToolIdByThreadId) state.codexWorkerToolIdByThreadId = /* @__PURE__ */ new Map();
|
|
17815
|
+
state.codexWorkerToolIdByThreadId.set(worker.threadId, worker.launcherId);
|
|
17816
|
+
if (worker.agentPath) {
|
|
17817
|
+
if (!state.codexWorkerToolIdByPath) state.codexWorkerToolIdByPath = /* @__PURE__ */ new Map();
|
|
17818
|
+
state.codexWorkerToolIdByPath.set(worker.agentPath, worker.launcherId);
|
|
17819
|
+
}
|
|
17820
|
+
replayCodexWorkerTranscript(context, worker, codexHome, state);
|
|
17821
|
+
}
|
|
17822
|
+
return workers;
|
|
17823
|
+
}
|
|
17705
17824
|
async function replayCodexMcpToolEventsFromSessionLog(context, state) {
|
|
17706
17825
|
const runtimeSessionId = state.runtimeSessionId;
|
|
17707
17826
|
if (!runtimeSessionId) return;
|
|
@@ -17758,10 +17877,51 @@ async function replayCodexMcpToolEventsFromSessionLog(context, state) {
|
|
|
17758
17877
|
}
|
|
17759
17878
|
}
|
|
17760
17879
|
}
|
|
17880
|
+
for (const worker of syncCodexWorkerEventsFromSessionLog(context, state)) {
|
|
17881
|
+
if (state.codexRecoveredLauncherIds?.has(worker.launcherId)) {
|
|
17882
|
+
const finalText = state.codexWorkerFinalTextByThreadId?.get(worker.threadId) ?? "";
|
|
17883
|
+
void context.presenter.onToolResult?.(worker.launcherId, finalText || "Subagent completed.");
|
|
17884
|
+
state.codexRecoveredLauncherIds.delete(worker.launcherId);
|
|
17885
|
+
}
|
|
17886
|
+
}
|
|
17761
17887
|
}
|
|
17762
17888
|
var CODEX_EXIT_GRACE_MS = 3e4;
|
|
17763
17889
|
var CODEX_BACKGROUND_EXIT_GRACE_MS = 10 * 6e4;
|
|
17764
17890
|
var CODEX_EXIT_GRACE_SIGKILL_MS = 3e3;
|
|
17891
|
+
var CODEX_WORKER_TRANSCRIPT_POLL_MS = 750;
|
|
17892
|
+
function ensureCodexWorkerEventPolling(context, state) {
|
|
17893
|
+
if (!state.runtimeSessionId || state.providerTranscriptPollTimer) return;
|
|
17894
|
+
const poll = () => {
|
|
17895
|
+
try {
|
|
17896
|
+
const before = [...state.codexWorkerReplayLineCountByThreadId?.values() ?? []].reduce(
|
|
17897
|
+
(total, count) => total + count,
|
|
17898
|
+
0
|
|
17899
|
+
) + (state.codexStreamedToolIds?.size ?? 0);
|
|
17900
|
+
syncCodexWorkerEventsFromSessionLog(context, state);
|
|
17901
|
+
const after = [...state.codexWorkerReplayLineCountByThreadId?.values() ?? []].reduce(
|
|
17902
|
+
(total, count) => total + count,
|
|
17903
|
+
0
|
|
17904
|
+
) + (state.codexStreamedToolIds?.size ?? 0);
|
|
17905
|
+
if (after > before) state.onNewOutput?.();
|
|
17906
|
+
state.providerTranscriptPollErrorLogged = false;
|
|
17907
|
+
} catch (error) {
|
|
17908
|
+
if (!state.providerTranscriptPollErrorLogged) {
|
|
17909
|
+
console.warn("[codex_app_server] Failed to poll worker rollout:", error);
|
|
17910
|
+
state.providerTranscriptPollErrorLogged = true;
|
|
17911
|
+
}
|
|
17912
|
+
}
|
|
17913
|
+
};
|
|
17914
|
+
poll();
|
|
17915
|
+
const timer = setInterval(poll, CODEX_WORKER_TRANSCRIPT_POLL_MS);
|
|
17916
|
+
timer.unref?.();
|
|
17917
|
+
state.providerTranscriptPollTimer = timer;
|
|
17918
|
+
}
|
|
17919
|
+
function codexParentToolUseId(record, state) {
|
|
17920
|
+
const threadId = [record.agent_thread_id, record.sender_thread_id, record.thread_id].find(
|
|
17921
|
+
(value2) => typeof value2 === "string" && value2.length > 0
|
|
17922
|
+
);
|
|
17923
|
+
return threadId ? state.backgroundToolIdByTaskId?.get(threadId) ?? null : null;
|
|
17924
|
+
}
|
|
17765
17925
|
function armCodexExitGraceKill(state, graceMs = CODEX_EXIT_GRACE_MS) {
|
|
17766
17926
|
if (state.exitGraceKillTimer) return;
|
|
17767
17927
|
const child = state.process;
|
|
@@ -17891,6 +18051,9 @@ function handleCodexCollabToolCallItem(context, state, item, phase) {
|
|
|
17891
18051
|
const prompt = typeof item.prompt === "string" ? item.prompt : "";
|
|
17892
18052
|
const agentsStates = typeof item.agents_states === "object" && item.agents_states !== null ? item.agents_states : {};
|
|
17893
18053
|
const itemStatus = typeof item.status === "string" ? item.status : "";
|
|
18054
|
+
if (tool === "wait") {
|
|
18055
|
+
syncCodexWorkerEventsFromSessionLog(context, state);
|
|
18056
|
+
}
|
|
17894
18057
|
if (tool === "spawn_agent") {
|
|
17895
18058
|
if (trackCodexStreamedToolId(state, itemId)) {
|
|
17896
18059
|
const parentToolUseId = senderThreadId ? state.backgroundToolIdByTaskId?.get(senderThreadId) ?? null : null;
|
|
@@ -17910,6 +18073,8 @@ function handleCodexCollabToolCallItem(context, state, item, phase) {
|
|
|
17910
18073
|
for (const threadId of receiverThreadIds) {
|
|
17911
18074
|
if (state.backgroundToolIdByTaskId?.get(threadId)) continue;
|
|
17912
18075
|
registerBackgroundTaskRecord(state, { task_id: threadId, tool_use_id: itemId });
|
|
18076
|
+
if (!state.codexWorkerToolIdByThreadId) state.codexWorkerToolIdByThreadId = /* @__PURE__ */ new Map();
|
|
18077
|
+
state.codexWorkerToolIdByThreadId.set(threadId, itemId);
|
|
17913
18078
|
}
|
|
17914
18079
|
applyCodexCollabAgentStates(context, state, agentsStates);
|
|
17915
18080
|
if (phase === "completed" && itemStatus === "failed") {
|
|
@@ -17983,6 +18148,7 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
17983
18148
|
touchCodexBackgroundGrace(state);
|
|
17984
18149
|
if (typeof parsed.thread_id === "string") {
|
|
17985
18150
|
state.runtimeSessionId = parsed.thread_id;
|
|
18151
|
+
ensureCodexWorkerEventPolling(context, state);
|
|
17986
18152
|
}
|
|
17987
18153
|
const extractCodexErrorMessage = (value2) => {
|
|
17988
18154
|
if (typeof value2 !== "string") return "";
|
|
@@ -18015,6 +18181,7 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18015
18181
|
case "session_configured":
|
|
18016
18182
|
if (typeof parsed.session_id === "string") {
|
|
18017
18183
|
state.runtimeSessionId = parsed.session_id;
|
|
18184
|
+
ensureCodexWorkerEventPolling(context, state);
|
|
18018
18185
|
}
|
|
18019
18186
|
return true;
|
|
18020
18187
|
case "task_started":
|
|
@@ -18084,14 +18251,26 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18084
18251
|
if (!item || typeof item.type !== "string") return true;
|
|
18085
18252
|
switch (item.type) {
|
|
18086
18253
|
case "reasoning": {
|
|
18087
|
-
if (typeof item.text === "string")
|
|
18254
|
+
if (typeof item.text === "string") {
|
|
18255
|
+
const parentToolUseId = codexParentToolUseId(item, state);
|
|
18256
|
+
if (parentToolUseId) {
|
|
18257
|
+
void presenter.onThinking(item.text, parentToolUseId);
|
|
18258
|
+
} else {
|
|
18259
|
+
void presenter.onThinking(item.text);
|
|
18260
|
+
}
|
|
18261
|
+
}
|
|
18088
18262
|
return true;
|
|
18089
18263
|
}
|
|
18090
18264
|
case "agent_message": {
|
|
18091
18265
|
if (typeof item.text === "string") {
|
|
18092
|
-
|
|
18266
|
+
const parentToolUseId = codexParentToolUseId(item, state);
|
|
18267
|
+
if (!parentToolUseId) state.summary += `${item.text}
|
|
18093
18268
|
`;
|
|
18094
|
-
|
|
18269
|
+
if (parentToolUseId) {
|
|
18270
|
+
void presenter.onAssistantText(item.text, parentToolUseId);
|
|
18271
|
+
} else {
|
|
18272
|
+
void presenter.onAssistantText(item.text);
|
|
18273
|
+
}
|
|
18095
18274
|
}
|
|
18096
18275
|
return true;
|
|
18097
18276
|
}
|
|
@@ -18153,8 +18332,13 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18153
18332
|
case "agent_message_content_delta": {
|
|
18154
18333
|
const delta = typeof parsed.delta === "string" ? parsed.delta : "";
|
|
18155
18334
|
if (!delta) return true;
|
|
18156
|
-
|
|
18157
|
-
|
|
18335
|
+
const parentToolUseId = codexParentToolUseId(parsed, state);
|
|
18336
|
+
if (!parentToolUseId) state.summary += delta;
|
|
18337
|
+
if (parentToolUseId) {
|
|
18338
|
+
void presenter.onAssistantText(delta, parentToolUseId);
|
|
18339
|
+
} else {
|
|
18340
|
+
void presenter.onAssistantText(delta);
|
|
18341
|
+
}
|
|
18158
18342
|
return true;
|
|
18159
18343
|
}
|
|
18160
18344
|
case "agent_reasoning_delta":
|
|
@@ -18162,7 +18346,12 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18162
18346
|
case "agent_reasoning_raw_content_delta": {
|
|
18163
18347
|
const delta = typeof parsed.delta === "string" ? parsed.delta : "";
|
|
18164
18348
|
if (!delta) return true;
|
|
18165
|
-
|
|
18349
|
+
const parentToolUseId = codexParentToolUseId(parsed, state);
|
|
18350
|
+
if (parentToolUseId) {
|
|
18351
|
+
void presenter.onThinking(delta, parentToolUseId);
|
|
18352
|
+
} else {
|
|
18353
|
+
void presenter.onThinking(delta);
|
|
18354
|
+
}
|
|
18166
18355
|
return true;
|
|
18167
18356
|
}
|
|
18168
18357
|
case "exec_command_begin": {
|
|
@@ -18230,6 +18419,7 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18230
18419
|
return true;
|
|
18231
18420
|
}
|
|
18232
18421
|
case "turn.completed": {
|
|
18422
|
+
syncCodexWorkerEventsFromSessionLog(context, state);
|
|
18233
18423
|
const usage = typeof parsed.usage === "object" && parsed.usage !== null ? parsed.usage : {};
|
|
18234
18424
|
state.usage = {
|
|
18235
18425
|
model: typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel : "codex",
|
|
@@ -18281,6 +18471,8 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18281
18471
|
registerBackgroundLauncher(state, toolId);
|
|
18282
18472
|
if (agentThreadId) {
|
|
18283
18473
|
registerBackgroundTaskRecord(state, { task_id: agentThreadId, tool_use_id: toolId });
|
|
18474
|
+
if (!state.codexWorkerToolIdByThreadId) state.codexWorkerToolIdByThreadId = /* @__PURE__ */ new Map();
|
|
18475
|
+
state.codexWorkerToolIdByThreadId.set(agentThreadId, toolId);
|
|
18284
18476
|
}
|
|
18285
18477
|
if (!state.codexWorkerToolIdByPath) state.codexWorkerToolIdByPath = /* @__PURE__ */ new Map();
|
|
18286
18478
|
state.codexWorkerToolIdByPath.set(agentPath, toolId);
|
|
@@ -18601,12 +18793,16 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
|
|
|
18601
18793
|
}
|
|
18602
18794
|
};
|
|
18603
18795
|
}
|
|
18796
|
+
function asRecord2(value2) {
|
|
18797
|
+
return typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
18798
|
+
}
|
|
18604
18799
|
function extractCursorToolEntry(toolCall) {
|
|
18605
18800
|
const [rawName, rawPayload] = Object.entries(toolCall)[0] ?? [];
|
|
18606
18801
|
if (!rawName || typeof rawPayload !== "object" || rawPayload === null) return null;
|
|
18607
18802
|
return { rawName, payload: rawPayload };
|
|
18608
18803
|
}
|
|
18609
18804
|
function formatCursorToolName(rawName, payload) {
|
|
18805
|
+
if (rawName === "taskToolCall") return "Agent";
|
|
18610
18806
|
if (rawName === "terminalToolCall") return "Bash";
|
|
18611
18807
|
if (rawName === "mcpToolCall") {
|
|
18612
18808
|
const provider = typeof payload.providerIdentifier === "string" ? payload.providerIdentifier : typeof payload.serverName === "string" ? payload.serverName : typeof payload.mcpServer === "string" ? payload.mcpServer : "";
|
|
@@ -18618,6 +18814,59 @@ function formatCursorToolName(rawName, payload) {
|
|
|
18618
18814
|
if (!trimmed) return "Cursor Tool";
|
|
18619
18815
|
return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^[a-z]/, (char) => char.toUpperCase());
|
|
18620
18816
|
}
|
|
18817
|
+
function cursorTaskResultVariant(payload, variant) {
|
|
18818
|
+
const result = asRecord2(payload.result);
|
|
18819
|
+
if (!result) return null;
|
|
18820
|
+
const direct = asRecord2(result[variant]);
|
|
18821
|
+
if (direct) return direct;
|
|
18822
|
+
const oneof = asRecord2(result.result);
|
|
18823
|
+
return oneof?.case === variant ? asRecord2(oneof.value) : null;
|
|
18824
|
+
}
|
|
18825
|
+
function cursorSubagentType(value2) {
|
|
18826
|
+
const normalize = (candidate) => {
|
|
18827
|
+
const trimmed = candidate?.trim();
|
|
18828
|
+
if (!trimmed) return void 0;
|
|
18829
|
+
const normalized = trimmed.toLowerCase();
|
|
18830
|
+
if (normalized === "unspecified" || normalized.endsWith("_unspecified")) return void 0;
|
|
18831
|
+
return trimmed;
|
|
18832
|
+
};
|
|
18833
|
+
if (typeof value2 === "string") return normalize(value2);
|
|
18834
|
+
const record = asRecord2(value2);
|
|
18835
|
+
if (!record) return void 0;
|
|
18836
|
+
if (typeof record.case === "string" && record.case) return normalize(record.case);
|
|
18837
|
+
if (typeof record.type === "string" && record.type) return normalize(record.type);
|
|
18838
|
+
const nestedType = asRecord2(record.type);
|
|
18839
|
+
if (typeof nestedType?.case === "string" && nestedType.case) return normalize(nestedType.case);
|
|
18840
|
+
return normalize(
|
|
18841
|
+
Object.keys(nestedType ?? record).find((key) => key !== "value" && key !== "case")
|
|
18842
|
+
);
|
|
18843
|
+
}
|
|
18844
|
+
function cursorToolArgs(entry) {
|
|
18845
|
+
const args = asRecord2(entry.payload.args) ?? asRecord2(entry.payload.arguments) ?? entry.payload;
|
|
18846
|
+
if (entry.rawName !== "taskToolCall") return args;
|
|
18847
|
+
const subagentType = cursorSubagentType(args.subagentType ?? args.subagent_type);
|
|
18848
|
+
return {
|
|
18849
|
+
...typeof args.description === "string" ? { description: args.description } : {},
|
|
18850
|
+
...typeof args.prompt === "string" ? { prompt: args.prompt } : {},
|
|
18851
|
+
...subagentType ? { subagent_type: subagentType } : {},
|
|
18852
|
+
...typeof args.model === "string" ? { model: args.model } : {}
|
|
18853
|
+
};
|
|
18854
|
+
}
|
|
18855
|
+
function cursorConversationStepValue(step, key) {
|
|
18856
|
+
const direct = asRecord2(step[key]);
|
|
18857
|
+
if (direct) return direct;
|
|
18858
|
+
const message = asRecord2(step.message);
|
|
18859
|
+
return message?.case === key ? asRecord2(message.value) : null;
|
|
18860
|
+
}
|
|
18861
|
+
function cursorConversationStepText(steps) {
|
|
18862
|
+
if (!Array.isArray(steps)) return "";
|
|
18863
|
+
return steps.flatMap((step) => {
|
|
18864
|
+
const record = asRecord2(step);
|
|
18865
|
+
if (!record) return [];
|
|
18866
|
+
const assistant = cursorConversationStepValue(record, "assistantMessage");
|
|
18867
|
+
return typeof assistant?.text === "string" ? [assistant.text] : [];
|
|
18868
|
+
}).join("\n").trim();
|
|
18869
|
+
}
|
|
18621
18870
|
function buildCursorToolResultText(result) {
|
|
18622
18871
|
if (typeof result === "string") return result;
|
|
18623
18872
|
if (!result || typeof result !== "object") return JSON.stringify(result ?? {});
|
|
@@ -18639,6 +18888,202 @@ function buildCursorToolResultText(result) {
|
|
|
18639
18888
|
}
|
|
18640
18889
|
return JSON.stringify(result, null, 2);
|
|
18641
18890
|
}
|
|
18891
|
+
function emitCursorSubagentConversationSteps(steps, parentToolUseId, presenter) {
|
|
18892
|
+
if (!Array.isArray(steps)) return;
|
|
18893
|
+
steps.forEach((step, index) => {
|
|
18894
|
+
const record = asRecord2(step);
|
|
18895
|
+
if (!record) return;
|
|
18896
|
+
const assistant = cursorConversationStepValue(record, "assistantMessage");
|
|
18897
|
+
if (typeof assistant?.text === "string" && assistant.text) {
|
|
18898
|
+
void presenter.onAssistantText(assistant.text, parentToolUseId);
|
|
18899
|
+
return;
|
|
18900
|
+
}
|
|
18901
|
+
const thinking = cursorConversationStepValue(record, "thinkingMessage");
|
|
18902
|
+
if (typeof thinking?.text === "string" && thinking.text) {
|
|
18903
|
+
void presenter.onThinking(thinking.text, parentToolUseId);
|
|
18904
|
+
return;
|
|
18905
|
+
}
|
|
18906
|
+
const toolCall = cursorConversationStepValue(record, "toolCall");
|
|
18907
|
+
if (!toolCall) return;
|
|
18908
|
+
const entry = extractCursorToolEntry(toolCall);
|
|
18909
|
+
if (!entry) return;
|
|
18910
|
+
const args = cursorToolArgs(entry);
|
|
18911
|
+
const toolId = typeof args.toolCallId === "string" && args.toolCallId || typeof args.tool_call_id === "string" && args.tool_call_id || `${parentToolUseId}-step-${index}`;
|
|
18912
|
+
void presenter.onToolUse(
|
|
18913
|
+
formatCursorToolName(entry.rawName, entry.payload),
|
|
18914
|
+
args,
|
|
18915
|
+
toolId,
|
|
18916
|
+
parentToolUseId
|
|
18917
|
+
);
|
|
18918
|
+
if (entry.payload.result !== void 0) {
|
|
18919
|
+
const isError = cursorTaskResultVariant(entry.payload, "error") !== null;
|
|
18920
|
+
void presenter.onToolResult?.(
|
|
18921
|
+
toolId,
|
|
18922
|
+
buildCursorToolResultText(entry.payload.result),
|
|
18923
|
+
isError || void 0,
|
|
18924
|
+
parentToolUseId
|
|
18925
|
+
);
|
|
18926
|
+
}
|
|
18927
|
+
});
|
|
18928
|
+
}
|
|
18929
|
+
function emitCursorSubagentTranscript(transcriptPath, parentToolUseId, presenter, startLine = 0) {
|
|
18930
|
+
if (typeof transcriptPath !== "string" || !transcriptPath) {
|
|
18931
|
+
return { found: false, processedLineCount: startLine, emittedEventCount: 0 };
|
|
18932
|
+
}
|
|
18933
|
+
let lines;
|
|
18934
|
+
try {
|
|
18935
|
+
lines = (0, import_fs6.readFileSync)(transcriptPath, "utf8").split(/\r?\n/);
|
|
18936
|
+
if (lines.at(-1) === "") lines.pop();
|
|
18937
|
+
} catch {
|
|
18938
|
+
return { found: false, processedLineCount: startLine, emittedEventCount: 0 };
|
|
18939
|
+
}
|
|
18940
|
+
let processedLineCount = startLine > lines.length ? 0 : startLine;
|
|
18941
|
+
let emittedEventCount = 0;
|
|
18942
|
+
for (let lineIndex = processedLineCount; lineIndex < lines.length; lineIndex += 1) {
|
|
18943
|
+
const line = lines[lineIndex];
|
|
18944
|
+
if (!line) {
|
|
18945
|
+
processedLineCount = lineIndex + 1;
|
|
18946
|
+
continue;
|
|
18947
|
+
}
|
|
18948
|
+
let entry;
|
|
18949
|
+
try {
|
|
18950
|
+
entry = JSON.parse(line);
|
|
18951
|
+
} catch {
|
|
18952
|
+
break;
|
|
18953
|
+
}
|
|
18954
|
+
processedLineCount = lineIndex + 1;
|
|
18955
|
+
if (entry.role !== "assistant") continue;
|
|
18956
|
+
const message = asRecord2(entry.message);
|
|
18957
|
+
const content = Array.isArray(message?.content) ? message.content : [];
|
|
18958
|
+
content.forEach((rawBlock, blockIndex) => {
|
|
18959
|
+
const block = asRecord2(rawBlock);
|
|
18960
|
+
if (!block) return;
|
|
18961
|
+
const type = typeof block.type === "string" ? block.type : "";
|
|
18962
|
+
const text = typeof block.text === "string" ? block.text : "";
|
|
18963
|
+
if (type === "text" && text) {
|
|
18964
|
+
emittedEventCount += 1;
|
|
18965
|
+
void presenter.onAssistantText(text, parentToolUseId);
|
|
18966
|
+
return;
|
|
18967
|
+
}
|
|
18968
|
+
if ((type === "thinking" || type === "reasoning") && text) {
|
|
18969
|
+
emittedEventCount += 1;
|
|
18970
|
+
void presenter.onThinking(text, parentToolUseId);
|
|
18971
|
+
return;
|
|
18972
|
+
}
|
|
18973
|
+
if (type !== "tool_use") return;
|
|
18974
|
+
const name = typeof block.name === "string" && block.name ? block.name : "Cursor Tool";
|
|
18975
|
+
const toolId = typeof block.id === "string" && block.id || `${parentToolUseId}-transcript-${lineIndex}-${blockIndex}`;
|
|
18976
|
+
emittedEventCount += 1;
|
|
18977
|
+
void presenter.onToolUse(name, asRecord2(block.input) ?? {}, toolId, parentToolUseId);
|
|
18978
|
+
});
|
|
18979
|
+
}
|
|
18980
|
+
return { found: true, processedLineCount, emittedEventCount };
|
|
18981
|
+
}
|
|
18982
|
+
function cursorTranscriptsRoot(context) {
|
|
18983
|
+
const projectKey = context.cwd.replace(/^[/\\]+/, "").replace(/[/\\]+/g, "-");
|
|
18984
|
+
const home = context.env.HOME || process.env.HOME || (0, import_os6.homedir)();
|
|
18985
|
+
return (0, import_path6.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
|
|
18986
|
+
}
|
|
18987
|
+
function cursorTranscriptPathForAgent(context, agentId) {
|
|
18988
|
+
return (0, import_path6.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
|
|
18989
|
+
}
|
|
18990
|
+
function resolveCursorSubagentTranscriptPath(success, context) {
|
|
18991
|
+
const explicit = success?.transcriptPath ?? success?.transcript_path;
|
|
18992
|
+
if (typeof explicit === "string" && explicit) return explicit;
|
|
18993
|
+
const agentId = typeof success?.agentId === "string" ? success.agentId : "";
|
|
18994
|
+
return agentId ? cursorTranscriptPathForAgent(context, agentId) : void 0;
|
|
18995
|
+
}
|
|
18996
|
+
function cursorTranscriptUserText(transcriptPath) {
|
|
18997
|
+
try {
|
|
18998
|
+
for (const line of (0, import_fs6.readFileSync)(transcriptPath, "utf8").split(/\r?\n/)) {
|
|
18999
|
+
if (!line) continue;
|
|
19000
|
+
const entry = asRecord2(JSON.parse(line));
|
|
19001
|
+
if (entry?.role !== "user") continue;
|
|
19002
|
+
const message = asRecord2(entry.message);
|
|
19003
|
+
const content = Array.isArray(message?.content) ? message.content : [];
|
|
19004
|
+
return content.flatMap((block) => {
|
|
19005
|
+
const record = asRecord2(block);
|
|
19006
|
+
return typeof record?.text === "string" ? [record.text] : [];
|
|
19007
|
+
}).join("");
|
|
19008
|
+
}
|
|
19009
|
+
} catch {
|
|
19010
|
+
}
|
|
19011
|
+
return "";
|
|
19012
|
+
}
|
|
19013
|
+
function discoverCursorSubagentTranscript(context, state, task) {
|
|
19014
|
+
const root = cursorTranscriptsRoot(context);
|
|
19015
|
+
if (!(0, import_fs6.existsSync)(root)) return void 0;
|
|
19016
|
+
const prompt = task.prompt?.trim();
|
|
19017
|
+
const description = task.description?.trim().toLowerCase();
|
|
19018
|
+
const candidates = [];
|
|
19019
|
+
let entries;
|
|
19020
|
+
try {
|
|
19021
|
+
entries = (0, import_fs6.readdirSync)(root, { withFileTypes: true });
|
|
19022
|
+
} catch {
|
|
19023
|
+
return void 0;
|
|
19024
|
+
}
|
|
19025
|
+
for (const entry of entries) {
|
|
19026
|
+
if (!entry.isDirectory() || entry.name === state.runtimeSessionId) continue;
|
|
19027
|
+
const path = cursorTranscriptPathForAgent(context, entry.name);
|
|
19028
|
+
let mtimeMs;
|
|
19029
|
+
try {
|
|
19030
|
+
mtimeMs = (0, import_fs6.statSync)(path).mtimeMs;
|
|
19031
|
+
} catch {
|
|
19032
|
+
continue;
|
|
19033
|
+
}
|
|
19034
|
+
if (mtimeMs < task.startedAtMs - 2e3) continue;
|
|
19035
|
+
const userText = cursorTranscriptUserText(path).trim();
|
|
19036
|
+
if (!userText) continue;
|
|
19037
|
+
let score = 0;
|
|
19038
|
+
if (prompt && userText === prompt) score = 3;
|
|
19039
|
+
else if (prompt && (userText.includes(prompt) || prompt.includes(userText))) score = 2;
|
|
19040
|
+
else if (description && userText.toLowerCase().includes(description)) score = 1;
|
|
19041
|
+
if (score > 0) candidates.push({ path, score, mtimeMs });
|
|
19042
|
+
}
|
|
19043
|
+
candidates.sort((a, b) => b.score - a.score || b.mtimeMs - a.mtimeMs);
|
|
19044
|
+
return candidates[0]?.path;
|
|
19045
|
+
}
|
|
19046
|
+
function syncCursorSubagentEventsFromTranscripts(context, state) {
|
|
19047
|
+
let emittedEventCount = 0;
|
|
19048
|
+
for (const [launcherId, task] of state.cursorSubagentTranscripts ?? []) {
|
|
19049
|
+
task.transcriptPath ??= discoverCursorSubagentTranscript(context, state, task);
|
|
19050
|
+
if (!task.transcriptPath) continue;
|
|
19051
|
+
const replay = emitCursorSubagentTranscript(
|
|
19052
|
+
task.transcriptPath,
|
|
19053
|
+
launcherId,
|
|
19054
|
+
context.presenter,
|
|
19055
|
+
task.replayedLineCount
|
|
19056
|
+
);
|
|
19057
|
+
task.replayedLineCount = replay.processedLineCount;
|
|
19058
|
+
task.emittedEventCount += replay.emittedEventCount;
|
|
19059
|
+
emittedEventCount += replay.emittedEventCount;
|
|
19060
|
+
}
|
|
19061
|
+
if (emittedEventCount > 0) state.onNewOutput?.();
|
|
19062
|
+
return emittedEventCount;
|
|
19063
|
+
}
|
|
19064
|
+
function ensureCursorSubagentTranscriptPolling(context, state) {
|
|
19065
|
+
if (state.providerTranscriptPollTimer) return;
|
|
19066
|
+
const poll = () => {
|
|
19067
|
+
try {
|
|
19068
|
+
syncCursorSubagentEventsFromTranscripts(context, state);
|
|
19069
|
+
state.providerTranscriptPollErrorLogged = false;
|
|
19070
|
+
} catch (error) {
|
|
19071
|
+
if (!state.providerTranscriptPollErrorLogged) {
|
|
19072
|
+
console.warn("[cursor_agent_cli] Failed to poll child transcript:", error);
|
|
19073
|
+
state.providerTranscriptPollErrorLogged = true;
|
|
19074
|
+
}
|
|
19075
|
+
}
|
|
19076
|
+
};
|
|
19077
|
+
poll();
|
|
19078
|
+
const timer = setInterval(poll, 750);
|
|
19079
|
+
timer.unref?.();
|
|
19080
|
+
state.providerTranscriptPollTimer = timer;
|
|
19081
|
+
}
|
|
19082
|
+
function stopCursorSubagentTranscriptPollingIfIdle(state) {
|
|
19083
|
+
if (state.cursorSubagentTranscripts?.size) return;
|
|
19084
|
+
if (state.providerTranscriptPollTimer) clearInterval(state.providerTranscriptPollTimer);
|
|
19085
|
+
state.providerTranscriptPollTimer = void 0;
|
|
19086
|
+
}
|
|
18642
19087
|
function handleCursorStructuredEvent(parsed, context, state) {
|
|
18643
19088
|
const presenter = context.presenter;
|
|
18644
19089
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
@@ -18646,8 +19091,22 @@ function handleCursorStructuredEvent(parsed, context, state) {
|
|
|
18646
19091
|
if (typeof parsed.session_id === "string") state.runtimeSessionId = parsed.session_id;
|
|
18647
19092
|
if (typeof parsed.model === "string") state.activeModel = parsed.model;
|
|
18648
19093
|
switch (type) {
|
|
18649
|
-
case "system":
|
|
19094
|
+
case "system": {
|
|
19095
|
+
if (parsed.subtype !== "task_notification") return true;
|
|
19096
|
+
const status = typeof parsed.status === "string" ? parsed.status.toLowerCase() : "completed";
|
|
19097
|
+
const isError = ["error", "failed", "aborted", "cancelled", "interrupted"].includes(status);
|
|
19098
|
+
const resultText = typeof parsed.detail === "string" && parsed.detail || typeof parsed.title === "string" && parsed.title || `Background subagent ${status}`;
|
|
19099
|
+
const toolUseId = resolveBackgroundTaskToolUseId(state, parsed);
|
|
19100
|
+
clearBackgroundTaskIds(state, backgroundTaskKeys(parsed));
|
|
19101
|
+
const launcherId = toolUseId ?? drainNextUnlinkedBackgroundLauncher(state);
|
|
19102
|
+
if (launcherId) {
|
|
19103
|
+
syncCursorSubagentEventsFromTranscripts(context, state);
|
|
19104
|
+
state.cursorSubagentTranscripts?.delete(launcherId);
|
|
19105
|
+
stopCursorSubagentTranscriptPollingIfIdle(state);
|
|
19106
|
+
void presenter.onToolResult?.(launcherId, resultText, isError || void 0);
|
|
19107
|
+
}
|
|
18650
19108
|
return true;
|
|
19109
|
+
}
|
|
18651
19110
|
case "thinking":
|
|
18652
19111
|
case "reasoning": {
|
|
18653
19112
|
const subtype = typeof parsed.subtype === "string" ? parsed.subtype : "";
|
|
@@ -18696,14 +19155,72 @@ function handleCursorStructuredEvent(parsed, context, state) {
|
|
|
18696
19155
|
if (!toolId) return true;
|
|
18697
19156
|
state.iterations = Math.max(state.iterations, 1);
|
|
18698
19157
|
const toolName = formatCursorToolName(entry.rawName, entry.payload);
|
|
18699
|
-
const toolArgs =
|
|
19158
|
+
const toolArgs = cursorToolArgs(entry);
|
|
18700
19159
|
if (subtype === "started") {
|
|
18701
19160
|
void presenter.onToolUse(toolName, toolArgs, toolId);
|
|
19161
|
+
if (entry.rawName === "taskToolCall") {
|
|
19162
|
+
if (!state.cursorSubagentTranscripts) state.cursorSubagentTranscripts = /* @__PURE__ */ new Map();
|
|
19163
|
+
state.cursorSubagentTranscripts.set(toolId, {
|
|
19164
|
+
description: typeof toolArgs.description === "string" ? toolArgs.description : void 0,
|
|
19165
|
+
prompt: typeof toolArgs.prompt === "string" ? toolArgs.prompt : void 0,
|
|
19166
|
+
startedAtMs: typeof parsed.timestamp_ms === "number" ? parsed.timestamp_ms : typeof entry.payload.startedAtMs === "number" ? entry.payload.startedAtMs : Number(entry.payload.startedAtMs) || Date.now(),
|
|
19167
|
+
replayedLineCount: 0,
|
|
19168
|
+
emittedEventCount: 0
|
|
19169
|
+
});
|
|
19170
|
+
ensureCursorSubagentTranscriptPolling(context, state);
|
|
19171
|
+
}
|
|
18702
19172
|
return true;
|
|
18703
19173
|
}
|
|
18704
19174
|
if (subtype === "completed") {
|
|
18705
19175
|
if (!hasCallId) state.lastAnonymousCursorToolId = void 0;
|
|
18706
|
-
|
|
19176
|
+
if (entry.rawName === "taskToolCall") {
|
|
19177
|
+
const resultEnvelope = typeof parsed.result === "object" && parsed.result !== null ? parsed : entry.payload;
|
|
19178
|
+
const success = cursorTaskResultVariant(resultEnvelope, "success");
|
|
19179
|
+
const failure = cursorTaskResultVariant(resultEnvelope, "error");
|
|
19180
|
+
const task = state.cursorSubagentTranscripts?.get(toolId);
|
|
19181
|
+
if (task) {
|
|
19182
|
+
task.transcriptPath = resolveCursorSubagentTranscriptPath(success, context) ?? task.transcriptPath;
|
|
19183
|
+
}
|
|
19184
|
+
let replayedTranscript = false;
|
|
19185
|
+
if (task) {
|
|
19186
|
+
syncCursorSubagentEventsFromTranscripts(context, state);
|
|
19187
|
+
replayedTranscript = task.emittedEventCount > 0;
|
|
19188
|
+
} else {
|
|
19189
|
+
replayedTranscript = emitCursorSubagentTranscript(
|
|
19190
|
+
resolveCursorSubagentTranscriptPath(success, context),
|
|
19191
|
+
toolId,
|
|
19192
|
+
presenter
|
|
19193
|
+
).emittedEventCount > 0;
|
|
19194
|
+
}
|
|
19195
|
+
if (!replayedTranscript) {
|
|
19196
|
+
emitCursorSubagentConversationSteps(success?.conversationSteps, toolId, presenter);
|
|
19197
|
+
}
|
|
19198
|
+
if (success?.isBackground === true) {
|
|
19199
|
+
registerBackgroundLauncher(state, toolId);
|
|
19200
|
+
const taskId = typeof success.agentId === "string" && success.agentId ? success.agentId : void 0;
|
|
19201
|
+
if (taskId) {
|
|
19202
|
+
registerBackgroundTaskRecord(state, {
|
|
19203
|
+
task_id: taskId,
|
|
19204
|
+
tool_use_id: toolId
|
|
19205
|
+
});
|
|
19206
|
+
}
|
|
19207
|
+
return true;
|
|
19208
|
+
}
|
|
19209
|
+
state.cursorSubagentTranscripts?.delete(toolId);
|
|
19210
|
+
stopCursorSubagentTranscriptPollingIfIdle(state);
|
|
19211
|
+
const summary = cursorConversationStepText(success?.conversationSteps);
|
|
19212
|
+
const failureText = typeof failure?.error === "string" && failure.error ? failure.error : "Cursor subagent failed";
|
|
19213
|
+
void presenter.onToolResult?.(
|
|
19214
|
+
toolId,
|
|
19215
|
+
failure ? failureText : summary || buildCursorToolResultText(resultEnvelope.result),
|
|
19216
|
+
failure ? true : void 0
|
|
19217
|
+
);
|
|
19218
|
+
return true;
|
|
19219
|
+
}
|
|
19220
|
+
void presenter.onToolResult?.(
|
|
19221
|
+
toolId,
|
|
19222
|
+
buildCursorToolResultText(parsed.result ?? entry.payload.result)
|
|
19223
|
+
);
|
|
18707
19224
|
}
|
|
18708
19225
|
return true;
|
|
18709
19226
|
}
|
|
@@ -19061,7 +19578,7 @@ function createDroidCliBackend(command = "droid", defaultArgs = []) {
|
|
|
19061
19578
|
};
|
|
19062
19579
|
}
|
|
19063
19580
|
var ACP_PROTOCOL_VERSION = 1;
|
|
19064
|
-
function
|
|
19581
|
+
function asRecord3(value2) {
|
|
19065
19582
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
19066
19583
|
}
|
|
19067
19584
|
function asString(value2) {
|
|
@@ -19071,7 +19588,7 @@ function resumeSessionId(context) {
|
|
|
19071
19588
|
return context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim() || "";
|
|
19072
19589
|
}
|
|
19073
19590
|
function chunkText(content) {
|
|
19074
|
-
const record =
|
|
19591
|
+
const record = asRecord3(content);
|
|
19075
19592
|
if (!record) return "";
|
|
19076
19593
|
if (typeof record.text === "string") return record.text;
|
|
19077
19594
|
return chunkText(record.content);
|
|
@@ -19087,23 +19604,23 @@ function toolResultText(update) {
|
|
|
19087
19604
|
return "";
|
|
19088
19605
|
}
|
|
19089
19606
|
function toolMetaName(update) {
|
|
19090
|
-
const meta =
|
|
19091
|
-
const tool =
|
|
19607
|
+
const meta = asRecord3(update._meta);
|
|
19608
|
+
const tool = asRecord3(meta?.["x.ai/tool"]);
|
|
19092
19609
|
return asString(tool?.name);
|
|
19093
19610
|
}
|
|
19094
19611
|
function resolvePermission(params, context) {
|
|
19095
|
-
const record =
|
|
19612
|
+
const record = asRecord3(params);
|
|
19096
19613
|
const options = Array.isArray(record?.options) ? record?.options : [];
|
|
19097
|
-
const toolCall =
|
|
19098
|
-
const meta =
|
|
19099
|
-
const tool =
|
|
19614
|
+
const toolCall = asRecord3(record?.toolCall);
|
|
19615
|
+
const meta = asRecord3(toolCall?._meta);
|
|
19616
|
+
const tool = asRecord3(meta?.["x.ai/tool"]);
|
|
19100
19617
|
const isReadOnlyTool = tool?.read_only === true || asString(tool?.kind) === "read";
|
|
19101
19618
|
const allow = !shouldUseReadOnlyRuntimePermissions(context.config) || isReadOnlyTool;
|
|
19102
19619
|
const allowKinds = ["allow_always", "allow_once", "allow"];
|
|
19103
19620
|
const rejectKinds = ["reject_always", "reject_once", "reject", "deny"];
|
|
19104
19621
|
const wanted = allow ? allowKinds : rejectKinds;
|
|
19105
|
-
const chosen = options.find((option) => wanted.includes(asString(
|
|
19106
|
-
const optionId = asString(
|
|
19622
|
+
const chosen = options.find((option) => wanted.includes(asString(asRecord3(option)?.kind))) ?? (allow ? options[0] : options[options.length - 1]);
|
|
19623
|
+
const optionId = asString(asRecord3(chosen)?.optionId);
|
|
19107
19624
|
if (!optionId) return { outcome: { outcome: "cancelled" } };
|
|
19108
19625
|
return { outcome: { outcome: "selected", optionId } };
|
|
19109
19626
|
}
|
|
@@ -19179,9 +19696,9 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19179
19696
|
finalize(state);
|
|
19180
19697
|
return;
|
|
19181
19698
|
}
|
|
19182
|
-
const result =
|
|
19699
|
+
const result = asRecord3(message.result);
|
|
19183
19700
|
if (message.id === initId) {
|
|
19184
|
-
const modelState =
|
|
19701
|
+
const modelState = asRecord3(asRecord3(result?._meta)?.modelState);
|
|
19185
19702
|
const model = asString(modelState?.currentModelId);
|
|
19186
19703
|
if (model) state.activeModel = model;
|
|
19187
19704
|
beginSession(context, state);
|
|
@@ -19195,7 +19712,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19195
19712
|
return;
|
|
19196
19713
|
}
|
|
19197
19714
|
if (message.id === promptId) {
|
|
19198
|
-
const meta =
|
|
19715
|
+
const meta = asRecord3(result?._meta);
|
|
19199
19716
|
const model = asString(meta?.modelId) || state.activeModel || (typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel.trim() : "grok");
|
|
19200
19717
|
const inputTokens = typeof meta?.inputTokens === "number" ? meta.inputTokens : 0;
|
|
19201
19718
|
const outputTokens = typeof meta?.outputTokens === "number" ? meta.outputTokens : 0;
|
|
@@ -19240,8 +19757,8 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19240
19757
|
}
|
|
19241
19758
|
}
|
|
19242
19759
|
function handleNotification(message, context, state) {
|
|
19243
|
-
const params =
|
|
19244
|
-
const update =
|
|
19760
|
+
const params = asRecord3(message.params);
|
|
19761
|
+
const update = asRecord3(params?.update);
|
|
19245
19762
|
if (!update || !isPromptActive) return;
|
|
19246
19763
|
const presenter = context.presenter;
|
|
19247
19764
|
switch (asString(update.sessionUpdate)) {
|
|
@@ -19288,7 +19805,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19288
19805
|
if (line.trim().length > 0) void context.presenter.onLog(`[grok_cli] ${line}`);
|
|
19289
19806
|
return;
|
|
19290
19807
|
}
|
|
19291
|
-
const message =
|
|
19808
|
+
const message = asRecord3(parsed);
|
|
19292
19809
|
if (!message) return;
|
|
19293
19810
|
if (message.id !== void 0 && message.method === void 0) {
|
|
19294
19811
|
handleResponse(message, context, state);
|
|
@@ -19355,9 +19872,9 @@ function buildGrokAgentArgs(config, defaultArgs = []) {
|
|
|
19355
19872
|
return args;
|
|
19356
19873
|
}
|
|
19357
19874
|
var DEFAULT_SKILL_ROOTS = [
|
|
19358
|
-
(0,
|
|
19359
|
-
(0,
|
|
19360
|
-
(0,
|
|
19875
|
+
(0, import_path7.join)((0, import_os7.homedir)(), ".agents", "skills"),
|
|
19876
|
+
(0, import_path7.join)((0, import_os7.homedir)(), ".claude", "skills"),
|
|
19877
|
+
(0, import_path7.join)((0, import_os7.homedir)(), ".config", "opencode", "skills")
|
|
19361
19878
|
];
|
|
19362
19879
|
function parseFrontmatter(content) {
|
|
19363
19880
|
if (!content.startsWith("---\n")) return {};
|
|
@@ -19373,12 +19890,12 @@ function parseFrontmatter(content) {
|
|
|
19373
19890
|
return result;
|
|
19374
19891
|
}
|
|
19375
19892
|
function listSkillFiles(root) {
|
|
19376
|
-
if (!(0,
|
|
19893
|
+
if (!(0, import_fs7.existsSync)(root)) return [];
|
|
19377
19894
|
const files = [];
|
|
19378
|
-
for (const entry of (0,
|
|
19895
|
+
for (const entry of (0, import_fs7.readdirSync)(root, { withFileTypes: true })) {
|
|
19379
19896
|
if (!entry.isDirectory()) continue;
|
|
19380
|
-
const skillPath = (0,
|
|
19381
|
-
if ((0,
|
|
19897
|
+
const skillPath = (0, import_path7.join)(root, entry.name, "SKILL.md");
|
|
19898
|
+
if ((0, import_fs7.existsSync)(skillPath)) files.push(skillPath);
|
|
19382
19899
|
}
|
|
19383
19900
|
return files;
|
|
19384
19901
|
}
|
|
@@ -19387,7 +19904,7 @@ function loadInstalledSkills(roots = DEFAULT_SKILL_ROOTS) {
|
|
|
19387
19904
|
for (const root of roots) {
|
|
19388
19905
|
for (const skillPath of listSkillFiles(root)) {
|
|
19389
19906
|
try {
|
|
19390
|
-
const frontmatter = parseFrontmatter((0,
|
|
19907
|
+
const frontmatter = parseFrontmatter((0, import_fs7.readFileSync)(skillPath, "utf8"));
|
|
19391
19908
|
const name = frontmatter.name;
|
|
19392
19909
|
const description = frontmatter.description;
|
|
19393
19910
|
if (!name || !description || skills.has(name)) continue;
|
|
@@ -20356,40 +20873,40 @@ function parseSkillInvocation(text) {
|
|
|
20356
20873
|
function candidateRoots(cwd) {
|
|
20357
20874
|
const roots = [];
|
|
20358
20875
|
if (cwd) {
|
|
20359
|
-
roots.push((0,
|
|
20360
|
-
roots.push((0,
|
|
20361
|
-
roots.push((0,
|
|
20362
|
-
if ((0,
|
|
20876
|
+
roots.push((0, import_path8.join)(cwd, ".agents", "skills"));
|
|
20877
|
+
roots.push((0, import_path8.join)(cwd, ".claude", "skills"));
|
|
20878
|
+
roots.push((0, import_path8.join)(cwd, ".codex", "skills"));
|
|
20879
|
+
if ((0, import_fs8.existsSync)(cwd)) {
|
|
20363
20880
|
let entries = [];
|
|
20364
20881
|
try {
|
|
20365
|
-
entries = (0,
|
|
20882
|
+
entries = (0, import_fs8.readdirSync)(cwd, { withFileTypes: true });
|
|
20366
20883
|
} catch {
|
|
20367
20884
|
}
|
|
20368
20885
|
for (const entry of entries) {
|
|
20369
20886
|
if (!entry.isDirectory()) continue;
|
|
20370
20887
|
if (entry.name.startsWith(".")) continue;
|
|
20371
|
-
const child = (0,
|
|
20372
|
-
roots.push((0,
|
|
20373
|
-
roots.push((0,
|
|
20374
|
-
roots.push((0,
|
|
20888
|
+
const child = (0, import_path8.join)(cwd, entry.name);
|
|
20889
|
+
roots.push((0, import_path8.join)(child, ".agents", "skills"));
|
|
20890
|
+
roots.push((0, import_path8.join)(child, ".claude", "skills"));
|
|
20891
|
+
roots.push((0, import_path8.join)(child, ".codex", "skills"));
|
|
20375
20892
|
}
|
|
20376
20893
|
}
|
|
20377
20894
|
}
|
|
20378
|
-
const home = (0,
|
|
20379
|
-
roots.push((0,
|
|
20380
|
-
roots.push((0,
|
|
20381
|
-
roots.push((0,
|
|
20895
|
+
const home = (0, import_os8.homedir)();
|
|
20896
|
+
roots.push((0, import_path8.join)(home, ".agents", "skills"));
|
|
20897
|
+
roots.push((0, import_path8.join)(home, ".claude", "skills"));
|
|
20898
|
+
roots.push((0, import_path8.join)(home, ".codex", "skills"));
|
|
20382
20899
|
return Array.from(new Set(roots));
|
|
20383
20900
|
}
|
|
20384
20901
|
function resolveSkillInvocation(text, cwd) {
|
|
20385
20902
|
const parsed = parseSkillInvocation(text);
|
|
20386
20903
|
if (!parsed) return null;
|
|
20387
20904
|
for (const root of candidateRoots(cwd)) {
|
|
20388
|
-
const skillPath = (0,
|
|
20389
|
-
if (!(0,
|
|
20905
|
+
const skillPath = (0, import_path8.join)(root, parsed.command, "SKILL.md");
|
|
20906
|
+
if (!(0, import_fs8.existsSync)(skillPath)) continue;
|
|
20390
20907
|
let content;
|
|
20391
20908
|
try {
|
|
20392
|
-
content = (0,
|
|
20909
|
+
content = (0, import_fs8.readFileSync)(skillPath, "utf-8");
|
|
20393
20910
|
} catch {
|
|
20394
20911
|
continue;
|
|
20395
20912
|
}
|
|
@@ -20986,14 +21503,14 @@ function normalizePath(candidate, cwd) {
|
|
|
20986
21503
|
} catch {
|
|
20987
21504
|
}
|
|
20988
21505
|
if (path.startsWith("~/")) return null;
|
|
20989
|
-
if ((0,
|
|
20990
|
-
return cwd ? (0,
|
|
21506
|
+
if ((0, import_path9.isAbsolute)(path)) return path;
|
|
21507
|
+
return cwd ? (0, import_path9.join)(cwd, path) : null;
|
|
20991
21508
|
}
|
|
20992
21509
|
function resolveToolCwd(cwd, toolInput) {
|
|
20993
21510
|
if (!isRecord(toolInput)) return cwd;
|
|
20994
21511
|
const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
|
|
20995
21512
|
if (!raw) return cwd;
|
|
20996
|
-
return (0,
|
|
21513
|
+
return (0, import_path9.isAbsolute)(raw) || !cwd ? raw : (0, import_path9.join)(cwd, raw);
|
|
20997
21514
|
}
|
|
20998
21515
|
function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
|
|
20999
21516
|
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
|
|
@@ -21036,19 +21553,19 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
|
|
|
21036
21553
|
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
21037
21554
|
for (const candidate of extractPathCandidates(content, options)) {
|
|
21038
21555
|
const path = normalizePath(candidate, effectiveCwd);
|
|
21039
|
-
if (!path || seen.has(path) || !(0,
|
|
21556
|
+
if (!path || seen.has(path) || !(0, import_fs9.existsSync)(path)) continue;
|
|
21040
21557
|
seen.add(path);
|
|
21041
|
-
const ext = (0,
|
|
21558
|
+
const ext = (0, import_path9.extname)(path).toLowerCase();
|
|
21042
21559
|
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
21043
21560
|
if (!mimeType) continue;
|
|
21044
|
-
const stat = (0,
|
|
21561
|
+
const stat = (0, import_fs9.statSync)(path);
|
|
21045
21562
|
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
21046
|
-
const buffer = (0,
|
|
21563
|
+
const buffer = (0, import_fs9.readFileSync)(path);
|
|
21047
21564
|
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
21048
21565
|
images.push({
|
|
21049
21566
|
type: "generated_image",
|
|
21050
21567
|
id: (0, import_crypto3.randomUUID)(),
|
|
21051
|
-
filename: (0,
|
|
21568
|
+
filename: (0, import_path9.basename)(path),
|
|
21052
21569
|
mimeType,
|
|
21053
21570
|
size: buffer.length,
|
|
21054
21571
|
width,
|
|
@@ -21075,20 +21592,20 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
|
|
|
21075
21592
|
const mimeByExt = kind === "video" ? VIDEO_MIME_BY_EXT : IMAGE_MIME_BY_EXT;
|
|
21076
21593
|
for (const candidate of extractPathCandidates(content, options, extensionsPattern)) {
|
|
21077
21594
|
const path = normalizePath(candidate, effectiveCwd);
|
|
21078
|
-
if (!path || seen.has(path) || !(0,
|
|
21595
|
+
if (!path || seen.has(path) || !(0, import_fs9.existsSync)(path)) continue;
|
|
21079
21596
|
seen.add(path);
|
|
21080
|
-
const ext = (0,
|
|
21597
|
+
const ext = (0, import_path9.extname)(path).toLowerCase();
|
|
21081
21598
|
const mimeType = mimeByExt[ext];
|
|
21082
21599
|
if (!mimeType) continue;
|
|
21083
|
-
const stat = (0,
|
|
21600
|
+
const stat = (0, import_fs9.statSync)(path);
|
|
21084
21601
|
if (!stat.isFile() || stat.size <= 0 || stat.size > maxBytes) continue;
|
|
21085
|
-
const buffer = (0,
|
|
21602
|
+
const buffer = (0, import_fs9.readFileSync)(path);
|
|
21086
21603
|
const dimensions = kind === "image" ? readImageDimensions2(buffer, mimeType) : null;
|
|
21087
21604
|
media.push({
|
|
21088
21605
|
type: "session_media",
|
|
21089
21606
|
kind,
|
|
21090
21607
|
id: (0, import_crypto3.randomUUID)(),
|
|
21091
|
-
filename: (0,
|
|
21608
|
+
filename: (0, import_path9.basename)(path),
|
|
21092
21609
|
mimeType,
|
|
21093
21610
|
size: buffer.length,
|
|
21094
21611
|
width: dimensions?.width,
|
|
@@ -23667,7 +24184,7 @@ var RunStartGate = class {
|
|
|
23667
24184
|
};
|
|
23668
24185
|
|
|
23669
24186
|
// src/version.ts
|
|
23670
|
-
var AGENT_VERSION = "0.1.
|
|
24187
|
+
var AGENT_VERSION = "0.1.46";
|
|
23671
24188
|
|
|
23672
24189
|
// src/workspace-relocation.ts
|
|
23673
24190
|
var import_node_child_process3 = require("child_process");
|
|
@@ -25380,11 +25897,21 @@ var RuntimePresenter = class {
|
|
|
25380
25897
|
onNotice(kind, message) {
|
|
25381
25898
|
this.emitEvent({ type: "session_notice", kind, message, ts: Date.now() });
|
|
25382
25899
|
}
|
|
25383
|
-
onAssistantText(text) {
|
|
25384
|
-
this.emitEvent({
|
|
25900
|
+
onAssistantText(text, parentToolUseId) {
|
|
25901
|
+
this.emitEvent({
|
|
25902
|
+
type: "text",
|
|
25903
|
+
text,
|
|
25904
|
+
ts: Date.now(),
|
|
25905
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
25906
|
+
});
|
|
25385
25907
|
}
|
|
25386
|
-
onThinking(text) {
|
|
25387
|
-
this.emitEvent({
|
|
25908
|
+
onThinking(text, parentToolUseId) {
|
|
25909
|
+
this.emitEvent({
|
|
25910
|
+
type: "thinking",
|
|
25911
|
+
text,
|
|
25912
|
+
ts: Date.now(),
|
|
25913
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
25914
|
+
});
|
|
25388
25915
|
}
|
|
25389
25916
|
onToolUse(tool, input, toolId, parentToolUseId) {
|
|
25390
25917
|
if (this.verifyWorkspaceLease && !this.verifyWorkspaceLease()) return;
|
|
@@ -27488,11 +28015,21 @@ var WebPresenter = class {
|
|
|
27488
28015
|
onNotice(kind, message) {
|
|
27489
28016
|
this.wsClient.emitEvent({ type: "session_notice", kind, message, ts: Date.now() });
|
|
27490
28017
|
}
|
|
27491
|
-
onAssistantText(text) {
|
|
27492
|
-
this.wsClient.emitEvent({
|
|
28018
|
+
onAssistantText(text, parentToolUseId) {
|
|
28019
|
+
this.wsClient.emitEvent({
|
|
28020
|
+
type: "text",
|
|
28021
|
+
text,
|
|
28022
|
+
ts: Date.now(),
|
|
28023
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
28024
|
+
});
|
|
27493
28025
|
}
|
|
27494
|
-
onThinking(text) {
|
|
27495
|
-
this.wsClient.emitEvent({
|
|
28026
|
+
onThinking(text, parentToolUseId) {
|
|
28027
|
+
this.wsClient.emitEvent({
|
|
28028
|
+
type: "thinking",
|
|
28029
|
+
text,
|
|
28030
|
+
ts: Date.now(),
|
|
28031
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
28032
|
+
});
|
|
27496
28033
|
}
|
|
27497
28034
|
hasKnownToolUse(toolId) {
|
|
27498
28035
|
return this.toolNamesById.has(toolId);
|