@f5-sales-demo/xcsh 20.3.2 → 20.4.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 (40) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +8 -8
  3. package/src/cli/resource-cli.ts +134 -0
  4. package/src/cli/sandbox-check.ts +84 -21
  5. package/src/cli/update-cli.ts +1 -1
  6. package/src/cli.ts +8 -0
  7. package/src/commands/apply.ts +21 -0
  8. package/src/commands/create.ts +21 -0
  9. package/src/commands/delete.ts +32 -0
  10. package/src/commands/diff.ts +20 -0
  11. package/src/commands/export.ts +36 -0
  12. package/src/commands/get.ts +30 -0
  13. package/src/commands/resource-flags.ts +30 -0
  14. package/src/commands/self-update.ts +18 -0
  15. package/src/commands/update.ts +14 -14
  16. package/src/commands/validate.ts +20 -0
  17. package/src/internal-urls/build-info.generated.ts +8 -8
  18. package/src/locales/ar.json +1 -1
  19. package/src/locales/de.json +1 -1
  20. package/src/locales/en.json +1 -1
  21. package/src/locales/es.json +1 -1
  22. package/src/locales/fr.json +1 -1
  23. package/src/locales/hi.json +1 -1
  24. package/src/locales/it.json +1 -1
  25. package/src/locales/ja.json +1 -1
  26. package/src/locales/ko.json +1 -1
  27. package/src/locales/pt-br.json +1 -1
  28. package/src/locales/th.json +1 -1
  29. package/src/locales/zh-cn.json +1 -1
  30. package/src/locales/zh-tw.json +1 -1
  31. package/src/main.ts +1 -1
  32. package/src/prompts/internal-urls/containment.md +16 -17
  33. package/src/resource-management/index.ts +8 -0
  34. package/src/sandbox/command-operands.ts +20 -290
  35. package/src/sandbox/containment.ts +41 -42
  36. package/src/sandbox/enforce.ts +45 -280
  37. package/src/sandbox/session-fence.ts +7 -0
  38. package/src/slash-commands/resource-commands.ts +63 -93
  39. package/src/tools/bash.ts +9 -3
  40. package/src/tools/shell-lex.ts +8 -10
@@ -0,0 +1,20 @@
1
+ import { Command } from "@f5-sales-demo/pi-utils/cli";
2
+ import { runResourceCli } from "../cli/resource-cli";
3
+ import { manifestInputFlags } from "./resource-flags";
4
+
5
+ export default class Validate extends Command {
6
+ static description = "Validate manifests locally without API credentials";
7
+ static flags = manifestInputFlags;
8
+
9
+ async run(): Promise<void> {
10
+ const { flags } = await this.parse(Validate);
11
+ await runResourceCli({
12
+ operation: "validate",
13
+ filenames: flags.filename,
14
+ namespace: flags.namespace,
15
+ outputFormat: flags.output as "json" | "yaml" | "table" | "wide",
16
+ recursive: flags.recursive,
17
+ resultFile: flags["result-file"],
18
+ });
19
+ }
20
+ }
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "20.3.2",
21
- "commit": "f886c6fe86e2f1d038a581e21f24aab6260b59b5",
22
- "shortCommit": "f886c6f",
20
+ "version": "20.4.0",
21
+ "commit": "cc173f02925c0e4cb6085e8d15058baa34e2fafb",
22
+ "shortCommit": "cc173f0",
23
23
  "branch": "main",
24
- "tag": "v20.3.2",
25
- "commitDate": "2026-08-04T15:39:32Z",
26
- "buildDate": "2026-08-04T16:14:10.597Z",
24
+ "tag": "v20.4.0",
25
+ "commitDate": "2026-08-04T21:59:37Z",
26
+ "buildDate": "2026-08-04T22:31:30.038Z",
27
27
  "dirty": true,
28
28
  "prNumber": "",
29
29
  "repoUrl": "https://github.com/f5-sales-demo/xcsh",
30
30
  "repoSlug": "f5-sales-demo/xcsh",
31
- "commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/f886c6fe86e2f1d038a581e21f24aab6260b59b5",
32
- "releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v20.3.2"
31
+ "commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/cc173f02925c0e4cb6085e8d15058baa34e2fafb",
32
+ "releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v20.4.0"
33
33
  };
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "مزود النموذج",
268
268
  "welcome.plugins": "الإضافات",
