Skip to content

fix(web): run new-session slash actions (skills, /goal, /btw) from the empty composer - #1445

Merged
wbxl2000 merged 11 commits into
mainfrom
fix/web-skill-activation-new-session
Jul 7, 2026
Merged

fix(web): run new-session slash actions (skills, /goal, /btw) from the empty composer#1445
wbxl2000 merged 11 commits into
mainfrom
fix/web-skill-activation-new-session

Conversation

@wbxl2000

@wbxl2000 wbxl2000 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue. Follow-up to #1392, which listed workspace skills in the composer before a session exists.

Problem

Several slash actions that run (or start) a turn silently do nothing from the new-session (onboarding) composer, because their implementations short-circuit when there is no active session id. The user types the command, the box clears, and nothing happens:

  • /<skill> — e.g. /pre-changelog (no args) or /write-goal ship it (with args).
  • /goal <objective>.
  • /btw [<question>] — opened an empty side-chat panel (the panel target was set even though the BTW sub-agent never started).

Plain text first prompts were fine because handleSubmit creates the session first; the slash actions didn't.

What changed

Mirror the existing first-prompt session-creation path for each affected action so the empty-composer case behaves like the first message:

  • Slash skills: new startSessionAndActivateSkill(workspaceId, name, args?).
    Creates the session first, then persists the draft runtime controls the prompt would have carried (planMode / swarmMode / permissionMode / thinking) and awaits that profile update before activating. Skill activation carries only args, so without this the first skill turn runs at daemon defaults while the UI shows the controls enabled. activateSkill also takes an explicit session id so a concurrent session switch can't redirect it.
  • /goal <objective>: createGoal now creates the session first when none exists and a workspace is usable (via the same fallback as the sidebar), then sets the goal profile and submits the objective — targeted by explicit sid for the same race reason. Plain prompts carry their own permissionMode / thinking / plan / swarm, so the goal path doesn't need the profile fallback.
  • /btw [<question>]: new startSessionAndOpenSideChat(workspaceId, prompt?) that creates the parent session then opens a BTW sub-agent on it via openSideChatOn(sid, prompt). Side-chat prompts now also carry model / thinking / permissionMode / plan / swarm (so a BTW first turn matches the UI even when the parent /profile is still in flight), so unlike skill activation no profile fallback is needed here.
  • Shared session creation extracted to createDraftSession so the model pick and draft modes are applied identically for prompts, goals, skills, and BTW. It stays pure (no profile persistence); the runtime controls that aren't on the turn-start request are persisted only on the paths that need them (skill activation).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my fix works.
  • Ran gen-changesets skill.
  • Ran gen-docs skill, or this PR needs no doc update.

The composer now lists workspace skills before a session exists, but
activating one from the empty-session composer silently did nothing:
activateSkill() short-circuits when there is no active session id, so
the command was cleared with no turn started.

Mirror the first-prompt path: when a slash skill is activated with no
active session (but a workspace is active), create the session first and
activate on the new session id. Extract the shared session-creation
block out of startSessionAndSendPrompt into createDraftSession and add a
startSessionAndActivateSkill counterpart; activateSkill now also accepts
an explicit session id so a concurrent session switch can't redirect it.

Unrecognized '/cmd' text still falls through to a plain-text message as
before.
@changeset-bot

changeset-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4edba6f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 6, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@4edba6f
npx https://pkg.pr.new/@moonshot-ai/kimi-code@4edba6f

commit: 4edba6f

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 670bfd6fbd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

