knodin 0.8.7 → 0.9.0

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 (44) hide show
  1. package/dist/bin/cli.js +307 -85
  2. package/dist/fixtures/update-verification/config/application.xml +4 -0
  3. package/dist/fixtures/update-verification/dbt/manifest.json +17 -0
  4. package/dist/fixtures/update-verification/dbt/models/accounts.sql +1 -0
  5. package/dist/fixtures/update-verification/dbt/models/contacts.sql +1 -0
  6. package/dist/fixtures/update-verification/fixture.json +147 -0
  7. package/dist/fixtures/update-verification/force-app/main/default/classes/UpdateFixture.cls +14 -0
  8. package/dist/fixtures/update-verification/force-app/main/default/flows/Update_Verification.flow-meta.xml +9 -0
  9. package/dist/fixtures/update-verification/package.json +5 -0
  10. package/dist/fixtures/update-verification/prisma/schema.prisma +10 -0
  11. package/dist/fixtures/update-verification/sql/functions.sql +16 -0
  12. package/dist/fixtures/update-verification/src/CsharpFixture.cs +6 -0
  13. package/dist/fixtures/update-verification/src/JavaFixture.java +9 -0
  14. package/dist/fixtures/update-verification/src/javascript.js +7 -0
  15. package/dist/fixtures/update-verification/src/python_fixture.py +6 -0
  16. package/dist/fixtures/update-verification/src/typescript.ts +7 -0
  17. package/dist/fixtures/update-verification/terraform/main.tf +7 -0
  18. package/dist/fixtures/update-verification/terraform/modules/verified-child/main.tf +3 -0
  19. package/dist/src/agent-integration.js +26 -3
  20. package/dist/src/backup-retention.js +811 -0
  21. package/dist/src/cli-model.js +35 -8
  22. package/dist/src/docs-sections.js +1 -0
  23. package/dist/src/doctor.js +142 -12
  24. package/dist/src/engine/embeddings.js +8 -1
  25. package/dist/src/engine/index.js +355 -292
  26. package/dist/src/init.js +222 -179
  27. package/dist/src/manager-update.js +455 -0
  28. package/dist/src/release-preflight.js +106 -95
  29. package/dist/src/repair-lease.js +77 -8
  30. package/dist/src/response-budget.js +5 -1
  31. package/dist/src/server.js +18 -5
  32. package/dist/src/shared-index/compatibility.js +4 -2
  33. package/dist/src/tools/knodin-tools.js +69 -10
  34. package/dist/src/update-ceremony.js +20 -24
  35. package/dist/src/update-coordination.js +158 -0
  36. package/dist/src/update-executor.js +336 -0
  37. package/dist/src/update-verifier.js +358 -0
  38. package/docs/BACKUP-RETENTION.md +54 -0
  39. package/docs/CLI.md +6 -0
  40. package/docs/DOCTOR-AND-UPDATES.md +44 -12
  41. package/docs/SIGNED-UPDATES.md +29 -22
  42. package/docs/releases/0.9.0.md +43 -0
  43. package/package.json +7 -1
  44. package/roadmap/competitive-roadmap.md +8 -0
