Install
$ agentstack add skill-xmake-io-xmake-skills-xmake-graph-module ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
core.base.graph — Graph Data Structure
core.base.graph is xmake's general-purpose graph module. It implements both directed and undirected graphs with topological sort and cycle detection. Use it when you need to model dependencies / relationships in a custom script but don't want to run them as async jobs (for that, use async.jobgraph, which wraps this).
Must be imported:
import("core.base.graph")
1. Create a graph
local dag = graph.new(true) -- directed (DAG)
local ug = graph.new(false) -- undirected
2. Vertices and edges
g:add_vertex("a")
g:add_vertex("b")
g:add_vertex("c")
g:add_edge("a", "b") -- a → b (directed)
g:add_edge("b", "c")
print(g:has_vertex("a")) -- true
print(g:has_edge("a", "b")) -- true
print(#g:vertices()) -- 3
Vertices can be any value (strings, numbers, tables — anything you can use as a table key).
Shorthand
add_edge auto-adds endpoints:
local g = graph.new(true)
g:add_edge("a", "b") -- "a" and "b" added automatically
g:add_edge("b", "c")
Inspect
for _, v in ipairs(g:vertices()) do print(v) end
for _, e in ipairs(g:edges()) do
print(e:from(), "->", e:to())
end
for _, e in ipairs(g:adjacent_edges("a")) do
print(e:to()) -- outgoing edges from "a"
end
Remove
g:remove_vertex("a") -- also removes incident edges
g:clear() -- reset
print(g:empty()) -- true
3. Topological sort (DAG only)
local g = graph.new(true)
g:add_edge("parse", "analyze")
g:add_edge("analyze", "optimize")
g:add_edge("optimize", "emit")
local order, has_cycle = g:topo_sort()
if has_cycle then
raise("cycle detected!")
end
for _, v in ipairs(order) do
print(v) -- parse, analyze, optimize, emit
end
topo_sort() returns (list, has_cycle). If there's a cycle, use find_cycle() to get the offending path:
local cycle = g:find_cycle()
if cycle then
raise("cycle: %s", table.concat(cycle, " -> "))
end
4. Partial (incremental) topo sort
For work loops where you want to process vertices as their dependencies become ready:
g:partial_topo_sort_reset()
while true do
local v, has_cycle = g:partial_topo_sort_next()
if has_cycle then raise("cycle") end
if not v then break end
process(v)
g:partial_topo_sort_remove(v) -- mark done, unblock dependents
end
Use this when processing is interleaved with new information (e.g. parallel workers feeding back completion signals).
5. Other utilities
local copy = g:clone() -- deep copy
local rev = g:reverse() -- reverse all edges (directed only)
g:dump() -- debug dump to stdout
print(g:is_directed())
6. Typical uses in xmake scripts
Custom build pipeline in a task
task("pipeline")
on_run(function ()
import("core.base.graph")
local g = graph.new(true)
for _, step in ipairs(pipeline_steps) do
g:add_vertex(step.name)
for _, dep in ipairs(step.deps or {}) do
g:add_edge(dep, step.name)
end
end
local order, cycle = g:topo_sort()
if cycle then
raise("pipeline has a cycle")
end
for _, name in ipairs(order) do
run_step(name)
end
end)
Dependency analysis of target metadata
import("core.base.graph")
import("core.project.project")
local g = graph.new(true)
for name, target in pairs(project.targets()) do
g:add_vertex(name)
for _, dep in ipairs(target:get("deps") or {}) do
g:add_edge(dep, name)
end
end
local cycle = g:find_cycle()
if cycle then
cprint("${red}cycle: %s", table.concat(cycle, " -> "))
end
-- print dependency-order build plan
for _, name in ipairs(g:topo_sort()) do
print(name)
end
Detecting stale edges / cycle in custom rule
rule("codegen")
before_build(function (target)
import("core.base.graph")
local g = graph.new(true)
-- add edges based on #include scan of generated files
...
if g:find_cycle() then
raise("include cycle in generated headers")
end
end)
7. graph vs async.jobgraph
| Feature | core.base.graph | async.jobgraph | | --- | --- | --- | | Data structure | generic DAG / undirected | DAG tailored to jobs | | Vertex payload | any value | name + job function | | Execution | none — you iterate yourself | scheduled by async.runjobs | | Groups | not built in | yes | | Cycle detection | find_cycle() / topo_sort() | yes |
Rule of thumb:
- Need a graph for analysis / planning →
core.base.graph. - Need a graph to run jobs in parallel →
async.jobgraph(which usescore.base.graphinternally).
Pitfalls
topo_sort()on an undirected graph. Doesn't make sense; xmake raises. Usegraph.new(true)for topo sort.- Cycles through self-loops.
g:add_edge("a", "a")is a cycle.find_cycle()will flag it. - Vertices are keyed by identity. For tables, two distinct tables with the same contents are different vertices. Use stable identifiers (strings) unless you want identity semantics.
- Large graphs — no persistent storage. The graph lives in memory only. For persistent DAG state across xmake runs, serialize yourself.
- Edge weights. Not supported — this is an unweighted graph. Roll your own weight table if you need Dijkstra/etc.
When to branch out
- Running the DAG as parallel jobs →
xmake-async-jobs - Working with target dependency metadata →
xmake-targets,xmake-scripting - Writing rules that need per-file ordering →
xmake-rulesandxmake-async-jobs
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: xmake-io
- Source: xmake-io/xmake-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.