Skip to documentation
SLOP

tiny.smg.command.session

Reference tiny.smg command session

Defined in command.

API (10)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callscommandsession
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallscommand.sessionloadReadcommand.sessionloadMutationcommand.sessionload
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallscommand.sessionloadReadGraphAndConceptscommand.sessionnoteGraphAgeconceptsloadFromReaderstorage.graphloadFromReaderstorage.storeopenReadcommand.sessionloadGraphAndConcepts
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallscommand.sessionloadcommand.sessionloadMutationAtcommand.sessionloadMutation
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallscommand.sessionloadMutationcommand.sessionnoteGraphAgestorage.graphloadSnapshotcommand.sessionloadMutationAt
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallscommand.nodeshowcommand.sessionloadcommand.sessionloadRead
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerscommand.sessionloadGraphAndConceptscommand.sessionloadReadGraphAndConcepts
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallscommand.searchruncommand.sessionloadGraphAndConceptscommand.sessionloadMutationAtcommand.statusruncommand.usagesruncli.outputwriteErrFmtprivate; no linktools.smg.src.command.sessionhumanAgecommand.sessionnoteGraphAge
Static calls · unresolved targets: 0 · external targets: 3.

Source: tools/smg/src/command/root.zig:21

zig
pub const session = @import("session.zig");

Source: tools/smg/src/command/session.zig