@@ -0,0 +1,147 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "fixtureVersion": "2026-08-14.2",
4
+ "languages": [
5
+ "typescript",
6
+ "javascript",
7
+ "python",
8
+ "java",
9
+ "csharp",
10
+ "apex",
11
+ "sql",
12
+ "prisma",
13
+ "xml",
14
+ "salesforce",
15
+ "terraform",
16
+ "dbt"
17
+ ],
18
+ "assertions": [
19
+ {
20
+ "pattern": "callers_of",
21
+ "symbol": "typescriptTarget",
22
+ "coverage": ["typescript"],
23
+ "expected": {
24
+ "symbol": "typescriptCaller",
25
+ "file": "src/typescript.ts",
26
+ "line": 6,
27
+ "kind": "call"
28
+ }
29
+ },
30
+ {
31
+ "pattern": "callers_of",
32
+ "symbol": "javascriptTarget",
33
+ "coverage": ["javascript"],
34
+ "expected": {
35
+ "symbol": "javascriptCaller",
36
+ "file": "src/javascript.js",
37
+ "line": 6,
38
+ "kind": "call"
39
+ }
40
+ },
41
+ {
42
+ "pattern": "callers_of",
43
+ "symbol": "python_target",
44
+ "coverage": ["python"],
45
+ "expected": {
46
+ "symbol": "python_caller",
47
+ "file": "src/python_fixture.py",
48
+ "line": 6,
49
+ "kind": "call"
50
+ }
51
+ },
52
+ {
53
+ "pattern": "callers_of",
54
+ "symbol": "javaTarget",
55
+ "coverage": ["java"],
56
+ "expected": {
57
+ "symbol": "javaCaller",
58
+ "file": "src/JavaFixture.java",
59
+ "line": 7,
60
+ "kind": "call"
61
+ }
62
+ },
63
+ {
64
+ "pattern": "callers_of",
65
+ "symbol": "CsharpTarget",
66
+ "coverage": ["csharp"],
67
+ "expected": {
68
+ "symbol": "CsharpCaller",
69
+ "file": "src/CsharpFixture.cs",
70
+ "line": 5,
71
+ "kind": "call"
72
+ }
73
+ },
74
+ {
75
+ "pattern": "callers_of",
76
+ "symbol": "apexTarget",
77
+ "coverage": ["apex"],
78
+ "expected": {
79
+ "symbol": "apexCaller",
80
+ "file": "force-app/main/default/classes/UpdateFixture.cls",
81
+ "line": 7,
82
+ "kind": "call"
83
+ }
84
+ },
85
+ {
86
+ "pattern": "file_summary",
87
+ "symbol": "sql/functions.sql",
88
+ "coverage": ["sql"],
89
+ "expected": {
90
+ "symbol": "verified_wrapper",
91
+ "file": "sql/functions.sql",
92
+ "line": 6,
93
+ "kind": "procedure",
94
+ "evidenceQuality": "parser-grounded"
95
+ }
96
+ },
97
+ {
98
+ "pattern": "file_summary",
99
+ "symbol": "prisma/schema.prisma",
100
+ "coverage": ["prisma"],
101
+ "expected": {
102
+ "symbol": "Contact",
103
+ "file": "prisma/schema.prisma",
104
+ "kind": "model",
105
+ "evidenceQuality": "parser-grounded"
106
+ }
107
+ },
108
+ {
109
+ "pattern": "file_summary",
110
+ "symbol": "force-app/main/default/flows/Update_Verification.flow-meta.xml",
111
+ "coverage": ["xml"],
112
+ "expected": {
113
+ "symbol": "Update_Verification",
114
+ "file": "force-app/main/default/flows/Update_Verification.flow-meta.xml",
115
+ "kind": "salesforce-metadata",
116
+ "evidenceQuality": "parser-grounded"
117
+ }
118
+ },
119
+ {
120
+ "pattern": "imports_of",
121
+ "symbol": "force-app/main/default/flows/Update_Verification.flow-meta.xml",
122
+ "coverage": ["salesforce"],
123
+ "expected": {
124
+ "file": "force-app/main/default/classes/UpdateFixture.cls",
125
+ "kind": "flow_apex_action"
126
+ }
127
+ },
128
+ {
129
+ "pattern": "file_summary",
130
+ "symbol": "terraform/main.tf",
131
+ "coverage": ["terraform"],
132
+ "expected": {
133
+ "symbol": "verified_child",
134
+ "file": "terraform/main.tf",
135
+ "line": 1,
136
+ "kind": "Module",
137
+ "evidenceQuality": "source-derived"
138
+ }
139
+ },
140
+ {
141
+ "pattern": "imports_of",
142
+ "symbol": ".knodin/dbt/model.fixture.contacts.sql",
143
+ "coverage": ["dbt"],
144
+ "expected": { "file": ".knodin/dbt/model.fixture.accounts.sql", "kind": "dbt-lineage" }
145
+ }
146
+ ]
147
+ }
@@ -0,0 +1,14 @@
1
+ public class UpdateFixture {
2
+ public static String apexTarget(String value) {
3
+ return value.toUpperCase();
4
+ }
5
+
6
+ public static String apexCaller() {
7
+ return apexTarget('verified');
8
+ }
9
+
10
+ @InvocableMethod
11
+ public static List<String> verifiedAction(List<String> values) {
12
+ return values;
13
+ }
14
+ }
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Flow xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <actionCalls>
4
+ <name>Call_Update_Fixture</name>
5
+ <actionName>UpdateFixture.verifiedAction</actionName>
6
+ <actionType>apex</actionType>
7
+ </actionCalls>
8
+ <status>Active</status>
9
+ </Flow>
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "knodin-update-verification-fixture",
3
+ "private": true,
4
+ "type": "module"
5
+ }
@@ -0,0 +1,10 @@
1
+ model Account {
2
+ id Int @id
3
+ contacts Contact[]
4
+ }
5
+
6
+ model Contact {
7
+ id Int @id
8
+ accountId Int
9
+ account Account @relation(fields: [accountId], references: [id])
10
+ }
@@ -0,0 +1,16 @@
1
+ CREATE OR REPLACE FUNCTION verified_message(input_text text)
2
+ RETURNS text
3
+ LANGUAGE plpgsql
4
+ AS $verified_body$
5
+ BEGIN
6
+ RETURN upper(input_text || '$not_a_delimiter$');
7
+ END;
8
+ $verified_body$;
9
+
10
+ CREATE OR REPLACE PROCEDURE verified_wrapper()
11
+ LANGUAGE plpgsql
12
+ AS $wrapper$
13
+ BEGIN
14
+ PERFORM verified_message('ready');
15
+ END;
16
+ $wrapper$;
@@ -0,0 +1,6 @@
1
+ public static class CsharpFixture
2
+ {
3
+ public static string CsharpTarget(string value) => value.ToUpperInvariant();
4
+
5
+ public static string CsharpCaller() => CsharpTarget("verified");
6
+ }
@@ -0,0 +1,9 @@
1
+ public final class JavaFixture {
2
+ public static String javaTarget(String value) {
3
+ return value.toUpperCase();
4
+ }
5
+
6
+ public static String javaCaller() {
7
+ return javaTarget("verified");
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ export function javascriptTarget(value) {
2
+ return value + 1;
3
+ }
4
+
5
+ export function javascriptCaller() {
6
+ return javascriptTarget(41);
7
+ }
@@ -0,0 +1,6 @@
1
+ def python_target(value: str) -> str:
2
+ return value.upper()
3
+
4
+
5
+ def python_caller() -> str:
6
+ return python_target("verified")
@@ -0,0 +1,7 @@
1
+ export function typescriptTarget(value: string): string {
2
+ return value.toUpperCase();
3
+ }
4
+
5
+ export function typescriptCaller(): string {
6
+ return typescriptTarget("verified");
7
+ }
@@ -0,0 +1,7 @@
1
+ module "verified_child" {
2
+ source = "./modules/verified-child"
3
+ }
4
+
5
+ output "verified_value" {
6
+ value = module.verified_child.value
7
+ }
@@ -0,0 +1,3 @@
1
+ output "value" {
2
+ value = "verified"
3
+ }
@@ -160,12 +160,29 @@ function removeEmptyParent(filePath) {
160
160
  throw error;
161
161
  }
162
162
  }
163
+ function compatibleMcpRegistration(value) {
164
+ if (typeof value !== "object" || value === null || Array.isArray(value))
165
+ return false;
166
+ const registration = value;
167
+ return ((registration.type === undefined || registration.type === "stdio") &&
168
+ registration.command === "knodin" &&
169
+ Array.isArray(registration.args) &&
170
+ registration.args.length === 1 &&
171
+ registration.args[0] === "serve");
172
+ }
163
173
  function updateJsonMcp(filePath, remove) {
164
174
  const document = readJsonObject(filePath);
165
175
  const existing = document.mcpServers;
166
- const servers = typeof existing === "object" && existing !== null && !Array.isArray(existing)
167
- ? { ...existing }
168
- : {};
176
+ const existingServers = typeof existing === "object" && existing !== null && !Array.isArray(existing)
177
+ ? existing
178
+ : undefined;
179
+ // Do nothing when the existing Knodin entry is compatible. Preserve
180
+ // whitespace, foreign entries, and type: stdio.
181
+ if (!remove && compatibleMcpRegistration(existingServers?.[MCP_NAME]))
182
+ return true;
183
+ if (remove && existingServers?.[MCP_NAME] === undefined)
184
+ return fs.existsSync(filePath);
185
+ const servers = existingServers ? { ...existingServers } : {};
169
186
  if (remove)
170
187
  delete servers[MCP_NAME];
171
188
  else
@@ -191,6 +208,12 @@ function updateVsCodeMcp(filePath, remove) {
191
208
  const servers = typeof existing === "object" && existing !== null && !Array.isArray(existing)
192
209
  ? { ...existing }
193
210
  : {};
211
+ // Do nothing when the existing Knodin entry is compatible. Preserve
212
+ // whitespace, foreign entries, and type: stdio.
213
+ if (!remove && compatibleMcpRegistration(servers[MCP_NAME]))
214
+ return true;
215
+ if (remove && servers[MCP_NAME] === undefined)
216
+ return fs.existsSync(filePath);
194
217
  if (remove)
195
218
  delete servers[MCP_NAME];
196
219
  else