269
269
  "welcome.pluginSetupHint": "شغّل: /plugin setup",
270
- "welcome.updateHint": "شغّل: xcsh update",
270
+ "welcome.updateHint": "شغّل: xcsh self-update",
271
271
  "welcome.newVersion": "إصدار جديد",
272
272
  "welcome.connectionFailed": "— فشل الاتصال",
273
273
  "welcome.runLoginReconnect": "شغّل /login لإعادة الاتصال",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "Modellanbieter",
268
268
  "welcome.plugins": "Plugins",
269
269
  "welcome.pluginSetupHint": "ausführen: /plugin setup",
270
- "welcome.updateHint": "ausführen: xcsh update",
270
+ "welcome.updateHint": "ausführen: xcsh self-update",
271
271
  "welcome.newVersion": "neue Version",
272
272
  "welcome.connectionFailed": "— Verbindung fehlgeschlagen",
273
273
  "welcome.runLoginReconnect": "Führen Sie /login aus, um die Verbindung wiederherzustellen",
@@ -288,7 +288,7 @@
288
288
  "welcome.modelProvider": "Model Provider",
289
289
  "welcome.plugins": "Plugins",
290
290
  "welcome.pluginSetupHint": "run: /plugin setup",
291
- "welcome.updateHint": "run: xcsh update",
291
+ "welcome.updateHint": "run: xcsh self-update",
292
292
  "welcome.newVersion": "new version",
293
293
  "welcome.connectionFailed": "— connection failed",
294
294
  "welcome.runLoginReconnect": "Run /login to reconnect",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "Proveedor de modelo",
268
268
  "welcome.plugins": "Plugins",
269
269
  "welcome.pluginSetupHint": "ejecutar: /plugin setup",
270
- "welcome.updateHint": "ejecutar: xcsh update",
270
+ "welcome.updateHint": "ejecutar: xcsh self-update",
271
271
  "welcome.newVersion": "nueva versión",
272
272
  "welcome.connectionFailed": "— conexión fallida",
273
273
  "welcome.runLoginReconnect": "Ejecute /login para reconectar",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "Fournisseur de modèle",
268
268
  "welcome.plugins": "Plugins",
269
269
  "welcome.pluginSetupHint": "exécuter : /plugin setup",
270
- "welcome.updateHint": "exécuter : xcsh update",
270
+ "welcome.updateHint": "exécuter : xcsh self-update",
271
271
  "welcome.newVersion": "nouvelle version",
272
272
  "welcome.connectionFailed": "— échec de connexion",
273
273
  "welcome.runLoginReconnect": "Exécutez /login pour vous reconnecter",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "मॉडल प्रदाता",
268
268
  "welcome.plugins": "प्लगइन",
269
269
  "welcome.pluginSetupHint": "चलाएँ: /plugin setup",
270
- "welcome.updateHint": "चलाएँ: xcsh update",
270
+ "welcome.updateHint": "चलाएँ: xcsh self-update",
271
271
  "welcome.newVersion": "नया संस्करण",
272
272
  "welcome.connectionFailed": "— कनेक्शन विफल",
273
273
  "welcome.runLoginReconnect": "पुनः कनेक्ट करने के लिए /login चलाएँ",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "Provider del Modello",
268
268
  "welcome.plugins": "Plugin",
269
269
  "welcome.pluginSetupHint": "esegui: /plugin setup",
270
- "welcome.updateHint": "esegui: xcsh update",
270
+ "welcome.updateHint": "esegui: xcsh self-update",
271
271
  "welcome.newVersion": "nuova versione",
272
272
  "welcome.connectionFailed": "— connessione non riuscita",
273
273
  "welcome.runLoginReconnect": "Esegui /login per riconnetterti",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "モデルプロバイダー",
268
268
  "welcome.plugins": "プラグイン",
269
269
  "welcome.pluginSetupHint": "実行: /plugin setup",
270
- "welcome.updateHint": "実行: xcsh update",
270
+ "welcome.updateHint": "実行: xcsh self-update",
271
271
  "welcome.newVersion": "新しいバージョン",
