@intentius/chant-lexicon-k8s 0.0.18 → 0.0.22
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.
- package/dist/integrity.json +3 -3
- package/dist/manifest.json +1 -1
- package/dist/skills/chant-k8s.md +1 -1
- package/package.json +20 -2
- package/src/plugin.ts +92 -2
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "xxhash64",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "b91b5f6c197826b1",
|
|
5
5
|
"meta.json": "1ce194f36f9b5f90",
|
|
6
6
|
"types/index.d.ts": "beec4cc869064186",
|
|
7
7
|
"rules/missing-resource-limits.ts": "a6f776d2ff477948",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"rules/wk8105.ts": "8dbcfe399f23656a",
|
|
32
32
|
"rules/k8s-helpers.ts": "53a6d3bfbedb2852",
|
|
33
33
|
"rules/wk8207.ts": "6f2bc621d530afa2",
|
|
34
|
-
"skills/chant-k8s.md": "
|
|
34
|
+
"skills/chant-k8s.md": "177efa9794242096",
|
|
35
35
|
"skills/chant-k8s-patterns.md": "c5151ed799145c4b"
|
|
36
36
|
},
|
|
37
|
-
"composite": "
|
|
37
|
+
"composite": "c7b4bc8445140fdf"
|
|
38
38
|
}
|
package/dist/manifest.json
CHANGED
package/dist/skills/chant-k8s.md
CHANGED
|
@@ -8,7 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
## How chant and Kubernetes relate
|
|
10
10
|
|
|
11
|
-
chant is a **synthesis
|
|
11
|
+
chant is a **synthesis compiler** — it compiles TypeScript source files into Kubernetes YAML manifests. `chant build` does not call the Kubernetes API; synthesis is pure and deterministic. The optional `chant state snapshot` command queries the Kubernetes API to capture deployment metadata (pod names, status, UIDs) for observability. Your job as an agent is to bridge synthesis and deployment:
|
|
12
12
|
|
|
13
13
|
- Use **chant** for: build, lint, diff (local YAML comparison)
|
|
14
14
|
- Use **kubectl / k8s API** for: apply, rollback, monitoring, troubleshooting
|
package/package.json
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-k8s",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
|
+
"description": "Kubernetes lexicon for chant — declarative IaC in TypeScript",
|
|
4
5
|
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://intentius.io/chant",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/intentius/chant.git",
|
|
10
|
+
"directory": "lexicons/k8s"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/intentius/chant/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"infrastructure-as-code",
|
|
17
|
+
"iac",
|
|
18
|
+
"typescript",
|
|
19
|
+
"kubernetes",
|
|
20
|
+
"k8s",
|
|
21
|
+
"chant"
|
|
22
|
+
],
|
|
5
23
|
"type": "module",
|
|
6
24
|
"files": [
|
|
7
25
|
"src/",
|
|
@@ -25,7 +43,7 @@
|
|
|
25
43
|
"prepack": "bun run generate && bun run bundle && bun run validate"
|
|
26
44
|
},
|
|
27
45
|
"dependencies": {
|
|
28
|
-
"@intentius/chant": "0.0.
|
|
46
|
+
"@intentius/chant": "0.0.22"
|
|
29
47
|
},
|
|
30
48
|
"devDependencies": {
|
|
31
49
|
"typescript": "^5.9.3"
|
package/src/plugin.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { createRequire } from "module";
|
|
9
|
-
import type { LexiconPlugin, SkillDefinition, InitTemplateSet } from "@intentius/chant/lexicon";
|
|
9
|
+
import type { LexiconPlugin, SkillDefinition, InitTemplateSet, ResourceMetadata } from "@intentius/chant/lexicon";
|
|
10
10
|
const require = createRequire(import.meta.url);
|
|
11
11
|
import type { LintRule } from "@intentius/chant/lint/rule";
|
|
12
12
|
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
@@ -299,6 +299,96 @@ export const service = new Service({
|
|
|
299
299
|
console.error(`Packaged ${stats.resources} resources, ${stats.ruleCount} rules, ${stats.skillCount} skills`);
|
|
300
300
|
},
|
|
301
301
|
|
|
302
|
+
async describeResources(options: {
|
|
303
|
+
environment: string;
|
|
304
|
+
buildOutput: string;
|
|
305
|
+
entityNames: string[];
|
|
306
|
+
}): Promise<Record<string, ResourceMetadata>> {
|
|
307
|
+
const { getRuntime } = await import("@intentius/chant/runtime-adapter");
|
|
308
|
+
const rt = getRuntime();
|
|
309
|
+
const resources: Record<string, ResourceMetadata> = {};
|
|
310
|
+
|
|
311
|
+
// Resolve namespace from environment (convention: env name = namespace)
|
|
312
|
+
const namespace = options.environment;
|
|
313
|
+
|
|
314
|
+
// Parse build output to extract kind/name pairs for each entity
|
|
315
|
+
let manifests: Array<{ kind: string; metadata: { name: string; namespace?: string }; apiVersion: string }> = [];
|
|
316
|
+
try {
|
|
317
|
+
// K8s build output is YAML with --- separators
|
|
318
|
+
const docs = options.buildOutput.split(/^---$/m).filter((d) => d.trim());
|
|
319
|
+
for (const doc of docs) {
|
|
320
|
+
// Simple YAML parsing — look for kind: and metadata.name:
|
|
321
|
+
const kindMatch = doc.match(/^kind:\s*(.+)$/m);
|
|
322
|
+
const nameMatch = doc.match(/^\s+name:\s*(.+)$/m);
|
|
323
|
+
const apiVersionMatch = doc.match(/^apiVersion:\s*(.+)$/m);
|
|
324
|
+
if (kindMatch && nameMatch && apiVersionMatch) {
|
|
325
|
+
manifests.push({
|
|
326
|
+
kind: kindMatch[1].trim(),
|
|
327
|
+
metadata: { name: nameMatch[1].trim() },
|
|
328
|
+
apiVersion: apiVersionMatch[1].trim(),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
} catch {
|
|
333
|
+
// If build output parsing fails, skip
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Query each resource
|
|
337
|
+
for (const entityName of options.entityNames) {
|
|
338
|
+
// Find the corresponding manifest
|
|
339
|
+
const manifest = manifests.find((m) => {
|
|
340
|
+
// Try matching by entity name convention
|
|
341
|
+
return m.metadata.name === entityName ||
|
|
342
|
+
entityName.toLowerCase().includes(m.metadata.name.toLowerCase());
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
if (!manifest) continue;
|
|
346
|
+
|
|
347
|
+
// Build kubectl resource type from apiVersion + kind
|
|
348
|
+
const resourceType = manifest.kind.toLowerCase();
|
|
349
|
+
const getResult = await rt.spawn([
|
|
350
|
+
"kubectl", "get", resourceType, manifest.metadata.name,
|
|
351
|
+
"-n", namespace,
|
|
352
|
+
"-o", "json",
|
|
353
|
+
]);
|
|
354
|
+
|
|
355
|
+
if (getResult.exitCode !== 0) continue;
|
|
356
|
+
|
|
357
|
+
try {
|
|
358
|
+
const obj = JSON.parse(getResult.stdout) as {
|
|
359
|
+
metadata: { name: string; uid: string; creationTimestamp: string };
|
|
360
|
+
status?: { phase?: string; conditions?: Array<{ type: string; status: string }> };
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// Derive status from conditions or phase
|
|
364
|
+
let status = "Unknown";
|
|
365
|
+
if (obj.status?.phase) {
|
|
366
|
+
status = obj.status.phase;
|
|
367
|
+
} else if (obj.status?.conditions) {
|
|
368
|
+
const ready = obj.status.conditions.find((c) => c.type === "Ready" || c.type === "Available");
|
|
369
|
+
status = ready?.status === "True" ? "Ready" : "NotReady";
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Build attributes, scrubbing sensitive data
|
|
373
|
+
const attributes: Record<string, unknown> = {
|
|
374
|
+
uid: obj.metadata.uid,
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
resources[entityName] = {
|
|
378
|
+
type: `${manifest.apiVersion}/${manifest.kind}`,
|
|
379
|
+
physicalId: obj.metadata.name,
|
|
380
|
+
status,
|
|
381
|
+
lastUpdated: obj.metadata.creationTimestamp,
|
|
382
|
+
attributes,
|
|
383
|
+
};
|
|
384
|
+
} catch {
|
|
385
|
+
// Skip parse failures
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return resources;
|
|
390
|
+
},
|
|
391
|
+
|
|
302
392
|
mcpTools() {
|
|
303
393
|
return [
|
|
304
394
|
{
|
|
@@ -400,7 +490,7 @@ user-invocable: true
|
|
|
400
490
|
|
|
401
491
|
## How chant and Kubernetes relate
|
|
402
492
|
|
|
403
|
-
chant is a **synthesis
|
|
493
|
+
chant is a **synthesis compiler** — it compiles TypeScript source files into Kubernetes YAML manifests. \`chant build\` does not call the Kubernetes API; synthesis is pure and deterministic. The optional \`chant state snapshot\` command queries the Kubernetes API to capture deployment metadata (pod names, status, UIDs) for observability. Your job as an agent is to bridge synthesis and deployment:
|
|
404
494
|
|
|
405
495
|
- Use **chant** for: build, lint, diff (local YAML comparison)
|
|
406
496
|
- Use **kubectl / k8s API** for: apply, rollback, monitoring, troubleshooting
|