@cspeach/cli 1.1.17 → 1.1.18

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.
@@ -31,7 +31,12 @@ export async function dispatchTool(name, args, ctx) {
31
31
  // GUIDE.md) — local scratch, not SAP objects. Rule 8 protects SAP batches;
32
32
  // applying it here made the 2nd+ file (GUIDE.md) hit the batch card and,
33
33
  // headless, get refused. Exempt from the gate AND from the batch count.
34
- const scratchWrite = isScratchOutputWrite(tool, args, ctx.cwd);
34
+ // Local project work (owner decision 2026-09-25, CAP spike F2): the same
35
+ // reasoning for ALL local work — file edits (the filesystem tools refuse any
36
+ // path outside the project) and the safelisted local build commands. One-shot
37
+ // refused the 2nd edit of a CAP schema and left it half-changed. SAP writes
38
+ // are gated exactly as before.
39
+ const scratchWrite = isLocalProjectWork(tool, args) || isScratchOutputWrite(tool, args, ctx.cwd);
35
40
  if (tool.isMutating && !scratchWrite && shouldGateRule8()) {
36
41
  const r = await presentSafetyConfirmation({
37
42
  rule: 'RULE_8_BATCH_PLAN',
@@ -83,6 +88,22 @@ export async function dispatchTool(name, args, ctx) {
83
88
  return { content: JSON.stringify({ error: String(err) }), is_error: true };
84
89
  }
85
90
  }
91
+ /**
92
+ * True for local project work: the filesystem tools (confined to the project
93
+ * folder by resolveSafePath) and shell_exec (a hardcoded safelist of local build
94
+ * and VCS commands run in the project). Neither touches an SAP object, which is
95
+ * what Rule 8 protects — EXCEPT a deploy or publish: `npm run deploy` /
96
+ * `ui5 deploy` / `fiori deploy` upload to the ABAP repository, so any shell
97
+ * command with a deploy/publish argument still counts (deliberately broad).
98
+ */
99
+ export function isLocalProjectWork(tool, args) {
100
+ if (tool.category === 'filesystem')
101
+ return true;
102
+ if (tool.category !== 'shell')
103
+ return false;
104
+ const argv = [args?.command, ...(Array.isArray(args?.args) ? args.args : [])].map((a) => String(a ?? ''));
105
+ return !argv.some((a) => /deploy|publish/i.test(a));
106
+ }
86
107
  /**
87
108
  * True for a mutating filesystem tool whose target sits under the project's
88
109
  * own ./cspeach-out/ (cwd). Accepts `cspeach-out/…`, `./cspeach-out/…`, the
@@ -1,6 +1,6 @@
1
1
  // GENERATED FILE — bundled skills for local mode.
2
2
  // Source: https://manifest.cspeach.dev/v1.json
3
- // Generated: 2026-09-24T16:31:52.103Z
3
+ // Generated: 2026-09-25T16:38:47.082Z
4
4
  // Manifest signature verified at build time.
5
5
  export const BUNDLED_SKILLS = {
6
6
  "abap-atc-fix": {
@@ -1,4 +1,4 @@
1
1
  // GENERATED FILE — do not edit by hand.
2
2
  // Build artifact: ed25519 public key for SKILL.md body verification.
3
3
  // Regenerated by `pnpm prebuild` on each release.
4
- export const MANIFEST_PUBLIC_KEYS = ['a7Qj8ibfLTj49kQRTn1DOE/UAExuoBgjhaXxf33+JPY='];
4
+ export const MANIFEST_PUBLIC_KEYS = ['Nexqg3TSUYzVPirLv6h1tbCmpQF7MbAtVDmqoLAie+8=', 'a7Qj8ibfLTj49kQRTn1DOE/UAExuoBgjhaXxf33+JPY='];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cspeach/cli",
3
- "version": "1.1.17",
3
+ "version": "1.1.18",
4
4
  "description": "CSPeach — AI-assisted ABAP development CLI. Direct SAP access, 34 skills, safety gates.",
5
5
  "keywords": [
6
6
  "abap",
@@ -52,7 +52,7 @@
52
52
  "dependencies": {
53
53
  "@anthropic-ai/sdk": "^0.90.0",
54
54
  "@cspeach/register-core": "0.1.0",
55
- "@cspeach/sap-client": "0.1.12",
55
+ "@cspeach/sap-client": "0.1.13",
56
56
  "@iarna/toml": "^2.2.5",
57
57
  "@inkjs/ui": "^2.0.0",
58
58
  "@inquirer/prompts": "^7.0.0",