@possumtech/rummy 0.3.0 → 0.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.
- package/.env.example +13 -1
- package/PLUGINS.md +1 -1
- package/README.md +5 -1
- package/SPEC.md +211 -54
- package/migrations/001_initial_schema.sql +3 -4
- package/package.json +7 -3
- package/service.js +5 -3
- package/src/agent/AgentLoop.js +183 -238
- package/src/agent/ContextAssembler.js +2 -0
- package/src/agent/KnownStore.js +36 -85
- package/src/agent/ResponseHealer.js +65 -31
- package/src/agent/TurnExecutor.js +284 -382
- package/src/agent/XmlParser.js +28 -4
- package/src/agent/known_queries.sql +1 -1
- package/src/agent/known_store.sql +32 -34
- package/src/agent/runs.sql +2 -2
- package/src/agent/tokens.js +1 -0
- package/src/agent/turns.sql +5 -0
- package/src/hooks/HookRegistry.js +7 -0
- package/src/hooks/Hooks.js +2 -4
- package/src/hooks/ToolRegistry.js +8 -13
- package/src/plugins/ask_user/ask_userDoc.js +3 -8
- package/src/plugins/budget/README.md +26 -30
- package/src/plugins/budget/budget.js +69 -36
- package/src/plugins/budget/recovery.js +47 -0
- package/src/plugins/cp/cp.js +1 -1
- package/src/plugins/cp/cpDoc.js +5 -10
- package/src/plugins/env/envDoc.js +3 -8
- package/src/plugins/get/get.js +70 -2
- package/src/plugins/get/getDoc.js +19 -16
- package/src/plugins/hedberg/matcher.js +10 -29
- package/src/plugins/helpers.js +2 -2
- package/src/plugins/instructions/instructions.js +3 -2
- package/src/plugins/instructions/preamble.md +33 -12
- package/src/plugins/known/known.js +66 -17
- package/src/plugins/known/knownDoc.js +7 -10
- package/src/plugins/mv/mv.js +18 -1
- package/src/plugins/mv/mvDoc.js +9 -10
- package/src/plugins/{current → performed}/README.md +4 -3
- package/src/plugins/{current/current.js → performed/performed.js} +15 -20
- package/src/plugins/policy/policy.js +47 -0
- package/src/plugins/previous/README.md +2 -1
- package/src/plugins/previous/previous.js +31 -25
- package/src/plugins/progress/README.md +1 -2
- package/src/plugins/progress/progress.js +10 -60
- package/src/plugins/prompt/prompt.js +10 -8
- package/src/plugins/rm/rm.js +27 -15
- package/src/plugins/rm/rmDoc.js +6 -11
- package/src/plugins/rpc/rpc.js +3 -1
- package/src/plugins/set/set.js +125 -92
- package/src/plugins/set/setDoc.js +28 -37
- package/src/plugins/sh/shDoc.js +2 -7
- package/src/plugins/summarize/summarize.js +7 -0
- package/src/plugins/summarize/summarizeDoc.js +6 -11
- package/src/plugins/telemetry/telemetry.js +14 -9
- package/src/plugins/think/think.js +12 -0
- package/src/plugins/think/thinkDoc.js +18 -0
- package/src/plugins/unknown/README.md +2 -1
- package/src/plugins/unknown/unknown.js +26 -4
- package/src/plugins/unknown/unknownDoc.js +9 -14
- package/src/plugins/update/update.js +7 -0
- package/src/plugins/update/updateDoc.js +6 -11
- package/src/server/ClientConnection.js +69 -45
- package/src/sql/v_model_context.sql +7 -17
- package/src/plugins/budget/BudgetGuard.js +0 -74
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
export default class
|
|
1
|
+
export default class Performed {
|
|
2
2
|
#core;
|
|
3
3
|
|
|
4
4
|
constructor(core) {
|
|
5
5
|
this.#core = core;
|
|
6
|
-
core.filter("assembly.user", this.
|
|
6
|
+
core.filter("assembly.user", this.assemblePerformed.bind(this), 100);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
async
|
|
9
|
+
async assemblePerformed(content, ctx) {
|
|
10
10
|
const entries = ctx.rows.filter(
|
|
11
|
-
(r) =>
|
|
11
|
+
(r) =>
|
|
12
|
+
r.category === "logging" &&
|
|
13
|
+
r.source_turn >= ctx.loopStartTurn &&
|
|
14
|
+
r.scheme !== "unknown",
|
|
12
15
|
);
|
|
13
16
|
if (entries.length === 0) return content;
|
|
14
17
|
|
|
15
|
-
const lines =
|
|
16
|
-
|
|
17
|
-
);
|
|
18
|
-
return `${content}<current>\n${lines.join("\n")}\n</current>\n`;
|
|
18
|
+
const lines = entries.map((e) => renderToolTag(e));
|
|
19
|
+
return `${content}<performed>\n${lines.join("\n")}\n</performed>\n`;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
function renderToolTag(entry) {
|
|
23
24
|
const attrs =
|
|
24
25
|
typeof entry.attributes === "string"
|
|
25
26
|
? JSON.parse(entry.attributes)
|
|
@@ -28,23 +29,17 @@ async function renderToolTag(entry, core) {
|
|
|
28
29
|
const target = attrs?.path || attrs?.file || attrs?.command || "";
|
|
29
30
|
const turn = entry.source_turn ? ` turn="${entry.source_turn}"` : "";
|
|
30
31
|
const status = entry.status ? ` status="${entry.status}"` : "";
|
|
32
|
+
const fidelity = entry.fidelity ? ` fidelity="${entry.fidelity}"` : "";
|
|
33
|
+
const tokens = entry.tokens ? ` tokens="${entry.tokens}"` : "";
|
|
31
34
|
const summary =
|
|
32
35
|
typeof attrs?.summary === "string"
|
|
33
36
|
? ` summary="${attrs.summary.slice(0, 80)}"`
|
|
34
37
|
: "";
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
body = await core.hooks.tools.view(entry.scheme, {
|
|
39
|
-
...entry,
|
|
40
|
-
attributes: attrs,
|
|
41
|
-
});
|
|
42
|
-
} catch {
|
|
43
|
-
body = entry.body;
|
|
44
|
-
}
|
|
39
|
+
const body = entry.body || null;
|
|
45
40
|
|
|
46
41
|
if (body) {
|
|
47
|
-
return `<${entry.scheme} path="${target}"${turn}${status}${summary}>${body}</${entry.scheme}>`;
|
|
42
|
+
return `<${entry.scheme} path="${target}"${turn}${status}${summary}${fidelity}${tokens}>${body}</${entry.scheme}>`;
|
|
48
43
|
}
|
|
49
|
-
return `<${entry.scheme} path="${target}"${turn}${status}${summary}/>`;
|
|
44
|
+
return `<${entry.scheme} path="${target}"${turn}${status}${summary}${fidelity}${tokens}/>`;
|
|
50
45
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import KnownStore from "../../agent/KnownStore.js";
|
|
2
|
+
|
|
3
|
+
export default class Policy {
|
|
4
|
+
constructor(core) {
|
|
5
|
+
core.filter("entry.recording", this.#enforceAskMode.bind(this), 1);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async #enforceAskMode(entry, ctx) {
|
|
9
|
+
if (ctx.mode !== "ask") return entry;
|
|
10
|
+
|
|
11
|
+
if (entry.scheme === "sh") {
|
|
12
|
+
console.warn("[RUMMY] Rejected <sh> in ask mode");
|
|
13
|
+
return { ...entry, status: 403 };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (entry.scheme === "set" && entry.attributes?.path) {
|
|
17
|
+
const scheme = KnownStore.scheme(entry.attributes.path);
|
|
18
|
+
if (scheme === null && entry.body) {
|
|
19
|
+
console.warn(
|
|
20
|
+
`[RUMMY] Rejected file edit to ${entry.attributes.path} in ask mode`,
|
|
21
|
+
);
|
|
22
|
+
return { ...entry, status: 403 };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (entry.scheme === "rm") {
|
|
27
|
+
const pathAttr = entry.attributes?.path || entry.path;
|
|
28
|
+
const scheme = KnownStore.scheme(pathAttr);
|
|
29
|
+
if (scheme === null) {
|
|
30
|
+
console.warn(`[RUMMY] Rejected file rm of ${pathAttr} in ask mode`);
|
|
31
|
+
return { ...entry, status: 403 };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (entry.scheme === "mv" || entry.scheme === "cp") {
|
|
36
|
+
const destScheme = KnownStore.scheme(entry.attributes?.to);
|
|
37
|
+
if (destScheme === null) {
|
|
38
|
+
console.warn(
|
|
39
|
+
`[RUMMY] Rejected ${entry.scheme} to file ${entry.attributes?.to} in ask mode`,
|
|
40
|
+
);
|
|
41
|
+
return { ...entry, status: 403 };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return entry;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -12,4 +12,5 @@ history from prior ask/act invocations on this run.
|
|
|
12
12
|
|
|
13
13
|
Filters turn_context rows where `category` is `logging` or `prompt`
|
|
14
14
|
and `source_turn < loopStartTurn`. Renders each entry chronologically
|
|
15
|
-
with turn
|
|
15
|
+
with turn, status, summary, fidelity, and tokens. The model can target
|
|
16
|
+
these entries by path with `<set>` or `<rm>` to free context space.
|
|
@@ -9,11 +9,20 @@ export default class Previous {
|
|
|
9
9
|
async assemblePrevious(content, ctx) {
|
|
10
10
|
if (ctx.loopStartTurn <= 1) return content;
|
|
11
11
|
|
|
12
|
-
const entries = ctx.rows
|
|
13
|
-
(
|
|
14
|
-
(r
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const entries = ctx.rows
|
|
13
|
+
.filter(
|
|
14
|
+
(r) =>
|
|
15
|
+
(r.category === "logging" || r.category === "prompt") &&
|
|
16
|
+
r.source_turn < ctx.loopStartTurn,
|
|
17
|
+
)
|
|
18
|
+
.toSorted((a, b) => {
|
|
19
|
+
if (a.source_turn !== b.source_turn)
|
|
20
|
+
return a.source_turn - b.source_turn;
|
|
21
|
+
// Within the same turn: prompt first (cause before effect)
|
|
22
|
+
if (a.category === "prompt" && b.category !== "prompt") return -1;
|
|
23
|
+
if (b.category === "prompt" && a.category !== "prompt") return 1;
|
|
24
|
+
return 0;
|
|
25
|
+
});
|
|
17
26
|
if (entries.length === 0) return content;
|
|
18
27
|
|
|
19
28
|
const lines = await Promise.all(
|
|
@@ -23,7 +32,7 @@ export default class Previous {
|
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
|
|
26
|
-
async function renderToolTag(entry,
|
|
35
|
+
async function renderToolTag(entry, _core) {
|
|
27
36
|
const attrs =
|
|
28
37
|
typeof entry.attributes === "string"
|
|
29
38
|
? JSON.parse(entry.attributes)
|
|
@@ -32,23 +41,20 @@ async function renderToolTag(entry, core) {
|
|
|
32
41
|
const target = attrs?.path || attrs?.file || attrs?.command || "";
|
|
33
42
|
const turn = entry.source_turn ? ` turn="${entry.source_turn}"` : "";
|
|
34
43
|
const status = entry.status ? ` status="${entry.status}"` : "";
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
body
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return `<${entry.scheme} path="${target}"${turn}${status}${summary}>${body}</${entry.scheme}>`;
|
|
52
|
-
}
|
|
53
|
-
return `<${entry.scheme} path="${target}"${turn}${status}${summary}/>`;
|
|
44
|
+
const fidelity = entry.fidelity ? ` fidelity="${entry.fidelity}"` : "";
|
|
45
|
+
const tokens = entry.tokens ? ` tokens="${entry.tokens}"` : "";
|
|
46
|
+
|
|
47
|
+
// Previous entries render at summary. Prompts get 512 chars for orientation.
|
|
48
|
+
const limit = entry.scheme === "prompt" ? 512 : 80;
|
|
49
|
+
const rawSummary =
|
|
50
|
+
(typeof attrs?.summary === "string" ? attrs.summary : null) ||
|
|
51
|
+
entry.body?.slice(0, limit) ||
|
|
52
|
+
"";
|
|
53
|
+
// Strip internal dedup namespace prefixes (e.g. "get://turn_3/src/app.js" → "src/app.js")
|
|
54
|
+
const summaryText = rawSummary.replace(/\b\w+:\/\/turn_\d+\//g, "");
|
|
55
|
+
const summaryAttr = summaryText
|
|
56
|
+
? ` summary="${summaryText.replace(/"/g, "'").slice(0, limit)}"`
|
|
57
|
+
: "";
|
|
58
|
+
|
|
59
|
+
return `<${entry.scheme} path="${target}"${turn}${status}${summaryAttr}${fidelity}${tokens}/>`;
|
|
54
60
|
}
|
|
@@ -9,9 +9,8 @@ current work log to the active prompt.
|
|
|
9
9
|
|
|
10
10
|
## Behavior
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Emits `<progress turn="N">` carrying token budget and fidelity stats.
|
|
13
13
|
On continuation turns with current entries: "The above actions were
|
|
14
14
|
performed in response to the following prompt:"
|
|
15
|
-
If a `progress://` entry exists, uses its body directly.
|
|
16
15
|
|
|
17
16
|
Progress text is the tuning knob for model orientation between turns.
|
|
@@ -7,70 +7,20 @@ export default class Progress {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
async assembleProgress(content, ctx) {
|
|
10
|
-
|
|
11
|
-
// Falls back to row token sum (less accurate — missing system prompt overhead).
|
|
12
|
-
const rowTokens = ctx.rows.reduce((sum, r) => sum + (r.tokens || 0), 0);
|
|
13
|
-
const usedTokens = ctx.lastContextTokens || rowTokens;
|
|
14
|
-
const contextSize = ctx.contextSize || 0;
|
|
10
|
+
const { lastContextTokens: usedTokens, contextSize } = ctx;
|
|
15
11
|
const pct = contextSize ? Math.round((usedTokens / contextSize) * 100) : 0;
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const indexEntries = entries.filter((r) => r.fidelity === "index");
|
|
22
|
-
const fullTokens = fullEntries.reduce((s, r) => s + (r.tokens || 0), 0);
|
|
23
|
-
const summaryTokens = summaryEntries.reduce(
|
|
24
|
-
(s, r) => s + (r.tokens || 0),
|
|
25
|
-
0,
|
|
26
|
-
);
|
|
27
|
-
const indexTokens = indexEntries.reduce((s, r) => s + (r.tokens || 0), 0);
|
|
28
|
-
|
|
29
|
-
const unknownCount = ctx.rows.filter(
|
|
30
|
-
(r) => r.category === "unknown",
|
|
31
|
-
).length;
|
|
32
|
-
|
|
33
|
-
const hasCurrent = ctx.rows.some(
|
|
34
|
-
(r) => r.category === "logging" && r.source_turn >= ctx.loopStartTurn,
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
const parts = [];
|
|
38
|
-
|
|
39
|
-
const knownCount = entries.length;
|
|
40
|
-
const tokenLine = contextSize
|
|
41
|
-
? `${usedTokens} of ${contextSize} tokens (${pct}%) · ${knownCount} known${knownCount !== 1 ? "s" : ""} · ${unknownCount} unknown${unknownCount !== 1 ? "s" : ""}`
|
|
42
|
-
: "";
|
|
43
|
-
if (tokenLine) parts.push(tokenLine);
|
|
44
|
-
|
|
45
|
-
// Fidelity distribution
|
|
46
|
-
const fidelityParts = [];
|
|
47
|
-
if (fullEntries.length > 0)
|
|
48
|
-
fidelityParts.push(`${fullEntries.length} full (${fullTokens} tok)`);
|
|
49
|
-
if (summaryEntries.length > 0)
|
|
50
|
-
fidelityParts.push(
|
|
51
|
-
`${summaryEntries.length} summary (${summaryTokens} tok)`,
|
|
52
|
-
);
|
|
53
|
-
if (indexEntries.length > 0)
|
|
54
|
-
fidelityParts.push(`${indexEntries.length} index (${indexTokens} tok)`);
|
|
55
|
-
if (fidelityParts.length > 0)
|
|
56
|
-
parts.push(`Entries: ${fidelityParts.join(" · ")}`);
|
|
57
|
-
|
|
58
|
-
if (pct > 75) {
|
|
59
|
-
parts.push(
|
|
60
|
-
'Context above 75%. YOU MUST free space: <set fidelity="summary" summary="topic,detail,keyword"/>, <set fidelity="archive"/>, or <rm/>. Target the largest entries.',
|
|
61
|
-
);
|
|
62
|
-
} else if (pct > 50) {
|
|
63
|
-
parts.push(
|
|
64
|
-
'Context above 50%. You may free space: <set fidelity="summary" summary="topic,detail,keyword"/>, <set fidelity="archive"/>, or <rm/>.',
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (hasCurrent) {
|
|
69
|
-
parts.push(
|
|
70
|
-
"The above actions were performed in response to the following prompt:",
|
|
13
|
+
const lines = [];
|
|
14
|
+
if (contextSize) {
|
|
15
|
+
lines.push(
|
|
16
|
+
`Using ${usedTokens} tokens (${pct}%) of ${contextSize} token budget. Use <get/> or set entry fidelity to "full" to spend tokens. Set entry fidelity to "summary" to save tokens.`,
|
|
71
17
|
);
|
|
72
18
|
}
|
|
19
|
+
lines.push(
|
|
20
|
+
'Conclude with a brief <update></update> to continue or a brief <summarize></summarize> if done.',
|
|
21
|
+
);
|
|
22
|
+
const body = lines.join("\n");
|
|
73
23
|
|
|
74
|
-
return `${content}<progress
|
|
24
|
+
return `${content}<progress turn="${ctx.turn}">${body}</progress>\n`;
|
|
75
25
|
}
|
|
76
26
|
}
|
|
@@ -3,8 +3,16 @@ export default class Prompt {
|
|
|
3
3
|
|
|
4
4
|
constructor(core) {
|
|
5
5
|
this.#core = core;
|
|
6
|
-
core.hooks.tools.onView("prompt", (entry) =>
|
|
7
|
-
|
|
6
|
+
core.hooks.tools.onView("prompt", (entry) => {
|
|
7
|
+
if (entry.fidelity === "summary") {
|
|
8
|
+
const limit = 500;
|
|
9
|
+
const text = entry.body?.slice(0, limit) || "";
|
|
10
|
+
return text.length < (entry.body?.length || 0)
|
|
11
|
+
? `${text}\n[truncated — promote to full to see the complete prompt]`
|
|
12
|
+
: text;
|
|
13
|
+
}
|
|
14
|
+
return entry.body;
|
|
15
|
+
});
|
|
8
16
|
core.on("turn.started", this.onTurnStarted.bind(this));
|
|
9
17
|
core.filter("assembly.user", this.assemblePrompt.bind(this), 300);
|
|
10
18
|
}
|
|
@@ -17,10 +25,6 @@ export default class Prompt {
|
|
|
17
25
|
attributes: { mode },
|
|
18
26
|
loopId,
|
|
19
27
|
});
|
|
20
|
-
} else {
|
|
21
|
-
await store.upsert(runId, turn, `progress://${turn}`, prompt || "", 200, {
|
|
22
|
-
loopId,
|
|
23
|
-
});
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -41,8 +45,6 @@ export default class Prompt {
|
|
|
41
45
|
const tools = toolNames.join(",");
|
|
42
46
|
let warn = "";
|
|
43
47
|
if (mode === "ask") warn = ' warn="File editing disallowed."';
|
|
44
|
-
if (mode === "panic")
|
|
45
|
-
warn = ' warn="Context overflow. Free space to continue."';
|
|
46
48
|
|
|
47
49
|
return `${content}<prompt mode="${mode}" tools="${tools}"${warn}>${body}</prompt>`;
|
|
48
50
|
}
|
package/src/plugins/rm/rm.js
CHANGED
|
@@ -41,25 +41,37 @@ export default class Rm {
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
44
|
+
const fileMatches = matches.filter((m) => m.scheme === null);
|
|
45
|
+
const schemeMatches = matches.filter((m) => m.scheme !== null);
|
|
46
|
+
|
|
47
|
+
// Scheme entries: remove all, write one aggregate result entry
|
|
48
|
+
for (const match of schemeMatches) await store.remove(runId, match.path);
|
|
49
|
+
if (schemeMatches.length > 0) {
|
|
50
|
+
const paths = schemeMatches.map((m) => m.path).join("\n");
|
|
51
|
+
await store.upsert(runId, turn, entry.resultPath, paths, 200, {
|
|
52
|
+
attributes: { path: target },
|
|
53
|
+
loopId,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// File entries: individual 202 proposals (require user resolution)
|
|
58
|
+
if (fileMatches.length > 0 && schemeMatches.length > 0)
|
|
59
|
+
await store.remove(runId, entry.resultPath);
|
|
60
|
+
for (const match of fileMatches) {
|
|
61
|
+
const resultPath =
|
|
62
|
+
schemeMatches.length === 0 && fileMatches.length === 1
|
|
63
|
+
? entry.resultPath
|
|
64
|
+
: await store.dedup(runId, "rm", match.path, turn);
|
|
65
|
+
await store.upsert(runId, turn, resultPath, match.path, 202, {
|
|
66
|
+
attributes: { path: match.path },
|
|
67
|
+
loopId,
|
|
68
|
+
});
|
|
58
69
|
}
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
full(entry) {
|
|
62
|
-
|
|
73
|
+
const header = `# rm ${entry.attributes.path || entry.path}`;
|
|
74
|
+
return entry.body ? `${header}\n${entry.body}` : header;
|
|
63
75
|
}
|
|
64
76
|
|
|
65
77
|
summary(entry) {
|
package/src/plugins/rm/rmDoc.js
CHANGED
|
@@ -2,28 +2,23 @@
|
|
|
2
2
|
// Text goes to the model. Rationale stays in source.
|
|
3
3
|
// Changing ANY line requires reading ALL rationales first.
|
|
4
4
|
const LINES = [
|
|
5
|
-
// --- Syntax: path attr, self-closing
|
|
6
5
|
['## <rm path="[path]"/> - Remove a file or entry'],
|
|
7
|
-
|
|
8
|
-
// --- Examples: file, known (with slug path), preview safety
|
|
9
6
|
['Example: <rm path="src/config.js"/>', "File removal. Simplest form."],
|
|
10
7
|
[
|
|
11
|
-
'Example: <rm path="known://
|
|
12
|
-
"Shows
|
|
8
|
+
'Example: <rm path="known://config/deprecated_service"/>',
|
|
9
|
+
"Shows topic-hierarchy path convention.",
|
|
13
10
|
],
|
|
14
11
|
[
|
|
15
12
|
'Example: <rm path="known://temp_*" preview/>',
|
|
16
|
-
"Preview before deleting.
|
|
13
|
+
"Preview before deleting. Safety pattern for bulk operations.",
|
|
17
14
|
],
|
|
18
|
-
|
|
19
|
-
// --- Constraints
|
|
20
15
|
[
|
|
21
16
|
'* Permanent. Prefer <set fidelity="archive"/> to preserve for later retrieval',
|
|
22
|
-
"Nudges toward archive over rm.
|
|
17
|
+
"Nudges toward archive over rm.",
|
|
23
18
|
],
|
|
24
19
|
[
|
|
25
|
-
"*
|
|
26
|
-
"Reinforces preview safety pattern.
|
|
20
|
+
"* Use `preview` to check matches before pattern-based bulk deletion",
|
|
21
|
+
"Reinforces preview safety pattern.",
|
|
27
22
|
],
|
|
28
23
|
];
|
|
29
24
|
|
package/src/plugins/rpc/rpc.js
CHANGED
|
@@ -178,7 +178,7 @@ export default class Rpc {
|
|
|
178
178
|
scheme: e.scheme,
|
|
179
179
|
status: e.status,
|
|
180
180
|
fidelity: e.fidelity,
|
|
181
|
-
tokens: e.
|
|
181
|
+
tokens: e.tokens,
|
|
182
182
|
}));
|
|
183
183
|
},
|
|
184
184
|
description: "Query entries by pattern.",
|
|
@@ -233,6 +233,7 @@ export default class Rpc {
|
|
|
233
233
|
contextLimit: params.contextLimit,
|
|
234
234
|
noRepo: params.noRepo,
|
|
235
235
|
noInteraction: params.noInteraction,
|
|
236
|
+
noProposals: params.noProposals,
|
|
236
237
|
noWeb: params.noWeb,
|
|
237
238
|
fork: params.fork,
|
|
238
239
|
},
|
|
@@ -269,6 +270,7 @@ export default class Rpc {
|
|
|
269
270
|
contextLimit: params.contextLimit,
|
|
270
271
|
noRepo: params.noRepo,
|
|
271
272
|
noInteraction: params.noInteraction,
|
|
273
|
+
noProposals: params.noProposals,
|
|
272
274
|
noWeb: params.noWeb,
|
|
273
275
|
fork: params.fork,
|
|
274
276
|
},
|