@intentius/chant-lexicon-k8s 0.31.0 → 0.32.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 (103) hide show
  1. package/dist/api/classify.d.ts +10 -0
  2. package/dist/api/classify.d.ts.map +1 -1
  3. package/dist/api/owner-chain.d.ts +46 -0
  4. package/dist/api/owner-chain.d.ts.map +1 -0
  5. package/dist/api/sweep-types.d.ts +17 -0
  6. package/dist/api/sweep-types.d.ts.map +1 -0
  7. package/dist/deep-observe-hooks.d.ts +86 -0
  8. package/dist/deep-observe-hooks.d.ts.map +1 -0
  9. package/dist/deep-observe.d.ts +146 -0
  10. package/dist/deep-observe.d.ts.map +1 -0
  11. package/dist/describe-resources.d.ts +15 -0
  12. package/dist/describe-resources.d.ts.map +1 -1
  13. package/dist/export-resources.d.ts +6 -2
  14. package/dist/export-resources.d.ts.map +1 -1
  15. package/dist/integrity.json +2 -2
  16. package/dist/kube/apply.d.ts +26 -0
  17. package/dist/kube/apply.d.ts.map +1 -0
  18. package/dist/kube/connect.d.ts +30 -0
  19. package/dist/kube/connect.d.ts.map +1 -0
  20. package/dist/kube/delete.d.ts +27 -0
  21. package/dist/kube/delete.d.ts.map +1 -0
  22. package/dist/kube/describe.d.ts +19 -0
  23. package/dist/kube/describe.d.ts.map +1 -0
  24. package/dist/kube/events.d.ts +34 -0
  25. package/dist/kube/events.d.ts.map +1 -0
  26. package/dist/kube/flags.d.ts +40 -0
  27. package/dist/kube/flags.d.ts.map +1 -0
  28. package/dist/kube/get.d.ts +21 -0
  29. package/dist/kube/get.d.ts.map +1 -0
  30. package/dist/kube/group.d.ts +19 -0
  31. package/dist/kube/group.d.ts.map +1 -0
  32. package/dist/kube/logs.d.ts +16 -0
  33. package/dist/kube/logs.d.ts.map +1 -0
  34. package/dist/kube/project.d.ts +59 -0
  35. package/dist/kube/project.d.ts.map +1 -0
  36. package/dist/kube/render.d.ts +75 -0
  37. package/dist/kube/render.d.ts.map +1 -0
  38. package/dist/kube/source.d.ts +19 -0
  39. package/dist/kube/source.d.ts.map +1 -0
  40. package/dist/kube/target.d.ts +52 -0
  41. package/dist/kube/target.d.ts.map +1 -0
  42. package/dist/kube/testing.d.ts +21 -0
  43. package/dist/kube/testing.d.ts.map +1 -0
  44. package/dist/kube/top.d.ts +23 -0
  45. package/dist/kube/top.d.ts.map +1 -0
  46. package/dist/kube/verdict.d.ts +45 -0
  47. package/dist/kube/verdict.d.ts.map +1 -0
  48. package/dist/kube/wait.d.ts +23 -0
  49. package/dist/kube/wait.d.ts.map +1 -0
  50. package/dist/manifest.json +1 -1
  51. package/dist/op/activities/index.d.ts +6 -3
  52. package/dist/op/activities/index.d.ts.map +1 -1
  53. package/dist/op/activities/kubectl.d.ts +91 -9
  54. package/dist/op/activities/kubectl.d.ts.map +1 -1
  55. package/dist/plugin.d.ts.map +1 -1
  56. package/package.json +3 -3
  57. package/src/api/classify.ts +13 -0
  58. package/src/api/owner-chain.test.ts +171 -0
  59. package/src/api/owner-chain.ts +144 -0
  60. package/src/api/sweep-types.ts +36 -0
  61. package/src/deep-observe-hooks.ts +125 -0
  62. package/src/deep-observe.test.ts +668 -0
  63. package/src/deep-observe.ts +299 -0
  64. package/src/describe-resources.test.ts +224 -1
  65. package/src/describe-resources.ts +86 -1
  66. package/src/export-resources.ts +6 -22
  67. package/src/kube/apply.test.ts +105 -0
  68. package/src/kube/apply.ts +101 -0
  69. package/src/kube/connect.ts +54 -0
  70. package/src/kube/delete.test.ts +123 -0
  71. package/src/kube/delete.ts +174 -0
  72. package/src/kube/describe.test.ts +106 -0
  73. package/src/kube/describe.ts +195 -0
  74. package/src/kube/events.test.ts +115 -0
  75. package/src/kube/events.ts +160 -0
  76. package/src/kube/flags.test.ts +65 -0
  77. package/src/kube/flags.ts +114 -0
  78. package/src/kube/get.test.ts +195 -0
  79. package/src/kube/get.ts +190 -0
  80. package/src/kube/group.test.ts +33 -0
  81. package/src/kube/group.ts +125 -0
  82. package/src/kube/logs.test.ts +126 -0
  83. package/src/kube/logs.ts +96 -0
  84. package/src/kube/project.test.ts +57 -0
  85. package/src/kube/project.ts +106 -0
  86. package/src/kube/render.test.ts +142 -0
  87. package/src/kube/render.ts +252 -0
  88. package/src/kube/source.test.ts +138 -0
  89. package/src/kube/source.ts +139 -0
  90. package/src/kube/target.test.ts +67 -0
  91. package/src/kube/target.ts +89 -0
  92. package/src/kube/testing.ts +42 -0
  93. package/src/kube/top.test.ts +149 -0
  94. package/src/kube/top.ts +120 -0
  95. package/src/kube/verdict.test.ts +48 -0
  96. package/src/kube/verdict.ts +77 -0
  97. package/src/kube/wait.test.ts +125 -0
  98. package/src/kube/wait.ts +160 -0
  99. package/src/op/activities/index.ts +6 -3
  100. package/src/op/activities/kubectl.test.ts +298 -26
  101. package/src/op/activities/kubectl.ts +313 -20
  102. package/src/plugin.test.ts +58 -1
  103. package/src/plugin.ts +29 -0
