Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/skills/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ function getDevTlsHint(): string | null {
return "Dev API TLS: set NODE_EXTRA_CA_CERTS to your Portless CA before starting Codex.";
}

function getAutoRecallStatus(): string {
return CONFIG.autoRecallEveryPrompt ? "every prompt" : "off";
}

function getAutoCaptureStatus(): string {
if (CONFIG.captureEveryNTurns <= 0) return "off";
return `every ${CONFIG.captureEveryNTurns} turn${CONFIG.captureEveryNTurns === 1 ? "" : "s"}`;
}

async function fetchJson(path: string): Promise<unknown | null> {
const apiKey = getApiKeyValue();
if (!apiKey) return null;
Expand Down Expand Up @@ -103,8 +112,8 @@ async function main(): Promise<void> {
lines.push(`API key: ${maskKey(apiKey)} (${getKeySource()})`);
lines.push(`API URL: ${API_URL}`);
lines.push(`Memory scope: one project container with metadata scopes`);
lines.push(`Recall mode: auto-recall on every prompt`);
lines.push(`Capture cadence: ${CONFIG.autoSaveEveryTurns > 0 ? `every ${CONFIG.autoSaveEveryTurns} turn${CONFIG.autoSaveEveryTurns === 1 ? "" : "s"} + session end` : "session end only"}`);
lines.push(`Auto-recall: ${getAutoRecallStatus()}`);
lines.push(`Auto-capture: ${getAutoCaptureStatus()}`);
lines.push(`Project container: ${tags.canonical}`);
lines.push(`Reads (including legacy): ${tags.allReads.join(", ")}`);

Expand Down
37 changes: 37 additions & 0 deletions test/unit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,18 @@ describe("skill scripts: search/add/save/forget/status/logout", () => {
});
}

function runStatusWithConfig(t, config) {
const tmpDir = makeTmpDir();
const codexDir = join(tmpDir, ".codex");
mkdirSync(codexDir, { recursive: true });
writeFileSync(join(codexDir, "supermemory.json"), JSON.stringify(config));
t.after(() => rmSync(tmpDir, { recursive: true, force: true }));
return spawnSync("node", [statusBin], {
env: { PATH: process.env.PATH, HOME: tmpDir, USERPROFILE: tmpDir, SUPERMEMORY_CODEX_API_KEY: "" },
encoding: "utf-8",
});
}

// Run a script with a (fake) API key but no network. We expect arg-parsing
// branches (missing query/content) to short-circuit before any network call.
function runSkillNoArgs(t, bin) {
Expand Down Expand Up @@ -796,6 +808,31 @@ describe("skill scripts: search/add/save/forget/status/logout", () => {
assert.match(result.stdout, /supermemory-login/);
});

test("status reports auto-recall off when auto recall is disabled", (t) => {
const result = runStatusWithConfig(t, { autoRecallEveryPrompt: false, captureEveryNTurns: 0 });
assert.equal(result.status, 0);
assert.match(result.stdout, /Auto-recall: off/);
});

test("status reports every-prompt auto-recall when enabled", (t) => {
const result = runStatusWithConfig(t, { autoRecallEveryPrompt: true, captureEveryNTurns: 0 });
assert.equal(result.status, 0);
assert.match(result.stdout, /Auto-recall: every prompt/);
});

test("status reports auto-capture off when captureEveryNTurns is zero", (t) => {
const result = runStatusWithConfig(t, { autoRecallEveryPrompt: false, captureEveryNTurns: 0 });
assert.equal(result.status, 0);
assert.match(result.stdout, /Auto-capture: off/);
});

test("status reports configured auto-capture cadence from captureEveryNTurns", (t) => {
const result = runStatusWithConfig(t, { autoRecallEveryPrompt: false, captureEveryNTurns: 5, autoSaveEveryTurns: 3 });
assert.equal(result.status, 0);
assert.match(result.stdout, /Auto-capture: every 5 turns/);
assert.doesNotMatch(result.stdout, /every 3 turns/);
});

test("logout removes saved credentials and config apiKey", (t) => {
const tmpDir = makeTmpDir();
const codexDir = join(tmpDir, ".codex");
Expand Down