@aiden-ade/sandbox-agent 0.1.44 → 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 +811 -285
- package/package.json +3 -3
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,48 +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
|
|
14483
|
-
|
|
14484
|
-
Do not present yourself as a runtime model, CLI, or backend vendor as your primary identity \u2014 those are runtime details. Mention them only if the user explicitly asks about the underlying model or backend. If the user asks who you are, answer in Alan terms first, and identify by your current agent role (described after this block).
|
|
14485
|
-
|
|
14486
|
-
## Voice
|
|
14487
|
-
|
|
14488
|
-
Direct. Structured. Concise. No hype, no "Great question!", no tool-brand roleplay. Speak like a teammate, not a data dump. Precise and decisive when working a task; listen, think, then act.
|
|
14358
|
+
var ALAN_IDENTITY_PROMPT = `You are Alan, the software factory agent. Alan ships software end to end: plan, write, review, test, deploy.
|
|
14489
14359
|
|
|
14490
14360
|
## How Alan is structured
|
|
14491
14361
|
|
|
14492
|
-
|
|
14493
|
-
|
|
14494
|
-
|
|
14495
|
-
|
|
14496
|
-
\u2502 \u251C\u2500\u2500 Conversations \u2192 Messages
|
|
14497
|
-
\u2502 \u2514\u2500\u2500 Artifacts (plans, test reports, document artifacts)
|
|
14498
|
-
\u251C\u2500\u2500 Documents (standalone pages \u2014 PRDs, specs, wikis)
|
|
14499
|
-
\u2502 \u2514\u2500\u2500 Artifacts
|
|
14500
|
-
\u2514\u2500\u2500 Whiteboard (beta)
|
|
14501
|
-
\`\`\`
|
|
14502
|
-
|
|
14503
|
-
- **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.
|
|
14504
|
-
- **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.
|
|
14505
|
-
|
|
14506
|
-
## Structure over chat
|
|
14507
|
-
|
|
14508
|
-
Deliverables persist as Alan artifacts and documents \u2014 not as chat. Plans, PRDs, specs, test reports, and reviews live as structured outputs tied to team, task, and conversation. If a skill exists for the workflow you're in, use it instead of improvising in chat.
|
|
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.
|
|
14509
14366
|
|
|
14510
14367
|
## Universal teammate principles
|
|
14511
14368
|
|
|
14512
14369
|
- Listen first. Don't jump to solutions. One question at a time, not a list.
|
|
14513
|
-
- Scan available context
|
|
14514
|
-
- Challenge
|
|
14515
|
-
- Human leads
|
|
14516
|
-
- Own mistakes. Wrong ID, jumped too fast \u2014 say so and fix it.
|
|
14517
|
-
- 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.
|
|
14518
14373
|
|
|
14519
14374
|
## Task Logging
|
|
14520
14375
|
|
|
14521
|
-
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.
|
|
14522
14377
|
|
|
14523
|
-
The
|
|
14378
|
+
The selected agent profile below defines the role-specific behavior.`;
|
|
14524
14379
|
function buildAlanTeamScopePrompt(teamId) {
|
|
14525
14380
|
return [
|
|
14526
14381
|
`You are operating within team \`${teamId}\`.`,
|
|
@@ -14545,7 +14400,6 @@ Examples: "where is X configured", "which file handles Y", "how does Z work", "f
|
|
|
14545
14400
|
- Do NOT start with \`grep\`, \`rg\`, \`find\`, or broad Bash filesystem search for codebase discovery or implementation-answer questions when \`search_code_context\` is available.
|
|
14546
14401
|
- Do NOT repeat or rephrase index searches after the first result identifies useful paths. Continue locally instead.
|
|
14547
14402
|
- Do NOT claim current behavior from an index excerpt without reading the cited local file.
|
|
14548
|
-
- Do NOT use graphify or local graph tools for the initial semantic "where is this implemented" pass.
|
|
14549
14403
|
|
|
14550
14404
|
### Local follow-ups
|
|
14551
14405
|
- Import/caller structure: use local \`code_graph_query\` or narrow symbol search after reading the cited files.
|
|
@@ -14561,15 +14415,7 @@ var PLAN_MODE_PROMPT = [
|
|
|
14561
14415
|
"Do not make code changes or execute write operations in plan mode.",
|
|
14562
14416
|
"Write the plan in natural markdown. Use whatever structure best communicates the work clearly.",
|
|
14563
14417
|
"Include dependencies, ordering, risks, key files/functions, and decision points where relevant.",
|
|
14564
|
-
"When
|
|
14565
|
-
"Pass title, content, summary, taskId, and conversationId. Include teamId too when available.",
|
|
14566
|
-
"If create_plan fails, retry it. Do not finish plan mode until the plan is persisted successfully.",
|
|
14567
|
-
"After create_plan succeeds, present the plan title and artifact link to the user for approval."
|
|
14568
|
-
].join("\n");
|
|
14569
|
-
var TEST_MODE_PROMPT = [
|
|
14570
|
-
"You are in test mode. Verify the implemented feature carefully.",
|
|
14571
|
-
"Prefer browser-based validation when available.",
|
|
14572
|
-
"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."
|
|
14573
14419
|
].join("\n");
|
|
14574
14420
|
var ASK_MODE_PROMPT = "You are in ask mode. Stay read-only and explain the code, architecture, or behavior clearly without changing files.";
|
|
14575
14421
|
var REVIEW_MODE_PROMPT = "You are in review mode. Inspect the relevant changes, find real issues, and summarize risks and regressions precisely.";
|
|
@@ -14577,8 +14423,6 @@ function getAlanModePrompt(mode) {
|
|
|
14577
14423
|
switch (mode) {
|
|
14578
14424
|
case "plan":
|
|
14579
14425
|
return PLAN_MODE_PROMPT;
|
|
14580
|
-
case "test":
|
|
14581
|
-
return TEST_MODE_PROMPT;
|
|
14582
14426
|
case "ask":
|
|
14583
14427
|
return ASK_MODE_PROMPT;
|
|
14584
14428
|
case "review":
|
|
@@ -15153,10 +14997,10 @@ var CLAUDE_CLI_PICKER_FALLBACK_MODELS = [
|
|
|
15153
14997
|
slugModel("claude_cli", "claude-opus-4-8", "Opus 4.8", ["200k", "1m"])
|
|
15154
14998
|
];
|
|
15155
14999
|
var CODEX_APP_SERVER_PICKER_FALLBACK_MODELS = [
|
|
15156
|
-
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"),
|
|
15157
15003
|
slugModel("codex_app_server", "gpt-5.5", "GPT-5.5", ["1m"]),
|
|
15158
|
-
slugModel("codex_app_server", "gpt-5.4-mini", "GPT-5.4 Mini"),
|
|
15159
|
-
slugModel("codex_app_server", "gpt-5.3-codex", "GPT-5.3 Codex"),
|
|
15160
15004
|
slugModel("codex_app_server", "gpt-5.3-codex-spark", "GPT-5.3 Codex Spark")
|
|
15161
15005
|
];
|
|
15162
15006
|
var ANTIGRAVITY_CLI_PICKER_FALLBACK_MODELS = [
|
|
@@ -15296,14 +15140,17 @@ var import_path5 = require("path");
|
|
|
15296
15140
|
var import_fs6 = require("fs");
|
|
15297
15141
|
var import_os6 = require("os");
|
|
15298
15142
|
var import_path6 = require("path");
|
|
15299
|
-
var import_readline2 = require("readline");
|
|
15300
|
-
var import_url2 = require("url");
|
|
15301
15143
|
var import_fs7 = require("fs");
|
|
15302
15144
|
var import_os7 = require("os");
|
|
15303
15145
|
var import_path7 = require("path");
|
|
15304
|
-
var
|
|
15146
|
+
var import_readline2 = require("readline");
|
|
15147
|
+
var import_url2 = require("url");
|
|
15305
15148
|
var import_fs8 = require("fs");
|
|
15149
|
+
var import_os8 = require("os");
|
|
15306
15150
|
var import_path8 = require("path");
|
|
15151
|
+
var import_crypto3 = require("crypto");
|
|
15152
|
+
var import_fs9 = require("fs");
|
|
15153
|
+
var import_path9 = require("path");
|
|
15307
15154
|
var MANAGED_ALAN_MCP_SERVER_NAMES = [
|
|
15308
15155
|
"alan",
|
|
15309
15156
|
"alan-prod",
|
|
@@ -15335,7 +15182,7 @@ function writeFileSafe(path, content) {
|
|
|
15335
15182
|
(0, import_fs2.rmSync)(pendingPath, { force: true });
|
|
15336
15183
|
}
|
|
15337
15184
|
}
|
|
15338
|
-
function acquireConfigLock(path) {
|
|
15185
|
+
async function acquireConfigLock(path) {
|
|
15339
15186
|
(0, import_fs2.mkdirSync)((0, import_path2.dirname)(path), { recursive: true });
|
|
15340
15187
|
const lockPath = `${path}.alan-lock`;
|
|
15341
15188
|
const startedAt = Date.now();
|
|
@@ -15357,7 +15204,7 @@ function acquireConfigLock(path) {
|
|
|
15357
15204
|
if (Date.now() - startedAt >= 2e3) {
|
|
15358
15205
|
throw new Error(`Alan could not safely update ${path}`);
|
|
15359
15206
|
}
|
|
15360
|
-
|
|
15207
|
+
await new Promise((resolve22) => setTimeout(resolve22, 20));
|
|
15361
15208
|
}
|
|
15362
15209
|
}
|
|
15363
15210
|
}
|
|
@@ -15621,13 +15468,13 @@ function buildJsonTargets(home) {
|
|
|
15621
15468
|
}
|
|
15622
15469
|
];
|
|
15623
15470
|
}
|
|
15624
|
-
function syncAlanMcpSessionHeaders(input) {
|
|
15471
|
+
async function syncAlanMcpSessionHeaders(input) {
|
|
15625
15472
|
const home = input.homeDir ?? (0, import_os2.homedir)();
|
|
15626
15473
|
const sessionHeaders = buildSessionHeaders(input);
|
|
15627
15474
|
const written = [];
|
|
15628
15475
|
for (const target of buildCodexTomlTargets(home)) {
|
|
15629
15476
|
if (!(0, import_fs2.existsSync)(target.guardDir)) continue;
|
|
15630
|
-
const releaseLock = acquireConfigLock(target.configPath);
|
|
15477
|
+
const releaseLock = await acquireConfigLock(target.configPath);
|
|
15631
15478
|
try {
|
|
15632
15479
|
if (patchCodexTomlMcpTarget(target, sessionHeaders)) {
|
|
15633
15480
|
written.push(target.cli);
|
|
@@ -15639,7 +15486,7 @@ function syncAlanMcpSessionHeaders(input) {
|
|
|
15639
15486
|
}
|
|
15640
15487
|
for (const target of buildJsonTargets(home)) {
|
|
15641
15488
|
if (!(0, import_fs2.existsSync)(target.guardDir)) continue;
|
|
15642
|
-
const releaseLock = acquireConfigLock(target.configPath);
|
|
15489
|
+
const releaseLock = await acquireConfigLock(target.configPath);
|
|
15643
15490
|
try {
|
|
15644
15491
|
if (patchJsonMcpTarget(target, sessionHeaders)) {
|
|
15645
15492
|
written.push(target.cli);
|
|
@@ -16365,6 +16212,10 @@ function createGenericCliBackend(options) {
|
|
|
16365
16212
|
}
|
|
16366
16213
|
} finally {
|
|
16367
16214
|
if (startupTimer) clearTimeout(startupTimer);
|
|
16215
|
+
if (state.providerTranscriptPollTimer) {
|
|
16216
|
+
clearInterval(state.providerTranscriptPollTimer);
|
|
16217
|
+
state.providerTranscriptPollTimer = void 0;
|
|
16218
|
+
}
|
|
16368
16219
|
stdoutRl.close();
|
|
16369
16220
|
stderrRl.close();
|
|
16370
16221
|
logUnhandledStructuredEventSummary(options.kind, state);
|
|
@@ -17310,16 +17161,26 @@ function handleClaudeStructuredEvent(parsed, context, state) {
|
|
|
17310
17161
|
if (typeof block !== "object" || block === null || !("type" in block)) continue;
|
|
17311
17162
|
if (block.type === "text" && typeof block.text === "string") {
|
|
17312
17163
|
const text = block.text;
|
|
17313
|
-
state.summary += `${text}
|
|
17164
|
+
if (!parentToolUseId) state.summary += `${text}
|
|
17314
17165
|
`;
|
|
17315
|
-
|
|
17316
|
-
${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
|
+
}
|
|
17317
17173
|
previousBlockWasText = true;
|
|
17318
17174
|
continue;
|
|
17319
17175
|
}
|
|
17320
17176
|
if (block.type === "thinking" && typeof block.thinking === "string") {
|
|
17321
17177
|
previousBlockWasText = false;
|
|
17322
|
-
|
|
17178
|
+
const thinking = block.thinking;
|
|
17179
|
+
if (parentToolUseId) {
|
|
17180
|
+
void presenter.onThinking(thinking, parentToolUseId);
|
|
17181
|
+
} else {
|
|
17182
|
+
void presenter.onThinking(thinking);
|
|
17183
|
+
}
|
|
17323
17184
|
continue;
|
|
17324
17185
|
}
|
|
17325
17186
|
if (block.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string") {
|
|
@@ -17697,7 +17558,7 @@ function isSyntheticUserRolloutMessage(payload) {
|
|
|
17697
17558
|
const text = extractRolloutMessageText(payload).trimStart();
|
|
17698
17559
|
if (!text) return false;
|
|
17699
17560
|
const lower = text.toLowerCase();
|
|
17700
|
-
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.
|
|
17701
17562
|
lower.startsWith("<compact") || lower.startsWith("[compact");
|
|
17702
17563
|
}
|
|
17703
17564
|
function latestUserMessageLineIndex(lines) {
|
|
@@ -17713,6 +17574,253 @@ function latestUserMessageLineIndex(lines) {
|
|
|
17713
17574
|
}
|
|
17714
17575
|
return latestIndex;
|
|
17715
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
|
+
}
|
|
17716
17824
|
async function replayCodexMcpToolEventsFromSessionLog(context, state) {
|
|
17717
17825
|
const runtimeSessionId = state.runtimeSessionId;
|
|
17718
17826
|
if (!runtimeSessionId) return;
|
|
@@ -17769,10 +17877,51 @@ async function replayCodexMcpToolEventsFromSessionLog(context, state) {
|
|
|
17769
17877
|
}
|
|
17770
17878
|
}
|
|
17771
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
|
+
}
|
|
17772
17887
|
}
|
|
17773
17888
|
var CODEX_EXIT_GRACE_MS = 3e4;
|
|
17774
17889
|
var CODEX_BACKGROUND_EXIT_GRACE_MS = 10 * 6e4;
|
|
17775
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
|
+
}
|
|
17776
17925
|
function armCodexExitGraceKill(state, graceMs = CODEX_EXIT_GRACE_MS) {
|
|
17777
17926
|
if (state.exitGraceKillTimer) return;
|
|
17778
17927
|
const child = state.process;
|
|
@@ -17902,6 +18051,9 @@ function handleCodexCollabToolCallItem(context, state, item, phase) {
|
|
|
17902
18051
|
const prompt = typeof item.prompt === "string" ? item.prompt : "";
|
|
17903
18052
|
const agentsStates = typeof item.agents_states === "object" && item.agents_states !== null ? item.agents_states : {};
|
|
17904
18053
|
const itemStatus = typeof item.status === "string" ? item.status : "";
|
|
18054
|
+
if (tool === "wait") {
|
|
18055
|
+
syncCodexWorkerEventsFromSessionLog(context, state);
|
|
18056
|
+
}
|
|
17905
18057
|
if (tool === "spawn_agent") {
|
|
17906
18058
|
if (trackCodexStreamedToolId(state, itemId)) {
|
|
17907
18059
|
const parentToolUseId = senderThreadId ? state.backgroundToolIdByTaskId?.get(senderThreadId) ?? null : null;
|
|
@@ -17921,6 +18073,8 @@ function handleCodexCollabToolCallItem(context, state, item, phase) {
|
|
|
17921
18073
|
for (const threadId of receiverThreadIds) {
|
|
17922
18074
|
if (state.backgroundToolIdByTaskId?.get(threadId)) continue;
|
|
17923
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);
|
|
17924
18078
|
}
|
|
17925
18079
|
applyCodexCollabAgentStates(context, state, agentsStates);
|
|
17926
18080
|
if (phase === "completed" && itemStatus === "failed") {
|
|
@@ -17994,6 +18148,7 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
17994
18148
|
touchCodexBackgroundGrace(state);
|
|
17995
18149
|
if (typeof parsed.thread_id === "string") {
|
|
17996
18150
|
state.runtimeSessionId = parsed.thread_id;
|
|
18151
|
+
ensureCodexWorkerEventPolling(context, state);
|
|
17997
18152
|
}
|
|
17998
18153
|
const extractCodexErrorMessage = (value2) => {
|
|
17999
18154
|
if (typeof value2 !== "string") return "";
|
|
@@ -18026,6 +18181,7 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18026
18181
|
case "session_configured":
|
|
18027
18182
|
if (typeof parsed.session_id === "string") {
|
|
18028
18183
|
state.runtimeSessionId = parsed.session_id;
|
|
18184
|
+
ensureCodexWorkerEventPolling(context, state);
|
|
18029
18185
|
}
|
|
18030
18186
|
return true;
|
|
18031
18187
|
case "task_started":
|
|
@@ -18095,14 +18251,26 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18095
18251
|
if (!item || typeof item.type !== "string") return true;
|
|
18096
18252
|
switch (item.type) {
|
|
18097
18253
|
case "reasoning": {
|
|
18098
|
-
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
|
+
}
|
|
18099
18262
|
return true;
|
|
18100
18263
|
}
|
|
18101
18264
|
case "agent_message": {
|
|
18102
18265
|
if (typeof item.text === "string") {
|
|
18103
|
-
|
|
18266
|
+
const parentToolUseId = codexParentToolUseId(item, state);
|
|
18267
|
+
if (!parentToolUseId) state.summary += `${item.text}
|
|
18104
18268
|
`;
|
|
18105
|
-
|
|
18269
|
+
if (parentToolUseId) {
|
|
18270
|
+
void presenter.onAssistantText(item.text, parentToolUseId);
|
|
18271
|
+
} else {
|
|
18272
|
+
void presenter.onAssistantText(item.text);
|
|
18273
|
+
}
|
|
18106
18274
|
}
|
|
18107
18275
|
return true;
|
|
18108
18276
|
}
|
|
@@ -18164,8 +18332,13 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18164
18332
|
case "agent_message_content_delta": {
|
|
18165
18333
|
const delta = typeof parsed.delta === "string" ? parsed.delta : "";
|
|
18166
18334
|
if (!delta) return true;
|
|
18167
|
-
|
|
18168
|
-
|
|
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
|
+
}
|
|
18169
18342
|
return true;
|
|
18170
18343
|
}
|
|
18171
18344
|
case "agent_reasoning_delta":
|
|
@@ -18173,7 +18346,12 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18173
18346
|
case "agent_reasoning_raw_content_delta": {
|
|
18174
18347
|
const delta = typeof parsed.delta === "string" ? parsed.delta : "";
|
|
18175
18348
|
if (!delta) return true;
|
|
18176
|
-
|
|
18349
|
+
const parentToolUseId = codexParentToolUseId(parsed, state);
|
|
18350
|
+
if (parentToolUseId) {
|
|
18351
|
+
void presenter.onThinking(delta, parentToolUseId);
|
|
18352
|
+
} else {
|
|
18353
|
+
void presenter.onThinking(delta);
|
|
18354
|
+
}
|
|
18177
18355
|
return true;
|
|
18178
18356
|
}
|
|
18179
18357
|
case "exec_command_begin": {
|
|
@@ -18241,6 +18419,7 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18241
18419
|
return true;
|
|
18242
18420
|
}
|
|
18243
18421
|
case "turn.completed": {
|
|
18422
|
+
syncCodexWorkerEventsFromSessionLog(context, state);
|
|
18244
18423
|
const usage = typeof parsed.usage === "object" && parsed.usage !== null ? parsed.usage : {};
|
|
18245
18424
|
state.usage = {
|
|
18246
18425
|
model: typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel : "codex",
|
|
@@ -18292,6 +18471,8 @@ function handleCodexStructuredEvent(parsed, context, state) {
|
|
|
18292
18471
|
registerBackgroundLauncher(state, toolId);
|
|
18293
18472
|
if (agentThreadId) {
|
|
18294
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);
|
|
18295
18476
|
}
|
|
18296
18477
|
if (!state.codexWorkerToolIdByPath) state.codexWorkerToolIdByPath = /* @__PURE__ */ new Map();
|
|
18297
18478
|
state.codexWorkerToolIdByPath.set(agentPath, toolId);
|
|
@@ -18612,12 +18793,16 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
|
|
|
18612
18793
|
}
|
|
18613
18794
|
};
|
|
18614
18795
|
}
|
|
18796
|
+
function asRecord2(value2) {
|
|
18797
|
+
return typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
18798
|
+
}
|
|
18615
18799
|
function extractCursorToolEntry(toolCall) {
|
|
18616
18800
|
const [rawName, rawPayload] = Object.entries(toolCall)[0] ?? [];
|
|
18617
18801
|
if (!rawName || typeof rawPayload !== "object" || rawPayload === null) return null;
|
|
18618
18802
|
return { rawName, payload: rawPayload };
|
|
18619
18803
|
}
|
|
18620
18804
|
function formatCursorToolName(rawName, payload) {
|
|
18805
|
+
if (rawName === "taskToolCall") return "Agent";
|
|
18621
18806
|
if (rawName === "terminalToolCall") return "Bash";
|
|
18622
18807
|
if (rawName === "mcpToolCall") {
|
|
18623
18808
|
const provider = typeof payload.providerIdentifier === "string" ? payload.providerIdentifier : typeof payload.serverName === "string" ? payload.serverName : typeof payload.mcpServer === "string" ? payload.mcpServer : "";
|
|
@@ -18629,6 +18814,59 @@ function formatCursorToolName(rawName, payload) {
|
|
|
18629
18814
|
if (!trimmed) return "Cursor Tool";
|
|
18630
18815
|
return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^[a-z]/, (char) => char.toUpperCase());
|
|
18631
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
|
+
}
|
|
18632
18870
|
function buildCursorToolResultText(result) {
|
|
18633
18871
|
if (typeof result === "string") return result;
|
|
18634
18872
|
if (!result || typeof result !== "object") return JSON.stringify(result ?? {});
|
|
@@ -18650,6 +18888,202 @@ function buildCursorToolResultText(result) {
|
|
|
18650
18888
|
}
|
|
18651
18889
|
return JSON.stringify(result, null, 2);
|
|
18652
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
|
+
}
|
|
18653
19087
|
function handleCursorStructuredEvent(parsed, context, state) {
|
|
18654
19088
|
const presenter = context.presenter;
|
|
18655
19089
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
@@ -18657,8 +19091,22 @@ function handleCursorStructuredEvent(parsed, context, state) {
|
|
|
18657
19091
|
if (typeof parsed.session_id === "string") state.runtimeSessionId = parsed.session_id;
|
|
18658
19092
|
if (typeof parsed.model === "string") state.activeModel = parsed.model;
|
|
18659
19093
|
switch (type) {
|
|
18660
|
-
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
|
+
}
|
|
18661
19108
|
return true;
|
|
19109
|
+
}
|
|
18662
19110
|
case "thinking":
|
|
18663
19111
|
case "reasoning": {
|
|
18664
19112
|
const subtype = typeof parsed.subtype === "string" ? parsed.subtype : "";
|
|
@@ -18707,14 +19155,72 @@ function handleCursorStructuredEvent(parsed, context, state) {
|
|
|
18707
19155
|
if (!toolId) return true;
|
|
18708
19156
|
state.iterations = Math.max(state.iterations, 1);
|
|
18709
19157
|
const toolName = formatCursorToolName(entry.rawName, entry.payload);
|
|
18710
|
-
const toolArgs =
|
|
19158
|
+
const toolArgs = cursorToolArgs(entry);
|
|
18711
19159
|
if (subtype === "started") {
|
|
18712
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
|
+
}
|
|
18713
19172
|
return true;
|
|
18714
19173
|
}
|
|
18715
19174
|
if (subtype === "completed") {
|
|
18716
19175
|
if (!hasCallId) state.lastAnonymousCursorToolId = void 0;
|
|
18717
|
-
|
|
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
|
+
);
|
|
18718
19224
|
}
|
|
18719
19225
|
return true;
|
|
18720
19226
|
}
|
|
@@ -19072,7 +19578,7 @@ function createDroidCliBackend(command = "droid", defaultArgs = []) {
|
|
|
19072
19578
|
};
|
|
19073
19579
|
}
|
|
19074
19580
|
var ACP_PROTOCOL_VERSION = 1;
|
|
19075
|
-
function
|
|
19581
|
+
function asRecord3(value2) {
|
|
19076
19582
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
19077
19583
|
}
|
|
19078
19584
|
function asString(value2) {
|
|
@@ -19082,7 +19588,7 @@ function resumeSessionId(context) {
|
|
|
19082
19588
|
return context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim() || "";
|
|
19083
19589
|
}
|
|
19084
19590
|
function chunkText(content) {
|
|
19085
|
-
const record =
|
|
19591
|
+
const record = asRecord3(content);
|
|
19086
19592
|
if (!record) return "";
|
|
19087
19593
|
if (typeof record.text === "string") return record.text;
|
|
19088
19594
|
return chunkText(record.content);
|
|
@@ -19098,23 +19604,23 @@ function toolResultText(update) {
|
|
|
19098
19604
|
return "";
|
|
19099
19605
|
}
|
|
19100
19606
|
function toolMetaName(update) {
|
|
19101
|
-
const meta =
|
|
19102
|
-
const tool =
|
|
19607
|
+
const meta = asRecord3(update._meta);
|
|
19608
|
+
const tool = asRecord3(meta?.["x.ai/tool"]);
|
|
19103
19609
|
return asString(tool?.name);
|
|
19104
19610
|
}
|
|
19105
19611
|
function resolvePermission(params, context) {
|
|
19106
|
-
const record =
|
|
19612
|
+
const record = asRecord3(params);
|
|
19107
19613
|
const options = Array.isArray(record?.options) ? record?.options : [];
|
|
19108
|
-
const toolCall =
|
|
19109
|
-
const meta =
|
|
19110
|
-
const tool =
|
|
19614
|
+
const toolCall = asRecord3(record?.toolCall);
|
|
19615
|
+
const meta = asRecord3(toolCall?._meta);
|
|
19616
|
+
const tool = asRecord3(meta?.["x.ai/tool"]);
|
|
19111
19617
|
const isReadOnlyTool = tool?.read_only === true || asString(tool?.kind) === "read";
|
|
19112
19618
|
const allow = !shouldUseReadOnlyRuntimePermissions(context.config) || isReadOnlyTool;
|
|
19113
19619
|
const allowKinds = ["allow_always", "allow_once", "allow"];
|
|
19114
19620
|
const rejectKinds = ["reject_always", "reject_once", "reject", "deny"];
|
|
19115
19621
|
const wanted = allow ? allowKinds : rejectKinds;
|
|
19116
|
-
const chosen = options.find((option) => wanted.includes(asString(
|
|
19117
|
-
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);
|
|
19118
19624
|
if (!optionId) return { outcome: { outcome: "cancelled" } };
|
|
19119
19625
|
return { outcome: { outcome: "selected", optionId } };
|
|
19120
19626
|
}
|
|
@@ -19190,9 +19696,9 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19190
19696
|
finalize(state);
|
|
19191
19697
|
return;
|
|
19192
19698
|
}
|
|
19193
|
-
const result =
|
|
19699
|
+
const result = asRecord3(message.result);
|
|
19194
19700
|
if (message.id === initId) {
|
|
19195
|
-
const modelState =
|
|
19701
|
+
const modelState = asRecord3(asRecord3(result?._meta)?.modelState);
|
|
19196
19702
|
const model = asString(modelState?.currentModelId);
|
|
19197
19703
|
if (model) state.activeModel = model;
|
|
19198
19704
|
beginSession(context, state);
|
|
@@ -19206,7 +19712,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19206
19712
|
return;
|
|
19207
19713
|
}
|
|
19208
19714
|
if (message.id === promptId) {
|
|
19209
|
-
const meta =
|
|
19715
|
+
const meta = asRecord3(result?._meta);
|
|
19210
19716
|
const model = asString(meta?.modelId) || state.activeModel || (typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel.trim() : "grok");
|
|
19211
19717
|
const inputTokens = typeof meta?.inputTokens === "number" ? meta.inputTokens : 0;
|
|
19212
19718
|
const outputTokens = typeof meta?.outputTokens === "number" ? meta.outputTokens : 0;
|
|
@@ -19251,8 +19757,8 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19251
19757
|
}
|
|
19252
19758
|
}
|
|
19253
19759
|
function handleNotification(message, context, state) {
|
|
19254
|
-
const params =
|
|
19255
|
-
const update =
|
|
19760
|
+
const params = asRecord3(message.params);
|
|
19761
|
+
const update = asRecord3(params?.update);
|
|
19256
19762
|
if (!update || !isPromptActive) return;
|
|
19257
19763
|
const presenter = context.presenter;
|
|
19258
19764
|
switch (asString(update.sessionUpdate)) {
|
|
@@ -19299,7 +19805,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
19299
19805
|
if (line.trim().length > 0) void context.presenter.onLog(`[grok_cli] ${line}`);
|
|
19300
19806
|
return;
|
|
19301
19807
|
}
|
|
19302
|
-
const message =
|
|
19808
|
+
const message = asRecord3(parsed);
|
|
19303
19809
|
if (!message) return;
|
|
19304
19810
|
if (message.id !== void 0 && message.method === void 0) {
|
|
19305
19811
|
handleResponse(message, context, state);
|
|
@@ -19366,9 +19872,9 @@ function buildGrokAgentArgs(config, defaultArgs = []) {
|
|
|
19366
19872
|
return args;
|
|
19367
19873
|
}
|
|
19368
19874
|
var DEFAULT_SKILL_ROOTS = [
|
|
19369
|
-
(0,
|
|
19370
|
-
(0,
|
|
19371
|
-
(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")
|
|
19372
19878
|
];
|
|
19373
19879
|
function parseFrontmatter(content) {
|
|
19374
19880
|
if (!content.startsWith("---\n")) return {};
|
|
@@ -19384,12 +19890,12 @@ function parseFrontmatter(content) {
|
|
|
19384
19890
|
return result;
|
|
19385
19891
|
}
|
|
19386
19892
|
function listSkillFiles(root) {
|
|
19387
|
-
if (!(0,
|
|
19893
|
+
if (!(0, import_fs7.existsSync)(root)) return [];
|
|
19388
19894
|
const files = [];
|
|
19389
|
-
for (const entry of (0,
|
|
19895
|
+
for (const entry of (0, import_fs7.readdirSync)(root, { withFileTypes: true })) {
|
|
19390
19896
|
if (!entry.isDirectory()) continue;
|
|
19391
|
-
const skillPath = (0,
|
|
19392
|
-
if ((0,
|
|
19897
|
+
const skillPath = (0, import_path7.join)(root, entry.name, "SKILL.md");
|
|
19898
|
+
if ((0, import_fs7.existsSync)(skillPath)) files.push(skillPath);
|
|
19393
19899
|
}
|
|
19394
19900
|
return files;
|
|
19395
19901
|
}
|
|
@@ -19398,7 +19904,7 @@ function loadInstalledSkills(roots = DEFAULT_SKILL_ROOTS) {
|
|
|
19398
19904
|
for (const root of roots) {
|
|
19399
19905
|
for (const skillPath of listSkillFiles(root)) {
|
|
19400
19906
|
try {
|
|
19401
|
-
const frontmatter = parseFrontmatter((0,
|
|
19907
|
+
const frontmatter = parseFrontmatter((0, import_fs7.readFileSync)(skillPath, "utf8"));
|
|
19402
19908
|
const name = frontmatter.name;
|
|
19403
19909
|
const description = frontmatter.description;
|
|
19404
19910
|
if (!name || !description || skills.has(name)) continue;
|
|
@@ -20367,40 +20873,40 @@ function parseSkillInvocation(text) {
|
|
|
20367
20873
|
function candidateRoots(cwd) {
|
|
20368
20874
|
const roots = [];
|
|
20369
20875
|
if (cwd) {
|
|
20370
|
-
roots.push((0,
|
|
20371
|
-
roots.push((0,
|
|
20372
|
-
roots.push((0,
|
|
20373
|
-
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)) {
|
|
20374
20880
|
let entries = [];
|
|
20375
20881
|
try {
|
|
20376
|
-
entries = (0,
|
|
20882
|
+
entries = (0, import_fs8.readdirSync)(cwd, { withFileTypes: true });
|
|
20377
20883
|
} catch {
|
|
20378
20884
|
}
|
|
20379
20885
|
for (const entry of entries) {
|
|
20380
20886
|
if (!entry.isDirectory()) continue;
|
|
20381
20887
|
if (entry.name.startsWith(".")) continue;
|
|
20382
|
-
const child = (0,
|
|
20383
|
-
roots.push((0,
|
|
20384
|
-
roots.push((0,
|
|
20385
|
-
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"));
|
|
20386
20892
|
}
|
|
20387
20893
|
}
|
|
20388
20894
|
}
|
|
20389
|
-
const home = (0,
|
|
20390
|
-
roots.push((0,
|
|
20391
|
-
roots.push((0,
|
|
20392
|
-
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"));
|
|
20393
20899
|
return Array.from(new Set(roots));
|
|
20394
20900
|
}
|
|
20395
20901
|
function resolveSkillInvocation(text, cwd) {
|
|
20396
20902
|
const parsed = parseSkillInvocation(text);
|
|
20397
20903
|
if (!parsed) return null;
|
|
20398
20904
|
for (const root of candidateRoots(cwd)) {
|
|
20399
|
-
const skillPath = (0,
|
|
20400
|
-
if (!(0,
|
|
20905
|
+
const skillPath = (0, import_path8.join)(root, parsed.command, "SKILL.md");
|
|
20906
|
+
if (!(0, import_fs8.existsSync)(skillPath)) continue;
|
|
20401
20907
|
let content;
|
|
20402
20908
|
try {
|
|
20403
|
-
content = (0,
|
|
20909
|
+
content = (0, import_fs8.readFileSync)(skillPath, "utf-8");
|
|
20404
20910
|
} catch {
|
|
20405
20911
|
continue;
|
|
20406
20912
|
}
|
|
@@ -20603,7 +21109,7 @@ var BaseMachineAgent = class _BaseMachineAgent {
|
|
|
20603
21109
|
};
|
|
20604
21110
|
const releaseGate = await acquireMcpConfigWriteGate();
|
|
20605
21111
|
try {
|
|
20606
|
-
const writtenClis = syncAlanMcpSessionHeaders({
|
|
21112
|
+
const writtenClis = await syncAlanMcpSessionHeaders({
|
|
20607
21113
|
conversationId,
|
|
20608
21114
|
teamId: config.teamId,
|
|
20609
21115
|
runHeaders: config.alanMcp?.headers,
|
|
@@ -20997,14 +21503,14 @@ function normalizePath(candidate, cwd) {
|
|
|
20997
21503
|
} catch {
|
|
20998
21504
|
}
|
|
20999
21505
|
if (path.startsWith("~/")) return null;
|
|
21000
|
-
if ((0,
|
|
21001
|
-
return cwd ? (0,
|
|
21506
|
+
if ((0, import_path9.isAbsolute)(path)) return path;
|
|
21507
|
+
return cwd ? (0, import_path9.join)(cwd, path) : null;
|
|
21002
21508
|
}
|
|
21003
21509
|
function resolveToolCwd(cwd, toolInput) {
|
|
21004
21510
|
if (!isRecord(toolInput)) return cwd;
|
|
21005
21511
|
const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
|
|
21006
21512
|
if (!raw) return cwd;
|
|
21007
|
-
return (0,
|
|
21513
|
+
return (0, import_path9.isAbsolute)(raw) || !cwd ? raw : (0, import_path9.join)(cwd, raw);
|
|
21008
21514
|
}
|
|
21009
21515
|
function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
|
|
21010
21516
|
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
|
|
@@ -21047,19 +21553,19 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
|
|
|
21047
21553
|
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
21048
21554
|
for (const candidate of extractPathCandidates(content, options)) {
|
|
21049
21555
|
const path = normalizePath(candidate, effectiveCwd);
|
|
21050
|
-
if (!path || seen.has(path) || !(0,
|
|
21556
|
+
if (!path || seen.has(path) || !(0, import_fs9.existsSync)(path)) continue;
|
|
21051
21557
|
seen.add(path);
|
|
21052
|
-
const ext = (0,
|
|
21558
|
+
const ext = (0, import_path9.extname)(path).toLowerCase();
|
|
21053
21559
|
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
21054
21560
|
if (!mimeType) continue;
|
|
21055
|
-
const stat = (0,
|
|
21561
|
+
const stat = (0, import_fs9.statSync)(path);
|
|
21056
21562
|
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
21057
|
-
const buffer = (0,
|
|
21563
|
+
const buffer = (0, import_fs9.readFileSync)(path);
|
|
21058
21564
|
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
21059
21565
|
images.push({
|
|
21060
21566
|
type: "generated_image",
|
|
21061
21567
|
id: (0, import_crypto3.randomUUID)(),
|
|
21062
|
-
filename: (0,
|
|
21568
|
+
filename: (0, import_path9.basename)(path),
|
|
21063
21569
|
mimeType,
|
|
21064
21570
|
size: buffer.length,
|
|
21065
21571
|
width,
|
|
@@ -21086,20 +21592,20 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
|
|
|
21086
21592
|
const mimeByExt = kind === "video" ? VIDEO_MIME_BY_EXT : IMAGE_MIME_BY_EXT;
|
|
21087
21593
|
for (const candidate of extractPathCandidates(content, options, extensionsPattern)) {
|
|
21088
21594
|
const path = normalizePath(candidate, effectiveCwd);
|
|
21089
|
-
if (!path || seen.has(path) || !(0,
|
|
21595
|
+
if (!path || seen.has(path) || !(0, import_fs9.existsSync)(path)) continue;
|
|
21090
21596
|
seen.add(path);
|
|
21091
|
-
const ext = (0,
|
|
21597
|
+
const ext = (0, import_path9.extname)(path).toLowerCase();
|
|
21092
21598
|
const mimeType = mimeByExt[ext];
|
|
21093
21599
|
if (!mimeType) continue;
|
|
21094
|
-
const stat = (0,
|
|
21600
|
+
const stat = (0, import_fs9.statSync)(path);
|
|
21095
21601
|
if (!stat.isFile() || stat.size <= 0 || stat.size > maxBytes) continue;
|
|
21096
|
-
const buffer = (0,
|
|
21602
|
+
const buffer = (0, import_fs9.readFileSync)(path);
|
|
21097
21603
|
const dimensions = kind === "image" ? readImageDimensions2(buffer, mimeType) : null;
|
|
21098
21604
|
media.push({
|
|
21099
21605
|
type: "session_media",
|
|
21100
21606
|
kind,
|
|
21101
21607
|
id: (0, import_crypto3.randomUUID)(),
|
|
21102
|
-
filename: (0,
|
|
21608
|
+
filename: (0, import_path9.basename)(path),
|
|
21103
21609
|
mimeType,
|
|
21104
21610
|
size: buffer.length,
|
|
21105
21611
|
width: dimensions?.width,
|
|
@@ -23678,7 +24184,7 @@ var RunStartGate = class {
|
|
|
23678
24184
|
};
|
|
23679
24185
|
|
|
23680
24186
|
// src/version.ts
|
|
23681
|
-
var AGENT_VERSION = "0.1.
|
|
24187
|
+
var AGENT_VERSION = "0.1.46";
|
|
23682
24188
|
|
|
23683
24189
|
// src/workspace-relocation.ts
|
|
23684
24190
|
var import_node_child_process3 = require("child_process");
|
|
@@ -25391,11 +25897,21 @@ var RuntimePresenter = class {
|
|
|
25391
25897
|
onNotice(kind, message) {
|
|
25392
25898
|
this.emitEvent({ type: "session_notice", kind, message, ts: Date.now() });
|
|
25393
25899
|
}
|
|
25394
|
-
onAssistantText(text) {
|
|
25395
|
-
this.emitEvent({
|
|
25900
|
+
onAssistantText(text, parentToolUseId) {
|
|
25901
|
+
this.emitEvent({
|
|
25902
|
+
type: "text",
|
|
25903
|
+
text,
|
|
25904
|
+
ts: Date.now(),
|
|
25905
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
25906
|
+
});
|
|
25396
25907
|
}
|
|
25397
|
-
onThinking(text) {
|
|
25398
|
-
this.emitEvent({
|
|
25908
|
+
onThinking(text, parentToolUseId) {
|
|
25909
|
+
this.emitEvent({
|
|
25910
|
+
type: "thinking",
|
|
25911
|
+
text,
|
|
25912
|
+
ts: Date.now(),
|
|
25913
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
25914
|
+
});
|
|
25399
25915
|
}
|
|
25400
25916
|
onToolUse(tool, input, toolId, parentToolUseId) {
|
|
25401
25917
|
if (this.verifyWorkspaceLease && !this.verifyWorkspaceLease()) return;
|
|
@@ -27499,11 +28015,21 @@ var WebPresenter = class {
|
|
|
27499
28015
|
onNotice(kind, message) {
|
|
27500
28016
|
this.wsClient.emitEvent({ type: "session_notice", kind, message, ts: Date.now() });
|
|
27501
28017
|
}
|
|
27502
|
-
onAssistantText(text) {
|
|
27503
|
-
this.wsClient.emitEvent({
|
|
28018
|
+
onAssistantText(text, parentToolUseId) {
|
|
28019
|
+
this.wsClient.emitEvent({
|
|
28020
|
+
type: "text",
|
|
28021
|
+
text,
|
|
28022
|
+
ts: Date.now(),
|
|
28023
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
28024
|
+
});
|
|
27504
28025
|
}
|
|
27505
|
-
onThinking(text) {
|
|
27506
|
-
this.wsClient.emitEvent({
|
|
28026
|
+
onThinking(text, parentToolUseId) {
|
|
28027
|
+
this.wsClient.emitEvent({
|
|
28028
|
+
type: "thinking",
|
|
28029
|
+
text,
|
|
28030
|
+
ts: Date.now(),
|
|
28031
|
+
...parentToolUseId ? { parentToolUseId } : {}
|
|
28032
|
+
});
|
|
27507
28033
|
}
|
|
27508
28034
|
hasKnownToolUse(toolId) {
|
|
27509
28035
|
return this.toolNamesById.has(toolId);
|