@cspeach/cli 1.1.4 → 1.1.5
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.
|
@@ -25,7 +25,13 @@ export async function dispatchTool(name, args, ctx) {
|
|
|
25
25
|
// Rule 8 — no batch without plan. 2nd+ mutating call this turn requires
|
|
26
26
|
// explicit confirmation. Fires regardless of /safety-mode toggle (batch
|
|
27
27
|
// detection is unconditional per Plan 3 §6.6).
|
|
28
|
-
|
|
28
|
+
// Scratch-output exemption (2026-09-16): files under ./cspeach-out/ are the
|
|
29
|
+
// standalone Manual Implementation Guide outputs (NN-<OBJECT>.<ext>,
|
|
30
|
+
// GUIDE.md) — local scratch, not SAP objects. Rule 8 protects SAP batches;
|
|
31
|
+
// applying it here made the 2nd+ file (GUIDE.md) hit the batch card and,
|
|
32
|
+
// headless, get refused. Exempt from the gate AND from the batch count.
|
|
33
|
+
const scratchWrite = isScratchOutputWrite(tool, args);
|
|
34
|
+
if (tool.isMutating && !scratchWrite && shouldGateRule8()) {
|
|
29
35
|
const r = await presentSafetyConfirmation({
|
|
30
36
|
rule: 'RULE_8_BATCH_PLAN',
|
|
31
37
|
op: tool.name,
|
|
@@ -67,7 +73,7 @@ export async function dispatchTool(name, args, ctx) {
|
|
|
67
73
|
// Always record AFTER successful mutating dispatch — applies to 1st and
|
|
68
74
|
// 2nd+ writes alike. The 1st write seeds the counter; without this the
|
|
69
75
|
// gate would never fire on the 2nd write.
|
|
70
|
-
if (tool.isMutating && !(result.is_error ?? false)) {
|
|
76
|
+
if (tool.isMutating && !scratchWrite && !(result.is_error ?? false)) {
|
|
71
77
|
recordWriteOp(tool.name, args);
|
|
72
78
|
}
|
|
73
79
|
return { content: result.content, is_error: result.is_error ?? false };
|
|
@@ -76,3 +82,22 @@ export async function dispatchTool(name, args, ctx) {
|
|
|
76
82
|
return { content: JSON.stringify({ error: String(err) }), is_error: true };
|
|
77
83
|
}
|
|
78
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* True for a mutating filesystem tool whose target sits under ./cspeach-out/
|
|
87
|
+
* (relative to cwd). Accepts `cspeach-out/…`, `./cspeach-out/…` and the
|
|
88
|
+
* Windows backslash form; rejects anything that climbs out (`..`) or is
|
|
89
|
+
* absolute. Deliberately narrow: only this one folder is exempt.
|
|
90
|
+
*/
|
|
91
|
+
export function isScratchOutputWrite(tool, args) {
|
|
92
|
+
if (!tool.isMutating || tool.category !== 'filesystem')
|
|
93
|
+
return false;
|
|
94
|
+
const raw = args?.path;
|
|
95
|
+
if (typeof raw !== 'string' || raw.length === 0)
|
|
96
|
+
return false;
|
|
97
|
+
const p = raw.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
98
|
+
if (p.startsWith('/') || /^[A-Za-z]:\//.test(p))
|
|
99
|
+
return false;
|
|
100
|
+
if (p.split('/').some((seg) => seg === '..'))
|
|
101
|
+
return false;
|
|
102
|
+
return p === 'cspeach-out' || p.startsWith('cspeach-out/');
|
|
103
|
+
}
|
|
@@ -223,8 +223,8 @@ export const STANDALONE_NOTE = '<standalone_note>No SAP system is connected (sta
|
|
|
223
223
|
'numbered steps in dependency order, one object per step, each stating the object type and name, where to create it (ADT wizard path, or SE80/SE11/SE24/SE38 transaction for SE80 teams), ' +
|
|
224
224
|
'the exact source to paste, the activation step, and any prerequisite (package, transport, number range, message class). ' +
|
|
225
225
|
'Finish with a short verification checklist (syntax check, activation, ATC, unit test) the user can run themselves.\n' +
|
|
226
|
-
'File outputs: when file tools are available (local build is on),
|
|
227
|
-
'Step failures: when the user reports a failure at a step ("step 3 failed" plus an error message or screenshot), ask only for what is missing to diagnose it, fix only the affected object, rewrite its file, re-issue that step and any step that depends on it, and state which steps are unchanged. Never restart the whole guide.</standalone_note>';
|
|
226
|
+
'File outputs: when file tools are available (local build is on), you MUST write every produced object to the working folder as ./cspeach-out/<yyyy-mm-dd>-<short-task-name>/NN-<OBJECT_NAME>.<abap|ddls|bdef|srvd|srvb|ddlx|dcls|txt> in dependency order, and you MUST write the Manual Implementation Guide to GUIDE.md in the same folder before finishing the reply — each step pointing at its file and carrying a status (pending, done, failed, fixed). Tell the user the folder path once. If file tools are not available, say so once and keep everything in the reply.\n' +
|
|
227
|
+
'Step failures: when the user reports a failure at a step ("step 3 failed" plus an error message or screenshot), first re-read GUIDE.md and the affected object file from disk so you work from the exact current state, then ask only for what is missing to diagnose it, fix only the affected object, rewrite its file, update that step in GUIDE.md (status and what changed), re-issue that step and any step that depends on it, and state which steps are unchanged. If the user pastes an error without naming a step, identify the object from the error and confirm it in one line. Never restart the whole guide.</standalone_note>';
|
|
228
228
|
/**
|
|
229
229
|
* The full standalone contribution to `<session_context>`: the sap_system
|
|
230
230
|
* element followed by the hand-off note.
|