try {
const sid = await createDraftSession(workspaceId);
if (!sid) return;
await modelProvider.activateSkill(skillName, args, sid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist draft modes before activating a new-session skill

When the user enables /plan or /swarm in the draft composer and then selects a workspace skill, createDraftSession only updates the web client's local rawState.*ModeBySession maps; the /skills/:activate request carries only args and does not send the prompt-time planMode/swarmMode flags or a /profile update. In that scenario the first skill turn runs on the daemon with the default modes while the UI shows them as enabled, so persist the draft modes to the new session before this activation (or include them in session creation) rather than relying on local state alone.

Useful? React with 👍 / 👎.

The skill-activate request carries only `args`, so for a skill launched
from the new-session composer createDraftSession's local plan/swarm maps
never reached the daemon, and the first skill turn ran at default modes
while the UI showed them enabled.

Persist the draft plan/swarm modes to the new session's profile inside
createDraftSession (by the new session id), and teach persistSessionProfile
to take an explicit session id so a concurrent session switch during the
snapshot load can't write the patch to the wrong session. Plain prompts
already send planMode/swarmMode on the prompt request itself, so this is
redundant but harmless on the first-prompt path. Goal mode is a one-shot
flag consumed per send, not a profile field, so there is nothing to
persist for it.

Add coverage that the profile is persisted before activation when draft
plan/swarm modes are enabled.
@wbxl2000

wbxl2000 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 822238f041

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// map writes above. Goal mode is a one-shot flag consumed per send, not a
// profile field, so there is nothing to persist for it.
if (draftModes.planMode || draftModes.swarmMode) {
persistSessionProfile(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Await draft mode persistence before skill activation

When the user enables draft plan/swarm mode and invokes a slash skill from the empty composer, this persistSessionProfile call starts POST /profile but returns immediately; startSessionAndActivateSkill then sends :activate without waiting. Since skill activation carries only args, the server can process the activation before applyAgentState from /profile finishes, so the first skill turn runs with plan/swarm disabled even though the UI shows it enabled. Make the profile update awaitable for this path, or pass the modes with the activation, before activating.

Useful? React with 👍 / 👎.

The previous fix wrote the draft plan/swarm modes to the new session's
profile but fire-and-forget: persistSessionProfile returned immediately
after starting POST /profile, so startSessionAndActivateSkill sent
:activate without waiting. Since skill activation carries only args, the
daemon could process :activate (and start the turn) before
applyAgentState from /profile finished, running the first skill turn at
default modes while the UI showed them enabled.

Make persistSessionProfile return the update promise and await it inside
createDraftSession, so any origin that follows (the skill activation, or
a plain prompt) only starts after the profile is applied. Existing
callers still fire-and-forget via `void persistSessionProfile(...)`.

Test coverage now blocks activation behind a deferred profile POST and
asserts it is issued only after the profile resolves.
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd82602fe9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +814 to +817
{
planMode: draftModes.planMode,
swarmMode: draftModes.swarmMode,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist draft permission and thinking before skill activation

When the first action from the empty composer is a slash skill after the user changed draft controls such as /auto//yolo or the thinking selector, those settings are never sent to the new session. Normal first prompts pass permissionMode and thinking in submitPromptInternal, but this path goes straight to activateSkill, whose REST request only carries args; this profile patch only copies plan/swarm (and is skipped entirely when only permission/thinking changed), so the first skill turn runs with daemon defaults while the UI shows the selected controls.

Useful? React with 👍 / 👎.

Move the awaited plan/swarm profile write out of createDraftSession and
into startSessionAndActivateSkill. The create path now only builds the
session and mirrors draft modes into the per-session maps, matching the
old first-prompt behavior: plain prompts already send planMode/swarmMode
on the prompt request itself, so a /profile write there was redundant.

The profile write stays on the one path that needs it: skill activation
carries only args, so the draft modes must be stored on the new session
and applied before :activate is sent.
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8989661190

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +850 to +853
const planMode = rawState.planModeBySession[sid] ?? false;
const swarmMode = rawState.swarmModeBySession[sid] ?? false;
if (planMode || swarmMode) {
await persistSessionProfile({ planMode, swarmMode }, sid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist draft permission and thinking before activation

When the user starts from the new-session composer and first changes runtime controls such as /auto, /yolo, or /thinking, those values live only in rawState because there is no session for persistSessionProfile yet. A normal first prompt still honors them because submitPromptInternal sends permissionMode and thinking with the prompt, but this new skill path only persists plan/swarm before calling activateSkill, whose REST body carries only args. In that scenario the first skill turn runs with the daemon defaults instead of the controls the UI shows; include the current permission/thinking in this profile patch before activation.

Useful? React with 👍 / 👎.

wbxl2000 added 2 commits July 7, 2026 12:01
/auto, /yolo, and /thinking on the new-session composer only update
rawState (there is no session to persist to yet). A plain first prompt
still honors them because submitPromptInternal sends permissionMode and
thinking on the request, but skill activation carries only args, so the
first skill turn was running at daemon defaults.

Include permissionMode and thinking in the awaited profile patch alongside
planMode/swarmMode before activating, so the skill turn matches the
controls the UI shows.
createGoal() short-circuited when there was no active session, so
`/goal <objective>` from the empty-session composer silently cleared and
ran nothing — the same bug class as the slash-skill activation fixed
earlier in this PR.

Mirror startSessionAndSendPrompt: when no session exists but a workspace
is active, create one first then target it with the goal profile update
and the objective prompt. Send via submitPromptInternal with the explicit
sid so a concurrent session switch during creation can't redirect it.
Plain prompts already carry their own permissionMode / thinking / plan /
swarm, so no profile fallback is needed here.
@wbxl2000 wbxl2000 changed the title fix(web): activate slash skills on the new-session screen fix(web): run new-session slash actions (skills, /goal) from the empty composer Jul 7, 2026
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

1 similar comment
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b04f4fb0bc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1595 to +1596
const wsId = rawState.activeWorkspaceId;
if (!wsId) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the active workspace fallback when creating goals

When the app has registered workspaces but no sessions yet, load() never writes rawState.activeWorkspaceId because there is no mostRecent session; the UI still has a usable workspace through the activeWorkspaceId computed fallback. In that empty-composer state, /goal <objective> now reaches this new branch, sees rawState.activeWorkspaceId as null, and silently returns instead of creating the first session, while normal first prompts and skill activations use the computed workspace id from App.vue. Use the same fallback (or pass the workspace id into createGoal) so first-session goals work in empty workspaces.

Useful? React with 👍 / 👎.

On a fresh-booted empty workspace, load() never writes
rawState.activeWorkspaceId (no most-recent session to anchor it). The
UI still has a usable workspace via the client-wide activeWorkspaceId
computed, which falls back to the first sidebar-visible workspace — but
createGoal read the raw value directly and silently no-op'd when it was
null.

Normal first prompts and skill activations didn't hit this because
App.vue passes the computed activeWorkspaceId in. Make createGoal use
the same fallback so a first-session `/goal <objective>` works in empty
workspaces too.
@wbxl2000 wbxl2000 changed the title fix(web): run new-session slash actions (skills, /goal) from the empty composer fix(web): run new-session slash actions (skills, /goal, /btw) from the empty composer Jul 7, 2026
openSideChat() reads rawState.activeSessionId directly, so `/btw
[<question>]` from the empty-session composer silently no-oped — it
still set detailTarget to 'btw', leaving the side chat panel open but
empty.

Add startSessionAndOpenSideChat(workspaceId, prompt?) that creates the
parent session first, then calls a new sideChat.openSideChatOn(sid,
prompt) which targets the explicit parent session id (race-safe against
a concurrent session switch, like the skill activation case). Route
through it from the empty-composer branch in openSideChatTab.

Side-chat prompts now also carry model / thinking / permissionMode /
plan / swarm (via a shared sendSideChatPromptOn), so a BTW first turn
matches the UI even when the parent /profile is still in flight. Unlike
skill activation, this means the BTW path needs no profile fallback.

Tests: startSessionAndOpenSideChat creates a session then opens BTW on
the new id, works without an initial question, and is a no-op for an
unknown workspace; sendSideChatPromptOn carries the runtime controls
on the submitted prompt.
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b90fefc62

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// redirect the goal prompt to the wrong session. Plain prompts carry their
// own permissionMode / thinking / plan / swarm on the request, so we don't
// need to persist them onto the profile here.
await submitPromptInternal(sid, trimmed);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the prompt queue when creating goals

When /goal <objective> is run against an already-active session that is still running, the composer still emits the command, but this now bypasses sendPrompt's activity !== 'idle' || inFlightPromptSessions.has(sid) guard and posts immediately via submitPromptInternal. That helper is explicitly the queue-bypassing path and also stamps promptIdBySession, so a goal created while another turn is running can race with the active turn instead of being locally queued like normal sends were before this change.

Useful? React with 👍 / 👎.

Switching createGoal from sendPrompt to submitPromptInternal avoided the
activeSessionId race during the empty-composer create window, but it also
bypassed sendPrompt's queue guard: when a goal is created against an
already-active session that is running another turn, the prompt posted
immediately instead of being locally queued.

Restore the guard for the overwhelmingly common case (the goal still
targets the active session): route through sendPrompt when activeSessionId
still matches the resolved sid, which enqueues when the session is
running or a prompt is already in flight. Only fall back to the explicit-
session submitPromptInternal(sid) when activeSessionId moved during the
create window, so a concurrent session switch can't redirect the goal
prompt. The newly-created session is idle+not-in-flight in that branch,
so the explicit submit does not race another turn.

Add a regression test: createGoal against a running existing session
enqueues instead of submits.
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ac7fe1aad

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

? raw
: (workspacesView.value[0]?.id ?? null);
if (!wsId) return;
sid = (await createDraftSession(wsId)) ?? undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle session creation failures for empty goals

When /goal <objective> is run from the empty composer, createDraftSession() can reject (for example if createSession or the initial snapshot fails), but this await happens before the existing try/catch. Since App.vue invokes client.createGoal() fire-and-forget, that leaves an unhandled rejection and no operation failure is surfaced, unlike the new skill/BTW and first-prompt paths that wrap draft-session creation.

Useful? React with 👍 / 👎.

content: [{ type: 'text', text: trimmed }],
agentId,
model,
thinking: rawState.thinking,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Coerce thinking before BTW prompts

When the stored/global thinking level is stale for the parent session's model (for example after switching from an effort-capable model to a session whose model does not support that effort), the composer displays the coerced level and normal prompts use coercePromptThinking(model), but this new BTW path submits rawState.thinking directly. That can make /btw <question> run with a different thinking setting than the UI shows and than an ordinary prompt in the same session would use.

Useful? React with 👍 / 👎.

planMode,
swarmMode,
permissionMode: rawState.permission,
thinking: rawState.thinking,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Coerce thinking before activating new-session skills

When a slash skill is launched from the empty composer after rawState.thinking was carried over from a different/default model, the composer and first-prompt path coerce that value for the newly created session's model, but this profile update persists the raw value before activation. In that case the first skill turn can run with a thinking level that the UI would not send for the same model.

Useful? React with 👍 / 👎.

…ures

Three follow-ups from review:

- createGoal now wraps createDraftSession in a try/catch: App.vue invokes
  it fire-and-forget, so a rejection from session creation previously
  leaked as an unhandled rejection with no operation failure surfaced.
  Mirrors the skill / BTW / first-prompt paths that already wrap it.

- startSessionAndActivateSkill coerces the draft thinking level against
  the new session's model before persisting the profile (via
  coercePromptThinking), matching what the first-prompt path submits.
  A value carried over from another/default model (e.g. 'max' from an
  effort model) would otherwise be persisted verbatim and the first
  skill turn would run at a level the UI wouldn't send for this model.

- sendSideChatPromptOn coerces thinking against the parent session's
  model the same way normal prompts do (coerceThinkingForModel against
  the model catalog). Model catalog threaded in via a new 'models' dep
  on useSideChat. Same reasoning: stale rawState.thinking must not be
  submitted raw into a BTW first turn.
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bca67b671f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1665 to +1666
if (rawState.activeSessionId === sid) {
await sendPrompt(trimmed);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear staged goal mode before submitting explicit goals

When the empty composer already has goal mode staged (for example the user ran bare /goal and then types /goal ship it), createDraftSession() copies that draft flag into rawState.goalModeBySession[sid]. This sendPrompt(trimmed) then re-enters submitPromptInternal, which sees goal mode still enabled and sends a second goalObjective update after the explicit one above already created the goal; the daemon rejects that as an existing goal, so the objective prompt is never submitted. Clear the one-shot flag before this submit, or bypass the goal-mode branch for explicit /goal <objective>.

Useful? React with 👍 / 👎.

When the empty composer has goal mode staged (e.g. the user runs bare
`/goal`, then `/goal <objective>`) and an explicit objective is then
submitted, createDraftSession copies draftModes.goalMode into
goalModeBySession[sid]. createGoal then updateSession(goalObjective) for
the explicit goal, and sendPrompt(trimmed) re-enters submitPromptInternal
which sees goalModeBySession[sid] still set and POSTs a second
goalObjective. The daemon rejects that as an existing goal, the catch in
submitPromptInternal rolls back the optimistic message, and the user's
objective prompt never lands.

Clear the staged goalModeBySession[sid] flag right after the explicit
update, since `/goal <objective>` has exactly the same effect as the
flag's consumption.
@wbxl2000

wbxl2000 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4edba6f881

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-web/src/App.vue
Comment on lines +498 to +499
if (!client.activeSessionId.value && client.activeWorkspaceId.value) {
void client.startSessionAndActivateSkill(client.activeWorkspaceId.value, name, args);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid creating sessions for unknown slash commands

When the empty composer receives a non-built-in slash typo such as /pre-changlog, this branch creates a real backend session before activateSkill can return skill.not_found; the optimistic message is removed on failure, but the blank session remains active/in the sidebar. That regresses the documented harmless stray-slash behavior for the new-session screen, so validate the name against the loaded workspace skills (or otherwise avoid creating a session) before taking this creation path.

Useful? React with 👍 / 👎.

@wbxl2000
wbxl2000 merged commit 809a88c into main Jul 7, 2026
10 checks passed
@wbxl2000
wbxl2000 deleted the fix/web-skill-activation-new-session branch July 7, 2026 06:18
@github-actions github-actions Bot mentioned this pull request Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant