@kontextmind/kxm 0.7.86 → 0.7.88

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.
Files changed (35) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/docs/configuration.md +2 -0
  3. package/package.json +1 -1
  4. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  5. package/plugins/kxm/dist/cli.js +897 -500
  6. package/plugins/kxm/dist/core.js +2 -2
  7. package/plugins/kxm/dist/extension.js +72 -63
  8. package/plugins/kxm/dist/mcp-server.js +3 -3
  9. package/plugins/kxm/dist/runtime.js +44 -26
  10. package/plugins/kxm/dist/server.js +56 -31
  11. package/plugins/kxm/package.json +1 -1
  12. package/plugins/kxm/src/cli/context-skills.ts +51 -6
  13. package/plugins/kxm/src/cli/hub.ts +39 -14
  14. package/plugins/kxm/src/cli/project.ts +78 -23
  15. package/plugins/kxm/src/cli/roles.ts +48 -4
  16. package/plugins/kxm/src/cli/system.ts +18 -1
  17. package/plugins/kxm/src/cli/tasks.ts +34 -5
  18. package/plugins/kxm/src/cli/types.ts +30 -0
  19. package/plugins/kxm/src/cli/workflows.ts +20 -4
  20. package/plugins/kxm/src/cli.ts +57 -0
  21. package/plugins/kxm/src/commands.ts +2 -2
  22. package/plugins/kxm/src/config.ts +4 -3
  23. package/plugins/kxm/src/context/providers.ts +4 -0
  24. package/plugins/kxm/src/database.ts +72 -33
  25. package/plugins/kxm/src/hub.ts +26 -8
  26. package/plugins/kxm/src/local-snapshot.ts +4 -4
  27. package/plugins/kxm/src/mcp-server.ts +1 -1
  28. package/plugins/kxm/src/memory.ts +10 -7
  29. package/plugins/kxm/src/role.ts +18 -6
  30. package/plugins/kxm/src/session-work.ts +4 -1
  31. package/plugins/kxm/src/skills.ts +29 -15
  32. package/plugins/kxm/src/sqlite.ts +18 -0
  33. package/plugins/kxm/src/state.ts +4 -1
  34. package/plugins/kxm/src/task-manager.ts +20 -13
  35. package/plugins/kxm/src/workflow-manager.ts +12 -4
