@hassangameryt/freeflow 0.7.1 → 0.7.3
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +153 -128
- package/capabilities/cognitive-routing/SKILL.md +126 -274
- package/command-surface.json +7 -1
- package/gemini-extension.json +1 -1
- package/package.json +4 -4
- package/pi-extension/dist/cognitive-routing-v2/budget.js +42 -0
- package/pi-extension/dist/cognitive-routing-v2/config.js +136 -0
- package/pi-extension/dist/cognitive-routing-v2/projection.js +330 -0
- package/pi-extension/dist/cognitive-routing-v2/render.js +252 -0
- package/pi-extension/dist/cognitive-routing-v2/runtime.js +2181 -0
- package/pi-extension/dist/cognitive-routing-v2/schemas.js +173 -0
- package/pi-extension/dist/cognitive-routing-v2/state.js +828 -0
- package/pi-extension/dist/cognitive-routing-v2/tools.js +60 -0
- package/pi-extension/dist/cognitive-routing-v2/types.js +48 -0
- package/pi-extension/dist/context-virtualization/runtime.js +29 -7
- package/pi-extension/dist/freeflow-context/tool.js +12 -6
- package/pi-extension/dist/index.js +302 -626
- package/pi-extension/dist/provider-support/astra/adapter.js +110 -0
- package/pi-extension/dist/provider-support/astra/history.js +125 -0
- package/pi-extension/dist/provider-support/astra/index.js +11 -0
- package/pi-extension/dist/provider-support/astra/session-state.js +114 -0
- package/pi-extension/dist/provider-support/index.js +4 -0
- package/pi-extension/dist/runtime/request-history.js +216 -0
- package/pi-extension/dist/runtime/runtime-context.js +85 -16
- package/pi-extension/dist/session-sources/events.js +217 -0
- package/pi-extension/dist/session-sources/provenance.js +32 -0
- package/pi-extension/dist/session-sources/read-only-session.js +148 -0
- package/pi-extension/dist/session-sources/sources.js +277 -0
- package/pi-extension/dist/settings/settings-ui.js +274 -147
- package/pi-extension/src/cognitive-routing-v2/budget.ts +42 -0
- package/pi-extension/src/cognitive-routing-v2/config.ts +173 -0
- package/pi-extension/src/cognitive-routing-v2/projection.ts +375 -0
- package/pi-extension/src/cognitive-routing-v2/render.ts +277 -0
- package/pi-extension/src/cognitive-routing-v2/runtime.ts +2241 -0
- package/pi-extension/src/cognitive-routing-v2/schemas.ts +180 -0
- package/pi-extension/src/cognitive-routing-v2/state.ts +839 -0
- package/pi-extension/src/cognitive-routing-v2/tools.ts +62 -0
- package/pi-extension/src/cognitive-routing-v2/types.ts +254 -0
- package/pi-extension/src/context-virtualization/runtime.ts +30 -8
- package/pi-extension/src/freeflow-context/tool.ts +12 -6
- package/pi-extension/src/index.ts +308 -675
- package/pi-extension/src/provider-support/astra/adapter.ts +108 -0
- package/pi-extension/src/provider-support/astra/history.ts +145 -0
- package/pi-extension/src/provider-support/astra/index.ts +12 -0
- package/pi-extension/src/provider-support/astra/session-state.ts +113 -0
- package/pi-extension/src/provider-support/index.ts +5 -0
- package/pi-extension/src/runtime/request-history.ts +243 -0
- package/pi-extension/src/runtime/runtime-context.ts +100 -17
- package/pi-extension/src/session-sources/events.ts +230 -0
- package/pi-extension/src/session-sources/provenance.ts +39 -0
- package/pi-extension/src/session-sources/read-only-session.ts +170 -0
- package/pi-extension/src/session-sources/sources.ts +334 -0
- package/pi-extension/src/settings/settings-ui.ts +311 -158
- package/pi-extension/tests/cache-reuse/history.test.js +117 -0
- package/pi-extension/tests/cache-reuse/native.test.js +91 -0
- package/pi-extension/tests/cache-reuse/settings.test.js +211 -0
- package/pi-extension/tests/cognitive-routing-v2/communication.test.js +577 -0
- package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +183 -0
- package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +557 -0
- package/pi-extension/tests/cognitive-routing-v2/native.test.js +474 -0
- package/pi-extension/tests/cognitive-routing-v2/performance.test.js +87 -0
- package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +300 -0
- package/pi-extension/tests/cognitive-routing-v2/projection.test.js +241 -0
- package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +1034 -0
- package/pi-extension/tests/cognitive-routing-v2/render.test.js +244 -0
- package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +423 -0
- package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +521 -0
- package/pi-extension/tests/cognitive-routing-v2/state.test.js +586 -0
- package/pi-extension/tests/context-virtualization/extension.test.js +33 -7
- package/pi-extension/tests/context-virtualization/runtime.test.js +17 -3
- package/pi-extension/tests/fixtures/routing-native.js +191 -0
- package/pi-extension/tests/integration/mode-free-core.test.js +6 -4
- package/pi-extension/tests/integration/pi-extension.test.js +655 -59
- package/pi-extension/tests/integration/prompt-architecture.test.js +127 -30
- package/pi-extension/tests/integration/unaffected-regressions.test.js +78 -11
- package/pi-extension/tests/provider-support/astra-boundaries.test.js +75 -0
- package/pi-extension/tests/provider-support/astra.test.js +306 -0
- package/pi-extension/tests/provider-support/cli.test.js +92 -0
- package/pi-extension/tests/provider-support/native.test.js +183 -0
- package/plugin.json +1 -1
- package/runtime/prompts/cognitive-routing.md +4 -5
- package/runtime/prompts/core.md +51 -45
- package/runtime/prompts/interaction-contract.md +5 -5
- package/skills/action-selection/SKILL.md +57 -97
- package/skills/design-for-depth/SKILL.md +58 -193
- package/skills/design-for-depth/references/implementation-decisions.md +76 -0
- package/skills/diagnose-failure/SKILL.md +64 -196
- package/skills/discuss/SKILL.md +64 -123
- package/skills/discuss/references/discussion-continuity.md +7 -3
- package/skills/execute-work/SKILL.md +69 -88
- package/skills/execute-work/references/execute-work-edges.md +9 -3
- package/skills/handoff/SKILL.md +44 -54
- package/skills/handoff/references/handoff-templates.md +15 -6
- package/skills/review-artifact/SKILL.md +80 -127
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +1 -1
- package/skills/review-work/SKILL.md +65 -115
- package/skills/review-work/references/independent-work-reviewer-contract.md +1 -1
- package/skills/simplify-code/SKILL.md +47 -100
- package/skills/track-work/SKILL.md +128 -119
- package/skills/track-work/references/working-record-format.md +14 -2
- package/skills/verify-work/SKILL.md +58 -62
- package/skills/verify-work/references/integration-evidence.md +4 -2
- package/skills/verify-work/references/test-design.md +89 -0
- package/skills/workflow/SKILL.md +73 -119
- package/skills/write-plan/SKILL.md +46 -77
- package/skills/write-plan/references/plan-shapes.md +5 -5
- package/skills/write-spec/SKILL.md +51 -63
- package/skills/write-spec/references/artifact-standards.md +2 -2
- package/skills/write-spec/references/decision-records.md +3 -2
- package/skills/write-spec/references/spec-shapes.md +15 -0
- package/pi-extension/dist/cognitive-routing/commands.js +0 -96
- package/pi-extension/dist/cognitive-routing/config.js +0 -232
- package/pi-extension/dist/cognitive-routing/controller.js +0 -1292
- package/pi-extension/dist/cognitive-routing/history.js +0 -451
- package/pi-extension/dist/cognitive-routing/host.js +0 -188
- package/pi-extension/dist/cognitive-routing/pi-routing-session.js +0 -414
- package/pi-extension/dist/cognitive-routing/pi-session-control.js +0 -320
- package/pi-extension/dist/cognitive-routing/runtime.js +0 -43
- package/pi-extension/dist/cognitive-routing/tool.js +0 -212
- package/pi-extension/dist/cognitive-routing/types.js +0 -6
- package/pi-extension/src/cognitive-routing/commands.ts +0 -129
- package/pi-extension/src/cognitive-routing/config.ts +0 -303
- package/pi-extension/src/cognitive-routing/controller.ts +0 -1628
- package/pi-extension/src/cognitive-routing/history.ts +0 -650
- package/pi-extension/src/cognitive-routing/host.ts +0 -266
- package/pi-extension/src/cognitive-routing/pi-routing-session.ts +0 -538
- package/pi-extension/src/cognitive-routing/pi-session-control.ts +0 -444
- package/pi-extension/src/cognitive-routing/runtime.ts +0 -57
- package/pi-extension/src/cognitive-routing/tool.ts +0 -273
- package/pi-extension/src/cognitive-routing/types.ts +0 -89
- package/pi-extension/tests/cognitive-routing/commands.test.js +0 -134
- package/pi-extension/tests/cognitive-routing/controller.test.js +0 -1128
- package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +0 -1142
- package/pi-extension/tests/cognitive-routing/history.test.js +0 -274
- package/pi-extension/tests/cognitive-routing/host-identity.test.js +0 -63
- package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +0 -434
- package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +0 -174
- package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +0 -91
- package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +0 -279
- package/pi-extension/tests/cognitive-routing/tool.test.js +0 -230
- package/skills/tdd/SKILL.md +0 -143
- package/skills/tdd/references/test-design.md +0 -96
- /package/pi-extension/tests/{cognitive-routing/host-fixture.js → fixtures/pi-host.js} +0 -0
|
@@ -208,9 +208,23 @@ test("mutation persistence failure returns an error without publishing projectio
|
|
|
208
208
|
assert.match(next.messages[0].content.at(-1).text, /ctx:tool-1/);
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
-
test("disabled projection
|
|
211
|
+
test("disabled projection keeps original content and the stable reference marker", async () => {
|
|
212
212
|
const { runtime } = createFixture();
|
|
213
213
|
const result = await runtime.project([toolMessage()], false);
|
|
214
|
-
assert.equal(result.changed,
|
|
215
|
-
assert.deepEqual(result.messages[0].content, [{ type: "text", text: "secret raw output" }]);
|
|
214
|
+
assert.equal(result.changed, true);
|
|
215
|
+
assert.deepEqual(result.messages[0].content.slice(0, -1), [{ type: "text", text: "secret raw output" }]);
|
|
216
|
+
assert.match(result.messages[0].content.at(-1).text, /context-ref: ctx:tool-1/);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test("unavailable decoration leaves the already projected view intact", () => {
|
|
220
|
+
const { runtime } = createFixture();
|
|
221
|
+
runtime.setContext({
|
|
222
|
+
sessionManager: {
|
|
223
|
+
getBranch() {
|
|
224
|
+
throw Error("unavailable");
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
const current = [{ role: "custom", customType: "blocked", content: "Only this safe view" }];
|
|
229
|
+
assert.equal(runtime.decorate(current), current);
|
|
216
230
|
});
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, mkdir, writeFile, rm } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import {
|
|
6
|
+
createAgentSession,
|
|
7
|
+
DefaultResourceLoader,
|
|
8
|
+
ModelRuntime,
|
|
9
|
+
SessionManager,
|
|
10
|
+
SettingsManager,
|
|
11
|
+
} from "@earendil-works/pi-coding-agent";
|
|
12
|
+
import freeflow from "../../dist/index.js";
|
|
13
|
+
import { replay } from "../../dist/cognitive-routing-v2/state.js";
|
|
14
|
+
|
|
15
|
+
export function response(n, calls = [], text = "fixture response") {
|
|
16
|
+
const output = [
|
|
17
|
+
{
|
|
18
|
+
type: "message",
|
|
19
|
+
id: `msg-${n}`,
|
|
20
|
+
role: "assistant",
|
|
21
|
+
status: "completed",
|
|
22
|
+
content: [{ type: "output_text", text, annotations: [] }],
|
|
23
|
+
},
|
|
24
|
+
...calls.map((c, i) => ({
|
|
25
|
+
type: "function_call",
|
|
26
|
+
id: `fc_${n}_${i}`,
|
|
27
|
+
call_id: `call-${n}-${i}`,
|
|
28
|
+
name: c.name,
|
|
29
|
+
arguments: JSON.stringify(c.args),
|
|
30
|
+
})),
|
|
31
|
+
];
|
|
32
|
+
const events = [{ type: "response.created", response: { id: `r-${n}`, status: "in_progress", output: [] } }];
|
|
33
|
+
output.forEach((item, i) => {
|
|
34
|
+
events.push({
|
|
35
|
+
type: "response.output_item.added",
|
|
36
|
+
output_index: i,
|
|
37
|
+
item: item.type === "message" ? { ...item, content: [] } : { ...item, arguments: "" },
|
|
38
|
+
});
|
|
39
|
+
if (item.type === "message")
|
|
40
|
+
events.push({ type: "response.output_text.delta", output_index: i, content_index: 0, delta: text });
|
|
41
|
+
else
|
|
42
|
+
events.push(
|
|
43
|
+
{ type: "response.function_call_arguments.delta", output_index: i, delta: item.arguments },
|
|
44
|
+
{ type: "response.function_call_arguments.done", output_index: i, arguments: item.arguments },
|
|
45
|
+
);
|
|
46
|
+
events.push({ type: "response.output_item.done", output_index: i, item });
|
|
47
|
+
});
|
|
48
|
+
events.push({
|
|
49
|
+
type: "response.completed",
|
|
50
|
+
response: {
|
|
51
|
+
id: `r-${n}`,
|
|
52
|
+
status: "completed",
|
|
53
|
+
output,
|
|
54
|
+
usage: { input_tokens: 10, output_tokens: 10, total_tokens: 20 },
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
return new Response(events.map((e) => `data: ${JSON.stringify(e)}\n\n`).join("") + "data: [DONE]\n\n", {
|
|
58
|
+
status: 200,
|
|
59
|
+
headers: { "content-type": "text/event-stream" },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function fixture(script, projection = true, after, withUI = true, options = {}) {
|
|
64
|
+
const root = await mkdtemp(join(tmpdir(), "freeflow-v2-native-"));
|
|
65
|
+
const cwd = join(root, "cwd"),
|
|
66
|
+
agentDir = join(root, "agent");
|
|
67
|
+
await mkdir(join(cwd, ".freeflow"), { recursive: true });
|
|
68
|
+
await mkdir(agentDir);
|
|
69
|
+
await writeFile(
|
|
70
|
+
join(cwd, ".freeflow/config.json"),
|
|
71
|
+
JSON.stringify({
|
|
72
|
+
cognitiveRouting: options.cognitiveRouting ?? {
|
|
73
|
+
enabled: true,
|
|
74
|
+
projection,
|
|
75
|
+
profiles: {
|
|
76
|
+
coordinator: { provider: "openai", model: "gpt-4o", thinking: "off" },
|
|
77
|
+
executor: { provider: "openai", model: "gpt-4.1-mini", thinking: "off" },
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
await writeFile(join(cwd, "evidence.txt"), "EXACT_EVIDENCE_BODY_81");
|
|
83
|
+
await writeFile(join(cwd, "unselected.txt"), "UNSELECTED_PRIVATE_BODY_93");
|
|
84
|
+
await writeFile(join(cwd, "recovery.txt"), "FRESH_RECOVERY_BODY_57");
|
|
85
|
+
await writeFile(join(cwd, "@recovery.txt"), "LITERAL_AT_FILE_BODY_68");
|
|
86
|
+
await writeFile(
|
|
87
|
+
join(agentDir, "models.json"),
|
|
88
|
+
JSON.stringify({ providers: { openai: { baseUrl: "https://fixture.invalid/v1" } } }),
|
|
89
|
+
);
|
|
90
|
+
const priorFetch = globalThis.fetch,
|
|
91
|
+
offline = process.env.PI_OFFLINE;
|
|
92
|
+
process.env.PI_OFFLINE = "1";
|
|
93
|
+
const requests = [],
|
|
94
|
+
errors = [],
|
|
95
|
+
contexts = [],
|
|
96
|
+
transportFailures = [],
|
|
97
|
+
notices = [];
|
|
98
|
+
let session;
|
|
99
|
+
const manager = SessionManager.create(cwd, join(root, "sessions"));
|
|
100
|
+
globalThis.fetch = async (url, init) => {
|
|
101
|
+
assert.match(String(url), /^https:\/\/fixture\.invalid\//, "no unexpected network destination");
|
|
102
|
+
const body = JSON.parse(String(init.body));
|
|
103
|
+
requests.push(body);
|
|
104
|
+
assert.ok(requests.length <= (options.maxRequests ?? 15), "bounded fixture request count");
|
|
105
|
+
try {
|
|
106
|
+
const calls = await script(requests.length, body, manager, requests);
|
|
107
|
+
return options.response ? options.response(requests.length, calls) : response(requests.length, calls);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
transportFailures.push(error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
const modelRuntime = await ModelRuntime.create({
|
|
115
|
+
authPath: join(agentDir, "auth.json"),
|
|
116
|
+
modelsPath: join(agentDir, "models.json"),
|
|
117
|
+
modelsStorePath: join(agentDir, "models-store.json"),
|
|
118
|
+
allowModelNetwork: false,
|
|
119
|
+
});
|
|
120
|
+
await modelRuntime.setRuntimeApiKey("openai", "fixture-not-a-real-key");
|
|
121
|
+
const settingsManager = SettingsManager.inMemory({
|
|
122
|
+
compaction: { enabled: false, keepRecentTokens: 1, reserveTokens: 1 },
|
|
123
|
+
retry: { enabled: false, maxRetries: 0, provider: { maxRetries: 0 } },
|
|
124
|
+
...options.settings,
|
|
125
|
+
});
|
|
126
|
+
const loader = new DefaultResourceLoader({
|
|
127
|
+
cwd,
|
|
128
|
+
agentDir,
|
|
129
|
+
settingsManager,
|
|
130
|
+
noExtensions: true,
|
|
131
|
+
noSkills: true,
|
|
132
|
+
noPromptTemplates: true,
|
|
133
|
+
noThemes: true,
|
|
134
|
+
noContextFiles: true,
|
|
135
|
+
extensionFactories: [
|
|
136
|
+
freeflow,
|
|
137
|
+
...(options.extensions ?? []),
|
|
138
|
+
(pi) => {
|
|
139
|
+
pi.on("context", (event) => {
|
|
140
|
+
contexts.push(structuredClone(event.messages));
|
|
141
|
+
});
|
|
142
|
+
pi.on("session_before_compact", () => ({
|
|
143
|
+
compaction: {
|
|
144
|
+
summary: "Fixture compacted prior work; evidence must come from canonical sources.",
|
|
145
|
+
firstKeptEntryId: manager.getLeafId(),
|
|
146
|
+
tokensBefore: 100,
|
|
147
|
+
},
|
|
148
|
+
}));
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
});
|
|
152
|
+
await loader.reload();
|
|
153
|
+
assert.deepEqual(loader.getExtensions().errors, []);
|
|
154
|
+
({ session } = await createAgentSession({
|
|
155
|
+
cwd,
|
|
156
|
+
agentDir,
|
|
157
|
+
modelRuntime,
|
|
158
|
+
model: modelRuntime.getModel("openai", "gpt-4o"),
|
|
159
|
+
thinkingLevel: "off",
|
|
160
|
+
settingsManager,
|
|
161
|
+
sessionManager: manager,
|
|
162
|
+
resourceLoader: loader,
|
|
163
|
+
}));
|
|
164
|
+
// Public retained bindings make Pi emit session_start again on SDK reload, including headless mode.
|
|
165
|
+
await session.bindExtensions({
|
|
166
|
+
mode: "print",
|
|
167
|
+
onError: (e) => errors.push(e),
|
|
168
|
+
...(withUI ? { uiContext: { notify: (...args) => notices.push(args), setStatus: () => {} } } : {}),
|
|
169
|
+
});
|
|
170
|
+
await options.onSession?.(session);
|
|
171
|
+
await options.beforePrompt?.({ session, manager, requests, contexts, cwd, notices });
|
|
172
|
+
await session.prompt("Complete the fixture assignment.");
|
|
173
|
+
await session.waitForIdle();
|
|
174
|
+
assert.deepEqual(errors, [], "extension lifecycle errors");
|
|
175
|
+
if (after) await after({ session, manager, requests, contexts, cwd, notices });
|
|
176
|
+
assert.deepEqual(errors, [], "post-lifecycle errors");
|
|
177
|
+
assert.deepEqual(transportFailures, [], "scripted provider assertions must not be swallowed as provider errors");
|
|
178
|
+
assert.notEqual(
|
|
179
|
+
session.messages.at(-1)?.stopReason,
|
|
180
|
+
"error",
|
|
181
|
+
`fixture completes without provider failure: ${session.messages.at(-1)?.errorMessage ?? ""}`,
|
|
182
|
+
);
|
|
183
|
+
return { requests, state: replay(manager.getBranch()), entries: manager.getEntries(), contexts };
|
|
184
|
+
} finally {
|
|
185
|
+
session?.dispose();
|
|
186
|
+
globalThis.fetch = priorFetch;
|
|
187
|
+
if (offline === undefined) delete process.env.PI_OFFLINE;
|
|
188
|
+
else process.env.PI_OFFLINE = offline;
|
|
189
|
+
await rm(root, { recursive: true, force: true });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
runtimeContext,
|
|
15
15
|
setSessionCoreOverride,
|
|
16
16
|
} from "../../dist/runtime/runtime-context.js";
|
|
17
|
-
import { PIFLOW_HOST } from "../
|
|
17
|
+
import { PIFLOW_HOST } from "../fixtures/pi-host.js";
|
|
18
18
|
|
|
19
19
|
function context(cwd) {
|
|
20
20
|
const notifications = [];
|
|
@@ -138,8 +138,9 @@ test("Pi exposes base skills without mode or Skills controls", async () => {
|
|
|
138
138
|
const { handlers, commands } = loadExtension();
|
|
139
139
|
const ctx = context(cwd);
|
|
140
140
|
const resources = await handlers.get("resources_discover")({ cwd }, ctx);
|
|
141
|
-
assert.equal(resources.skillPaths.length,
|
|
141
|
+
assert.equal(resources.skillPaths.length, 27);
|
|
142
142
|
assert.ok(resources.skillPaths.some((path) => path.endsWith("/skills/workflow/SKILL.md")));
|
|
143
|
+
assert.ok(!resources.skillPaths.some((path) => path.endsWith("/skills/tdd/SKILL.md")));
|
|
143
144
|
assert.ok(!resources.skillPaths.some((path) => path.endsWith("/skills/mode-contract/SKILL.md")));
|
|
144
145
|
|
|
145
146
|
const freeflowCommand = commands.find((command) => command.name === "freeflow");
|
|
@@ -180,9 +181,10 @@ test("mandatory prompt readiness gates Runtime State, discovery, and direct skil
|
|
|
180
181
|
const { handlers, commands, sentMessages } = loadExtension(extension);
|
|
181
182
|
const ctx = context(cwd);
|
|
182
183
|
const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
|
|
183
|
-
assert.
|
|
184
|
+
assert.ok(before.systemPrompt.startsWith("base prompt\n\n"));
|
|
185
|
+
assert.match(before.systemPrompt, /guidance is dormant/);
|
|
184
186
|
const resources = await handlers.get("resources_discover")({ cwd }, ctx);
|
|
185
|
-
assert.
|
|
187
|
+
assert.equal(resources.skillPaths.length, 27);
|
|
186
188
|
|
|
187
189
|
const discuss = commands.find((command) => command.name === "discuss");
|
|
188
190
|
assert.ok(discuss);
|