272
272
  "welcome.connectionFailed": "— 接続に失敗しました",
273
273
  "welcome.runLoginReconnect": "/login を実行して再接続してください",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "모델 프로바이더",
268
268
  "welcome.plugins": "플러그인",
269
269
  "welcome.pluginSetupHint": "실행: /plugin setup",
270
- "welcome.updateHint": "실행: xcsh update",
270
+ "welcome.updateHint": "실행: xcsh self-update",
271
271
  "welcome.newVersion": "새 버전",
272
272
  "welcome.connectionFailed": "— 연결 실패",
273
273
  "welcome.runLoginReconnect": "/login을 실행하여 재연결하세요",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "Provedor de Modelo",
268
268
  "welcome.plugins": "Plugins",
269
269
  "welcome.pluginSetupHint": "execute: /plugin setup",
270
- "welcome.updateHint": "execute: xcsh update",
270
+ "welcome.updateHint": "execute: xcsh self-update",
271
271
  "welcome.newVersion": "nova versão",
272
272
  "welcome.connectionFailed": "— falha na conexão",
273
273
  "welcome.runLoginReconnect": "Execute /login para reconectar",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "ผู้ให้บริการโมเดล",
268
268
  "welcome.plugins": "ปลั๊กอิน",
269
269
  "welcome.pluginSetupHint": "รัน: /plugin setup",
270
- "welcome.updateHint": "รัน: xcsh update",
270
+ "welcome.updateHint": "รัน: xcsh self-update",
271
271
  "welcome.newVersion": "เวอร์ชันใหม่",
272
272
  "welcome.connectionFailed": "— การเชื่อมต่อล้มเหลว",
273
273
  "welcome.runLoginReconnect": "รัน /login เพื่อเชื่อมต่อใหม่",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "模型提供商",
268
268
  "welcome.plugins": "插件",
269
269
  "welcome.pluginSetupHint": "运行:/plugin setup",
270
- "welcome.updateHint": "运行:xcsh update",
270
+ "welcome.updateHint": "运行:xcsh self-update",
271
271
  "welcome.newVersion": "新版本",
272
272
  "welcome.connectionFailed": "— 连接失败",
273
273
  "welcome.runLoginReconnect": "运行 /login 重新连接",
@@ -267,7 +267,7 @@
267
267
  "welcome.modelProvider": "模型供應商",
268
268
  "welcome.plugins": "外掛程式",
269
269
  "welcome.pluginSetupHint": "執行:/plugin setup",
270
- "welcome.updateHint": "執行:xcsh update",
270
+ "welcome.updateHint": "執行:xcsh self-update",
271
271
  "welcome.newVersion": "新版本",
272
272
  "welcome.connectionFailed": "— 連線失敗",
273
273
  "welcome.runLoginReconnect": "執行 /login 重新連線",