@@ -37,6 +37,16 @@ export type K8sReadOutcome =
37
37
  };
38
38
  /** Classify a failure from the typed client into the observation tri-state. */
39
39
  export declare function classifyApiFailure(err: unknown): K8sReadOutcome;
40
+ /**
41
+ * The cluster's own discovery reports no such kind at all — distinct from a
42
+ * kind that exists but currently has zero live instances. `classifyApiFailure`
43
+ * folds both into `absent` for the declared-entity read path, where "no
44
+ * instance can exist" is exactly the signal a `create` needs. `chant kube get`
45
+ * (chant #1079) needs the finer distinction: an ad hoc `chant kube get
46
+ * widgets` against a kind the cluster has never heard of should say so, not
47
+ * print "No resources found." as if `widgets` were a real, empty kind.
48
+ */
49
+ export declare function isUnknownResource(err: unknown): boolean;
40
50
  /**
41
51
  * Whether a failure kills the whole observation rather than one entity. A
42
52
  * refused binding, a missing client package and a rejected credential plugin
@@ -1 +1 @@
1
- {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/api/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,+EAA+E;AAC/E,MAAM,MAAM,cAAc;AACxB,kFAAkF;AAChF;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,4DAA4D;GAC1D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuBrE,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAwC/D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAEuE,CAAC"}
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/api/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,+EAA+E;AAC/E,MAAM,MAAM,cAAc;AACxB,kFAAkF;AAChF;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,4DAA4D;GAC1D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuBrE,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAwC/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAEuE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Resolving a live Kubernetes object's `ownerReferences` chain up to a
3
+ * declared, chant-observed entity (chant #1077).
4
+ *
5
+ * There is no server-side "who ultimately owns this object" query — Kubernetes'
6
+ * own garbage collector does not have one either; it walks the same chain one
7
+ * hop at a time, reading each intermediate owner. A Pod's `ownerReferences`
8
+ * names its ReplicaSet, which chant never declared; the ReplicaSet's own
9
+ * `ownerReferences` names the Deployment, which is declared. Reaching that
10
+ * declared entity takes reading the ReplicaSet in between.
11
+ *
12
+ * This module's only job is assembling that chain — fetching each hop through
13
+ * the typed client, bounded and cycle-guarded so a corrupt or adversarial
14
+ * chain cannot hang an observation. The bounded/cycle-safe *interpretation* of
15
+ * the assembled chain (declared / unowned / foreign / unknown) is core's
16
+ * `classifyOwnerChain` (`@intentius/chant/owner-chain`) — the issue's own
17
+ * division of labor: core owns the category, the lexicon supplies the chain.
18
+ */
19
+ import type { K8sClient, K8sObject } from "@intentius/chant-k8s-client";
20
+ import { type OwnerChainVerdict } from "@intentius/chant/owner-chain";
21
+ /** The client surface this module needs — a single object read, addressed by
22
+ * an owner reference's own coordinates. */
23
+ export type OwnerChainReader = Pick<K8sClient, "readIfPresent">;
24
+ export interface ResolveOwnerChainOptions {
25
+ /** uid → declared chant entity name, from this observation's own resolved entities. */
26
+ declaredByUid: ReadonlyMap<string, string>;
27
+ /** Reads each intermediate owner. */
28
+ reader: OwnerChainReader;
29
+ /**
30
+ * Namespace the starting object lives in. Owner references are same-namespace
31
+ * only — a namespaced object cannot be owned by an object in another
32
+ * namespace, the same rule Kubernetes' own garbage collector enforces —so
33
+ * every hop is read in this namespace.
34
+ */
35
+ namespace: string | undefined;
36
+ maxDepth?: number;
37
+ }
38
+ /**
39
+ * Walk `obj`'s owner-reference chain up to a declared entity, a foreign root,
40
+ * or a bound (#1077). Fetches at most `maxDepth + 1` objects (the starting
41
+ * object plus up to `maxDepth` ancestors) — the same bound `classifyOwnerChain`
42
+ * enforces when interpreting the result, so nothing is fetched that the
43
+ * interpretation would not have used anyway.
44
+ */
45
+ export declare function resolveK8sOwnerChain(obj: K8sObject, options: ResolveOwnerChainOptions): Promise<OwnerChainVerdict>;
46
+ //# sourceMappingURL=owner-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-chain.d.ts","sourceRoot":"","sources":["../../src/api/owner-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;AA2BtC;2CAC2C;AAC3C,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAEhE,MAAM,WAAW,wBAAwB;IACvC,uFAAuF;IACvF,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,qCAAqC;IACrC,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,iBAAiB,CAAC,CA8D5B"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The kinds chant sweeps when nothing narrows the question.
3
+ *
4
+ * A *product* decision — what a bare `chant import` should pull back, and
5
+ * (chant #1075) which kinds an ownership-scoped prune has to look at to notice
6
+ * that a whole kind was removed from source. Not an addressing limit: since
7
+ * chant #1074 removed `KUBECTL_RESOURCE`, a `--selector type=<entity type>`
8
+ * import can name any of the ~180 types the generated operation surface
9
+ * carries, CRDs included.
10
+ *
11
+ * It lives in its own module, with no imports of its own, because both
12
+ * consumers reach it from different directions — `../export-resources.ts`
13
+ * pulls in the whole import parser, and a Temporal worker loading the apply
14
+ * activity should not.
15
+ */
16
+ export declare const DEFAULT_IMPORT_TYPES: readonly string[];
17
+ //# sourceMappingURL=sweep-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep-types.d.ts","sourceRoot":"","sources":["../../src/api/sweep-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAoBjD,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The k8s lexicon's *static* deep-observation noise rules (#1076, epic #1073).
3
+ *
4
+ * Split out from `./deep-observe.ts` for one reason: this file must be safe
5
+ * to import from `plugin.ts` at module load time, because
6
+ * `LexiconPlugin.deepNormalizationHooks` is plain data core reads to
7
+ * normalize the *declared* tree — the half of the contract that runs whether
8
+ * or not a cluster is ever touched (`lifecycle diff` without `--live`,
9
+ * `chant build`, tests that only exercise normalization). `./deep-observe.ts`
10
+ * itself imports `@intentius/chant-k8s-client` for the live read, and chant
11
+ * #1074 made that package's reachability from the build path a structural
12
+ * property (`examples/k8s-client-boundary.test.ts`) rather than a lint rule —
13
+ * so nothing this file exports may pull that package in, directly or
14
+ * transitively. It imports nothing but the core contract's own types.
15
+ *
16
+ * What lives here is deliberately the *entityType-keyed, resource-agnostic*
17
+ * half of the rules: which fields the API server always populates regardless
18
+ * of what a manager wrote (`status`, `metadata.uid`, …), which fields
19
+ * Kubernetes defaults when a manifest is silent about them, and which arrays
20
+ * are sets addressed by a well-known identity (containers by name, ports by
21
+ * containerPort+protocol). None of that needs a live object in hand.
22
+ *
23
+ * What does *not* live here is the managed-fields prune — whether one
24
+ * specific field on one specific live object is chant-owned, foreign-owned,
25
+ * or contested. That is inherently per-object (it depends on *that* object's
26
+ * `metadata.managedFields`, which the declared tree never carries and which
27
+ * differs between two Deployments of the same type), so it cannot be
28
+ * expressed as a fixed rule keyed only by entity type and path — the shape
29
+ * every other hook in this file takes. `./deep-observe.ts` computes it once
30
+ * per resource and layers it on top of the rules below.
31
+ *
32
+ * The *entity-type-agnostic* half of these rules — which fields every
33
+ * Kubernetes API object carries regardless of kind, and the well-known
34
+ * list-map-key ordering conventions (containers/env/volumes/ports) — lives in
35
+ * `@intentius/chant/managed-fields` (chant #1087), because a GCP Config
36
+ * Connector custom resource is a Kubernetes object too and needs the exact
37
+ * same rules without depending on this lexicon's package. What stays here is
38
+ * only what's genuinely k8s-*lexicon*-specific: {@link K8S_SERVICE_DEFAULTS},
39
+ * keyed by chant's own k8s entityType catalog.
40
+ */
41
+ import type { DeepNormalizationHooks } from "@intentius/chant/lexicon";
42
+ /**
43
+ * Kubernetes-defaulted fields, per entity type, as index-erased property
44
+ * paths. Subtracted only where source never declared the property
45
+ * (`side === "live" && counterpart === "absent"`) — cdk-real-drift's default
46
+ * subtraction, same convention as AWS/Azure/Temporal's tables.
47
+ *
48
+ * Sparse and evidence-based rather than derived from the generated schema:
49
+ * the k8s OpenAPI spec this lexicon's codegen consumes
50
+ * (`lexicons/k8s/src/spec/parse.ts`) does not carry a `default` value for
51
+ * these fields the way ARM's schema sometimes does, so "per discovery" is not
52
+ * actually expressible today. Widening this table is additive and needs no
53
+ * contract change.
54
+ *
55
+ * `spec.strategy` is listed whole, not as `spec.strategy.type`, for the same
56
+ * reason Temporal's `TEMPORAL_SCHEDULE_DEFAULTS` lists `state` whole: pruning
57
+ * only the leaf would still recurse into the object, and a nested default the
58
+ * table does not separately name (`rollingUpdate.maxSurge`/`maxUnavailable`,
59
+ * both `"25%"` when `spec.strategy` is omitted entirely) would leave behind an
60
+ * empty `strategy: {}` — a value distinct from no `strategy` key at all, and
61
+ * itself a spurious "undeclared" finding. Matching the whole node first, before
62
+ * its children are ever visited, drops the wrapper outright when every field
63
+ * under it is exactly at its default.
64
+ */
65
+ export declare const K8S_SERVICE_DEFAULTS: Record<string, Record<string, unknown>>;
66
+ /**
67
+ * The k8s lexicon's static noise rules: the generic Kubernetes object
68
+ * envelope (unconditional, by pattern, `@intentius/chant/managed-fields`) and
69
+ * Kubernetes-defaulted fields (gated on `counterpart === "absent"`), plus the
70
+ * array orderings the acceptance criteria name — `x-kubernetes-patch-merge-
71
+ * key`/`list-map-keys` conventions the generated surface does not currently
72
+ * carry (see the module doc), so these are the "else named-by-name
73
+ * conventions" the issue calls for: containers by `name`, `env` by `name`,
74
+ * `volumes` by `name`, container/service `ports` by `containerPort`/`port` +
75
+ * `protocol` — the same conventions `@intentius/chant/managed-fields`'s
76
+ * `k8sListMapOrderKey` implements, reused verbatim.
77
+ *
78
+ * This is the object `k8sPlugin.deepNormalizationHooks` is. It is also what
79
+ * `./deep-observe.ts` layers its per-resource managed-fields prune on top of,
80
+ * so the two normalization passes (the reader's own, and core's later
81
+ * re-normalization of both the declared and the already-normalized live tree
82
+ * — see `packages/core/src/lifecycle/deep-observe.ts`) apply the identical
83
+ * entityType-keyed rules either way.
84
+ */
85
+ export declare const k8sDeepNormalizationHooks: DeepNormalizationHooks;
86
+ //# sourceMappingURL=deep-observe-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-observe-hooks.d.ts","sourceRoot":"","sources":["../src/deep-observe-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAY,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGjF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAcxE,CAAC;AAaF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yBAAyB,EAAE,sBAWvC,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Kubernetes deep observation (#1076) — the k8s row of the deep-observe
3
+ * contract (#1014), and the epic's (#1073) thesis made real: chant compiled
4
+ * the manifest, so it knows which fields it authored; the API server records,
5
+ * per field, which manager last wrote it (`metadata.managedFields`, chant
6
+ * #1075/#1178). Intersecting those two makes Kubernetes drift *derived*
7
+ * rather than the hand-maintained `ignoreDifferences` list every Argo user
8
+ * keeps.
9
+ *
10
+ * ## Why this is not "the AWS reader, with `kubectl get` instead of Cloud
11
+ * Control"
12
+ *
13
+ * AWS, Azure and Temporal's rows all prune by a **static, entityType-keyed**
14
+ * table: an ARN always looks like an ARN, `provisioningState` is always
15
+ * server-populated, a namespace's retention default is always the same
16
+ * value. None of that needs the specific live object in hand — it is exactly
17
+ * what `./deep-observe-hooks.ts`'s `k8sDeepNormalizationHooks` is, and it
18
+ * covers Kubernetes' *equivalent* static noise (`status`,
19
+ * `metadata.{uid,resourceVersion,generation,creationTimestamp}`, a handful of
20
+ * server-defaulted pod-spec fields).
21
+ *
22
+ * managedFields is not that kind of rule. Whether `spec.replicas` is noise on
23
+ * *this* Deployment depends on whether *this* Deployment's
24
+ * `metadata.managedFields` says a controller owns it — a fact that differs
25
+ * between two Deployments of the same type, and that the declared tree never
26
+ * carries at all (chant's source has no `managedFields` key to normalize).
27
+ * `DeepNormalizationHooks.prune` cannot see the object it is walking, only a
28
+ * path and a value, so this cannot be expressed as a fixed hook the way the
29
+ * other three rows' entire contribution is. It has to be computed once per
30
+ * resource, here, and layered on top of the static rules before the tree is
31
+ * normalized.
32
+ *
33
+ * ## The contested-field rule, precisely
34
+ *
35
+ * For every path on the live tree, three questions, each independent:
36
+ *
37
+ * 1. **Does any chant field manager (`chant`, `chant:<stack>` — chant #1075,
38
+ * matched on the family so a stack rename does not stop recognizing its
39
+ * own history) own this path?** If so it is chant's business regardless of
40
+ * what else is true — always diffable, never pruned by this rule.
41
+ * 2. **Does some *other* manager own this path, and chant does not?** That is
42
+ * controller-managed noise — HPA rewriting `spec.replicas`, a mutating
43
+ * webhook defaulting a field, `kubectl-client-side-apply` from a human
44
+ * operator — *provided* nobody declared it (next question). Prune it.
45
+ * 3. **Does chant's own manifest *also* set this path?** — independent of
46
+ * who currently owns it live. This is the case the issue calls out by
47
+ * name: **a contested field chant declared is drift-relevant.** The
48
+ * reasoning: chant's source is a statement of intent regardless of
49
+ * whether a previous apply is what currently holds the field, and a
50
+ * foreign write that overrides a value chant's manifest asks for is
51
+ * exactly the thing `lifecycle diff --live` exists to surface — silencing
52
+ * it because *something else* currently owns the field would hide the one
53
+ * case where chant and the cluster disagree about a property chant is
54
+ * actively declaring. So: foreign-owned *and* declared is never pruned by
55
+ * this rule, whatever #2 would otherwise do.
56
+ *
57
+ * `counterpart: "unknown"` and why it does not help here: core's own
58
+ * counterpart tri-state (`side === "live" && counterpart === "absent"`, what
59
+ * {@link K8S_SERVICE_DEFAULTS} is gated on) answers "did the *declared tree*
60
+ * carry this path at all" — which is exactly question 3, but it is computed
61
+ * by *core*, from the raw declared and raw live trees, only on the **second**
62
+ * normalization pass (`packages/core/src/lifecycle/deep-observe.ts`'s
63
+ * `diffDeepObservation`). This reader's own call to
64
+ * {@link normalizeDeepProperties} runs first, with no `counterpartPaths`
65
+ * supplied — same as the other three rows — so `counterpart` is `"unknown"`
66
+ * for every node here, and a rule gated on `"absent"` would never fire during
67
+ * this read at all. That is fine for a table keyed only by entityType (AWS's
68
+ * service defaults are subtracted on core's later pass, not this one), but it
69
+ * is *not* fine for the managed-fields rule: if this reader left
70
+ * `spec.replicas` in the tree waiting for core's second pass to prune it,
71
+ * core would be normalizing with the *static* `k8sDeepNormalizationHooks`,
72
+ * which has no managedFields for this object in hand either (this reader
73
+ * already computed its ownership sets from data it read once and does not
74
+ * return). So question 3 is answered **here**, directly against the declared
75
+ * `props` this reader was handed — not via `counterpart` — and the result is
76
+ * baked into what this reader returns: a foreign-owned, undeclared field is
77
+ * gone from the tree before it ever reaches core, and a contested one is
78
+ * still there for the ordinary declared-vs-live comparison to catch.
79
+ *
80
+ * ## Resolving a managedFields entry against a live array
81
+ *
82
+ * `metadata.managedFields[].fieldsV1` encodes a list item three ways —
83
+ * `k:{"name":"web"}` (by key), `v:"blue"` (by value), `i:3` (by index) — and
84
+ * chant #1178's `managed-fields.ts` renders all three to a path *string*
85
+ * (`.spec.containers[name="web"]`) for display. Parsing that string back
86
+ * would be ambiguous in general (a label key may itself contain `.`, e.g.
87
+ * `app.kubernetes.io/name`, indistinguishable in the rendered form from
88
+ * nested fields), so this reader does not parse strings at all: it walks the
89
+ * *structured* `fieldsV1` tree directly (`walkOwnership`, below), matching
90
+ * each `k:`/`v:` entry against the actual live array to find the concrete
91
+ * index, and against the actual declared array (by the same key or value) to
92
+ * answer question 3 for that element specifically — a declared container
93
+ * named `app` at index 0 is still "declared" if a sidecar gets injected in
94
+ * front of it and shifts it to live index 1.
95
+ *
96
+ * ## What is deliberately not modeled
97
+ *
98
+ * A manager's `.` entry (SSA's "I own this element's presence") on a
99
+ * container that also sets no scalar sub-fields (unusual — a real apply
100
+ * setting a container almost always sets `image`/`name` too) would not confer
101
+ * ownership onto a sibling field nobody's `fieldsV1` entry lists explicitly.
102
+ * That is the conservative direction: a path absent from every manager's
103
+ * fields is treated as "no ownership information", which leaves it diffable
104
+ * rather than silently pruned. Reported drift that turns out to be more
105
+ * noise than expected is a tuning problem; drift silently dropped is not.
106
+ *
107
+ * ## `buildOwnershipSets` lives in core now
108
+ *
109
+ * The ownership walk itself (`walkOwnership`, resolving a `fieldsV1` tree
110
+ * against the live and declared trees) has nothing k8s-*lexicon*-specific
111
+ * about it — it is generic Kubernetes SSA machinery. Chant #1087 (GCP's row,
112
+ * reusing this one, since a Config Connector CR is a Kubernetes object too)
113
+ * moved it to `@intentius/chant/managed-fields` rather than have gcp depend
114
+ * on this lexicon's package, the same reason chant #1100's
115
+ * `resolveClusterTarget` lives in core. This module re-exports
116
+ * `buildOwnershipSets`/`OwnershipSets` from there so nothing here changes for
117
+ * an existing importer of this file.
118
+ */
119
+ import type { DeepObservationResult } from "@intentius/chant/lexicon";
120
+ import { buildOwnershipSets, type OwnershipSets } from "@intentius/chant/managed-fields";
121
+ import { type K8sConnector } from "./api/connect.js";
122
+ import { k8sDeepNormalizationHooks } from "./deep-observe-hooks.js";
123
+ export { k8sDeepNormalizationHooks, buildOwnershipSets, type OwnershipSets };
124
+ export interface K8sDeepObserveOptions {
125
+ environment: string;
126
+ buildOutput?: string;
127
+ entityNames: string[];
128
+ entities: Map<string, {
129
+ entityType: string;
130
+ props: Record<string, unknown>;
131
+ }>;
132
+ stack?: string;
133
+ owned?: boolean;
134
+ /** Directory whose `chant.config.ts` carries the cluster binding. Defaults to cwd. */
135
+ cwd?: string;
136
+ }
137
+ /**
138
+ * Read the live property tree for each declared entity, pruning by
139
+ * `metadata.managedFields` (see the module doc). Reuses the same connector,
140
+ * discovery/caching client and tri-state failure classification as the thin
141
+ * read (`./describe-resources.ts`) — the binding check (chant #1100/#1155)
142
+ * still refuses before any resource is touched, and a connect failure still
143
+ * becomes NOT-OBSERVED for every declared entity rather than an empty result.
144
+ */
145
+ export declare function observeResourcesDeepK8s(options: K8sDeepObserveOptions, connect?: K8sConnector): Promise<DeepObservationResult>;
146
+ //# sourceMappingURL=deep-observe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-observe.d.ts","sourceRoot":"","sources":["../src/deep-observe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqHG;AAGH,OAAO,KAAK,EAEV,qBAAqB,EAGtB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,kBAAkB,EAAoB,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAC3G,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAQvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AASjE,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAuBD;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,qBAAqB,EAC9B,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,qBAAqB,CAAC,CA0GhC"}
@@ -35,6 +35,21 @@
35
35
  * NOT-OBSERVED with a reason. A declared `k8s.profiles.<env>.context` that
36
36
  * disagrees with the ambient one still refuses before a single resource is
37
37
  * touched, via the same `resolveClusterTarget` the GCP lexicon shares.
38
+ *
39
+ * ## Runtime children (chant #1077)
40
+ *
41
+ * A Pod a declared Deployment's controller created is live and undeclared —
42
+ * exactly the shape `lifecycle diff --live` has always classified `orphan`.
43
+ * On Kubernetes that is wrong: it is expected runtime, not drift, and will be
44
+ * recreated the moment it is deleted. After the declared-entity reads above
45
+ * resolve, this scans Pods in the namespaces they actually live in and walks
46
+ * each one's `ownerReferences` chain (`./api/owner-chain.ts`) against the
47
+ * entities this very call resolved. A chain reaching one of them is reported
48
+ * with `ownerChain: { root: "declared", ... }`; core's diff/change-set engine
49
+ * reads that as `runtime` instead of `orphan`. Deliberately scoped to Pods —
50
+ * the concrete case the issue and its acceptance criteria name — and to the
51
+ * namespaces this observation already touched, not a cluster-wide sweep;
52
+ * widening to other controller-spawned kinds is the same walk repeated.
38
53
  */
39
54
  import type { ObservationResult } from "@intentius/chant/lexicon";
40
55
  import type { K8sObject } from "@intentius/chant-k8s-client";
@@ -1 +1 @@
1
- {"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAsC,MAAM,0BAA0B,CAAC;AAGtG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAiBvE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAUvD;AAQD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAmH5B"}
1
+ {"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAsC,MAAM,0BAA0B,CAAC;AAGtG,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAkBvE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAUvD;AAQD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAqH5B"}
@@ -18,12 +18,16 @@
18
18
  */
19
19
  import type { ExportedTemplate, ResourceSelector } from "@intentius/chant/lexicon";
20
20
  import { type K8sConnector } from "./api/connect.js";
21
+ import { DEFAULT_IMPORT_TYPES } from "./api/sweep-types.js";
21
22
  /**
22
23
  * Entity types a bare `chant import --from <cluster>` sweeps: the workload,
23
24
  * config, networking and RBAC kinds people actually author. Everything else is
24
- * reachable by naming it with `--selector type=...`.
25
+ * reachable by naming it with `--selector type=...`. Defined in
26
+ * `./api/sweep-types.ts` and re-exported here, its original home — chant
27
+ * #1075's ownership-scoped prune needs the same list without pulling the
28
+ * import parser into a Temporal worker.
25
29
  */
26
- export declare const DEFAULT_IMPORT_TYPES: readonly string[];
30
+ export { DEFAULT_IMPORT_TYPES };
27
31
  export declare function exportResources(options: {
28
32
  environment: string;
29
33
  selector?: ResourceSelector;
@@ -1 +1 @@
1
- {"version":3,"file":"export-resources.d.ts","sourceRoot":"","sources":["../src/export-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAIvE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAoBjD,CAAC;AAEF,wBAAsB,eAAe,CACnC,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,EACD,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,gBAAgB,CAAC,CA4B3B"}
1
+ {"version":3,"file":"export-resources.d.ts","sourceRoot":"","sources":["../src/export-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;;;GAOG;AACH,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,wBAAsB,eAAe,CACnC,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,EACD,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,gBAAgB,CAAC,CA4B3B"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "be792b33ca067c06a359ee06d250f08fc9ae3401507ee275c18568cfc5e55483",
4
+ "manifest.json": "115699ca99d75d4b540b73fc2bbae4ca9b2c10a58e2229d24f72571b9daee693",
5
5
  "meta.json": "6d112006daa7196eb28619ac5a3893b709dc2b845edbd537db7d7b471e8dc104",
6
6
  "types/index.d.ts": "7b873148146a5512c22baabfde6cfcc3248c24c2c7578f68a19544af5dc675f6",
7
7
  "rules/argo-appset-single-project.ts": "afa9f310753aa2d475f35012b13135b2dfaebed2a35d44edbe185ebc07673674",
@@ -50,5 +50,5 @@
50
50
  "skills/chant-k8s-aks.md": "e18f0e2b055f72cd7a37deaf258d7027c2d4d3e286e8fd4975b27a1f981a3ad9",
51
51
  "skills/chant-k8s-argo.md": "b1a0b826559d8c5033a479c5781efaf650320f0aee4419d8841170bd3393cea5"
52
52
  },
53
- "composite": "3620d7f17ce6375203ab8de306d37be7d96b1e5658c883acbf908307d52d2703"
53
+ "composite": "57c3eed6bb041d08264adcedaa5e166e624257e15c6d8121053cc945e7d212f3"
54
54
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `chant kube apply` (chant #1079) — "writes are not cloned": this calls
3
+ * `applyManifest` (`../op/activities/kubectl.ts`) directly, the exact
4
+ * function the k8s Op activity registers under `kubectlApply` — server-side
5
+ * apply, chant's field-manager identity, the same `FieldManagerConflictError`
6
+ * surface (chant #1075/#1178) — never a second implementation of `kubectl
7
+ * apply`. An explicit manifest path is mandatory; there is no bare-sweep form.
8
+ *
9
+ * The one thing this verb adds on top of the activity is a confirmation
10
+ * gate, matching the issue's "route through plan, gate, and ownership": a
11
+ * bare `chant kube apply -f x.yaml` performs a server-side dry run — every
12
+ * document validated and previewed, nothing persisted — and says so; only
13
+ * `--yes` performs the real, persisting apply. That is a deliberate
14
+ * divergence from `kubectl apply`, which persists by default; a terminal
15
+ * command that can rewrite a live Deployment is worth one extra keystroke of
16
+ * intent.
17
+ */
18
+ import { type K8sConnector } from "../api/connect.js";
19
+ import { type KubectlApplyArgs, type ApplyManifestResult } from "../op/activities/kubectl.js";
20
+ export type ApplyFn = (args: KubectlApplyArgs, signal?: AbortSignal, connect?: K8sConnector) => Promise<ApplyManifestResult>;
21
+ export interface ApplyDeps {
22
+ connect?: K8sConnector;
23
+ apply?: ApplyFn;
24
+ }
25
+ export declare function runApply(rawArgs: string[], deps?: ApplyDeps): Promise<number>;
26
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/kube/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAExE,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG1G,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE7H,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,SAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoEvF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Connecting to a cluster on `chant kube`'s behalf (chant #1079), honoring
3
+ * the exact same environment→cluster binding every other observing path
4
+ * does (chant #1100/#1155): `--env` resolves `k8s.profiles.<env>.context`
5
+ * and refuses loudly on a mismatch, `--context` is an explicit override that
6
+ * skips the binding entirely, and neither given falls back to the ambient
7
+ * kubeconfig context — the same three modes `describeResources` and the Op
8
+ * activities already use, via the same `defaultK8sConnector`. Nothing here
9
+ * reimplements that resolution; this only turns a connect failure into the
10
+ * observation tri-state so a verb can render NOT-OBSERVED-with-reason
11
+ * instead of a stack trace.
12
+ */
13
+ import type { UnobservedReason } from "@intentius/chant/observation";
14
+ import { type ConnectOptions, type ConnectedClient, type K8sConnector } from "../api/connect.js";
15
+ export type KubeConnectResult = ({
16
+ kind: "connected";
17
+ } & ConnectedClient) | {
18
+ kind: "unobserved";
19
+ reason: UnobservedReason;
20
+ detail: string;
21
+ };
22
+ /**
23
+ * Connect, or classify the failure into the tri-state. A bound-but-mismatched
24
+ * `--env` (`ClusterBindingMismatchError`), a missing `@intentius/chant-k8s-client`
25
+ * install, and a refused exec-credential plugin are the "nothing left the
26
+ * process" failures every verb must treat identically: NOT-OBSERVED, never
27
+ * an empty/absent result.
28
+ */
29
+ export declare function kubeConnect(options: ConnectOptions, connect?: K8sConnector): Promise<KubeConnectResult>;
30
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/kube/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAuB,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnH,MAAM,MAAM,iBAAiB,GACzB,CAAC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GAAG,eAAe,CAAC,GACzC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAqB5B"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `chant kube delete` (chant #1079) — routes through the typed client's own
3
+ * `delete()` (`packages/k8s-client/src/client.ts`), the identical typed
4
+ * delete `applyManifest`'s prune step already uses (chant #1075) — never a
5
+ * second implementation. A kind and a name are both mandatory: there is no
6
+ * bare `chant kube delete deployments` form, so nothing here can become a
7
+ * sweep by omission (the issue's "nothing destructive happens without an
8
+ * explicit resource argument").
9
+ *
10
+ * Two guardrails on top of the typed delete itself:
11
+ *
12
+ * - **Gate.** A bare invocation reads the object, reports what it found (and
13
+ * whether chant owns it), and stops — only `--yes` performs the delete.
14
+ * - **Ownership, surfaced not enforced.** kubectl itself deletes anything
15
+ * RBAC allows, chant-applied or not, and this keeps that: an explicit name
16
+ * is already an informed decision. What's added is visibility — a
17
+ * warning when the object carries no chant ownership marker, so the
18
+ * operator knows they are about to delete something chant did not apply.
19
+ */
20
+ import { type K8sConnector } from "../api/connect.js";
21
+ import { type KubeProjectContext } from "./project.js";
22
+ export interface DeleteDeps {
23
+ connect?: K8sConnector;
24
+ loadProject?: (cwd?: string) => Promise<KubeProjectContext | undefined>;
25
+ }
26
+ export declare function runDelete(rawArgs: string[], deps?: DeleteDeps): Promise<number>;
27
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/kube/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAIxE,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAG5E,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;CACzE;AAQD,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA0GzF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `chant kube describe` (chant #1079) — a generic, multi-section human view:
3
+ * identity, chant's own verdict + provenance (when inside a project), a
4
+ * pretty-printed spec/status, and the object's Events (reusing `./events.ts`'s
5
+ * `listEvents`/`filterInvolved`, the same machinery `chant kube events`
6
+ * itself uses — one implementation, not two). This is not kubectl's
7
+ * per-kind template set (`OldReplicaSets`/`NewReplicaSet` for a Deployment,
8
+ * per-container detail for a Pod, and so on for every built-in kind) — a
9
+ * generic describe covering the fields every object carries, plus the
10
+ * context only chant can add.
11
+ */
12
+ import { type K8sConnector } from "../api/connect.js";
13
+ import { type KubeProjectContext } from "./project.js";
14
+ export interface DescribeDeps {
15
+ connect?: K8sConnector;
16
+ loadProject?: (cwd?: string) => Promise<KubeProjectContext | undefined>;
17
+ }
18
+ export declare function runDescribe(rawArgs: string[], deps?: DescribeDeps): Promise<number>;
19
+ //# sourceMappingURL=describe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/kube/describe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKxE,OAAO,EAA8C,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAMhG,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;CACzE;AA0ED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4F7F"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * `chant kube events` (chant #1079) — the core `v1 Event` kind is addressed
3
+ * exactly like any other read (`client.list`), no client extension needed.
4
+ * The one thing the typed client's `ListOptions` does not carry is a field
5
+ * selector, so `--for <kind>/<name>` (kubectl's own `kubectl events
6
+ * --for=kind/name` shape) filters client-side against `involvedObject` after
7
+ * the list comes back, rather than asking the server to. Event volume in a
8
+ * single namespace is small enough that this is a fine trade for not
9
+ * widening the client's surface for one caller.
10
+ */
11
+ import type { K8sClient, K8sObject } from "@intentius/chant-k8s-client";
12
+ import { type K8sConnector } from "../api/connect.js";
13
+ export interface EventsDeps {
14
+ connect?: K8sConnector;
15
+ }
16
+ /** Events whose `involvedObject` names `ref`, oldest first — kubectl's own default order. */
17
+ export declare function filterInvolved(events: readonly K8sObject[], ref: {
18
+ kind: string;
19
+ name: string;
20
+ }): K8sObject[];
21
+ /**
22
+ * List Events for `namespace` (or every namespace, when `namespace` is
23
+ * undefined), sorted oldest first. Shared by `runEvents` and `describe`'s own
24
+ * Events section, so the two verbs agree on what "the events for this object"
25
+ * means.
26
+ */
27
+ export declare function listEvents(client: K8sClient, options?: {
28
+ namespace?: string;
29
+ labelSelector?: string;
30
+ }): Promise<K8sObject[]>;
31
+ /** Render an events table — reused by `describe`'s Events section. */
32
+ export declare function renderEvents(events: readonly K8sObject[]): string;
33
+ export declare function runEvents(rawArgs: string[], deps?: EventsDeps): Promise<number>;
34
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/kube/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAMxE,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAoBD,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAAE,CAK7G;AAaD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3D,OAAO,CAAC,SAAS,EAAE,CAAC,CAMtB;AAcD,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAGjE;AASD,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDzF"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Flag parsing shared by every `chant kube <verb>` (chant #1079).
3
+ *
4
+ * `CommandGroupContext.rawArgs` is unparsed argv — core has no vocabulary for
5
+ * a lexicon's own verbs (chant #1078) — so every verb here does its own
6
+ * parsing, reusing `splitJoinedFlags`/`unknownFlagError` for the same
7
+ * `--flag=value` splitting and rejection discipline core's own parser
8
+ * applies (chant #1127). This module adds the flag vocabulary every verb
9
+ * shares (namespace, selector, output, cluster targeting) so each verb file
10
+ * only has to declare what is actually its own (`--tail`, `--for`, ...).
11
+ */
12
+ import type { ConnectOptions } from "../api/connect.js";
13
+ /** A verb's own flag vocabulary, merged with the common set below. */
14
+ export interface FlagSpec {
15
+ /** Value flags this verb accepts, alias → canonical key (e.g. `{ "--tail": "tail" }`). */
16
+ value?: Record<string, string>;
17
+ /** Boolean flags this verb accepts, alias → canonical key. */
18
+ boolean?: Record<string, string>;
19
+ }
20
+ export interface ParsedFlags {
21
+ /** Non-flag tokens, in order — the verb's own positional arguments (kind, name, ...). */
22
+ positional: string[];
23
+ /** Resolved value-flag key → the value given. */
24
+ values: Record<string, string>;
25
+ /** Resolved boolean-flag key → true (absent keys are false). */
26
+ flags: Record<string, boolean>;
27
+ }
28
+ /**
29
+ * Parse `rawArgs` against the common flag set plus `spec`. Throws
30
+ * {@link unknownFlagError}'s shape on anything starting with `-` that
31
+ * neither set recognizes, and on a value flag given with nothing after it.
32
+ */
33
+ export declare function parseKubeFlags(rawArgs: string[], spec?: FlagSpec): ParsedFlags;
34
+ /** Build the typed client's `ConnectOptions` from a parsed common flag set. */
35
+ export declare function connectOptionsFrom(values: Record<string, string>): ConnectOptions;
36
+ /** kubectl duration shorthand: "3600" (bare seconds), "1h", "90m", "45s". Shared by `logs --since` and `wait --timeout`. */
37
+ export declare function parseDurationSeconds(value: string): number;
38
+ /** {@link parseDurationSeconds} in milliseconds. */
39
+ export declare function parseDurationMs(value: string): number;
40
+ //# sourceMappingURL=flags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/kube/flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,sEAAsE;AACtE,MAAM,WAAW,QAAQ;IACvB,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAoBD,MAAM,WAAW,WAAW;IAC1B,yFAAyF;IACzF,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,QAAa,GAAG,WAAW,CA6BlF;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,CAMjF;AAED,4HAA4H;AAC5H,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAY1D;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD"}