zig
const std = @import("std");const alloc = @import("alloc");const sql = @import("sql");const sys = @import("sys");const smg = @import("../root.zig");const concepts = smg.concepts;const graph_mod = smg.graph;const model = smg.model;const output = smg.cli.output;const search = smg.search;const storage = smg.storage;pub const PhaseBoundary = alloc.PhaseBoundary;pub fn load(    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    limits: smg.Limits,) !struct { []const u8, graph_mod.Graph } {    const loaded = try loadMutation(allocator, scratch, limits);    return .{ loaded.root, loaded.graph };}pub const GraphMutation = struct {    root: []const u8,    graph: graph_mod.Graph,    head: sql.Hash,};pub fn loadMutation(    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    limits: smg.Limits,) !GraphMutation {    const root = try storage.requireRoot(allocator);    return try loadMutationAt(allocator, scratch, root, limits);}pub fn loadMutationAt(    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    root: []const u8,    limits: smg.Limits,) !GraphMutation {    try noteGraphAge(allocator, root);    const snapshot = try storage.graph.loadSnapshot(        allocator,        scratch,        root,        limits.storage,    );    return .{ .root = root, .graph = snapshot.graph, .head = snapshot.head };}pub fn loadRead(    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    limits: smg.Limits,    boundary: PhaseBoundary,) !struct { []const u8, graph_mod.Graph } {    const loaded = try load(allocator, scratch, limits);    boundary.seal();    return loaded;}pub const GraphConcepts = struct {    root: []const u8,    graph: graph_mod.Graph,    concepts: []const concepts.Concept,};pub fn loadGraphAndConcepts(    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    limits: smg.Limits,) !GraphConcepts {    const root = try storage.requireRoot(allocator);    try noteGraphAge(allocator, root);    var opened = try storage.store.openRead(scratch, root, limits.storage);    defer opened.close();    var graph = try storage.graph.loadFromReader(allocator, scratch, &opened.reader);    errdefer graph_mod.deinit(&graph);    return .{        .root = root,        .graph = graph,        .concepts = try concepts.loadFromReader(allocator, &opened.reader),    };}pub fn loadReadGraphAndConcepts(    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    limits: smg.Limits,    boundary: PhaseBoundary,) !GraphConcepts {    const loaded = try loadGraphAndConcepts(allocator, scratch, limits);    boundary.seal();    return loaded;}const graph_age_note_ns: i128 = 60 * 60 * std.time.ns_per_s;pub fn noteGraphAge(allocator: std.mem.Allocator, root: []const u8) !void {    var newest: ?i128 = null;    for ([_][]const u8{ storage.paths.wal_file_name, storage.paths.database_file_name }) |file_name| {        const path = try std.fs.path.join(allocator, &.{ root, storage.paths.smg_dir_name, file_name });        defer allocator.free(path);        const stat = sys.fs.statFile(path) catch continue;        if (newest == null or stat.mtime.nanoseconds > newest.?) newest = stat.mtime.nanoseconds;    }    const mtime = newest orelse return;    const age_ns = sys.time.realNanoTimestamp() - mtime;    if (age_ns < graph_age_note_ns) return;    const age_text = try humanAge(allocator, age_ns);    defer allocator.free(age_text);    try output.writeErrFmt(allocator, "note: graph last scanned {s} ago; run smg scan to refresh\n", .{age_text});}fn humanAge(allocator: std.mem.Allocator, age_ns: i128) ![]u8 {    const seconds: i64 = @intCast(@divTrunc(age_ns, std.time.ns_per_s));    if (seconds >= 2 * 24 * 60 * 60) return try std.fmt.allocPrint(allocator, "{d}d", .{@divTrunc(seconds, 24 * 60 * 60)});    if (seconds >= 60 * 60) return try std.fmt.allocPrint(allocator, "{d}h", .{@divTrunc(seconds, 60 * 60)});    if (seconds >= 60) return try std.fmt.allocPrint(allocator, "{d}m", .{@divTrunc(seconds, 60)});    return try std.fmt.allocPrint(allocator, "{d}s", .{@max(seconds, 0)});}test "humanAge reports days hours and minutes" {    const day = try humanAge(std.testing.allocator, 3 * 24 * 60 * 60 * std.time.ns_per_s);    defer std.testing.allocator.free(day);    try std.testing.expectEqualStrings("3d", day);    const hour = try humanAge(std.testing.allocator, 5 * 60 * 60 * std.time.ns_per_s);    defer std.testing.allocator.free(hour);    try std.testing.expectEqualStrings("5h", hour);    const minute = try humanAge(std.testing.allocator, 7 * 60 * std.time.ns_per_s);    defer std.testing.allocator.free(minute);    try std.testing.expectEqualStrings("7m", minute);}test "graph publication releases persistence scratch and preserves search row order" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    const root = try std.fmt.allocPrint(allocator, "/tmp/smg-main-search-rowids-{x}", .{@as(u64, @intCast(@max(0, sys.time.realMilliTimestamp())))});    defer sys.fs.deleteTree(root) catch {};    try sys.fs.createDirPath(root);    _ = try storage.initProject(allocator, root, smg.default_limits.storage);    const snapshot = try storage.graph.loadSnapshot(        allocator,        allocator,        root,        smg.default_limits.storage,    );    var graph = graph_mod.init(allocator);    try graph_mod.addNode(&graph, .{ .name = "smg.cli.helpers._truncate", .type = model.NodeType.function, .file = "src/smg/cli/_helpers.py", .line = 42, .docstring = "Trim a string to width with an ellipsis" });    try graph_mod.addNode(&graph, .{ .name = "smg.graph.SemGraph", .type = model.NodeType.class, .file = "src/smg/graph.py", .line = 10, .docstring = "Core semantic graph data structure" });    try graph_mod.addNode(&graph, .{ .name = "smg.graph.SemGraph.truncate_path", .type = model.NodeType.method, .file = "src/smg/graph.py", .line = 412, .docstring = "Drop path components after max depth" });    try graph_mod.addNode(&graph, .{ .name = "smg.scan.scan_paths", .type = model.NodeType.function, .file = "src/smg/scan.py", .line = 100, .docstring = "Scan source files and populate graph" });    try graph_mod.addNode(&graph, .{ .name = "smg.cli.helpers.format_output", .type = model.NodeType.function, .file = "src/smg/cli/_helpers.py", .line = 80, .docstring = "Format output for display" });    try storage.graph.publish(        std.testing.allocator,        root,        graph,        snapshot.head,        smg.default_limits,    );    const result = try testSearchStored(allocator, root, "truncate", null, 10);    try std.testing.expectEqual(@as(i64, 2), result.total);    try std.testing.expectEqual(@as(usize, 2), result.hits.len);    try std.testing.expectEqualStrings("smg.cli.helpers._truncate", result.hits[0].name);    try std.testing.expectEqualStrings("smg.graph.SemGraph.truncate_path", result.hits[1].name);    const near_path = try testSearchStored(allocator, root, "NEAR(truncate path, 5)", null, 10);    try std.testing.expectEqual(@as(i64, 1), near_path.total);    try std.testing.expectEqualStrings("smg.graph.SemGraph.truncate_path", near_path.hits[0].name);    const near_helpers = try testSearchStored(allocator, root, "NEAR(truncate helpers, 5)", null, 10);    try std.testing.expectEqual(@as(i64, 1), near_helpers.total);    try std.testing.expectEqualStrings("smg.cli.helpers._truncate", near_helpers.hits[0].name);    const bare_near = try testSearchStored(allocator, root, "NEAR", null, 10);    try std.testing.expectEqual(@as(i64, 0), bare_near.total);    try std.testing.expectError(search.Error.InvalidSearchQuery, testSearchStored(allocator, root, "NEAR(truncate path, bad)", null, 10));    const cross_field_phrase = try testSearchStored(allocator, root, "\"path Drop\"", null, 10);    try std.testing.expectEqual(@as(i64, 0), cross_field_phrase.total);    const cross_field_near = try testSearchStored(allocator, root, "NEAR(truncate max, 10)", null, 10);    try std.testing.expectEqual(@as(i64, 0), cross_field_near.total);    const cross_field_and = try testSearchStored(allocator, root, "truncate AND max", null, 10);    try std.testing.expectEqual(@as(i64, 1), cross_field_and.total);    try std.testing.expectEqualStrings("smg.graph.SemGraph.truncate_path", cross_field_and.hits[0].name);    const name_filter = try testSearchStored(allocator, root, "name_tokens:truncate", null, 10);    try std.testing.expectEqual(@as(i64, 2), name_filter.total);    try std.testing.expectEqualStrings("smg.cli.helpers._truncate", name_filter.hits[0].name);    try std.testing.expectEqualStrings("smg.graph.SemGraph.truncate_path", name_filter.hits[1].name);    const doc_filter = try testSearchStored(allocator, root, "docstring:max", null, 10);    try std.testing.expectEqual(@as(i64, 1), doc_filter.total);    try std.testing.expectEqualStrings("smg.graph.SemGraph.truncate_path", doc_filter.hits[0].name);    const left_group = try testSearchStored(allocator, root, "(truncate OR output) AND format", null, 10);    try std.testing.expectEqual(@as(i64, 1), left_group.total);    try std.testing.expectEqualStrings("smg.cli.helpers.format_output", left_group.hits[0].name);    const right_group = try testSearchStored(allocator, root, "truncate AND (path OR helpers)", null, 10);    try std.testing.expectEqual(@as(i64, 2), right_group.total);    try std.testing.expectEqualStrings("smg.graph.SemGraph.truncate_path", right_group.hits[0].name);    try std.testing.expectEqualStrings("smg.cli.helpers._truncate", right_group.hits[1].name);}fn testSearchStored(    allocator: std.mem.Allocator,    root: []const u8,    query: []const u8,    kind: ?[]const u8,    limit: i64,) !search.Result {    return try search.searchStored(        allocator,        root,        query,        kind,        limit,        smg.default_limits.storage,    );}

Audit

Definitions11
Public names11
Members6
Version26.7.0
Revisiondaab053ee433