@selesai/code 0.3.0 → 0.3.1
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/dist/core/diagnostics.d.ts +1 -0
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/diagnostics.js.map +1 -1
- package/dist/core/package-manager.d.ts +10 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +93 -8
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-manager.test.d.ts +2 -0
- package/dist/core/package-manager.test.d.ts.map +1 -0
- package/dist/core/package-manager.test.js +20 -0
- package/dist/core/package-manager.test.js.map +1 -0
- package/dist/core/resource-loader.d.ts +3 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +10 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/extensions/caveman/caveman-instructions.cjs +39 -0
- package/dist/extensions/caveman/index.js +116 -0
- package/dist/extensions/caveman/package.json +8 -0
- package/dist/extensions/caveman/test/extension.test.js +185 -0
- package/dist/extensions/caveman/test/helpers.test.js +67 -0
- package/dist/extensions/pi-intercom/broker/broker.ts +2 -3
- package/dist/extensions/pi-intercom/broker/paths.ts +10 -5
- package/dist/extensions/pi-intercom/broker/spawn.ts +2 -3
- package/dist/extensions/pi-intercom/config.ts +2 -2
- package/dist/extensions/pi-intercom/index.ts +2 -2
- package/dist/extensions/pi-intercom/package.json +2 -2
- package/dist/extensions/pi-intercom/ui/compose.ts +3 -3
- package/dist/extensions/pi-intercom/ui/inline-message.ts +3 -3
- package/dist/extensions/pi-intercom/ui/session-list.ts +3 -3
- package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +2 -1
- package/dist/extensions/pi-powerline-footer/index.ts +9 -16
- package/dist/extensions/pi-powerline-footer/welcome.ts +23 -16
- package/dist/extensions/pi-powerline-footer/working-vibes.ts +2 -9
- package/dist/extensions/pi-rewind-hook/index.ts +1 -1
- package/dist/extensions/pi-rewind-hook/package.json +1 -1
- package/dist/extensions/pi-subagents/README.md +224 -52
- package/dist/extensions/pi-subagents/install.mjs +93 -0
- package/dist/extensions/pi-subagents/package.json +4 -5
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +76 -13
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +179 -2
- package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +254 -0
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +11 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +193 -19
- package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +27 -2
- package/dist/extensions/pi-subagents/src/extension/config.ts +27 -4
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +1 -7
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -2
- package/dist/extensions/pi-subagents/src/extension/index.ts +73 -71
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +369 -0
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +54 -10
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +200 -0
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +21 -253
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +519 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +195 -105
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +88 -2
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +67 -10
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +34 -4
- package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +166 -0
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +156 -1
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +515 -0
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +161 -44
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +1 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +3 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +167 -6
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +514 -0
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +28 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +873 -204
- package/dist/extensions/pi-subagents/src/runs/background/wait.ts +353 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +123 -27
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +174 -70
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +569 -81
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +45 -22
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +172 -21
- package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +128 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +89 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +50 -1
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +35 -4
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +63 -45
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +125 -5
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +74 -0
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +52 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +28 -5
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +16 -1
- package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +15 -2
- package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +212 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +133 -22
- package/dist/extensions/pi-subagents/src/shared/settings.ts +3 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +197 -4
- package/dist/extensions/pi-subagents/src/shared/utils.ts +100 -15
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +330 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +135 -4
- package/dist/extensions/pi-subagents/src/tui/render.ts +32 -12
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +2772 -0
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +1107 -0
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +463 -0
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +274 -0
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +1535 -0
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +242 -0
- package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +252 -0
- package/dist/extensions/pi-subagents/test/integration/foreground-result-size.test.ts +188 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +1306 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +1033 -0
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +397 -0
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +583 -0
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +691 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +892 -0
- package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1824 -0
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1284 -0
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +299 -0
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +37 -0
- package/dist/extensions/pi-subagents/test/support/helpers.ts +189 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +335 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +129 -0
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +184 -0
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +285 -0
- package/dist/extensions/pi-subagents/test/support/register-loader.mjs +15 -0
- package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +108 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +421 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +213 -0
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +343 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +1199 -0
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +556 -0
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +420 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +579 -0
- package/dist/extensions/pi-subagents/test/unit/agent-scope.test.ts +20 -0
- package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +221 -0
- package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +98 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +285 -0
- package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +206 -0
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +159 -0
- package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +229 -0
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +225 -0
- package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +101 -0
- package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +228 -0
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +152 -0
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +72 -0
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +327 -0
- package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +161 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +159 -0
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +217 -0
- package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +415 -0
- package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +126 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +271 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +173 -0
- package/dist/extensions/pi-subagents/test/unit/jsonl-writer.test.ts +119 -0
- package/dist/extensions/pi-subagents/test/unit/live-async-resume.test.ts +170 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +346 -0
- package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +145 -0
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +162 -0
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +470 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +329 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +319 -0
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +70 -0
- package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +247 -0
- package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +113 -0
- package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +803 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +238 -0
- package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +118 -0
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +299 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +408 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +134 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +257 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +226 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +294 -0
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +147 -0
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +997 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +478 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +562 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +213 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +438 -0
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +54 -0
- package/dist/extensions/pi-subagents/test/unit/slash-chain-groups.test.ts +464 -0
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +255 -0
- package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +19 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +245 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +517 -0
- package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +72 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +237 -0
- package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +60 -0
- package/dist/extensions/pi-subagents/test/unit/ts-loader.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +202 -0
- package/dist/extensions/pi-subagents/test/unit/types-fork-preamble.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/wait.test.ts +398 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +26 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +134 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +479 -0
- package/dist/extensions/pi-web-agent/src/changelog-notice.ts +5 -2
- package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +6 -4
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +19 -5
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/skills/caveman/SKILL.md +49 -0
- package/dist/skills/handoff-text/SKILL.md +13 -0
- package/docs/docs.json +4 -0
- package/docs/extensions.md +2 -0
- package/docs/settings.md +15 -0
- package/docs/shared-host-extensions.md +109 -0
- package/package.json +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import cavemanExtension from "../index.js";
|
|
5
|
+
|
|
6
|
+
function createPiHarness() {
|
|
7
|
+
const events = new Map();
|
|
8
|
+
const commands = new Map();
|
|
9
|
+
const appendedEntries = [];
|
|
10
|
+
const sentUserMessages = [];
|
|
11
|
+
|
|
12
|
+
const pi = {
|
|
13
|
+
on(eventName, handler) { events.set(eventName, handler); },
|
|
14
|
+
registerCommand(name, options) { commands.set(name, options); },
|
|
15
|
+
appendEntry(customType, data) { appendedEntries.push({ customType, data }); },
|
|
16
|
+
sendUserMessage(text, options) { sentUserMessages.push({ text, options }); },
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
cavemanExtension(pi);
|
|
20
|
+
return { events, commands, appendedEntries, sentUserMessages };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function createCommandContext(overrides = {}) {
|
|
24
|
+
return {
|
|
25
|
+
isIdle: () => true,
|
|
26
|
+
sessionManager: { getEntries: () => [] },
|
|
27
|
+
ui: { notify() {} },
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
test("extension registers the /caveman command", () => {
|
|
33
|
+
const { commands } = createPiHarness();
|
|
34
|
+
assert.deepEqual([...commands.keys()], ["caveman"]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("/caveman on/off appends a caveman-mode entry", async () => {
|
|
38
|
+
const { commands, events, appendedEntries } = createPiHarness();
|
|
39
|
+
const ctx = createCommandContext();
|
|
40
|
+
|
|
41
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
42
|
+
await commands.get("caveman").handler("off", ctx);
|
|
43
|
+
|
|
44
|
+
assert.deepEqual(appendedEntries.at(-1), { customType: "caveman-mode", data: { active: false } });
|
|
45
|
+
|
|
46
|
+
await commands.get("caveman").handler("on", ctx);
|
|
47
|
+
assert.deepEqual(appendedEntries.at(-1), { customType: "caveman-mode", data: { active: true } });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("bare /caveman toggles off then back on", async () => {
|
|
51
|
+
const { commands, events, appendedEntries } = createPiHarness();
|
|
52
|
+
const ctx = createCommandContext();
|
|
53
|
+
|
|
54
|
+
await events.get("session_start")({ reason: "startup" }, ctx); // starts on
|
|
55
|
+
await commands.get("caveman").handler("", ctx);
|
|
56
|
+
assert.equal(appendedEntries.at(-1).data.active, false);
|
|
57
|
+
await commands.get("caveman").handler("", ctx);
|
|
58
|
+
assert.equal(appendedEntries.at(-1).data.active, true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("before_agent_start injects instructions while active", async () => {
|
|
62
|
+
const { events } = createPiHarness();
|
|
63
|
+
const ctx = createCommandContext();
|
|
64
|
+
|
|
65
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
66
|
+
const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
|
|
67
|
+
|
|
68
|
+
assert.ok(result.systemPrompt.startsWith("BASE"));
|
|
69
|
+
assert.ok(result.systemPrompt.includes("CAVEMAN MODE ACTIVE"));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("disabled caveman skips instruction injection", async () => {
|
|
73
|
+
const { commands, events } = createPiHarness();
|
|
74
|
+
const ctx = createCommandContext();
|
|
75
|
+
|
|
76
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
77
|
+
await commands.get("caveman").handler("off", ctx);
|
|
78
|
+
const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
|
|
79
|
+
|
|
80
|
+
assert.equal(result, undefined);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("session_start restores latest persisted active flag", async () => {
|
|
84
|
+
const { events } = createPiHarness();
|
|
85
|
+
const ctx = createCommandContext({
|
|
86
|
+
sessionManager: {
|
|
87
|
+
getEntries: () => [
|
|
88
|
+
{ type: "custom", customType: "caveman-mode", data: { active: false } },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await events.get("session_start")({ reason: "resume" }, ctx);
|
|
94
|
+
const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
|
|
95
|
+
|
|
96
|
+
assert.equal(result, undefined); // persisted false -> no injection
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("'stop caveman' as a whole message deactivates mid-session", async () => {
|
|
100
|
+
const { events } = createPiHarness();
|
|
101
|
+
const ctx = createCommandContext();
|
|
102
|
+
|
|
103
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
104
|
+
await events.get("input")({ text: "stop caveman", source: "interactive" }, ctx);
|
|
105
|
+
|
|
106
|
+
const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
|
|
107
|
+
assert.equal(result, undefined);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("a request merely mentioning 'stop caveman' stays active", async () => {
|
|
111
|
+
const { events } = createPiHarness();
|
|
112
|
+
const ctx = createCommandContext();
|
|
113
|
+
|
|
114
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
115
|
+
await events.get("input")({ text: "how do I stop caveman re-rendering?", source: "interactive" }, ctx);
|
|
116
|
+
|
|
117
|
+
const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
|
|
118
|
+
assert.ok(result.systemPrompt.includes("CAVEMAN MODE ACTIVE"));
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("status bar renders ON and flips active on agent_start", async () => {
|
|
122
|
+
const { events } = createPiHarness();
|
|
123
|
+
const statusWrites = [];
|
|
124
|
+
const ctx = createCommandContext({
|
|
125
|
+
sessionManager: { getEntries: () => [] },
|
|
126
|
+
ui: { notify() {}, setStatus: (key, text) => statusWrites.push({ key, text }), theme: { fg: (_c, t) => t } },
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
130
|
+
await events.get("agent_start")({}, ctx);
|
|
131
|
+
|
|
132
|
+
assert.equal(statusWrites.at(-2).key, "caveman");
|
|
133
|
+
assert.match(statusWrites.at(-2).text, /○.*ON/);
|
|
134
|
+
assert.match(statusWrites.at(-1).text, /●.*ON/);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("status bar clears when disabled", async () => {
|
|
138
|
+
const { events, commands } = createPiHarness();
|
|
139
|
+
const statusWrites = [];
|
|
140
|
+
const ctx = createCommandContext({
|
|
141
|
+
ui: { notify() {}, setStatus: (key, text) => statusWrites.push({ key, text }), theme: { fg: (_c, t) => t } },
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
145
|
+
await commands.get("caveman").handler("off", ctx);
|
|
146
|
+
|
|
147
|
+
assert.deepEqual(statusWrites.at(-1), { key: "caveman", text: "" });
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("status bar stays silent when ui lacks a theme", async () => {
|
|
151
|
+
const { events } = createPiHarness();
|
|
152
|
+
const calls = [];
|
|
153
|
+
const ctx = createCommandContext({
|
|
154
|
+
sessionManager: { getEntries: () => [] },
|
|
155
|
+
ui: { notify() {}, setStatus: (_key, text) => calls.push(text) }, // no theme
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await events.get("session_start")({ reason: "startup" }, ctx);
|
|
159
|
+
await events.get("agent_start")({}, ctx);
|
|
160
|
+
|
|
161
|
+
assert.deepEqual(calls, []);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test("invalid subcommand notifies warning and does not append", async () => {
|
|
165
|
+
const { commands, appendedEntries } = createPiHarness();
|
|
166
|
+
let notified = null;
|
|
167
|
+
const ctx = createCommandContext({ ui: { notify: (_m, kind) => { notified = kind; } } });
|
|
168
|
+
|
|
169
|
+
await commands.get("caveman").handler("banana", ctx);
|
|
170
|
+
|
|
171
|
+
assert.equal(notified, "warning");
|
|
172
|
+
assert.equal(appendedEntries.length, 0);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test("status subcommand reports without changing state", async () => {
|
|
176
|
+
const { commands, events, appendedEntries } = createPiHarness();
|
|
177
|
+
let reported = null;
|
|
178
|
+
const ctx = createCommandContext({ ui: { notify: (m) => { reported = m; } } });
|
|
179
|
+
|
|
180
|
+
await events.get("session_start")({ reason: "startup" }, ctx); // starts on
|
|
181
|
+
await commands.get("caveman").handler("status", ctx);
|
|
182
|
+
|
|
183
|
+
assert.match(reported, /ON/);
|
|
184
|
+
assert.equal(appendedEntries.length, 0);
|
|
185
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
getCavemanInstructions,
|
|
8
|
+
isDeactivationCommand,
|
|
9
|
+
parseCavemanCommand,
|
|
10
|
+
resolveSessionActive,
|
|
11
|
+
} from "../index.js";
|
|
12
|
+
|
|
13
|
+
test("parseCavemanCommand: bare toggles", () => {
|
|
14
|
+
assert.deepEqual(parseCavemanCommand(""), { type: "toggle" });
|
|
15
|
+
assert.deepEqual(parseCavemanCommand(" "), { type: "toggle" });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("parseCavemanCommand: on/off/status", () => {
|
|
19
|
+
assert.deepEqual(parseCavemanCommand("on"), { type: "set", active: true });
|
|
20
|
+
assert.deepEqual(parseCavemanCommand("ENABLE"), { type: "set", active: true });
|
|
21
|
+
assert.deepEqual(parseCavemanCommand("off"), { type: "set", active: false });
|
|
22
|
+
assert.deepEqual(parseCavemanCommand("disable"), { type: "set", active: false });
|
|
23
|
+
assert.deepEqual(parseCavemanCommand("status"), { type: "status" });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("parseCavemanCommand: unknown arg is invalid", () => {
|
|
27
|
+
assert.deepEqual(parseCavemanCommand("banana"), { type: "invalid", reason: "unknown-subcommand", arg: "banana" });
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("resolveSessionActive: latest persisted entry wins", () => {
|
|
31
|
+
const entries = [
|
|
32
|
+
{ type: "custom", customType: "caveman-mode", data: { active: false } },
|
|
33
|
+
{ type: "custom", customType: "caveman-mode", data: { active: true } },
|
|
34
|
+
];
|
|
35
|
+
assert.equal(resolveSessionActive(entries, true), true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("resolveSessionActive: non-array entries fall back", () => {
|
|
39
|
+
assert.equal(resolveSessionActive(null, true), true);
|
|
40
|
+
assert.equal(resolveSessionActive(undefined, false), false);
|
|
41
|
+
assert.equal(resolveSessionActive({}, true), true);
|
|
42
|
+
assert.equal(resolveSessionActive("nope"), true); // DEFAULT fallback
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("isDeactivationCommand: only the whole message, case-insensitive, trailing punct ok", () => {
|
|
46
|
+
assert.equal(isDeactivationCommand("stop caveman"), true);
|
|
47
|
+
assert.equal(isDeactivationCommand("STOP CAVEMAN!"), true);
|
|
48
|
+
assert.equal(isDeactivationCommand("normal mode"), true);
|
|
49
|
+
assert.equal(isDeactivationCommand("Normal Mode."), true);
|
|
50
|
+
assert.equal(isDeactivationCommand("add a normal mode toggle"), false);
|
|
51
|
+
assert.equal(isDeactivationCommand("how do I stop caveman re-rendering"), false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("getCavemanInstructions reads SKILL.md and strips frontmatter", () => {
|
|
55
|
+
const instructions = getCavemanInstructions();
|
|
56
|
+
assert.ok(instructions.startsWith("CAVEMAN MODE ACTIVE"));
|
|
57
|
+
assert.ok(!instructions.includes("name: caveman")); // frontmatter gone
|
|
58
|
+
assert.ok(instructions.includes("Respond terse like smart caveman"));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("getCavemanInstructions matches src/skills/caveman/SKILL.md body", () => {
|
|
62
|
+
const skillPath = fileURLToPath(new URL("../../../skills/caveman/SKILL.md", import.meta.url));
|
|
63
|
+
const raw = readFileSync(skillPath, "utf8");
|
|
64
|
+
const body = raw.replace(/^---[\s\S]*?---\s*/, "");
|
|
65
|
+
|
|
66
|
+
assert.ok(getCavemanInstructions().endsWith(body));
|
|
67
|
+
});
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import net from "net";
|
|
2
2
|
import { writeFileSync, unlinkSync, mkdirSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
|
-
import { homedir } from "os";
|
|
5
4
|
import { randomUUID } from "crypto";
|
|
6
5
|
import { writeMessage, createMessageReader } from "./framing.js";
|
|
7
|
-
import { getBrokerSocketPath } from "./paths.js";
|
|
6
|
+
import { getBrokerSocketPath, getIntercomDir } from "./paths.js";
|
|
8
7
|
import type { SessionInfo, Message, Attachment, BrokerMessage } from "../types.js";
|
|
9
8
|
|
|
10
|
-
const INTERCOM_DIR =
|
|
9
|
+
const INTERCOM_DIR = getIntercomDir();
|
|
11
10
|
const SOCKET_PATH = getBrokerSocketPath();
|
|
12
11
|
const PID_PATH = join(INTERCOM_DIR, "broker.pid");
|
|
13
12
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from "path";
|
|
2
|
-
import {
|
|
2
|
+
import { getAgentDir } from "@selesai/code";
|
|
3
3
|
|
|
4
4
|
function sanitizePipeSegment(value: string): string {
|
|
5
5
|
return value
|
|
@@ -8,13 +8,18 @@ function sanitizePipeSegment(value: string): string {
|
|
|
8
8
|
.toLowerCase() || "default";
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/** selesai config dir (~/.selesai/agent on the selesai fork, ~/.pi/agent upstream). */
|
|
12
|
+
export function getIntercomDir(): string {
|
|
13
|
+
return join(getAgentDir(), "intercom");
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
export function getBrokerSocketPath(
|
|
12
17
|
platform: NodeJS.Platform = process.platform,
|
|
13
|
-
|
|
18
|
+
intercomDir: string = getIntercomDir(),
|
|
14
19
|
): string {
|
|
15
20
|
if (platform === "win32") {
|
|
16
|
-
return `\\\\.\\pipe\\pi-intercom-${sanitizePipeSegment(
|
|
21
|
+
return `\\\\.\\pipe\\pi-intercom-${sanitizePipeSegment(intercomDir)}`;
|
|
17
22
|
}
|
|
18
23
|
|
|
19
|
-
return join(
|
|
20
|
-
}
|
|
24
|
+
return join(intercomDir, "broker.sock");
|
|
25
|
+
}
|
|
@@ -2,11 +2,10 @@ import { spawn } from "child_process";
|
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
3
3
|
import { join, dirname } from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
|
-
import { homedir } from "os";
|
|
6
5
|
import net from "net";
|
|
7
|
-
import { getBrokerSocketPath } from "./paths.js";
|
|
6
|
+
import { getBrokerSocketPath, getIntercomDir } from "./paths.js";
|
|
8
7
|
|
|
9
|
-
const INTERCOM_DIR =
|
|
8
|
+
const INTERCOM_DIR = getIntercomDir();
|
|
10
9
|
const EXTENSION_DIR = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
10
|
const BROKER_SOCKET = getBrokerSocketPath();
|
|
12
11
|
const BROKER_PID = join(INTERCOM_DIR, "broker.pid");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
|
-
import {
|
|
3
|
+
import { getIntercomDir } from "./broker/paths.js";
|
|
4
4
|
|
|
5
5
|
export interface IntercomConfig {
|
|
6
6
|
/** Broker command used to spawn the broker process (e.g. "npx" or "bun") */
|
|
@@ -22,7 +22,7 @@ export interface IntercomConfig {
|
|
|
22
22
|
replyHint: boolean;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const CONFIG_PATH = join(
|
|
25
|
+
const CONFIG_PATH = join(getIntercomDir(), "config.json");
|
|
26
26
|
|
|
27
27
|
const defaults: IntercomConfig = {
|
|
28
28
|
brokerCommand: "npx",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ExtensionAPI, ExtensionContext } from "@
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@selesai/code";
|
|
2
2
|
import { randomUUID } from "crypto";
|
|
3
3
|
import { Type } from "typebox";
|
|
4
|
-
import { Text } from "@
|
|
4
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
5
5
|
import { IntercomClient } from "./broker/client.ts";
|
|
6
6
|
import { spawnBrokerIfNeeded } from "./broker/spawn.ts";
|
|
7
7
|
import { SessionListOverlay } from "./ui/session-list.ts";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Component, TUI } from "@
|
|
2
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
3
|
-
import type { KeybindingsManager, Theme } from "@
|
|
1
|
+
import type { Component, TUI } from "@earendil-works/pi-tui";
|
|
2
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
|
+
import type { KeybindingsManager, Theme } from "@selesai/code";
|
|
4
4
|
import type { IntercomClient } from "../broker/client.js";
|
|
5
5
|
import type { SessionInfo } from "../types.js";
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Component } from "@
|
|
2
|
-
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@
|
|
3
|
-
import type { Theme } from "@
|
|
1
|
+
import type { Component } from "@earendil-works/pi-tui";
|
|
2
|
+
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
3
|
+
import type { Theme } from "@selesai/code";
|
|
4
4
|
import type { SessionInfo, Message } from "../types.js";
|
|
5
5
|
|
|
6
6
|
export class InlineMessageComponent implements Component {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Component } from "@
|
|
2
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
3
|
-
import type { KeybindingsManager, Theme } from "@
|
|
1
|
+
import type { Component } from "@earendil-works/pi-tui";
|
|
2
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
|
+
import type { KeybindingsManager, Theme } from "@selesai/code";
|
|
4
4
|
import type { SessionInfo } from "../types.js";
|
|
5
5
|
|
|
6
6
|
function middleTruncate(text: string, maxWidth: number): string {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
|
+
import { getAgentDir } from "@selesai/code";
|
|
4
5
|
|
|
5
6
|
interface PersistedHistoryEntry {
|
|
6
7
|
command: string;
|
|
@@ -13,7 +14,7 @@ function getHomeDir(): string {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
function getHistoryDir(): string {
|
|
16
|
-
return join(
|
|
17
|
+
return join(getAgentDir(), "powerline-footer", "bash-history");
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
function projectKey(cwd: string): string {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
copyToClipboard,
|
|
3
|
+
CONFIG_DIR_NAME,
|
|
4
|
+
getAgentDir,
|
|
5
|
+
getSettingsPath,
|
|
3
6
|
type ExtensionAPI,
|
|
4
7
|
type ReadonlyFooterDataProvider,
|
|
5
8
|
type Theme,
|
|
@@ -8,7 +11,6 @@ import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
|
8
11
|
import { isKeyRelease, matchesKey, type AutocompleteProvider, type SelectItem, SelectList, truncateToWidth, TUI_KEYBINDINGS, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
12
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
10
13
|
import { join, dirname } from "node:path";
|
|
11
|
-
import { homedir } from "node:os";
|
|
12
14
|
|
|
13
15
|
import type { ColorScheme, SegmentContext, StatusLinePreset, StatusLineSegmentId } from "./types.ts";
|
|
14
16
|
import type { PowerlineConfig } from "./powerline-config.ts";
|
|
@@ -324,23 +326,16 @@ function trackPromptHistory(editor: any): void {
|
|
|
324
326
|
snapshotPromptHistory(editor);
|
|
325
327
|
}
|
|
326
328
|
|
|
327
|
-
function getSettingsPath(): string {
|
|
328
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || homedir();
|
|
329
|
-
return join(homeDir, ".pi", "agent", "settings.json");
|
|
330
|
-
}
|
|
331
|
-
|
|
332
329
|
function getProjectSettingsPath(cwd: string): string {
|
|
333
|
-
return join(cwd,
|
|
330
|
+
return join(cwd, CONFIG_DIR_NAME, "settings.json");
|
|
334
331
|
}
|
|
335
332
|
|
|
336
333
|
function getGlobalCompactionPolicyPath(): string {
|
|
337
|
-
|
|
338
|
-
return join(homeDir, ".pi", "agent", "compaction-policy.json");
|
|
334
|
+
return join(getAgentDir(), "compaction-policy.json");
|
|
339
335
|
}
|
|
340
336
|
|
|
341
337
|
function getCustomCompactionExtensionPath(): string {
|
|
342
|
-
|
|
343
|
-
return join(homeDir, ".pi", "agent", "extensions", "pi-custom-compaction");
|
|
338
|
+
return join(getAgentDir(), "extensions", "pi-custom-compaction");
|
|
344
339
|
}
|
|
345
340
|
|
|
346
341
|
function mergeSettings(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {
|
|
@@ -413,7 +408,7 @@ function readCompactionPolicyEnabled(configPath: string): boolean | undefined {
|
|
|
413
408
|
function detectCustomCompactionEnabled(cwd: string): boolean {
|
|
414
409
|
if (!existsSync(getCustomCompactionExtensionPath())) return false;
|
|
415
410
|
|
|
416
|
-
const projectSetting = readCompactionPolicyEnabled(join(cwd,
|
|
411
|
+
const projectSetting = readCompactionPolicyEnabled(join(cwd, CONFIG_DIR_NAME, "compaction-policy.json"));
|
|
417
412
|
if (projectSetting !== undefined) return projectSetting;
|
|
418
413
|
|
|
419
414
|
return readCompactionPolicyEnabled(getGlobalCompactionPolicyPath()) ?? false;
|
|
@@ -424,13 +419,11 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
424
419
|
}
|
|
425
420
|
|
|
426
421
|
function getStashHistoryPath(): string {
|
|
427
|
-
|
|
428
|
-
return join(homeDir, ".pi", "agent", "powerline-footer", "stash-history.json");
|
|
422
|
+
return join(getAgentDir(), "powerline-footer", "stash-history.json");
|
|
429
423
|
}
|
|
430
424
|
|
|
431
425
|
function getSessionsPath(): string {
|
|
432
|
-
|
|
433
|
-
return join(homeDir, ".pi", "agent", "sessions");
|
|
426
|
+
return join(getAgentDir(), "sessions");
|
|
434
427
|
}
|
|
435
428
|
|
|
436
429
|
function getProjectSessionsPath(cwd: string): string {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdirSync, existsSync, statSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, basename } from "node:path";
|
|
3
3
|
import { homedir as osHomedir } from "node:os";
|
|
4
|
+
import { CONFIG_DIR_NAME, getAgentDir, getSettingsPath } from "@selesai/code";
|
|
4
5
|
import type { Component } from "@earendil-works/pi-tui";
|
|
5
6
|
import { truncateToWidth as tuiTruncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
6
7
|
import { ansi, fgOnly, getFgAnsiCode } from "./colors.ts";
|
|
@@ -330,11 +331,16 @@ function logDiscoveryError(scope: string, error: unknown): void {
|
|
|
330
331
|
console.debug(`[powerline-welcome] ${scope}:`, error);
|
|
331
332
|
}
|
|
332
333
|
|
|
334
|
+
// ponytail: only .claude paths still need raw home; everything else routes via getAgentDir.
|
|
335
|
+
function homedirSafe(): string {
|
|
336
|
+
return process.env.HOME || process.env.USERPROFILE || osHomedir();
|
|
337
|
+
}
|
|
338
|
+
|
|
333
339
|
/**
|
|
334
340
|
* Discover loaded counts by scanning filesystem.
|
|
335
341
|
*/
|
|
336
342
|
export function discoverLoadedCounts(): LoadedCounts {
|
|
337
|
-
const homeDir =
|
|
343
|
+
const homeDir = getAgentDir();
|
|
338
344
|
const cwd = process.cwd();
|
|
339
345
|
|
|
340
346
|
let contextFiles = 0;
|
|
@@ -343,10 +349,10 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
343
349
|
let promptTemplates = 0;
|
|
344
350
|
|
|
345
351
|
const agentsMdPaths = [
|
|
346
|
-
join(homeDir, "
|
|
347
|
-
join(
|
|
352
|
+
join(homeDir, "AGENTS.md"),
|
|
353
|
+
join(homedirSafe(), ".claude", "AGENTS.md"),
|
|
348
354
|
join(cwd, "AGENTS.md"),
|
|
349
|
-
join(cwd,
|
|
355
|
+
join(cwd, CONFIG_DIR_NAME, "AGENTS.md"),
|
|
350
356
|
join(cwd, ".claude", "AGENTS.md"),
|
|
351
357
|
];
|
|
352
358
|
|
|
@@ -355,16 +361,16 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
355
361
|
}
|
|
356
362
|
|
|
357
363
|
const extensionDirs = [
|
|
358
|
-
join(homeDir, "
|
|
364
|
+
join(homeDir, "extensions"),
|
|
359
365
|
join(cwd, "extensions"),
|
|
360
|
-
join(cwd,
|
|
366
|
+
join(cwd, CONFIG_DIR_NAME, "extensions"),
|
|
361
367
|
];
|
|
362
368
|
|
|
363
369
|
const countedExtensions = new Set<string>();
|
|
364
370
|
|
|
365
371
|
const settingsPaths = [
|
|
366
|
-
|
|
367
|
-
join(cwd,
|
|
372
|
+
getSettingsPath(),
|
|
373
|
+
join(cwd, CONFIG_DIR_NAME, "settings.json"),
|
|
368
374
|
];
|
|
369
375
|
|
|
370
376
|
for (const settingsPath of settingsPaths) {
|
|
@@ -460,8 +466,8 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
460
466
|
}
|
|
461
467
|
|
|
462
468
|
const skillDirs = [
|
|
463
|
-
join(homeDir, "
|
|
464
|
-
join(cwd,
|
|
469
|
+
join(homeDir, "skills"),
|
|
470
|
+
join(cwd, CONFIG_DIR_NAME, "skills"),
|
|
465
471
|
join(cwd, "skills"),
|
|
466
472
|
];
|
|
467
473
|
|
|
@@ -493,9 +499,9 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
493
499
|
}
|
|
494
500
|
|
|
495
501
|
const templateDirs = [
|
|
496
|
-
join(homeDir, "
|
|
497
|
-
join(
|
|
498
|
-
join(cwd,
|
|
502
|
+
join(homeDir, "commands"),
|
|
503
|
+
join(homedirSafe(), ".claude", "commands"),
|
|
504
|
+
join(cwd, CONFIG_DIR_NAME, "commands"),
|
|
499
505
|
join(cwd, ".claude", "commands"),
|
|
500
506
|
];
|
|
501
507
|
|
|
@@ -538,11 +544,12 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
538
544
|
* Get recent sessions from the sessions directory.
|
|
539
545
|
*/
|
|
540
546
|
export function getRecentSessions(maxCount: number = 3): RecentSession[] {
|
|
541
|
-
const homeDir =
|
|
547
|
+
const homeDir = getAgentDir();
|
|
548
|
+
const home = homedirSafe();
|
|
542
549
|
|
|
543
550
|
const sessionsDirs = [
|
|
544
|
-
join(homeDir, "
|
|
545
|
-
join(
|
|
551
|
+
join(homeDir, "sessions"),
|
|
552
|
+
join(home, CONFIG_DIR_NAME, "sessions"),
|
|
546
553
|
];
|
|
547
554
|
|
|
548
555
|
const sessions: { name: string; mtime: number }[] = [];
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
// Uses module-level state (matching powerline-footer pattern).
|
|
4
4
|
|
|
5
5
|
import { complete, type Context } from "@earendil-works/pi-ai";
|
|
6
|
-
import type
|
|
6
|
+
import { getAgentDir, getSettingsPath, type ExtensionContext } from "@selesai/code";
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
8
8
|
import { join, dirname } from "node:path";
|
|
9
|
-
import { homedir } from "node:os";
|
|
10
9
|
|
|
11
10
|
type VibeMode = "generate" | "file";
|
|
12
11
|
|
|
@@ -76,11 +75,6 @@ let recentVibes: string[] = [];
|
|
|
76
75
|
// Configuration Management
|
|
77
76
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
78
77
|
|
|
79
|
-
function getSettingsPath(): string {
|
|
80
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || homedir();
|
|
81
|
-
return join(homeDir, ".pi", "agent", "settings.json");
|
|
82
|
-
}
|
|
83
|
-
|
|
84
78
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
85
79
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
86
80
|
}
|
|
@@ -208,8 +202,7 @@ function saveModelConfig(): boolean {
|
|
|
208
202
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
209
203
|
|
|
210
204
|
function getVibesDir(): string {
|
|
211
|
-
|
|
212
|
-
return join(homeDir, ".pi", "agent", "vibes");
|
|
205
|
+
return join(getAgentDir(), "vibes");
|
|
213
206
|
}
|
|
214
207
|
|
|
215
208
|
function toVibeFileSlug(theme: string): string {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAgentDir, type ExtensionAPI, type ExtensionContext } from "@
|
|
1
|
+
import { getAgentDir, type ExtensionAPI, type ExtensionContext } from "@selesai/code";
|
|
2
2
|
import { exec as execCb } from "child_process";
|
|
3
3
|
import { existsSync, readFileSync, realpathSync } from "fs";
|
|
4
4
|
import { mkdtemp, readdir, readFile, rm, stat } from "fs/promises";
|