@kontextmind/kxm 0.6.0 → 0.7.4

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 (136) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/agents/coordinator.yaml +9 -0
  3. package/.kxm/agents/critic-arch.yaml +13 -0
  4. package/.kxm/agents/critic-cli.yaml +13 -0
  5. package/.kxm/agents/implementer.yaml +13 -0
  6. package/.kxm/gates.yaml +8 -0
  7. package/.kxm/producers.yaml +22 -0
  8. package/.kxm/project.yaml +15 -0
  9. package/.kxm/roles/writer.yaml +7 -0
  10. package/.kxm/workflows/default.yaml +47 -0
  11. package/CHANGELOG.md +39 -7
  12. package/README.md +1 -0
  13. package/docs/README.md +4 -0
  14. package/docs/agent-skills.md +121 -0
  15. package/docs/architecture.md +1 -1
  16. package/docs/assignment-runner.md +21 -8
  17. package/docs/configuration.md +11 -2
  18. package/docs/getting-started.md +21 -0
  19. package/docs/kxm-handbook.md +3 -3
  20. package/docs/operations.md +24 -0
  21. package/docs/operator-pi-packages.md +63 -0
  22. package/docs/skills/repo-work-delivery.md +107 -0
  23. package/docs/skills.md +2 -0
  24. package/docs/test-matrix.md +4 -3
  25. package/docs/troubleshooting.md +41 -1
  26. package/docs/vnext/validation.md +9 -0
  27. package/docs/webhook-workflows.md +2 -2
  28. package/examples/README.md +1 -1
  29. package/package.json +16 -17
  30. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  31. package/plugins/kxm/README.md +1 -1
  32. package/plugins/kxm/dist/cli.js +8955 -3934
  33. package/plugins/kxm/dist/core.js +271 -34
  34. package/plugins/kxm/dist/extension.js +7759 -86
  35. package/plugins/kxm/dist/mcp-server.js +75 -21
  36. package/plugins/kxm/dist/runtime.js +5637 -1125
  37. package/plugins/kxm/dist/server.js +3125 -2260
  38. package/plugins/kxm/dist/vnext-runtime-supervisor.js +5808 -565
  39. package/plugins/kxm/package.json +1 -1
  40. package/plugins/kxm/skills/SUITE.md +5 -0
  41. package/plugins/kxm/skills/hints.json +73 -0
  42. package/plugins/kxm/skills/kxm/SKILL.md +30 -83
  43. package/plugins/kxm/skills/kxm-context-memory/SKILL.md +69 -0
  44. package/plugins/kxm/skills/kxm-definitions/SKILL.md +65 -0
  45. package/plugins/kxm/skills/kxm-harness-auth/SKILL.md +34 -0
  46. package/plugins/kxm/skills/kxm-harvest/SKILL.md +48 -0
  47. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +43 -0
  48. package/plugins/kxm/skills/kxm-insights/SKILL.md +48 -0
  49. package/plugins/kxm/skills/kxm-mind/SKILL.md +59 -0
  50. package/plugins/kxm/skills/kxm-peer/SKILL.md +110 -0
  51. package/plugins/kxm/skills/kxm-project-setup/SKILL.md +42 -0
  52. package/plugins/kxm/skills/kxm-projects/SKILL.md +43 -0
  53. package/plugins/kxm/skills/kxm-protocol/SKILL.md +66 -0
  54. package/plugins/kxm/skills/kxm-query/SKILL.md +45 -0
  55. package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +30 -0
  56. package/plugins/kxm/skills/kxm-runs/SKILL.md +29 -0
  57. package/plugins/kxm/skills/kxm-setup/SKILL.md +55 -0
  58. package/plugins/kxm/skills/kxm-skill-lifecycle/SKILL.md +31 -0
  59. package/plugins/kxm/skills/kxm-tasks/SKILL.md +33 -0
  60. package/plugins/kxm/skills/kxm-triage/SKILL.md +47 -0
  61. package/plugins/kxm/skills/kxm-work/SKILL.md +44 -0
  62. package/plugins/kxm/skills/kxm-workflow/SKILL.md +45 -0
  63. package/plugins/kxm/src/autocomplete.ts +9 -3
  64. package/plugins/kxm/src/cli.ts +1637 -73
  65. package/plugins/kxm/src/commands.ts +150 -8
  66. package/plugins/kxm/src/completion-install.ts +223 -0
  67. package/plugins/kxm/src/config.ts +7 -4
  68. package/plugins/kxm/src/context-packet.ts +172 -0
  69. package/plugins/kxm/src/database.ts +1 -1
  70. package/plugins/kxm/src/extension.ts +36 -1
  71. package/plugins/kxm/src/external-effects.ts +357 -8
  72. package/plugins/kxm/src/hub-env.ts +193 -0
  73. package/plugins/kxm/src/hub.ts +2 -4
  74. package/plugins/kxm/src/improve.ts +72 -0
  75. package/plugins/kxm/src/init-guide-setup.ts +547 -0
  76. package/plugins/kxm/src/local-snapshot.ts +1 -1
  77. package/plugins/kxm/src/mcp-server.ts +1 -1
  78. package/plugins/kxm/src/model-inventory.ts +127 -0
  79. package/plugins/kxm/src/policy-draft.d.mts +55 -0
  80. package/plugins/kxm/src/policy-draft.mjs +565 -0
  81. package/plugins/kxm/src/price-calc.ts +17 -18
  82. package/plugins/kxm/src/prices.ts +32 -16
  83. package/plugins/kxm/src/producers.ts +71 -0
  84. package/plugins/kxm/src/protocol.ts +111 -0
  85. package/plugins/kxm/src/restricted-yaml.d.mts +31 -0
  86. package/plugins/kxm/src/restricted-yaml.mjs +145 -0
  87. package/plugins/kxm/src/role.ts +710 -0
  88. package/plugins/kxm/src/routing.ts +99 -1
  89. package/plugins/kxm/src/safety-integrity.ts +76 -0
  90. package/plugins/kxm/src/session-work.ts +9 -2
  91. package/plugins/kxm/src/sqlite.ts +76 -0
  92. package/plugins/kxm/src/store.ts +1 -1
  93. package/plugins/kxm/src/studio-layout.ts +660 -17
  94. package/plugins/kxm/src/suggest.ts +7 -13
  95. package/plugins/kxm/src/telemetry.ts +82 -0
  96. package/plugins/kxm/src/tui.ts +140 -0
  97. package/plugins/kxm/src/vnext-bindings.ts +1 -1
  98. package/plugins/kxm/src/vnext-config.ts +53 -111
  99. package/plugins/kxm/src/vnext-engine-command.ts +2 -0
  100. package/plugins/kxm/src/vnext-engine.ts +214 -62
  101. package/plugins/kxm/src/vnext-harness.ts +267 -83
  102. package/plugins/kxm/src/vnext-oneshot-evidence.ts +85 -0
  103. package/plugins/kxm/src/vnext-oneshot-process.ts +166 -0
  104. package/plugins/kxm/src/vnext-oneshot-producer.ts +179 -224
  105. package/plugins/kxm/src/vnext-runtime-store.ts +36 -2
  106. package/plugins/kxm/src/vnext-runtime-supervisor.ts +120 -5
  107. package/plugins/kxm/src/vnext-runtime.ts +14 -0
  108. package/plugins/kxm/src/workflow-manager.ts +392 -0
  109. package/plugins/kxm/src/workflow-tui.ts +255 -0
  110. package/plugins/kxm/src/workflow.ts +144 -0
  111. package/schemas/policy-draft/README.md +17 -0
  112. package/schemas/policy-draft/model.v2.schema.json +140 -0
  113. package/schemas/policy-draft/role.v2.schema.json +91 -0
  114. package/schemas/vnext/role.schema.json +76 -0
  115. package/schemas/vnext/run-event.schema.json +1 -0
  116. package/scripts/assignment-run.d.mts +1 -1
  117. package/scripts/assignment-run.mjs +44 -35
  118. package/scripts/check-generated.mjs +33 -9
  119. package/scripts/emit-codex-artifacts.mjs +255 -11
  120. package/scripts/harness-run.d.mts +12 -4
  121. package/scripts/harness-run.mjs +65 -17
  122. package/scripts/kxm-bump-version.mjs +146 -0
  123. package/scripts/kxm-hub.mjs +150 -2
  124. package/scripts/kxm-publish-npm.mjs +3 -1
  125. package/scripts/kxm-release-github.mjs +3 -1
  126. package/scripts/kxm.mjs +0 -0
  127. package/scripts/native-critic.d.mts +5 -0
  128. package/scripts/native-critic.mjs +60 -0
  129. package/.kxm/config/README.md +0 -5
  130. package/.kxm/config/agents.json +0 -43
  131. package/.kxm/config/env.example +0 -56
  132. package/.kxm/config/update.example.yaml +0 -9
  133. package/.kxm/config/workflows/fix.json +0 -160
  134. package/.kxm/config/workflows/jira-development.json +0 -116
  135. package/.kxm/config/workflows/provenance-quorum.json +0 -150
  136. package/.kxm/config/workflows/v04-dogfood.json +0 -72
