mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 22:14:25 +01:00
G6: context-save computes session duration on Linux (#2704)
The duration step parsed 'ps -o lstart=' with BSD-only 'date -jf', so on Linux session_duration_s was always unknown. It now falls back to GNU 'date -d', and never parses an empty start (GNU reads that as midnight). Ported onto the current block instead of #2704's ~/.gstack/sessions mtime, which bypassed the state root. Co-authored-by: Evgenii Lopatin <e75533@gmail.com>
This commit is contained in:
1 parent
5ee77d2ec4
commit
e2cf27ff5e
2 files changed
+30
-1
No files matched your search
@@ -94,7 +94,10 @@ Try to determine how long this session has been active:
|
||||
if [ -n "$_TEL_START" ]; then
|
||||
START_EPOCH="$_TEL_START"
|
||||
elif [ -n "$PPID" ]; then
|
||||
START_EPOCH=$(ps -o lstart= -p $PPID 2>/dev/null | xargs -I{} date -jf "%c" "{}" "+%s" 2>/dev/null || echo "")
|
||||
_LSTART=$(ps -o lstart= -p "$PPID" 2>/dev/null)
|
||||
# BSD date (macOS) parses with -jf; GNU date (Linux) with -d. Never parse an
|
||||
# empty start: GNU date -d "" means today at midnight.
|
||||
[ -n "$_LSTART" ] && START_EPOCH=$(date -jf "%c" "$_LSTART" "+%s" 2>/dev/null || date -d "$_LSTART" "+%s" 2>/dev/null || echo "")
|
||||
fi
|
||||
if [ -n "$START_EPOCH" ]; then
|
||||
NOW=$(date +%s)
|
||||
|
||||
@@ -432,3 +432,29 @@ describe('migration v1.1.3.0: HOME guard', () => {
|
||||
expect(result.stdout.toString().trim()).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
// G6 rider #2704: the duration block parsed `ps -o lstart=` with BSD-only
|
||||
// `date -jf`, so on Linux session_duration_s was always "unknown". Runs the
|
||||
// block extracted from the template, so it cannot drift from the skill.
|
||||
describe('context-save session duration (#2704)', () => {
|
||||
const tmpl = fs.readFileSync(path.join(ROOT, 'context-save', 'SKILL.md.tmpl'), 'utf-8');
|
||||
const step = tmpl.slice(tmpl.indexOf('### Step 3: Compute session duration'));
|
||||
const block = step.match(/```bash\n([\s\S]*?)\n```/)![1];
|
||||
const psWorks = spawnSync('bash', ['-c', 'ps -o lstart= -p $$'], { encoding: 'utf-8', timeout: 5000 }).stdout.trim() !== '';
|
||||
|
||||
test.skipIf(!psWorks)('computes a numeric duration from the parent process start time', () => {
|
||||
const r = spawnSync('bash', ['-c', block], { env: { PATH: process.env.PATH! }, encoding: 'utf-8', timeout: 10_000 });
|
||||
expect(r.stdout).toMatch(/^SESSION_DURATION_S=\d+$/m);
|
||||
});
|
||||
|
||||
test('an unreadable parent start says unknown instead of inventing midnight', () => {
|
||||
const shim = fs.mkdtempSync(path.join(os.tmpdir(), 'ctxsave-ps-'));
|
||||
try {
|
||||
fs.writeFileSync(path.join(shim, 'ps'), '#!/bin/sh\nexit 1\n', { mode: 0o755 });
|
||||
const r = spawnSync('bash', ['-c', block], { env: { PATH: `${shim}:${process.env.PATH}` }, encoding: 'utf-8', timeout: 10_000 });
|
||||
expect(r.stdout.trim()).toBe('SESSION_DURATION_S=unknown');
|
||||
} finally {
|
||||
fs.rmSync(shim, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user