@@ -184,6 +184,9 @@ export class NativeStateProvider implements StateProvider {
184
184
  if (change?.schema !== "kxm.state-change-proposal.v1") {
185
185
  throw new ProtocolError(400, "invalid state change proposal schema", "invalid_state_proposal");
186
186
  }
187
+ if (change.origin !== "peer" && change.origin !== "human") {
188
+ throw new ProtocolError(400, "state change proposal origin must be peer or human", "invalid_state_proposal");
189
+ }
187
190
  const project = requireNonEmpty(change.project, "proposal project");
188
191
  const key = requireNonEmpty(change.key, "proposal key");
189
192
  const evidenceRefs = boundedRefs(change.evidenceRefs, "proposal evidenceRefs");
@@ -193,7 +196,7 @@ export class NativeStateProvider implements StateProvider {
193
196
  project,
194
197
  summary: change.summary,
195
198
  provenance: {
196
- sourceType: change.proposedBy.startsWith("agent_") ? "peer" : "human",
199
+ sourceType: change.origin,
197
200
  sourceRef: `proposed-by:${change.proposedBy}`,
198
201
  },
199
202
  authority: change.authority,
@@ -58,6 +58,14 @@ function tasksDirectory(repoRoot: string): string {
58
58
  return resolve(repoRoot, ".kxm", "tasks");
59
59
  }
60
60
 
61
+ export function goalFilePath(repoRoot: string, goalId: string): string {
62
+ return join(goalsDirectory(repoRoot), `${goalId}.yaml`);
63
+ }
64
+
65
+ export function taskFilePath(repoRoot: string, taskId: string): string {
66
+ return join(tasksDirectory(repoRoot), `${taskId}.yaml`);
67
+ }
68
+
61
69
  export function createGoal(
62
70
  repoRoot: string,
63
71
  input: {
@@ -66,9 +74,8 @@ export function createGoal(
66
74
  successMetrics?: string[] | undefined;
67
75
  targetDate?: string | undefined;
68
76
  },
77
+ options: { dryRun?: boolean | undefined } = {},
69
78
  ): GoalRecord {
70
- const dir = goalsDirectory(repoRoot);
71
- mkdirSync(dir, { recursive: true });
72
79
 
73
80
  const id = `goal_${randomUUID().replaceAll("-", "").slice(0, 12)}`;
74
81
  const now = new Date().toISOString();
@@ -84,8 +91,9 @@ export function createGoal(
84
91
  updatedAt: now,
85
92
  };
86
93
 
87
- const filePath = join(dir, `${id}.yaml`);
88
- writeFileSync(filePath, stringify(record).trim() + "\n", "utf8");
94
+ if (options.dryRun) return record;
95
+ mkdirSync(goalsDirectory(repoRoot), { recursive: true });
96
+ writeFileSync(goalFilePath(repoRoot, id), stringify(record).trim() + "\n", "utf8");
89
97
  return record;
90
98
  }
91
99
 
@@ -123,9 +131,8 @@ export function createTask(
123
131
  issueKey: string;
124
132
  } | undefined;
125
133
  },
134
+ options: { dryRun?: boolean | undefined } = {},
126
135
  ): TaskRecord {
127
- const dir = tasksDirectory(repoRoot);
128
- mkdirSync(dir, { recursive: true });
129
136
 
130
137
  const id = `task_${randomUUID().replaceAll("-", "").slice(0, 12)}`;
131
138
  const now = new Date().toISOString();
@@ -151,8 +158,9 @@ export function createTask(
151
158
  updatedAt: now,
152
159
  };
153
160
 
154
- const filePath = join(dir, `${id}.yaml`);
155
- writeFileSync(filePath, stringify(record).trim() + "\n", "utf8");
161
+ if (options.dryRun) return record;
162
+ mkdirSync(tasksDirectory(repoRoot), { recursive: true });
163
+ writeFileSync(taskFilePath(repoRoot, id), stringify(record).trim() + "\n", "utf8");
156
164
  return record;
157
165
  }
158
166
 
@@ -201,7 +209,7 @@ export function updateTaskStatus(
201
209
  repoRoot: string,
202
210
  taskId: string,
203
211
  status: TaskStatus,
204
- options: { workflowRunId?: string } = {},
212
+ options: { workflowRunId?: string; dryRun?: boolean | undefined } = {},
205
213
  ): TaskRecord {
206
214
  const task = getTask(repoRoot, taskId);
207
215
  if (!task) {
@@ -212,8 +220,7 @@ export function updateTaskStatus(
212
220
  if (options.workflowRunId) task.workflowRunId = options.workflowRunId;
213
221
  task.updatedAt = new Date().toISOString();
214
222
 
215
- const filePath = join(tasksDirectory(repoRoot), `${taskId}.yaml`);
216
- writeFileSync(filePath, stringify(task).trim() + "\n", "utf8");
223
+ if (!options.dryRun) writeFileSync(taskFilePath(repoRoot, taskId), stringify(task).trim() + "\n", "utf8");
217
224
  return task;
218
225
  }
219
226
 
@@ -223,6 +230,7 @@ export function syncTaskWithTracker(
223
230
  options: {
224
231
  mockRemoteState?: string;
225
232
  commentReceipt?: string;
233
+ dryRun?: boolean | undefined;
226
234
  } = {},
227
235
  ): TaskRecord {
228
236
  const task = getTask(repoRoot, taskId);
@@ -238,7 +246,6 @@ export function syncTaskWithTracker(
238
246
  task.trackerSync.lastSyncedAt = now;
239
247
  task.updatedAt = now;
240
248
 
241
- const filePath = join(tasksDirectory(repoRoot), `${taskId}.yaml`);
242
- writeFileSync(filePath, stringify(task).trim() + "\n", "utf8");
249
+ if (!options.dryRun) writeFileSync(taskFilePath(repoRoot, taskId), stringify(task).trim() + "\n", "utf8");
243
250
  return task;
244
251
  }
@@ -326,11 +326,14 @@ export function addWorkflowDefinition(
326
326
  repoRoot?: string | undefined;
327
327
  userConfigDir?: string | undefined;
328
328
  overwrite?: boolean | undefined;
329
+ dryRun?: boolean | undefined;
329
330
  } = {},
330
331
  ): { id: string; filePath: string; scope: "global" | "local" } {
331
332
  const scope = options.scope ?? "local";
332
333
  const repoRoot = options.repoRoot ?? process.cwd();
333
- const dir = ensureWorkflowsDirectory(scope, repoRoot, options.userConfigDir);
334
+ const dir = options.dryRun
335
+ ? workflowsDirectory(scope, repoRoot, options.userConfigDir)
336
+ : ensureWorkflowsDirectory(scope, repoRoot, options.userConfigDir);
334
337
  const filePath = join(dir, `${workflowId}.yaml`);
335
338
 
336
339
  if (existsSync(filePath) && !options.overwrite) {
@@ -338,7 +341,7 @@ export function addWorkflowDefinition(
338
341
  }
339
342
 
340
343
  const payload = typeof content === "string" ? content : stringify(content);
341
- writeFileSync(filePath, payload, "utf8");
344
+ if (!options.dryRun) writeFileSync(filePath, payload, "utf8");
342
345
  return { id: workflowId, filePath, scope };
343
346
  }
344
347
 
@@ -348,6 +351,7 @@ export function removeWorkflowDefinition(
348
351
  scope?: "global" | "local" | undefined;
349
352
  repoRoot?: string | undefined;
350
353
  userConfigDir?: string | undefined;
354
+ dryRun?: boolean | undefined;
351
355
  } = {},
352
356
  ): { id: string; removed: boolean; filePath: string; scope: "global" | "local" } {
353
357
  const scope = options.scope ?? "local";
@@ -359,6 +363,7 @@ export function removeWorkflowDefinition(
359
363
  throw new Error(`workflow_not_found: workflow '${workflowId}' not found in ${scope} directory (${filePath})`);
360
364
  }
361
365
 
366
+ if (options.dryRun) return { id: workflowId, removed: false, filePath, scope };
362
367
  rmSync(filePath);
363
368
  return { id: workflowId, removed: true, filePath, scope };
364
369
  }
@@ -370,6 +375,7 @@ export function modifyWorkflowDefinition(
370
375
  scope?: "global" | "local" | undefined;
371
376
  repoRoot?: string | undefined;
372
377
  userConfigDir?: string | undefined;
378
+ dryRun?: boolean | undefined;
373
379
  } = {},
374
380
  ): { id: string; workflow: Record<string, unknown>; filePath: string; scope: "global" | "local" } {
375
381
  const target = getWorkflowDefinition(workflowId, { scope: options.scope, repoRoot: options.repoRoot, userConfigDir: options.userConfigDir });
@@ -384,9 +390,11 @@ export function modifyWorkflowDefinition(
384
390
 
385
391
  const scope = options.scope ?? target.scope;
386
392
  const repoRoot = options.repoRoot ?? process.cwd();
387
- const dir = ensureWorkflowsDirectory(scope, repoRoot, options.userConfigDir);
393
+ const dir = options.dryRun
394
+ ? workflowsDirectory(scope, repoRoot, options.userConfigDir)
395
+ : ensureWorkflowsDirectory(scope, repoRoot, options.userConfigDir);
388
396
  const filePath = join(dir, `${workflowId}.yaml`);
389
397
 
390
- writeFileSync(filePath, stringify(updated), "utf8");
398
+ if (!options.dryRun) writeFileSync(filePath, stringify(updated), "utf8");
391
399
  return { id: workflowId, workflow: updated, filePath, scope };
392
400
  }