@@ -0,0 +1,127 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { spawnSync } from "node:child_process";
3
+ import { join } from "node:path";
4
+ import { stringify } from "yaml";
5
+
6
+ export interface InventoryPrice {
7
+ inputPerMillion: number | null;
8
+ outputPerMillion: number | null;
9
+ cacheReadPerMillion: number | null;
10
+ cacheWritePerMillion: number | null;
11
+ }
12
+
13
+ export interface InventoryCapabilities {
14
+ thinking: { supported: boolean | null; levels?: string[]; default?: string; source: string };
15
+ speed: { fast: boolean | null; tiers?: string[]; source: string };
16
+ }
17
+
18
+ export interface InventoryModel {
19
+ id: string;
20
+ name?: string;
21
+ contextLength?: number;
22
+ capabilities: InventoryCapabilities;
23
+ standard?: InventoryPrice;
24
+ discount?: InventoryPrice;
25
+ sources: string[];
26
+ }
27
+
28
+ export interface ModelInventory {
29
+ schema: "kxm.model-inventory.v1";
30
+ fetchedAt: string;
31
+ currency: "USD";
32
+ sources: Record<string, { url: string; ok: boolean; error?: string }>;
33
+ models: InventoryModel[];
34
+ }
35
+
36
+ const OR_URL = "https://openrouter.ai/api/v1/models";
37
+ const NOUS_URL = "https://inference-api.nousresearch.com/v1/models";
38
+
39
+ function price(value: unknown): number | null {
40
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) return value * 1_000_000;
41
+ if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value)) && Number(value) >= 0) return Number(value) * 1_000_000;
42
+ return null;
43
+ }
44
+ function rates(raw: any): InventoryPrice | undefined {
45
+ if (!raw || typeof raw !== "object") return undefined;
46
+ const input = price(raw.prompt ?? raw.input);
47
+ const output = price(raw.completion ?? raw.output);
48
+ if (input === null && output === null) return undefined;
49
+ return {
50
+ inputPerMillion: input,
51
+ outputPerMillion: output,
52
+ cacheReadPerMillion: price(raw.input_cache_read ?? raw.cache_read),
53
+ cacheWritePerMillion: price(raw.input_cache_write ?? raw.cache_write),
54
+ };
55
+ }
56
+ function modelId(id: string): string {
57
+ return id.trim().toLowerCase();
58
+ }
59
+ async function fetchModels(url: string, authorization?: string): Promise<{ data: any[]; error?: string }> {
60
+ try {
61
+ const headers: Record<string, string> = { Accept: "application/json" };
62
+ if (authorization) headers.Authorization = `Bearer ${authorization}`;
63
+ const response = await fetch(url, { headers, signal: AbortSignal.timeout(15_000) });
64
+ if (!response.ok) return { data: [], error: `HTTP ${response.status}` };
65
+ const payload = await response.json() as any;
66
+ if (Array.isArray(payload?.data)) return { data: payload.data };
67
+ return { data: [], error: "response has no data array" };
68
+ } catch (error) {
69
+ return { data: [], error: error instanceof Error ? error.message : "request failed" };
70
+ }
71
+ }
72
+
73
+ /** Refreshes a provenance-bearing model inventory. Aggregator prices are never treated as native auth evidence. */
74
+ export async function refreshModelInventory(options: { outputRoot: string; env?: NodeJS.ProcessEnv; now?: Date }): Promise<ModelInventory> {
75
+ const env = options.env ?? process.env;
76
+ const fetchedAt = (options.now ?? new Date()).toISOString();
77
+ const sources: ModelInventory["sources"] = {};
78
+ const byId = new Map<string, InventoryModel>();
79
+ const add = (item: any, source: string, kind: "standard" | "discount") => {
80
+ if (!item || typeof item.id !== "string" || !item.id.trim()) return;
81
+ const key = modelId(item.id);
82
+ const current: InventoryModel = byId.get(key) ?? { id: item.id, ...(typeof item.name === "string" ? { name: item.name } : {}), ...(typeof item.context_length === "number" ? { contextLength: item.context_length } : {}), capabilities: { thinking: { supported: null, source: "unknown" }, speed: { fast: null, source: "unknown" } }, sources: [] };
83
+ if (!current.sources.includes(source)) current.sources.push(source);
84
+ const parsed = rates(item.pricing);
85
+ if (parsed) {
86
+ if (kind === "standard") current.standard = parsed;
87
+ else current.discount = parsed;
88
+ }
89
+ if (!current.name && typeof item.name === "string") current.name = item.name;
90
+ if (!current.contextLength && typeof item.context_length === "number") current.contextLength = item.context_length;
91
+ const parameters = Array.isArray(item.supported_parameters) ? item.supported_parameters.filter((value: unknown): value is string => typeof value === "string") : [];
92
+ if (parameters.some((value: string) => /reasoning|thinking/i.test(value))) current.capabilities.thinking = { supported: true, source };
93
+ if (parameters.some((value: string) => /speed|service.?tier|fast/i.test(value))) current.capabilities.speed = { fast: true, tiers: ["fast"], source };
94
+ if (Array.isArray(item.thinkingLevels) && item.thinkingLevels.length > 0) current.capabilities.thinking = { supported: true, levels: item.thinkingLevels, ...(item.defaultThinking ? { default: item.defaultThinking } : {}), source };
95
+ if (item.fast === true) current.capabilities.speed = { fast: true, tiers: ["fast"], source };
96
+ byId.set(key, current);
97
+ };
98
+ const native = (command: string, args: string[], source: string) => {
99
+ const result = spawnSync(command, args, { encoding: "utf8", timeout: 20_000, shell: false });
100
+ const ok = result.status === 0;
101
+ sources[source] = { url: `${command} ${args.join(" ")}`, ok, ...(ok ? {} : { error: (result.stderr || "command failed").trim().slice(0, 240) }) };
102
+ if (!ok) return;
103
+ for (const line of (result.stdout || "").split(/\r?\n/)) {
104
+ const parts = line.trim().split(/\s+/);
105
+ const id = source === "pi" && parts.length >= 2 && parts[0] !== "provider" ? `${parts[0]}/${parts[1]}` : parts[0];
106
+ if (id && /^[a-z0-9][a-z0-9._/-]+$/i.test(id) && id !== "Available") {
107
+ const effortMatch = source === "agy" ? id.match(/-(low|medium|high)$/i) : null;
108
+ add({ id, ...(effortMatch?.[1] ? { thinkingLevels: [effortMatch[1].toLowerCase()] } : {}) }, source, "standard");
109
+ }
110
+ }
111
+ };
112
+ native("pi", ["--list-models"], "pi");
113
+ native("grok", ["models"], "grok");
114
+ native("agy", ["models"], "agy");
115
+ const openrouter = await fetchModels(env.KXM_OPENROUTER_MODELS_URL?.trim() || OR_URL, env.OPENROUTER_API_KEY);
116
+ const openrouterUrl = env.KXM_OPENROUTER_MODELS_URL?.trim() || OR_URL;
117
+ sources.openrouter = { url: openrouterUrl, ok: !openrouter.error, ...(openrouter.error ? { error: openrouter.error } : {}) };
118
+ for (const item of openrouter.data) add(item, "openrouter", "standard");
119
+ const nousUrl = env.KXM_NOUS_MODELS_URL?.trim() || NOUS_URL;
120
+ const nous = await fetchModels(nousUrl, env.NOUS_API_KEY);
121
+ sources.nous = { url: nousUrl, ok: !nous.error, ...(nous.error ? { error: nous.error } : {}) };
122
+ for (const item of nous.data) add(item, "nous", "discount");
123
+ const inventory: ModelInventory = { schema: "kxm.model-inventory.v1", fetchedAt, currency: "USD", sources, models: [...byId.values()].sort((a, b) => a.id.localeCompare(b.id)) };
124
+ mkdirSync(join(options.outputRoot, ".kxm", "models"), { recursive: true });
125
+ writeFileSync(join(options.outputRoot, ".kxm", "models", "inventory.yaml"), stringify(inventory), "utf8");
126
+ return inventory;
127
+ }
@@ -0,0 +1,55 @@
1
+ import type { JsonObject } from "./restricted-yaml.mjs";
2
+
3
+ export const POLICY_DRAFT_MODEL_SCHEMA: "kxm.model.v2";
4
+ export const POLICY_DRAFT_ROLE_SCHEMA: "kxm.role.v2";
5
+ export const POLICY_DRAFT_PURPOSES: readonly [
6
+ "writer",
7
+ "planner",
8
+ "reviewer-arch",
9
+ "reviewer-cli",
10
+ "experiment",
11
+ ];
12
+ export const POLICY_DRAFT_PERMISSIONS: readonly ["edit", "read-only"];
13
+ export const POLICY_DRAFT_STATUSES: readonly ["admitted", "candidate", "retired"];
14
+
15
+ export interface PolicyDraftIssue {
16
+ phase: "parse" | "schema" | "reference" | "semantic";
17
+ code: string;
18
+ file: string;
19
+ message: string;
20
+ }
21
+
22
+ export interface PolicyDraftCeiling {
23
+ readonly provider: string;
24
+ readonly roles?: readonly string[];
25
+ readonly permissions: readonly string[];
26
+ readonly models?: readonly string[];
27
+ readonly efforts?: readonly string[];
28
+ }
29
+
30
+ export interface PolicyDraftOptions {
31
+ readonly ceilings: Readonly<Record<string, PolicyDraftCeiling>>;
32
+ readonly nativePiBrakeProviders: readonly string[];
33
+ readonly piAllowedProviders: readonly string[];
34
+ readonly vendorAliases?: Readonly<Record<string, string>>;
35
+ }
36
+
37
+ export type PolicyDraftDocument = JsonObject | string | Uint8Array;
38
+
39
+ export interface PolicyDraftInput {
40
+ readonly models?: Readonly<Record<string, PolicyDraftDocument>> | readonly PolicyDraftDocument[];
41
+ readonly roles?: Readonly<Record<string, PolicyDraftDocument>> | readonly PolicyDraftDocument[];
42
+ readonly evidence?: Readonly<Record<string, string | Uint8Array>>;
43
+ }
44
+
45
+ export interface PolicyDraftData {
46
+ readonly models: Readonly<Record<string, JsonObject>>;
47
+ readonly roles: Readonly<Record<string, JsonObject>>;
48
+ }
49
+
50
+ export type PolicyDraftResult =
51
+ | { readonly ok: true; readonly data: PolicyDraftData }
52
+ | { readonly ok: false; readonly issues: readonly PolicyDraftIssue[] };
53
+
54
+ /** Pure draft validation. Not admission, not a trusted loader, and not file I/O. */
55
+ export function validatePolicyDraft(input: PolicyDraftInput, options: PolicyDraftOptions): PolicyDraftResult;