@canonmsg/codex-plugin 0.18.8 → 0.18.10

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.
@@ -534,7 +534,9 @@ function readNullableString(record, key) {
534
534
  return typeof value === 'string' && value.trim() ? value.trim() : undefined;
535
535
  }
536
536
  function parseSkillSlashPrompt(prompt) {
537
- const match = prompt.trim().match(/^\/skill\s+([A-Za-z0-9:_-]+)(?:\s+([\s\S]*))?$/);
537
+ const trimmed = prompt.trim();
538
+ const match = trimmed.match(/^\$([A-Za-z0-9:_-]+)(?:\s+([\s\S]*))?$/)
539
+ ?? trimmed.match(/^\/skill\s+([A-Za-z0-9:_-]+)(?:\s+([\s\S]*))?$/);
538
540
  if (!match?.[1])
539
541
  return null;
540
542
  return {
package/dist/host.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { type CanonRuntimeCommandDescriptor } from '@canonmsg/core';
2
+ import { type CanonRuntimeCommandDescriptor, type ExecutionEnvironmentMode } from '@canonmsg/core';
3
3
  import { type CodexSkillMetadata } from './app-server-adapter.js';
4
4
  interface HostSessionState {
5
5
  lastError?: string;
@@ -17,6 +17,21 @@ export declare function buildCodexInitialSessionState(input: {
17
17
  permissionMode?: string;
18
18
  effort?: string | null;
19
19
  }): HostSessionState;
20
+ export declare function buildCodexLiveSessionConfig(input: {
21
+ model?: string;
22
+ permissionMode?: string;
23
+ effort?: string;
24
+ workspaceId?: string | null;
25
+ executionMode: ExecutionEnvironmentMode;
26
+ executionBranch?: string | null;
27
+ }): {
28
+ executionMode: ExecutionEnvironmentMode;
29
+ executionBranch: string | null;
30
+ workspaceId?: string | undefined;
31
+ effort?: string | undefined;
32
+ permissionMode?: string | undefined;
33
+ model?: string | undefined;
34
+ };
20
35
  /** GPT reasoning-effort levels, applied next turn via model_reasoning_effort. */
21
36
  export declare const CODEX_EFFORT_OPTIONS: readonly [{
22
37
  readonly value: "minimal";
@@ -34,6 +49,7 @@ export declare const CODEX_EFFORT_OPTIONS: readonly [{
34
49
  readonly value: "xhigh";
35
50
  readonly label: "Extra high";
36
51
  }];
37
- export declare function buildCodexSkillCommand(skills: ReadonlyArray<CodexSkillMetadata>): CanonRuntimeCommandDescriptor | null;
52
+ export declare const CODEX_SESSION_CONFIG_FIELDS: readonly ["permissionMode", "effort"];
53
+ export declare function buildCodexSkillCommands(skills: ReadonlyArray<CodexSkillMetadata>): CanonRuntimeCommandDescriptor[];
38
54
  export declare function main(): Promise<void>;
39
55
  export {};
package/dist/host.js CHANGED
@@ -61,6 +61,16 @@ export function buildCodexInitialSessionState(input) {
61
61
  state: 'idle',
62
62
  };
63
63
  }
64
+ export function buildCodexLiveSessionConfig(input) {
65
+ return {
66
+ ...(input.model ? { model: input.model } : {}),
67
+ ...(input.permissionMode ? { permissionMode: input.permissionMode } : {}),
68
+ ...(input.effort ? { effort: input.effort } : {}),
69
+ ...(input.workspaceId ? { workspaceId: input.workspaceId } : {}),
70
+ executionMode: input.executionMode,
71
+ executionBranch: input.executionBranch ?? null,
72
+ };
73
+ }
64
74
  const MAX_SESSIONS = 12;
65
75
  const IDLE_TIMEOUT_MS = 30 * 60 * 1000;
66
76
  const HEARTBEAT_MS = 30_000;
@@ -85,9 +95,10 @@ export const CODEX_EFFORT_OPTIONS = [
85
95
  { value: 'xhigh', label: 'Extra high' },
86
96
  ];
87
97
  const CODEX_EFFORT_VALUES = new Set(CODEX_EFFORT_OPTIONS.map((option) => option.value));
98
+ export const CODEX_SESSION_CONFIG_FIELDS = ['permissionMode', 'effort'];
88
99
  const MAX_CODEX_SKILL_COMMAND_CHOICES = 50;
89
- export function buildCodexSkillCommand(skills) {
90
- const choices = skills
100
+ export function buildCodexSkillCommands(skills) {
101
+ return skills
91
102
  .filter((skill) => /^[A-Za-z0-9:_-]+$/.test(skill.name))
92
103
  .slice(0, MAX_CODEX_SKILL_COMMAND_CHOICES)
93
104
  .map((skill) => {
@@ -95,39 +106,25 @@ export function buildCodexSkillCommand(skills) {
95
106
  ?? skill.description
96
107
  ?? (skill.scope ? `${skill.scope} skill` : undefined);
97
108
  return {
98
- value: skill.name,
109
+ id: `codex-skill-${skill.name}`,
99
110
  label: skill.displayName ?? skill.name,
111
+ aliases: [skill.name],
112
+ category: 'skill',
113
+ placements: ['composer_slash', 'command_palette'],
114
+ availability: ['always'],
115
+ trailingTextBehavior: 'send_as_prompt',
116
+ args: [
117
+ {
118
+ id: 'prompt',
119
+ label: 'Prompt',
120
+ kind: 'string',
121
+ captureRemaining: true,
122
+ },
123
+ ],
100
124
  ...(description ? { description } : {}),
125
+ dispatch: { kind: 'text_passthrough', template: `$${skill.name} {argument}` },
101
126
  };
102
127
  });
103
- if (choices.length === 0)
104
- return null;
105
- return {
106
- id: 'codex-skill',
107
- label: 'Use skill',
108
- description: 'Invoke one of the Codex skills available to this runtime.',
109
- aliases: ['skill'],
110
- category: 'skill',
111
- placements: ['composer_slash', 'command_palette'],
112
- availability: ['always'],
113
- trailingTextBehavior: 'send_as_prompt',
114
- args: [
115
- {
116
- id: 'skill',
117
- label: 'Skill',
118
- kind: 'enum',
119
- required: true,
120
- choices,
121
- },
122
- {
123
- id: 'prompt',
124
- label: 'Prompt',
125
- kind: 'string',
126
- captureRemaining: true,
127
- },
128
- ],
129
- dispatch: { kind: 'text_passthrough', template: '/skill {args.skill} {args.prompt}' },
130
- };
131
128
  }
132
129
  function buildCodexRuntimeDescriptor(input) {
133
130
  const commands = [
@@ -149,9 +146,9 @@ function buildCodexRuntimeDescriptor(input) {
149
146
  RUNTIME_STOP_ACTION,
150
147
  RUNTIME_STOP_AND_DROP_ACTION,
151
148
  ];
152
- const skillCommand = input.skills?.length ? buildCodexSkillCommand(input.skills) : null;
153
- if (skillCommand) {
154
- commands.push(skillCommand);
149
+ const skillCommands = input.skills?.length ? buildCodexSkillCommands(input.skills) : [];
150
+ if (skillCommands.length) {
151
+ commands.push(...skillCommands);
155
152
  }
156
153
  const descriptor = buildFirstPartyCodingRuntimeDescriptor({
157
154
  clientType: 'codex',
@@ -238,7 +235,7 @@ async function loadSessionConfig(conversationId, agentId) {
238
235
  return loadHostSessionConfig({
239
236
  conversationId,
240
237
  agentId,
241
- extraStringFields: ['permissionMode', 'effort'],
238
+ extraStringFields: CODEX_SESSION_CONFIG_FIELDS,
242
239
  });
243
240
  }
244
241
  function resolveSessionExecutionMode(config) {
@@ -1886,18 +1883,19 @@ export async function main() {
1886
1883
  runtime: runtimeDescriptor,
1887
1884
  workspaceOptions,
1888
1885
  defaultCwd: workingDir,
1889
- extraSessionConfigFields: ['permissionMode'],
1886
+ extraSessionConfigFields: CODEX_SESSION_CONFIG_FIELDS,
1890
1887
  liveSessionConfigByConversation: new Map(Array.from(sessions.values()).map((session) => {
1891
1888
  const workspaceId = resolveWorkspaceIdForBaseCwd(session.environment.baseCwd);
1892
1889
  return [
1893
1890
  session.conversationId,
1894
- {
1895
- ...(session.state.model ? { model: session.state.model } : {}),
1896
- ...(session.state.permissionMode ? { permissionMode: session.state.permissionMode } : {}),
1897
- ...(workspaceId ? { workspaceId } : {}),
1891
+ buildCodexLiveSessionConfig({
1892
+ model: session.state.model,
1893
+ permissionMode: session.state.permissionMode,
1894
+ effort: session.state.effort,
1895
+ workspaceId,
1898
1896
  executionMode: session.environment.mode,
1899
1897
  executionBranch: session.environment.branch ?? null,
1900
- },
1898
+ }),
1901
1899
  ];
1902
1900
  })),
1903
1901
  }).catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/codex-plugin",
3
- "version": "0.18.8",
3
+ "version": "0.18.10",
4
4
  "description": "Canon host integration for Codex CLI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",