kontexted 0.1.10 → 0.1.12

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.
@@ -1,6 +1,6 @@
1
1
  import * as readline from "readline";
2
2
  import { readConfig, writeConfig } from "../lib/config.js";
3
- import { getProfile } from "../lib/profile.js";
3
+ import { getProfile, listProfiles } from "../lib/profile.js";
4
4
  import { ApiClient } from "../lib/api-client.js";
5
5
  import { ensureValidTokens } from "../lib/oauth.js";
6
6
  import { getProvider, allTemplates } from "../skill-init/index.js";
@@ -117,6 +117,51 @@ async function createApiClient(alias) {
117
117
  function displayResult(result) {
118
118
  console.log(JSON.stringify(result, null, 2));
119
119
  }
120
+ /**
121
+ * Interactive profile selection for skill init
122
+ * Returns { alias, hasWrite } or null if user chose generic
123
+ */
124
+ async function selectProfile(profiles) {
125
+ // Build choices array
126
+ const choices = profiles.map(({ alias, profile }) => ({
127
+ alias,
128
+ hasWrite: profile.write,
129
+ label: `${alias} (write: ${profile.write ? '✓' : '✗'})`,
130
+ }));
131
+ // Add option to skip
132
+ choices.push({
133
+ alias: '',
134
+ hasWrite: false,
135
+ label: '[Skip - use generic template]',
136
+ });
137
+ console.log('\nSelect a profile to embed in kontexted-cli skill:\n');
138
+ choices.forEach((choice, index) => {
139
+ const marker = index === 0 ? '❯' : ' ';
140
+ console.log(` ${marker} ${index + 1}. ${choice.label}`);
141
+ });
142
+ const rl = readline.createInterface({
143
+ input: process.stdin,
144
+ output: process.stdout,
145
+ });
146
+ return new Promise((resolve) => {
147
+ rl.question('\nEnter selection (1-' + choices.length + '): ', (answer) => {
148
+ rl.close();
149
+ const selection = parseInt(answer.trim(), 10);
150
+ if (isNaN(selection) || selection < 1 || selection > choices.length) {
151
+ console.log('Invalid selection, using generic template.');
152
+ resolve(null);
153
+ return;
154
+ }
155
+ const chosen = choices[selection - 1];
156
+ if (!chosen.alias) {
157
+ // User chose "Skip - use generic"
158
+ resolve(null);
159
+ return;
160
+ }
161
+ resolve({ alias: chosen.alias, hasWrite: chosen.hasWrite });
162
+ });
163
+ });
164
+ }
120
165
  /**
121
166
  * Register the skill command and its subcommands
122
167
  */
@@ -279,6 +324,7 @@ export function registerSkillCommand(program) {
279
324
  .description("Initialize AI agent skills for the current project")
280
325
  .option("--provider <name>", "Provider to use (default: opencode)", "opencode")
281
326
  .option("--all", "Generate all available skills without prompting", false)
327
+ .option("--no-prompt", "Skip profile selection, use generic template", false)
282
328
  .action(async (options) => {
283
329
  try {
284
330
  // Get the provider
@@ -291,6 +337,28 @@ export function registerSkillCommand(program) {
291
337
  console.error(`Available providers: ${["opencode"].join(", ")}`);
292
338
  process.exit(1);
293
339
  }
340
+ // Resolve alias and write permissions through interactive selection
341
+ let alias;
342
+ let hasWrite = false;
343
+ if (!options.noPrompt) {
344
+ const config = await readConfig();
345
+ const profiles = listProfiles(config);
346
+ if (profiles.length > 0) {
347
+ const selection = await selectProfile(profiles);
348
+ if (selection) {
349
+ alias = selection.alias;
350
+ hasWrite = selection.hasWrite;
351
+ console.log(`\nUsing profile: ${alias} (write: ${hasWrite})\n`);
352
+ }
353
+ else {
354
+ console.log('\nUsing generic template (no alias)\n');
355
+ }
356
+ }
357
+ else {
358
+ console.log('No profiles found. Using generic template.\n');
359
+ console.log('To create a profile, run: kontexted login --alias <name> --url <url> --workspace <slug>\n');
360
+ }
361
+ }
294
362
  // Show what will be generated
295
363
  console.log(`This will generate the following skills for ${provider.name}:`);
296
364
  for (const template of allTemplates) {
@@ -321,6 +389,8 @@ export function registerSkillCommand(program) {
321
389
  const result = await initSkill({
322
390
  skill: template,
323
391
  provider,
392
+ alias,
393
+ hasWrite,
324
394
  });
325
395
  const status = result.created ? "Created" : "Updated";
326
396
  console.log(`✓ ${status} ${result.path}`);
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Options passed to skill content generator functions
3
+ */
4
+ export interface SkillContentOptions {
5
+ /** Profile alias to substitute in commands */
6
+ alias?: string;
7
+ /** Whether the profile has write permissions */
8
+ hasWrite: boolean;
9
+ }
1
10
  /**
2
11
  * Definition of a skill to be generated
3
12
  */
@@ -6,8 +15,15 @@ export interface SkillDefinition {
6
15
  name: string;
7
16
  /** Short description (1-1024 characters) */
8
17
  description: string;
9
- /** The full skill content (markdown) */
10
- content: string;
18
+ /** Static content string OR content generator function that receives options */
19
+ content: string | ((options: SkillContentOptions) => string);
20
+ }
21
+ /**
22
+ * Options for skill content generation
23
+ */
24
+ export interface GenerateContentOptions {
25
+ /** Optional alias to include in frontmatter */
26
+ alias?: string;
11
27
  }
12
28
  /**
13
29
  * Provider interface for different AI agent platforms
@@ -22,5 +38,5 @@ export interface SkillProvider {
22
38
  /** Validate skill name according to provider rules */
23
39
  validateSkillName(name: string): boolean;
24
40
  /** Generate the complete skill file content including frontmatter */
25
- generateSkillContent(skill: SkillDefinition): string;
41
+ generateSkillContent(skill: SkillDefinition, resolvedContent: string, options?: GenerateContentOptions): string;
26
42
  }
@@ -33,16 +33,23 @@ export const opencodeProvider = {
33
33
  },
34
34
  /**
35
35
  * Generate the complete skill file content including frontmatter
36
- * @param skill - The skill definition to generate content for
36
+ * @param skill - The skill definition (for name and description)
37
+ * @param resolvedContent - The resolved content string (after generator function if applicable)
38
+ * @param options - Optional metadata to include in frontmatter
37
39
  * @returns The complete markdown content with frontmatter
38
40
  */
39
- generateSkillContent(skill) {
40
- const frontmatter = `---
41
- name: ${skill.name}
42
- description: ${skill.description}
43
- ---`;
41
+ generateSkillContent(skill, resolvedContent, options) {
42
+ const frontmatterLines = [
43
+ `name: ${skill.name}`,
44
+ `description: ${skill.description}`,
45
+ ];
46
+ // Add alias to frontmatter if provided
47
+ if (options?.alias) {
48
+ frontmatterLines.push(`alias: ${options.alias}`);
49
+ }
50
+ const frontmatter = `---\n${frontmatterLines.join('\n')}\n---`;
44
51
  return `${frontmatter}
45
52
 
46
- ${skill.content}`;
53
+ ${resolvedContent}`;
47
54
  }
48
55
  };
@@ -1,24 +1,28 @@
1
- export const kontextedCliSkill = {
2
- name: 'kontexted-cli',
3
- description: 'Access and manage Kontexted workspaces, search notes, retrieve content, and create/update notes and folders through the kontexted CLI. Use when the user needs to explore workspace structure, find specific notes, read note content, or modify workspace content using profile aliases.',
4
- content: String.raw `# Kontexted CLI Skill Commands
1
+ /**
2
+ * Generate kontexted-cli skill content based on profile settings
3
+ */
4
+ function generateKontextedCliContent(options) {
5
+ const { alias, hasWrite } = options;
6
+ // Use actual alias or generic placeholder
7
+ const a = alias || '<profile>';
8
+ return String.raw `# Kontexted CLI Skill Commands
5
9
 
6
- ## Read Commands (No --write flag needed)
10
+ ## Read Commands
7
11
 
8
12
  \`\`\`
9
- kontexted skill workspace-tree --alias <profile> # Get workspace folder/note structure
10
- kontexted skill search-notes --alias <profile> --query "<text>" # Search notes
11
- kontexted skill note-by-id --alias <profile> --note-id <id> # Get specific note
13
+ kontexted skill workspace-tree --alias ${a}
14
+ kontexted skill search-notes --alias ${a} --query "<text>" [--limit <n>]
15
+ kontexted skill note-by-id --alias ${a} --note-id <id>
12
16
  \`\`\`
13
-
14
- ## Write Commands (Require write-enabled profile)
17
+ ${hasWrite ? `
18
+ ## Write Commands
15
19
 
16
20
  \`\`\`
17
- kontexted skill create-folder --alias <profile> --name <name> --display-name "<displayName>" [--parent-id <id>]
18
- kontexted skill create-note --alias <profile> --name <name> --title "<title>" [--folder-id <id>] [--content "<content>"]
19
- kontexted skill update-note-content --alias <profile> --note-id <id> --content "<content>"
21
+ kontexted skill create-folder --alias ${a} --name <name> --display-name "<displayName>" [--parent-id <id>]
22
+ kontexted skill create-note --alias ${a} --name <name> --title "<title>" [--folder-id <id>] [--content "<content>"]
23
+ kontexted skill update-note-content --alias ${a} --note-id <id> --content "<content>"
20
24
  \`\`\`
21
-
25
+ ` : ''}
22
26
  ## Prerequisites
23
27
 
24
28
  Before using the kontexted CLI skill commands, ensure:
@@ -26,9 +30,9 @@ Before using the kontexted CLI skill commands, ensure:
26
30
  1. **kontexted CLI is installed** - Install via npm or your preferred package manager
27
31
  2. **User has authenticated** - User must have run \`kontexted login\` with a profile alias
28
32
  3. **Profile has a workspace configured** - The profile alias must be associated with an active workspace
29
- 4. **Write operations require write-enabled profile** - To use write commands, the profile must have been created with \`kontexted login --write\`
33
+ ${hasWrite ? `4. **Write operations enabled** - This profile has write access enabled` : ''}
30
34
 
31
- All commands require the \`--alias\` parameter to specify which profile to use. The profile must already be set up and authenticated.
35
+ All commands require the \`--alias\` parameter. ${alias ? `This skill is configured for the \`${alias}\` profile.` : 'The profile must already be set up and authenticated.'}
32
36
 
33
37
  ## Available Tools
34
38
 
@@ -39,7 +43,7 @@ All commands require the \`--alias\` parameter to specify which profile to use.
39
43
  Get the complete folder and note structure of a workspace.
40
44
 
41
45
  \`\`\`bash
42
- kontexted skill workspace-tree --alias <profile>
46
+ kontexted skill workspace-tree --alias ${a}
43
47
  \`\`\`
44
48
 
45
49
  **Options:**
@@ -57,7 +61,7 @@ kontexted skill workspace-tree --alias <profile>
57
61
  Search for notes containing specific text content.
58
62
 
59
63
  \`\`\`bash
60
- kontexted skill search-notes --alias <profile> --query "<text>" [--limit <n>]
64
+ kontexted skill search-notes --alias ${a} --query "<text>" [--limit <n>]
61
65
  \`\`\`
62
66
 
63
67
  **Options:**
@@ -77,7 +81,7 @@ kontexted skill search-notes --alias <profile> --query "<text>" [--limit <n>]
77
81
  Retrieve the complete content of a specific note by its ID.
78
82
 
79
83
  \`\`\`bash
80
- kontexted skill note-by-id --alias <profile> --note-id <id>
84
+ kontexted skill note-by-id --alias ${a} --note-id <id>
81
85
  \`\`\`
82
86
 
83
87
  **Options:**
@@ -90,7 +94,7 @@ kontexted skill note-by-id --alias <profile> --note-id <id>
90
94
  - When you have a specific note ID and need its content
91
95
  - After finding a note via search or workspace tree exploration
92
96
  - When the user asks to read a specific note
93
-
97
+ ${hasWrite ? `
94
98
  ### Write Tools
95
99
 
96
100
  #### create-folder
@@ -98,7 +102,7 @@ kontexted skill note-by-id --alias <profile> --note-id <id>
98
102
  Create a new folder in the workspace. Optionally nest under a parent folder.
99
103
 
100
104
  \`\`\`bash
101
- kontexted skill create-folder --alias <profile> --name <name> --display-name "<displayName>" [--parent-id <parentPublicId>]
105
+ kontexted skill create-folder --alias ${a} --name <name> --display-name "<displayName>" [--parent-id <parentPublicId>]
102
106
  \`\`\`
103
107
 
104
108
  **Options:**
@@ -123,7 +127,7 @@ kontexted skill create-folder --alias <profile> --name <name> --display-name "<d
123
127
  Create a new note in the workspace. Optionally place in a folder.
124
128
 
125
129
  \`\`\`bash
126
- kontexted skill create-note --alias <profile> --name <name> --title "<title>" [--folder-id <folderPublicId>] [--content "<content>"]
130
+ kontexted skill create-note --alias ${a} --name <name> --title "<title>" [--folder-id <folderPublicId>] [--content "<content>"]
127
131
  \`\`\`
128
132
 
129
133
  **Options:**
@@ -149,7 +153,7 @@ kontexted skill create-note --alias <profile> --name <name> --title "<title>" [-
149
153
  Update the content of an existing note. This creates a revision for history.
150
154
 
151
155
  \`\`\`bash
152
- kontexted skill update-note-content --alias <profile> --note-id <notePublicId> --content "<content>"
156
+ kontexted skill update-note-content --alias ${a} --note-id <notePublicId> --content "<content>"
153
157
  \`\`\`
154
158
 
155
159
  **Options:**
@@ -172,7 +176,7 @@ kontexted skill update-note-content --alias <profile> --note-id <notePublicId> -
172
176
  **Error cases:**
173
177
  - **"Note not found"** - Verify the note ID
174
178
  - **"Invalid note public ID"** - Check the ID format
175
-
179
+ ` : ''}
176
180
  ## Typical Workflow
177
181
 
178
182
  The skill commands work best when combined in a logical sequence:
@@ -182,7 +186,7 @@ The skill commands work best when combined in a logical sequence:
182
186
  1. **Explore** - Use \`workspace-tree\` to understand workspace structure
183
187
  2. **Search** - Use \`search-notes\` to find relevant notes by content
184
188
  3. **Read** - Use \`note-by-id\` to retrieve full content of specific notes
185
-
189
+ ${hasWrite ? `
186
190
  ### Write Workflow
187
191
 
188
192
  1. **Create structure** - Use \`create-folder\` to organize content
@@ -192,91 +196,76 @@ The skill commands work best when combined in a logical sequence:
192
196
  **Example write workflow:**
193
197
  \`\`\`bash
194
198
  # Create a folder for project documentation
195
- kontexted skill create-folder --alias work --name "project-docs" --display-name "Project Documentation"
199
+ kontexted skill create-folder --alias ${a} --name "project-docs" --display-name "Project Documentation"
196
200
 
197
201
  # Create a note in that folder (use the returned publicId)
198
- kontexted skill create-note --alias work --name "requirements" --title "Requirements" --folder-id "FOLDER_PUBLIC_ID"
202
+ kontexted skill create-note --alias ${a} --name "requirements" --title "Requirements" --folder-id "FOLDER_PUBLIC_ID"
199
203
 
200
204
  # Update the note content
201
- kontexted skill update-note-content --alias work --note-id "NOTE_PUBLIC_ID" --content "# Requirements\n\n- Feature A\n- Feature B"
205
+ kontexted skill update-note-content --alias ${a} --note-id "NOTE_PUBLIC_ID" --content "# Requirements\n\n- Feature A\n- Feature B"
202
206
  \`\`\`
203
-
207
+ ` : ''}
204
208
  ## Example Usage
205
209
 
206
210
  ### Exploring a workspace
207
211
 
208
212
  \`\`\`bash
209
- # Get the complete structure of a personal workspace
210
- kontexted skill workspace-tree --alias personal
213
+ kontexted skill workspace-tree --alias ${a}
211
214
  \`\`\`
212
215
 
213
216
  ### Searching for content
214
217
 
215
218
  \`\`\`bash
216
- # Find notes about meeting notes
217
- kontexted skill search-notes --alias work --query "meeting notes"
218
-
219
- # Limit results to 3 notes
220
- kontexted skill search-notes --alias work --query "todo" --limit 3
219
+ kontexted skill search-notes --alias ${a} --query "meeting notes"
220
+ kontexted skill search-notes --alias ${a} --query "todo" --limit 3
221
221
  \`\`\`
222
222
 
223
223
  ### Reading specific notes
224
224
 
225
225
  \`\`\`bash
226
- # Get content of a note when you have its ID
227
- kontexted skill note-by-id --alias work --note-id "note-uuid-123"
226
+ kontexted skill note-by-id --alias ${a} --note-id "note-uuid-123"
228
227
  \`\`\`
229
-
228
+ ${hasWrite ? `
230
229
  ### Creating a folder structure
231
230
 
232
231
  \`\`\`bash
233
- # Create a root-level folder
234
- kontexted skill create-folder --alias work --name "meetings" --display-name "Meeting Notes"
235
-
236
- # Create a nested folder (use the returned publicId as parent-id)
237
- kontexted skill create-folder --alias work --name "2024" --display-name "2024 Meetings" --parent-id "PARENT_FOLDER_ID"
232
+ kontexted skill create-folder --alias ${a} --name "meetings" --display-name "Meeting Notes"
233
+ kontexted skill create-folder --alias ${a} --name "2024" --display-name "2024 Meetings" --parent-id "PARENT_FOLDER_ID"
238
234
  \`\`\`
239
235
 
240
236
  ### Creating and populating a note
241
237
 
242
238
  \`\`\`bash
243
- # Create a note with initial content
244
- kontexted skill create-note --alias work --name "todo" --title "Todo List" --content "# Todo\n\n- [ ] Task 1\n- [ ] Task 2"
245
-
246
- # Later, update the note content
247
- kontexted skill update-note-content --alias work --note-id "NOTE_ID" --content "# Todo\n\n- [x] Task 1\n- [ ] Task 2\n- [ ] Task 3"
239
+ kontexted skill create-note --alias ${a} --name "todo" --title "Todo List" --content "# Todo\n\n- [ ] Task 1\n- [ ] Task 2"
240
+ kontexted skill update-note-content --alias ${a} --note-id "NOTE_ID" --content "# Todo\n\n- [x] Task 1\n- [ ] Task 2\n- [ ] Task 3"
248
241
  \`\`\`
249
242
 
250
243
  ### Combining read and write operations
251
244
 
252
245
  \`\`\`bash
253
- # Task: Find a note and update it
254
- # Step 1: Search for the note
255
- kontexted skill search-notes --alias work --query "meeting notes"
256
-
257
- # Step 2: Update the found note
258
- kontexted skill update-note-content --alias work --note-id "FOUND_NOTE_ID" --content "Updated content here"
246
+ kontexted skill search-notes --alias ${a} --query "meeting notes"
247
+ kontexted skill update-note-content --alias ${a} --note-id "FOUND_NOTE_ID" --content "Updated content here"
259
248
  \`\`\`
260
-
249
+ ` : ''}
261
250
  ## Error Handling
262
251
 
263
252
  ### Authentication errors
264
253
 
265
- If you encounter authentication errors:
266
-
267
254
  1. **"Profile not found"** - The specified alias doesn't exist. Ask the user to run \`kontexted login --alias <profile>\` first.
268
-
269
- 2. **"Not authenticated"** - The profile exists but isn't authenticated. Ask the user to re-authenticate with \`kontexted login --alias <profile>\`.
270
-
271
- 3. **"No workspace configured"** - The profile is authenticated but has no workspace. Ask the user to set up a workspace with \`kontexted workspace set --alias <profile>\`.
272
-
255
+ 2. **"Not authenticated"** - The profile exists but isn't authenticated. Ask the user to re-authenticate.
256
+ 3. **"No workspace configured"** - The profile is authenticated but has no workspace. Ask the user to set up a workspace.
257
+ ${hasWrite ? `
273
258
  ### Write operation errors
274
259
 
275
- 1. **"Write operations not enabled for this profile"** - Re-login with \`kontexted login --alias <alias> --write\` to enable write access
260
+ 1. **"Write operations not enabled for this profile"** - Re-login with \`kontexted login --alias ${a} --write\` to enable write access
276
261
  2. **"Folder with this name already exists"** - Use a unique name or check existing folders
277
262
  3. **"Note with this name already exists"** - Use a unique name or check existing notes
278
263
  4. **"Parent folder not found"** - Verify the parent folder ID exists
279
264
  5. **"Note not found"** - Verify the note ID is correct
265
+ ` : `
266
+ ### Write operation errors
267
+
268
+ Write commands are not available for this profile. To enable write access, run \`kontexted login --alias <profile> --write\` and regenerate the skill.`}
280
269
 
281
270
  ### Other errors
282
271
 
@@ -284,8 +273,6 @@ If you encounter authentication errors:
284
273
  - **"Workspace not accessible"** - The workspace exists but the user lacks access permissions
285
274
  - **"Connection error"** - Network issues. Retry the command or check the user's connection
286
275
 
287
- When errors occur, report them clearly to the user so they can take appropriate action. The kontexted CLI handles most errors with descriptive messages.
288
-
289
276
  ## Output Format
290
277
 
291
278
  All commands return JSON output that is easy to parse:
@@ -294,12 +281,16 @@ All commands return JSON output that is easy to parse:
294
281
  - \`workspace-tree\`: Returns nested object with folders and notes
295
282
  - \`search-notes\`: Returns array of matching notes with ID, title, and snippets
296
283
  - \`note-by-id\`: Returns complete note object with body and metadata
297
-
284
+ ${hasWrite ? `
298
285
  ### Write commands
299
286
  - \`create-folder\`: Returns \`{ folder: { publicId, name, displayName, parentPublicId } }\`
300
287
  - \`create-note\`: Returns \`{ note: { publicId, name, title, folderPublicId, content } }\`
301
288
  - \`update-note-content\`: Returns \`{ note: { publicId, revisionId, updatedAt } }\`
302
-
303
- Use this structured output to provide clear responses to users about workspace contents and note information.
304
- `
289
+ ` : ''}
290
+ `;
291
+ }
292
+ export const kontextedCliSkill = {
293
+ name: 'kontexted-cli',
294
+ description: 'Access and manage Kontexted workspaces, search notes, retrieve content, and create/update notes and folders through the kontexted CLI. Use when the user needs to explore workspace structure, find specific notes, read note content, or modify workspace content using profile aliases.',
295
+ content: generateKontextedCliContent,
305
296
  };
@@ -9,6 +9,10 @@ export interface InitSkillOptions {
9
9
  provider: SkillProvider;
10
10
  /** Base directory (defaults to current working directory) */
11
11
  basePath?: string;
12
+ /** Profile alias to embed in skill content */
13
+ alias?: string;
14
+ /** Whether the profile has write permissions */
15
+ hasWrite?: boolean;
12
16
  }
13
17
  /**
14
18
  * Result of initializing a skill
@@ -81,9 +81,11 @@ export function validateSkill(skill, provider) {
81
81
  else if (skill.description.length < 1 || skill.description.length > 1024) {
82
82
  errors.push(`Skill description must be between 1 and 1024 characters (currently ${skill.description.length})`);
83
83
  }
84
- // Validate content is not empty
85
- if (!skill.content || skill.content.trim().length === 0) {
86
- errors.push('Skill content is required and cannot be empty');
84
+ // Validate content is not empty (skip for generator functions)
85
+ if (typeof skill.content === 'string') {
86
+ if (!skill.content || skill.content.trim().length === 0) {
87
+ errors.push('Skill content is required and cannot be empty');
88
+ }
87
89
  }
88
90
  return errors;
89
91
  }
@@ -96,13 +98,21 @@ export function validateSkill(skill, provider) {
96
98
  * @throws Error if validation fails or if the skill cannot be written
97
99
  */
98
100
  export async function initSkill(options) {
99
- const { skill, provider } = options;
101
+ const { skill, provider, alias, hasWrite = false } = options;
100
102
  const basePath = options.basePath || process.cwd();
101
103
  // Validate the skill definition
102
104
  const validationErrors = validateSkill(skill, provider);
103
105
  if (validationErrors.length > 0) {
104
106
  throw new Error(`Skill validation failed:\n${validationErrors.join('\n')}`);
105
107
  }
108
+ // Resolve content - handle both static string and generator function
109
+ let resolvedContent;
110
+ if (typeof skill.content === 'function') {
111
+ resolvedContent = skill.content({ alias, hasWrite });
112
+ }
113
+ else {
114
+ resolvedContent = skill.content;
115
+ }
106
116
  // Get the skill path from the provider
107
117
  const relativeSkillPath = provider.getSkillPath(skill.name);
108
118
  const absoluteSkillPath = path.isAbsolute(relativeSkillPath)
@@ -110,8 +120,8 @@ export async function initSkill(options) {
110
120
  : path.resolve(basePath, relativeSkillPath);
111
121
  // Check if file already exists
112
122
  const alreadyExists = await fileExists(absoluteSkillPath);
113
- // Generate the skill content
114
- const skillContent = provider.generateSkillContent(skill);
123
+ // Generate the skill content with resolved content and metadata
124
+ const skillContent = provider.generateSkillContent(skill, resolvedContent, { alias });
115
125
  // Write the skill file
116
126
  await writeFile(absoluteSkillPath, skillContent);
117
127
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kontexted",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "CLI tool for Kontexted - MCP proxy, workspaces management, and local server",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,8 +43,8 @@
43
43
  "typescript": "^5.6.0"
44
44
  },
45
45
  "optionalDependencies": {
46
- "@kontexted/darwin-arm64": "0.1.10",
47
- "@kontexted/linux-x64": "0.1.10",
48
- "@kontexted/windows-x64": "0.1.10"
46
+ "@kontexted/darwin-arm64": "0.1.12",
47
+ "@kontexted/linux-x64": "0.1.12",
48
+ "@kontexted/windows-x64": "0.1.12"
49
49
  }
50
50
  }