package/src/main.ts CHANGED
@@ -180,7 +180,7 @@ async function runInteractiveMode(
180
180
  if (settings.get("startup.checkUpdate")) {
181
181
  void versionCheckPromise
182
182
  .then(latest => {
183
- if (latest) mode.showStatus(`Update available: v${latest} — run: xcsh update`, { dim: true });
183
+ if (latest) mode.showStatus(`Update available: v${latest} — run: xcsh self-update`, { dim: true });
184
184
  })
185
185
  .catch(() => {});
186
186
  }
@@ -13,19 +13,20 @@ followed symlinks — so how a path is spelled does not change what is reachable
13
13
  - The operator's home and configuration belong to the operator. Shell profiles, SSH and GPG state,
14
14
  Git and cloud CLI configuration, xcsh settings, plugins, and skills are readable and writable with
15
15
  the operator's normal filesystem rights.
16
- - Cross-tenant isolation removes the discovery step. The directory containing the session root cannot
17
- be enumerated, but a sibling path the operator names directly can still be read, written, or entered.
18
- An explicit read grant, including `--allow-path <dir>`, restores enumeration for that directory.
19
- - Cross-session stores, other operators' accounts, and data roots remain denied. Another session's
20
- transcripts, memories, internal contexts, and temporary working state are not reachable through
21
- tools, nor are sibling local accounts, unrelated data roots, and mounted data volumes.
16
+ - Cross-tenant isolation removes the discovery step. The session container, local-account containers,
17
+ data roots, and mounted-data containers cannot be enumerated, but a descendant path the operator
18
+ names directly can still be read, written, or entered. An explicit read grant restores enumeration.
19
+ - Xcsh-private cross-session stores remain denied recursively. Another session's transcripts, memories,
20
+ internal contexts, credentials, and temporary working state are not reachable unless the operator
21
+ explicitly grants the relevant root.
22
22
 
23
- The same boundary answers for every tool. `read`, `write`, `grep`, `find`, `python`, and `bash` consult
24
- the same rules, so changing tools or spelling a path differently does not widen the session.
23
+ Structured filesystem tools and the `bash` runtime consult the same fence. Bash command text is not
24
+ scanned for path-looking strings; the operating system decides when a process actually opens a path.
25
+ The persistent `python` kernel cannot carry a per-session runtime fence, so only an explicit Python
26
+ `cwd` is checked. Python source and cell text are not scanned.
25
27
 
26
28
  If parent enumeration is refused, use a known path or ask the operator for an explicit read grant. If
27
- a cross-session or data-root path is refused, do not try to reach it another way. Say what you needed
28
- and why.
29
+ an xcsh-private cross-session path is refused, say what you needed and why.
29
30
 
30
31
  This sandbox is a courtesy for session-context isolation, not a privilege boundary against xcsh or the
31
32
  operator. The rule of thumb is that if a file belongs to someone other than the operator you are
@@ -47,14 +48,12 @@ Three things behave differently under this backend, and none of them is a bug to
47
48
  {{/if}}
48
49
  {{else}}
49
50
  On this platform there is **no OS-level backend**, so for `bash` the boundary is enforced only by
50
- scanning the command text before it runs. That check is best-effort by construction: it reads what you
51
- wrote rather than what the shell will do, so a path assembled at runtime or reached through an unusual
52
- spelling may not be caught.
51
+ precise pre-checks for an explicit `cwd`, literal redirections, known write operands, and literal
52
+ directory changes. Command and source text are never scanned for path-looking strings.
53
53
 
54
- The intended rules are the same ones a confined session has: parent enumeration is refused while named
55
- operator access remains available, operator-owned home and configuration stay readable and writable,
56
- and cross-session stores, other operators' accounts, and unrelated data roots stay denied. Ordinary
57
- work remains unrestricted.
54
+ Without a runtime backend, Bash child-process reads cannot enforce protected-container enumeration or
55
+ xcsh-private-root denial. Structured tools still enforce those rules, and ordinary work remains
56
+ unrestricted. The persistent `python` kernel is likewise unfenced beyond its explicit `cwd` check.
58
57
 
59
58
  Treat the boundary as a statement of intent rather than a guarantee, and do not go looking for paths
60
59
  outside the session directory on the assumption that something would stop you.
@@ -10,6 +10,7 @@ export type {
10
10
  ApiSpecValidationResourceEntry,
11
11
  DiffEntry,
12
12
  KindResolver,
13
+ ManifestOperationInput,
13
14
  ManifestValidationResult,
14
15
  OperationResult,
15
16
  ParsedResourceArgs,
@@ -18,6 +19,10 @@ export type {
18
19
  ResourceDiff,
19
20
  ResourceError,
20
21
  ResourceManifest,
22
+ ResourceOperation,
23
+ ResourceOperationCounts,
24
+ ResourceOperationItem,
25
+ ResourceOperationReport,
21
26
  ValidationError,
22
27
  ValidationWarning,
23
28
  } from "@f5-sales-demo/pi-resource-management";
@@ -29,6 +34,7 @@ export {
29
34
  formatOperationResult,
30
35
  formatResourceDetail,
31
36
  formatResourceList,
37
+ formatResourceOperationReport,
32
38
  formatValidationErrors,
33
39
  KindResolutionError,
34
40
  ManifestFileError,
@@ -37,6 +43,8 @@ export {
37
43
  parseResourceArgs,
38
44
  ResourceClient,
39
45
  readManifestFiles,
46
+ readManifestInputs,
47
+ runResourceOperation,
40
48
  validateManifest,
41
49
  validateManifests,
42
50
  } from "@f5-sales-demo/pi-resource-management";