@possumtech/rummy 0.5.0 → 2.0.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 +21 -5
- package/PLUGINS.md +389 -194
- package/README.md +25 -8
- package/SPEC.md +850 -373
- package/bin/demo.js +166 -0
- package/bin/rummy.js +9 -3
- package/biome/no-fallbacks.grit +50 -0
- package/lang/en.json +2 -2
- package/migrations/001_initial_schema.sql +88 -37
- package/package.json +6 -4
- package/service.js +50 -9
- package/src/agent/AgentLoop.js +460 -330
- package/src/agent/ContextAssembler.js +4 -4
- package/src/agent/Entries.js +655 -0
- package/src/agent/ProjectAgent.js +30 -18
- package/src/agent/TurnExecutor.js +229 -421
- package/src/agent/XmlParser.js +99 -33
- package/src/agent/budget.js +56 -0
- package/src/agent/errors.js +22 -0
- package/src/agent/httpStatus.js +39 -0
- package/src/agent/known_checks.sql +8 -4
- package/src/agent/known_queries.sql +9 -13
- package/src/agent/known_store.sql +275 -125
- package/src/agent/materializeContext.js +102 -0
- package/src/agent/runs.sql +10 -7
- package/src/agent/schemes.sql +14 -3
- package/src/agent/turns.sql +9 -9
- package/src/hooks/HookRegistry.js +6 -5
- package/src/hooks/Hooks.js +44 -3
- package/src/hooks/PluginContext.js +29 -21
- package/src/{server → hooks}/RpcRegistry.js +2 -1
- package/src/hooks/RummyContext.js +135 -35
- package/src/hooks/ToolRegistry.js +21 -16
- package/src/llm/LlmProvider.js +64 -90
- package/src/llm/errors.js +21 -0
- package/src/plugins/ask_user/README.md +1 -1
- package/src/plugins/ask_user/ask_user.js +37 -12
- package/src/plugins/ask_user/ask_userDoc.js +2 -25
- package/src/plugins/ask_user/ask_userDoc.md +10 -0
- package/src/plugins/budget/README.md +27 -25
- package/src/plugins/budget/budget.js +260 -88
- package/src/plugins/cp/README.md +2 -2
- package/src/plugins/cp/cp.js +29 -11
- package/src/plugins/cp/cpDoc.js +2 -15
- package/src/plugins/cp/cpDoc.md +7 -0
- package/src/plugins/engine/README.md +2 -2
- package/src/plugins/engine/engine.sql +4 -4
- package/src/plugins/engine/turn_context.sql +10 -10
- package/src/plugins/env/README.md +20 -5
- package/src/plugins/env/env.js +45 -6
- package/src/plugins/env/envDoc.js +2 -23
- package/src/plugins/env/envDoc.md +13 -0
- package/src/plugins/error/README.md +16 -0
- package/src/plugins/error/error.js +151 -0
- package/src/plugins/file/README.md +6 -6
- package/src/plugins/file/file.js +15 -2
- package/src/plugins/get/README.md +1 -1
- package/src/plugins/get/get.js +103 -48
- package/src/plugins/get/getDoc.js +2 -32
- package/src/plugins/get/getDoc.md +36 -0
- package/src/plugins/hedberg/README.md +1 -2
- package/src/plugins/hedberg/hedberg.js +8 -4
- package/src/plugins/hedberg/matcher.js +16 -17
- package/src/plugins/hedberg/normalize.js +0 -48
- package/src/plugins/helpers.js +42 -2
- package/src/plugins/index.js +146 -123
- package/src/plugins/instructions/README.md +35 -9
- package/src/plugins/instructions/instructions.js +122 -9
- package/src/plugins/instructions/instructions.md +25 -0
- package/src/plugins/instructions/instructions_104.md +7 -0
- package/src/plugins/instructions/instructions_105.md +46 -0
- package/src/plugins/instructions/instructions_106.md +0 -0
- package/src/plugins/instructions/instructions_107.md +0 -0
- package/src/plugins/instructions/instructions_108.md +8 -0
- package/src/plugins/instructions/protocol.js +12 -0
- package/src/plugins/known/README.md +2 -2
- package/src/plugins/known/known.js +67 -36
- package/src/plugins/known/knownDoc.js +2 -17
- package/src/plugins/known/knownDoc.md +8 -0
- package/src/plugins/log/README.md +48 -0
- package/src/plugins/log/log.js +109 -0
- package/src/plugins/mv/README.md +2 -2
- package/src/plugins/mv/mv.js +55 -22
- package/src/plugins/mv/mvDoc.js +2 -18
- package/src/plugins/mv/mvDoc.md +10 -0
- package/src/plugins/ollama/README.md +15 -0
- package/src/{llm/OllamaClient.js → plugins/ollama/ollama.js} +40 -18
- package/src/plugins/openai/README.md +17 -0
- package/src/plugins/openai/openai.js +120 -0
- package/src/plugins/openrouter/README.md +27 -0
- package/src/plugins/openrouter/openrouter.js +121 -0
- package/src/plugins/persona/README.md +20 -0
- package/src/plugins/persona/persona.js +9 -16
- package/src/plugins/policy/README.md +21 -0
- package/src/plugins/policy/policy.js +29 -14
- package/src/plugins/prompt/README.md +1 -1
- package/src/plugins/prompt/prompt.js +58 -16
- package/src/plugins/rm/README.md +1 -1
- package/src/plugins/rm/rm.js +56 -12
- package/src/plugins/rm/rmDoc.js +2 -20
- package/src/plugins/rm/rmDoc.md +13 -0
- package/src/plugins/rpc/README.md +2 -2
- package/src/plugins/rpc/rpc.js +515 -296
- package/src/plugins/set/README.md +1 -1
- package/src/plugins/set/set.js +318 -75
- package/src/plugins/set/setDoc.js +2 -35
- package/src/plugins/set/setDoc.md +22 -0
- package/src/plugins/sh/README.md +28 -5
- package/src/plugins/sh/sh.js +50 -6
- package/src/plugins/sh/shDoc.js +2 -23
- package/src/plugins/sh/shDoc.md +13 -0
- package/src/plugins/skill/README.md +23 -0
- package/src/plugins/skill/skill.js +14 -18
- package/src/plugins/stream/README.md +101 -0
- package/src/plugins/stream/stream.js +290 -0
- package/src/plugins/telemetry/README.md +1 -1
- package/src/plugins/telemetry/telemetry.js +129 -80
- package/src/plugins/think/README.md +1 -1
- package/src/plugins/think/think.js +12 -0
- package/src/plugins/think/thinkDoc.js +2 -15
- package/src/plugins/think/thinkDoc.md +7 -0
- package/src/plugins/unknown/README.md +3 -3
- package/src/plugins/unknown/unknown.js +47 -19
- package/src/plugins/unknown/unknownDoc.js +2 -21
- package/src/plugins/unknown/unknownDoc.md +11 -0
- package/src/plugins/update/README.md +1 -1
- package/src/plugins/update/update.js +67 -5
- package/src/plugins/update/updateDoc.js +2 -30
- package/src/plugins/update/updateDoc.md +8 -0
- package/src/plugins/xai/README.md +23 -0
- package/src/{llm/XaiClient.js → plugins/xai/xai.js} +58 -37
- package/src/server/ClientConnection.js +64 -37
- package/src/server/SocketServer.js +23 -10
- package/src/server/protocol.js +11 -0
- package/src/sql/v_model_context.sql +27 -31
- package/src/sql/v_run_log.sql +9 -14
- package/EXCEPTIONS.md +0 -46
- package/FIDELITY_CONTRACT.md +0 -172
- package/src/agent/KnownStore.js +0 -337
- package/src/agent/ResponseHealer.js +0 -241
- package/src/llm/OpenAiClient.js +0 -100
- package/src/llm/OpenRouterClient.js +0 -100
- package/src/plugins/budget/recovery.js +0 -47
- package/src/plugins/instructions/preamble.md +0 -45
- package/src/plugins/performed/README.md +0 -15
- package/src/plugins/performed/performed.js +0 -45
- package/src/plugins/previous/README.md +0 -16
- package/src/plugins/previous/previous.js +0 -56
- package/src/plugins/progress/README.md +0 -16
- package/src/plugins/progress/progress.js +0 -43
- package/src/plugins/summarize/README.md +0 -19
- package/src/plugins/summarize/summarize.js +0 -32
- package/src/plugins/summarize/summarizeDoc.js +0 -27
|
@@ -1,44 +1,59 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Entries from "../../agent/Entries.js";
|
|
2
2
|
|
|
3
3
|
export default class Policy {
|
|
4
|
+
#core;
|
|
5
|
+
|
|
4
6
|
constructor(core) {
|
|
7
|
+
this.#core = core;
|
|
5
8
|
core.filter("entry.recording", this.#enforceAskMode.bind(this), 1);
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
async #reject(ctx, message) {
|
|
12
|
+
await this.#core.hooks.error.log.emit({
|
|
13
|
+
store: ctx.store,
|
|
14
|
+
runId: ctx.runId,
|
|
15
|
+
turn: ctx.turn,
|
|
16
|
+
loopId: ctx.loopId,
|
|
17
|
+
message,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
8
21
|
async #enforceAskMode(entry, ctx) {
|
|
9
22
|
if (ctx.mode !== "ask") return entry;
|
|
10
23
|
|
|
11
24
|
if (entry.scheme === "sh") {
|
|
12
|
-
|
|
13
|
-
return { ...entry,
|
|
25
|
+
await this.#reject(ctx, "Rejected <sh> in ask mode");
|
|
26
|
+
return { ...entry, state: "failed", outcome: "permission" };
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
if (entry.scheme === "set" && entry.attributes?.path) {
|
|
17
|
-
const scheme =
|
|
30
|
+
const scheme = Entries.scheme(entry.attributes.path);
|
|
18
31
|
if (scheme === null && entry.body) {
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
await this.#reject(
|
|
33
|
+
ctx,
|
|
34
|
+
`Rejected file edit to ${entry.attributes.path} in ask mode`,
|
|
21
35
|
);
|
|
22
|
-
return { ...entry,
|
|
36
|
+
return { ...entry, state: "failed", outcome: "permission" };
|
|
23
37
|
}
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
if (entry.scheme === "rm") {
|
|
27
41
|
const pathAttr = entry.attributes?.path || entry.path;
|
|
28
|
-
const scheme =
|
|
42
|
+
const scheme = Entries.scheme(pathAttr);
|
|
29
43
|
if (scheme === null) {
|
|
30
|
-
|
|
31
|
-
return { ...entry,
|
|
44
|
+
await this.#reject(ctx, `Rejected file rm of ${pathAttr} in ask mode`);
|
|
45
|
+
return { ...entry, state: "failed", outcome: "permission" };
|
|
32
46
|
}
|
|
33
47
|
}
|
|
34
48
|
|
|
35
49
|
if (entry.scheme === "mv" || entry.scheme === "cp") {
|
|
36
|
-
const destScheme =
|
|
50
|
+
const destScheme = Entries.scheme(entry.attributes?.to);
|
|
37
51
|
if (destScheme === null) {
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
await this.#reject(
|
|
53
|
+
ctx,
|
|
54
|
+
`Rejected ${entry.scheme} to file ${entry.attributes?.to} in ask mode`,
|
|
40
55
|
);
|
|
41
|
-
return { ...entry,
|
|
56
|
+
return { ...entry, state: "failed", outcome: "permission" };
|
|
42
57
|
}
|
|
43
58
|
}
|
|
44
59
|
|
|
@@ -3,17 +3,16 @@ export default class Prompt {
|
|
|
3
3
|
|
|
4
4
|
constructor(core) {
|
|
5
5
|
this.#core = core;
|
|
6
|
-
core.hooks.tools.onView("prompt", (entry) => entry.body, "
|
|
6
|
+
core.hooks.tools.onView("prompt", (entry) => entry.body, "visible");
|
|
7
7
|
core.hooks.tools.onView(
|
|
8
8
|
"prompt",
|
|
9
9
|
(entry) => {
|
|
10
10
|
const limit = 500;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
: text;
|
|
11
|
+
const full = entry.body;
|
|
12
|
+
if (full.length <= limit) return full;
|
|
13
|
+
return `${full.slice(0, limit)}\n[truncated — promote to see the complete prompt]`;
|
|
15
14
|
},
|
|
16
|
-
"
|
|
15
|
+
"summarized",
|
|
17
16
|
);
|
|
18
17
|
core.on("turn.started", this.onTurnStarted.bind(this));
|
|
19
18
|
core.filter("assembly.user", this.assemblePrompt.bind(this), 300);
|
|
@@ -23,15 +22,23 @@ export default class Prompt {
|
|
|
23
22
|
const { entries: store, sequence: turn, runId, loopId } = rummy;
|
|
24
23
|
|
|
25
24
|
if (!isContinuation && prompt) {
|
|
26
|
-
|
|
25
|
+
// prompt:// writable_by: ["plugin"] — explicit for clarity.
|
|
26
|
+
await store.set({
|
|
27
|
+
runId,
|
|
28
|
+
turn,
|
|
29
|
+
path: `prompt://${turn}`,
|
|
30
|
+
body: prompt,
|
|
31
|
+
state: "resolved",
|
|
27
32
|
attributes: { mode },
|
|
28
33
|
loopId,
|
|
34
|
+
writer: "plugin",
|
|
29
35
|
});
|
|
30
36
|
}
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
async assemblePrompt(content, ctx) {
|
|
34
|
-
const
|
|
40
|
+
const { rows, contextSize, toolSet } = ctx;
|
|
41
|
+
const promptEntry = rows.findLast(
|
|
35
42
|
(r) => r.category === "prompt" && r.scheme === "prompt",
|
|
36
43
|
);
|
|
37
44
|
|
|
@@ -39,16 +46,51 @@ export default class Prompt {
|
|
|
39
46
|
typeof promptEntry?.attributes === "string"
|
|
40
47
|
? JSON.parse(promptEntry.attributes)
|
|
41
48
|
: promptEntry?.attributes;
|
|
42
|
-
const mode = attrs?.mode
|
|
43
|
-
const body = promptEntry
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
const mode = attrs?.mode ? attrs.mode : ctx.type;
|
|
50
|
+
const body = promptEntry ? promptEntry.body : "";
|
|
51
|
+
const activeTools = toolSet
|
|
52
|
+
? new Set(toolSet)
|
|
53
|
+
: new Set(this.#core.hooks.tools.names);
|
|
54
|
+
const commands = this.#core.hooks.tools.advertisedNames
|
|
55
|
+
.filter((n) => activeTools.has(n))
|
|
56
|
+
.join(",");
|
|
49
57
|
let warn = "";
|
|
50
58
|
if (mode === "ask") warn = ' warn="File editing disallowed."';
|
|
51
59
|
|
|
52
|
-
|
|
60
|
+
// Surface the most recent prior-turn budget demotion as a
|
|
61
|
+
// `reverted="N"` attribute on <prompt>. Historical error
|
|
62
|
+
// entries sit in <log> but read as ambient noise; this signal
|
|
63
|
+
// is dynamic and always fresh — the model sees that its
|
|
64
|
+
// promotions last turn were reverted, in the same spot where
|
|
65
|
+
// it reads budget numbers.
|
|
66
|
+
let reverted = "";
|
|
67
|
+
const priorTurn = ctx.turn - 1;
|
|
68
|
+
if (priorTurn >= 1) {
|
|
69
|
+
const priorDemotion = rows.find((r) => {
|
|
70
|
+
if (!r.path.startsWith(`log://turn_${priorTurn}/error/`)) return false;
|
|
71
|
+
const attrs =
|
|
72
|
+
typeof r.attributes === "string"
|
|
73
|
+
? JSON.parse(r.attributes)
|
|
74
|
+
: r.attributes;
|
|
75
|
+
return attrs?.status === 413 && attrs?.demotedCount > 0;
|
|
76
|
+
});
|
|
77
|
+
if (priorDemotion) {
|
|
78
|
+
const attrs =
|
|
79
|
+
typeof priorDemotion.attributes === "string"
|
|
80
|
+
? JSON.parse(priorDemotion.attributes)
|
|
81
|
+
: priorDemotion.attributes;
|
|
82
|
+
reverted = ` reverted="${attrs.demotedCount}"`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const path = promptEntry ? ` path="${promptEntry.path}"` : "";
|
|
87
|
+
const visibility = promptEntry?.visibility
|
|
88
|
+
? ` visibility="${promptEntry.visibility}"`
|
|
89
|
+
: "";
|
|
90
|
+
const tokens =
|
|
91
|
+
promptEntry?.aTokens != null
|
|
92
|
+
? ` tokens="${promptEntry.aTokens}"`
|
|
93
|
+
: "";
|
|
94
|
+
return `${content}<prompt mode="${mode}"${path} commands="${commands}"${warn}${reverted}${visibility}${tokens}>${body}</prompt>`;
|
|
53
95
|
}
|
|
54
96
|
}
|
package/src/plugins/rm/README.md
CHANGED
package/src/plugins/rm/rm.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Entries from "../../agent/Entries.js";
|
|
2
2
|
import docs from "./rmDoc.js";
|
|
3
3
|
|
|
4
|
+
const LOG_ACTION_RE = /^log:\/\/turn_\d+\/(\w+)\//;
|
|
5
|
+
|
|
4
6
|
export default class Rm {
|
|
5
7
|
#core;
|
|
6
8
|
|
|
@@ -8,25 +10,50 @@ export default class Rm {
|
|
|
8
10
|
this.#core = core;
|
|
9
11
|
core.registerScheme();
|
|
10
12
|
core.on("handler", this.handler.bind(this));
|
|
11
|
-
core.on("
|
|
12
|
-
core.on("
|
|
13
|
+
core.on("visible", this.full.bind(this));
|
|
14
|
+
core.on("summarized", this.summary.bind(this));
|
|
13
15
|
core.filter("instructions.toolDocs", async (docsMap) => {
|
|
14
16
|
docsMap.rm = docs;
|
|
15
17
|
return docsMap;
|
|
16
18
|
});
|
|
19
|
+
core.on("proposal.accepted", this.#onAccepted.bind(this));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async #onAccepted(ctx) {
|
|
23
|
+
const m = LOG_ACTION_RE.exec(ctx.path);
|
|
24
|
+
if (m?.[1] !== "rm") return;
|
|
25
|
+
const target = ctx.attrs?.path;
|
|
26
|
+
if (!target) return;
|
|
27
|
+
await ctx.entries.rm({ runId: ctx.runId, path: target });
|
|
28
|
+
if (ctx.projectRoot) {
|
|
29
|
+
const { unlink } = await import("node:fs/promises");
|
|
30
|
+
const { join } = await import("node:path");
|
|
31
|
+
try {
|
|
32
|
+
await unlink(join(ctx.projectRoot, target));
|
|
33
|
+
} catch (err) {
|
|
34
|
+
// File may already be absent — entry rm'd regardless.
|
|
35
|
+
if (err.code !== "ENOENT") throw err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
17
38
|
}
|
|
18
39
|
|
|
19
40
|
async handler(entry, rummy) {
|
|
20
41
|
const { entries: store, sequence: turn, runId, loopId } = rummy;
|
|
21
42
|
const target = entry.attributes.path;
|
|
22
43
|
if (!target) {
|
|
23
|
-
await store.
|
|
44
|
+
await store.set({
|
|
45
|
+
runId,
|
|
46
|
+
turn,
|
|
47
|
+
path: entry.resultPath,
|
|
48
|
+
body: "",
|
|
49
|
+
state: "failed",
|
|
50
|
+
outcome: "validation",
|
|
24
51
|
attributes: { error: "path is required" },
|
|
25
52
|
loopId,
|
|
26
53
|
});
|
|
27
54
|
return;
|
|
28
55
|
}
|
|
29
|
-
const normalized =
|
|
56
|
+
const normalized = Entries.normalizePath(target);
|
|
30
57
|
const matches = await store.getEntriesByPattern(
|
|
31
58
|
runId,
|
|
32
59
|
normalized,
|
|
@@ -34,7 +61,13 @@ export default class Rm {
|
|
|
34
61
|
);
|
|
35
62
|
|
|
36
63
|
if (matches.length === 0) {
|
|
37
|
-
await store.
|
|
64
|
+
await store.set({
|
|
65
|
+
runId,
|
|
66
|
+
turn,
|
|
67
|
+
path: entry.resultPath,
|
|
68
|
+
body: "",
|
|
69
|
+
state: "failed",
|
|
70
|
+
outcome: "not_found",
|
|
38
71
|
attributes: { path: target, error: `${target} not found` },
|
|
39
72
|
loopId,
|
|
40
73
|
});
|
|
@@ -45,24 +78,35 @@ export default class Rm {
|
|
|
45
78
|
const schemeMatches = matches.filter((m) => m.scheme !== null);
|
|
46
79
|
|
|
47
80
|
// Scheme entries: remove all, write one aggregate result entry
|
|
48
|
-
for (const match of schemeMatches)
|
|
81
|
+
for (const match of schemeMatches)
|
|
82
|
+
await store.rm({ runId: runId, path: match.path });
|
|
49
83
|
if (schemeMatches.length > 0) {
|
|
50
84
|
const paths = schemeMatches.map((m) => m.path).join("\n");
|
|
51
|
-
await store.
|
|
85
|
+
await store.set({
|
|
86
|
+
runId,
|
|
87
|
+
turn,
|
|
88
|
+
path: entry.resultPath,
|
|
89
|
+
body: paths,
|
|
90
|
+
state: "resolved",
|
|
52
91
|
attributes: { path: target },
|
|
53
92
|
loopId,
|
|
54
93
|
});
|
|
55
94
|
}
|
|
56
95
|
|
|
57
|
-
// File entries: individual
|
|
96
|
+
// File entries: individual proposals (require user resolution)
|
|
58
97
|
if (fileMatches.length > 0 && schemeMatches.length > 0)
|
|
59
|
-
await store.
|
|
98
|
+
await store.rm({ runId: runId, path: entry.resultPath });
|
|
60
99
|
for (const match of fileMatches) {
|
|
61
100
|
const resultPath =
|
|
62
101
|
schemeMatches.length === 0 && fileMatches.length === 1
|
|
63
102
|
? entry.resultPath
|
|
64
|
-
: await store.
|
|
65
|
-
await store.
|
|
103
|
+
: await store.logPath(runId, turn, "rm", match.path);
|
|
104
|
+
await store.set({
|
|
105
|
+
runId,
|
|
106
|
+
turn,
|
|
107
|
+
path: resultPath,
|
|
108
|
+
body: match.path,
|
|
109
|
+
state: "proposed",
|
|
66
110
|
attributes: { path: match.path },
|
|
67
111
|
loopId,
|
|
68
112
|
});
|
package/src/plugins/rm/rmDoc.js
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
// Text goes to the model. Rationale stays in source.
|
|
3
|
-
// Changing ANY line requires reading ALL rationales first.
|
|
4
|
-
const LINES = [
|
|
5
|
-
['## <rm path="[path]"/> - Remove a file or entry'],
|
|
6
|
-
['Example: <rm path="src/config.js"/>', "File removal. Simplest form."],
|
|
7
|
-
[
|
|
8
|
-
'Example: <rm path="known://temp_*" preview/>',
|
|
9
|
-
"Preview before deleting. Safety pattern for bulk operations.",
|
|
10
|
-
],
|
|
11
|
-
[
|
|
12
|
-
'* Permanent. Prefer <set path="..." fidelity="archived"/> to preserve for later retrieval',
|
|
13
|
-
"Nudges toward archive over rm. Path attr included so the model sees a complete invocation shape, not a fragment.",
|
|
14
|
-
],
|
|
15
|
-
[
|
|
16
|
-
"* `preview` shows what paths would be affected without performing the operation.",
|
|
17
|
-
"Canonical preview teaching lives here — rm is the most intuitive 'check before committing' case. Model generalizes to cp/mv/get by analogy. Advanced uses (e.g. archive rediscovery via <get preview>) belong in persona/skill docs, not here.",
|
|
18
|
-
],
|
|
19
|
-
];
|
|
1
|
+
import { loadDoc } from "../helpers.js";
|
|
20
2
|
|
|
21
|
-
export default
|
|
3
|
+
export default loadDoc(import.meta.url, "rmDoc.md");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## <rm path="[path]"/> - Remove a file or entry
|
|
2
|
+
|
|
3
|
+
Example: <rm path="src/config.js"/>
|
|
4
|
+
<!-- File removal. Simplest form. -->
|
|
5
|
+
|
|
6
|
+
Example: <rm path="known://temp_*" preview/>
|
|
7
|
+
<!-- Preview before deleting. Safety pattern for bulk operations. -->
|
|
8
|
+
|
|
9
|
+
* Permanent. Prefer <set path="..." visibility="archived"/> to preserve for later retrieval
|
|
10
|
+
<!-- Nudges toward archive over rm. Path attr included so the model sees a complete invocation shape, not a fragment. -->
|
|
11
|
+
|
|
12
|
+
* `preview` shows what paths would be affected without performing the operation.
|
|
13
|
+
<!-- Canonical preview teaching lives here — rm is the most intuitive 'check before committing' case. Model generalizes to cp/mv/get by analogy. Advanced uses (e.g. archive rediscovery via <get preview>) belong in persona/skill docs, not here. -->
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# rpc
|
|
1
|
+
# rpc {#rpc_plugin}
|
|
2
2
|
|
|
3
3
|
Registers core RPC methods and provides automatic tool dispatch for
|
|
4
4
|
all registered tools.
|
|
@@ -29,4 +29,4 @@ all registered tools.
|
|
|
29
29
|
- `getRuns`, `getRun`
|
|
30
30
|
|
|
31
31
|
### Notifications
|
|
32
|
-
- `run/state`, `run/progress`, `ui/render`, `ui/notify`
|
|
32
|
+
- `run/state`, `run/progress`, `run/proposal`, `ui/render`, `ui/notify`, `stream/cancelled`
|