okstra 0.130.4 → 0.131.0
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/README.md +0 -1
- package/docs/architecture.md +2 -2
- package/docs/cli.md +1 -1
- package/docs/for-ai/README.md +0 -2
- package/docs/for-ai/skills/okstra-run.md +13 -2
- package/docs/for-ai/skills/okstra-setup.md +4 -1
- package/docs/project-structure-overview.md +5 -4
- package/docs/task-process/implementation-planning.md +13 -0
- package/docs/task-process/implementation.md +17 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +7 -0
- package/runtime/bin/lib/okstra/usage.sh +4 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/plan-body-verification.md +26 -5
- package/runtime/prompts/lead/report-writer.md +6 -2
- package/runtime/prompts/profiles/_common-contract.md +2 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +6 -1
- package/runtime/prompts/profiles/_implementation-executor.md +2 -2
- package/runtime/prompts/profiles/_implementation-verifier.md +33 -10
- package/runtime/prompts/profiles/final-verification.md +21 -6
- package/runtime/prompts/profiles/implementation-planning.md +16 -4
- package/runtime/python/okstra_ctl/codex_dispatch.py +31 -0
- package/runtime/python/okstra_ctl/conformance.py +49 -11
- package/runtime/python/okstra_ctl/report_finalize.py +52 -1
- package/runtime/python/okstra_ctl/run.py +15 -3
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +14 -6
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +19 -1
- package/runtime/python/okstra_vendor/__init__.py +0 -44
- package/runtime/schemas/final-report-v1.0.schema.json +99 -5
- package/runtime/skills/okstra-run/SKILL.md +11 -4
- package/runtime/skills/okstra-setup/SKILL.md +3 -2
- package/runtime/skills/okstra-setup/references/project-config.md +16 -7
- package/runtime/templates/reports/final-report.template.md +15 -9
- package/runtime/templates/reports/i18n/en.json +1 -0
- package/runtime/templates/reports/i18n/ko.json +1 -0
- package/runtime/validators/lib/fixtures.sh +6 -0
- package/runtime/validators/validate-run.py +1722 -98
- package/src/cli-registry.mjs +0 -7
- package/src/commands/lifecycle/doctor.mjs +0 -9
- package/src/lib/skill-catalog.mjs +0 -1
- package/docs/for-ai/skills/okstra-graphify.md +0 -64
- package/runtime/python/okstra_ctl/graphify_cmd.py +0 -225
- package/runtime/python/okstra_vendor/graphify/.vendored-version +0 -1
- package/runtime/python/okstra_vendor/graphify/__init__.py +0 -28
- package/runtime/python/okstra_vendor/graphify/__main__.py +0 -1371
- package/runtime/python/okstra_vendor/graphify/analyze.py +0 -540
- package/runtime/python/okstra_vendor/graphify/benchmark.py +0 -129
- package/runtime/python/okstra_vendor/graphify/build.py +0 -107
- package/runtime/python/okstra_vendor/graphify/cache.py +0 -169
- package/runtime/python/okstra_vendor/graphify/cluster.py +0 -137
- package/runtime/python/okstra_vendor/graphify/detect.py +0 -510
- package/runtime/python/okstra_vendor/graphify/export.py +0 -1014
- package/runtime/python/okstra_vendor/graphify/extract.py +0 -3277
- package/runtime/python/okstra_vendor/graphify/hooks.py +0 -220
- package/runtime/python/okstra_vendor/graphify/ingest.py +0 -297
- package/runtime/python/okstra_vendor/graphify/manifest.py +0 -4
- package/runtime/python/okstra_vendor/graphify/report.py +0 -175
- package/runtime/python/okstra_vendor/graphify/security.py +0 -203
- package/runtime/python/okstra_vendor/graphify/serve.py +0 -373
- package/runtime/python/okstra_vendor/graphify/skill-aider.md +0 -1184
- package/runtime/python/okstra_vendor/graphify/skill-claw.md +0 -1184
- package/runtime/python/okstra_vendor/graphify/skill-codex.md +0 -1242
- package/runtime/python/okstra_vendor/graphify/skill-copilot.md +0 -1268
- package/runtime/python/okstra_vendor/graphify/skill-droid.md +0 -1239
- package/runtime/python/okstra_vendor/graphify/skill-kiro.md +0 -1183
- package/runtime/python/okstra_vendor/graphify/skill-opencode.md +0 -1238
- package/runtime/python/okstra_vendor/graphify/skill-trae.md +0 -1208
- package/runtime/python/okstra_vendor/graphify/skill-vscode.md +0 -253
- package/runtime/python/okstra_vendor/graphify/skill-windows.md +0 -1245
- package/runtime/python/okstra_vendor/graphify/skill.md +0 -1319
- package/runtime/python/okstra_vendor/graphify/transcribe.py +0 -182
- package/runtime/python/okstra_vendor/graphify/validate.py +0 -72
- package/runtime/python/okstra_vendor/graphify/watch.py +0 -188
- package/runtime/python/okstra_vendor/graphify/wiki.py +0 -214
- package/runtime/python/okstra_vendor/networkx/__init__.py +0 -62
- package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +0 -134
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +0 -26
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +0 -259
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +0 -71
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +0 -412
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +0 -396
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +0 -149
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +0 -369
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +0 -44
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +0 -143
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +0 -53
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +0 -265
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +0 -1508
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +0 -255
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +0 -83
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +0 -122
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +0 -302
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +0 -255
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +0 -160
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +0 -127
- package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +0 -164
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +0 -322
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +0 -290
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +0 -289
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +0 -360
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +0 -105
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +0 -603
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +0 -316
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +0 -590
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +0 -232
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +0 -526
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +0 -112
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +0 -69
- package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +0 -168
- package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +0 -205
- package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +0 -164
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +0 -20
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +0 -591
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +0 -236
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +0 -282
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +0 -364
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +0 -227
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +0 -96
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +0 -357
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +0 -130
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +0 -787
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +0 -331
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +0 -200
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +0 -128
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +0 -209
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +0 -141
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +0 -361
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +0 -181
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +0 -95
- package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +0 -172
- package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +0 -443
- package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +0 -818
- package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +0 -732
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +0 -4
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +0 -505
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +0 -565
- package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +0 -163
- package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +0 -28
- package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +0 -153
- package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +0 -354
- package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +0 -171
- package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +0 -30
- package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +0 -216
- package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +0 -79
- package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +0 -338
- package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +0 -162
- package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +0 -384
- package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +0 -227
- package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +0 -452
- package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +0 -347
- package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +0 -6
- package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +0 -115
- package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +0 -394
- package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +0 -282
- package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +0 -71
- package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +0 -359
- package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +0 -11
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +0 -811
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +0 -616
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +0 -408
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +0 -1270
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +0 -592
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +0 -235
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +0 -152
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/core.py +0 -588
- package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +0 -416
- package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +0 -1234
- package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +0 -677
- package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +0 -1392
- package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +0 -1095
- package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +0 -272
- package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +0 -268
- package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +0 -167
- package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +0 -470
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +0 -11
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +0 -370
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +0 -407
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +0 -238
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +0 -241
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +0 -178
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +0 -611
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +0 -356
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +0 -662
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +0 -425
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +0 -300
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +0 -194
- package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +0 -435
- package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +0 -483
- package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +0 -1306
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +0 -336
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +0 -1262
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +0 -352
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +0 -308
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +0 -1102
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +0 -192
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +0 -2
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +0 -337
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +0 -498
- package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +0 -687
- package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +0 -280
- package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +0 -1148
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +0 -27
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +0 -738
- package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +0 -78
- package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +0 -59
- package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +0 -219
- package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +0 -155
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +0 -4
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +0 -324
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +0 -468
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +0 -633
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +0 -73
- package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +0 -464
- package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +0 -1463
- package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +0 -306
- package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +0 -98
- package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +0 -167
- package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +0 -239
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +0 -716
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +0 -625
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +0 -2542
- package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +0 -2107
- package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +0 -966
- package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +0 -404
- package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +0 -30
- package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +0 -296
- package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +0 -374
- package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +0 -564
- package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +0 -406
- package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +0 -981
- package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +0 -406
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +0 -90
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +0 -576
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +0 -529
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +0 -185
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +0 -182
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +0 -1042
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +0 -413
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +0 -219
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +0 -1281
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +0 -106
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +0 -273
- package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +0 -500
- package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +0 -76
- package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +0 -86
- package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +0 -278
- package/runtime/python/okstra_vendor/networkx/classes/__init__.py +0 -13
- package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +0 -435
- package/runtime/python/okstra_vendor/networkx/classes/digraph.py +0 -1363
- package/runtime/python/okstra_vendor/networkx/classes/filters.py +0 -95
- package/runtime/python/okstra_vendor/networkx/classes/function.py +0 -1549
- package/runtime/python/okstra_vendor/networkx/classes/graph.py +0 -2082
- package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +0 -269
- package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +0 -977
- package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +0 -1294
- package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +0 -1447
- package/runtime/python/okstra_vendor/networkx/convert.py +0 -502
- package/runtime/python/okstra_vendor/networkx/convert_matrix.py +0 -1314
- package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/drawing/layout.py +0 -2036
- package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +0 -470
- package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +0 -570
- package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +0 -361
- package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +0 -2978
- package/runtime/python/okstra_vendor/networkx/exception.py +0 -131
- package/runtime/python/okstra_vendor/networkx/generators/__init__.py +0 -34
- package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
- package/runtime/python/okstra_vendor/networkx/generators/atlas.py +0 -227
- package/runtime/python/okstra_vendor/networkx/generators/classic.py +0 -1091
- package/runtime/python/okstra_vendor/networkx/generators/cographs.py +0 -68
- package/runtime/python/okstra_vendor/networkx/generators/community.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +0 -886
- package/runtime/python/okstra_vendor/networkx/generators/directed.py +0 -572
- package/runtime/python/okstra_vendor/networkx/generators/duplication.py +0 -174
- package/runtime/python/okstra_vendor/networkx/generators/ego.py +0 -66
- package/runtime/python/okstra_vendor/networkx/generators/expanders.py +0 -499
- package/runtime/python/okstra_vendor/networkx/generators/geometric.py +0 -1037
- package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +0 -163
- package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +0 -443
- package/runtime/python/okstra_vendor/networkx/generators/intersection.py +0 -125
- package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +0 -70
- package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +0 -664
- package/runtime/python/okstra_vendor/networkx/generators/lattice.py +0 -405
- package/runtime/python/okstra_vendor/networkx/generators/line.py +0 -501
- package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +0 -110
- package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +0 -259
- package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +0 -117
- package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +0 -1416
- package/runtime/python/okstra_vendor/networkx/generators/small.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/social.py +0 -554
- package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +0 -120
- package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +0 -54
- package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +0 -131
- package/runtime/python/okstra_vendor/networkx/generators/time_series.py +0 -74
- package/runtime/python/okstra_vendor/networkx/generators/trees.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/triads.py +0 -94
- package/runtime/python/okstra_vendor/networkx/lazy_imports.py +0 -188
- package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +0 -13
- package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +0 -650
- package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +0 -466
- package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +0 -77
- package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +0 -168
- package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +0 -512
- package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +0 -166
- package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +0 -186
- package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +0 -17
- package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +0 -330
- package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +0 -489
- package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +0 -1084
- package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +0 -879
- package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +0 -427
- package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +0 -1053
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +0 -19
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +0 -156
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +0 -190
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +0 -261
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +0 -137
- package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +0 -108
- package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +0 -393
- package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +0 -113
- package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +0 -286
- package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +0 -379
- package/runtime/python/okstra_vendor/networkx/readwrite/text.py +0 -851
- package/runtime/python/okstra_vendor/networkx/relabel.py +0 -285
- package/runtime/python/okstra_vendor/networkx/utils/__init__.py +0 -8
- package/runtime/python/okstra_vendor/networkx/utils/backends.py +0 -2171
- package/runtime/python/okstra_vendor/networkx/utils/configs.py +0 -396
- package/runtime/python/okstra_vendor/networkx/utils/decorators.py +0 -1233
- package/runtime/python/okstra_vendor/networkx/utils/heaps.py +0 -338
- package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +0 -297
- package/runtime/python/okstra_vendor/networkx/utils/misc.py +0 -703
- package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +0 -198
- package/runtime/python/okstra_vendor/networkx/utils/rcm.py +0 -159
- package/runtime/python/okstra_vendor/networkx/utils/union_find.py +0 -106
- package/runtime/skills/okstra-graphify/SKILL.md +0 -169
- package/src/commands/graphify.mjs +0 -32
package/src/cli-registry.mjs
CHANGED
|
@@ -236,13 +236,6 @@ export const COMMAND_REGISTRY = [
|
|
|
236
236
|
category: "introspection",
|
|
237
237
|
summary: ["Manage cross-project okstra tasks"],
|
|
238
238
|
},
|
|
239
|
-
{
|
|
240
|
-
name: "graphify",
|
|
241
|
-
module: "./commands/graphify.mjs",
|
|
242
|
-
export: "run",
|
|
243
|
-
category: "introspection",
|
|
244
|
-
summary: ["Build/query a .okstra-scoped knowledge graph"],
|
|
245
|
-
},
|
|
246
239
|
{
|
|
247
240
|
name: "worktree-lookup",
|
|
248
241
|
module: "./commands/execute/worktree-lookup.mjs",
|
|
@@ -113,14 +113,6 @@ async function checkPythonImport(moduleName, pythonpath) {
|
|
|
113
113
|
return { ok: true, detail: `${moduleName} importable` };
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
async function checkGraphifyVendor() {
|
|
117
|
-
const r = await runPythonSnippet({ script: "import okstra_vendor, graphify, networkx" });
|
|
118
|
-
if (r.code !== 0) {
|
|
119
|
-
return { ok: false, detail: `vendored graphify import failed: ${r.stderr.trim().split("\n").pop()}` };
|
|
120
|
-
}
|
|
121
|
-
return { ok: true, detail: "okstra_vendor, graphify, networkx importable" };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
116
|
async function checkBashEntry(binDir, name) {
|
|
125
117
|
const p = join(binDir, name);
|
|
126
118
|
if (!(await fileExists(p))) return { ok: false, detail: `missing ${p}` };
|
|
@@ -226,7 +218,6 @@ export async function run(args) {
|
|
|
226
218
|
await check("python3", checkPython3),
|
|
227
219
|
await check("okstra_project import", () => checkPythonImport("okstra_project", paths.pythonpath)),
|
|
228
220
|
await check("okstra_ctl import", () => checkPythonImport("okstra_ctl", paths.pythonpath)),
|
|
229
|
-
await check("graphify vendor import", checkGraphifyVendor),
|
|
230
221
|
await check("agents dir", async () =>
|
|
231
222
|
(await fileExists(paths.agents))
|
|
232
223
|
? { ok: true, detail: paths.agents }
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# okstra-graphify AI Manual
|
|
2
|
-
|
|
3
|
-
## Sources
|
|
4
|
-
|
|
5
|
-
- Skill source: [`skills/okstra-graphify/SKILL.md`](../../../skills/okstra-graphify/SKILL.md)
|
|
6
|
-
- Graph core (CLI): [`scripts/okstra_ctl/graphify_cmd.py`](../../../scripts/okstra_ctl/graphify_cmd.py)
|
|
7
|
-
- Node wrapper: [`src/commands/graphify.mjs`](../../../src/commands/graphify.mjs)
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
`okstra-graphify` builds and queries a **knowledge graph** over the project's own okstra memory (the final reports, `decisions/*.md`, `glossary.md`, and briefs under `<projectRoot>/.okstra`). The corpus is **fixed** to `.okstra` and the outputs land at `<projectRoot>/.okstra/graph/` — the CLI enforces both, so this skill takes no user path argument and never touches files outside `.okstra/`.
|
|
12
|
-
|
|
13
|
-
- Docs-only. There is no code AST extraction here (that is the standalone `/graphify`).
|
|
14
|
-
- Distinguish it from the arbitrary-code / non-okstra folder graph (`/graphify`), single-task inspection (`okstra-inspect`), and rollup (`okstra-rollup`).
|
|
15
|
-
|
|
16
|
-
## Sub-commands
|
|
17
|
-
|
|
18
|
-
| Sub-command | What it does |
|
|
19
|
-
|---|---|
|
|
20
|
-
| `build` | Extract entities/relationships from `.okstra` docs (parallel subagent dispatch), then assemble the graph + report + HTML |
|
|
21
|
-
| `query` | BFS/DFS traversal over the graph to answer a broad question |
|
|
22
|
-
| `path` | Shortest path between two named concepts |
|
|
23
|
-
| `explain` | Plain-language explanation of one node and its connections |
|
|
24
|
-
| `wiki` | Agent-crawlable wiki (`index.md` + one article per community) |
|
|
25
|
-
| `mcp` | A stdio MCP server exposing the graph to other agents (opt-in — additionally needs `pip install mcp`) |
|
|
26
|
-
|
|
27
|
-
## Preflight
|
|
28
|
-
|
|
29
|
-
A single Bash call starting with the literal token `okstra` (not wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=`/`||`/`&&`/`npx`):
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
okstra preflight --runtime claude-code --json
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
`ok:true` → carry `projectRoot` as a literal string. Every `okstra graphify` call passes `--project-root <projectRoot>` (**REQUIRED**, no cwd injection — a bare `okstra graphify build` is a usage error). `ok:false` → first check once whether the user pointed at a specific project directory; if it is still `ok:false`, point to `/okstra-setup` and stop. On `unknown command: preflight`, the `okstra` on PATH is older than the skill — point to `npm i -g okstra@latest` and stop.
|
|
36
|
-
|
|
37
|
-
## build (the core division of labor)
|
|
38
|
-
|
|
39
|
-
Two parts: **semantic extraction** (subagents read `.okstra` docs and write chunk JSON) → **assemble** (the CLI does clustering and output generation).
|
|
40
|
-
|
|
41
|
-
1. Detect the corpus: `find <projectRoot>/.okstra -type f -name '*.md' -not -path '*/graph/*'`. If zero, stop.
|
|
42
|
-
2. Semantic extraction: **you MUST use the Agent tool** (reading files one-by-one is forbidden — far slower). Split into chunks of 20-25 files and **dispatch in parallel, once per chunk in a single response**, with `subagent_type="general-purpose"` fixed (`Explore` is read-only, cannot write chunk files, and silently drops results). Each subagent writes `<projectRoot>/.okstra/graph/.chunks/chunk-NN.json`. It MUST fill in EXTRACTED/INFERRED/AMBIGUOUS + `confidence_score`.
|
|
43
|
-
3. Assemble: `okstra graphify build --project-root <projectRoot>` — merges `graph/.chunks/*.json` and writes `graph.json`, `GRAPH_REPORT.md`, `graph.html`. On a `no extraction chunks` error, the subagents did not write their files — re-dispatch.
|
|
44
|
-
|
|
45
|
-
After a successful build, paste **only** the God Nodes / Surprising Connections / Suggested Questions sections of `GRAPH_REPORT.md` (not the whole file), then offer to trace the single most interesting question via `query`.
|
|
46
|
-
|
|
47
|
-
## query / path / explain / wiki / mcp
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
okstra graphify query "<question>" --project-root <projectRoot>
|
|
51
|
-
okstra graphify path "<ConceptA>" "<ConceptB>" --project-root <projectRoot>
|
|
52
|
-
okstra graphify explain "<NodeName>" --project-root <projectRoot>
|
|
53
|
-
okstra graphify wiki --project-root <projectRoot>
|
|
54
|
-
okstra graphify mcp --project-root <projectRoot>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
`query`/`path`/`explain`/`wiki`/`mcp` **require a built graph** — if the CLI says none exists, run `build` first. `mcp` additionally needs `pip install mcp` and is long-running (the user stops it with Ctrl+C). After doc changes, re-run `build` to re-extract.
|
|
58
|
-
|
|
59
|
-
## Output Rules
|
|
60
|
-
|
|
61
|
-
- Be concise, in Korean, unless the user requests otherwise.
|
|
62
|
-
- Outputs go under `<projectRoot>/.okstra/graph/`, in project-relative paths where possible.
|
|
63
|
-
- **Never invent an edge** — if unsure, it is AMBIGUOUS. Never hide cohesion/confidence scores.
|
|
64
|
-
- Say plainly when a fact is not in the graph. Quote `source_file`/`source_location`.
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
"""okstra-graphify 스코프 래퍼 — resolve_scope + assemble + main 디스패치.
|
|
2
|
-
|
|
3
|
-
입력은 항상 ``<project_root>/.okstra`` 로, 출력은 ``<project_root>/.okstra/graph``
|
|
4
|
-
로 고정한다. resolve_scope 가 corpus·output 경로의 유일 정의점이며,
|
|
5
|
-
assemble 이 추출 청크를 그래프·리포트로 병합하고, main 이 query/path/explain/
|
|
6
|
-
mcp/wiki 서브커맨드를 디스패치한다.
|
|
7
|
-
"""
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import argparse
|
|
11
|
-
import json
|
|
12
|
-
import sys
|
|
13
|
-
from dataclasses import dataclass
|
|
14
|
-
from pathlib import Path
|
|
15
|
-
|
|
16
|
-
import okstra_vendor # noqa: F401 (registers vendored graphify/networkx)
|
|
17
|
-
|
|
18
|
-
OUT_DIRNAME = "graph"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@dataclass(frozen=True)
|
|
22
|
-
class ScopePaths:
|
|
23
|
-
corpus: Path
|
|
24
|
-
out_dir: Path
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def resolve_scope(project_root: Path) -> ScopePaths:
|
|
28
|
-
root = Path(project_root).resolve()
|
|
29
|
-
okstra = root / ".okstra"
|
|
30
|
-
return ScopePaths(corpus=okstra, out_dir=okstra / OUT_DIRNAME)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def assemble(project_root: Path) -> Path:
|
|
34
|
-
sp = resolve_scope(project_root)
|
|
35
|
-
chunk_dir = sp.out_dir / ".chunks"
|
|
36
|
-
chunks = sorted(chunk_dir.glob("*.json")) if chunk_dir.is_dir() else []
|
|
37
|
-
if not chunks:
|
|
38
|
-
raise FileNotFoundError(f"no extraction chunks under {chunk_dir}")
|
|
39
|
-
|
|
40
|
-
merged = {"nodes": [], "edges": []}
|
|
41
|
-
for c in chunks:
|
|
42
|
-
data = json.loads(c.read_text(encoding="utf-8"))
|
|
43
|
-
merged["nodes"].extend(data.get("nodes", []))
|
|
44
|
-
merged["edges"].extend(data.get("edges", []))
|
|
45
|
-
|
|
46
|
-
from graphify.build import build_from_json
|
|
47
|
-
from graphify.cluster import cluster, score_all
|
|
48
|
-
from graphify.analyze import god_nodes, surprising_connections, suggest_questions
|
|
49
|
-
from graphify.report import generate
|
|
50
|
-
from graphify.export import to_json, to_html
|
|
51
|
-
|
|
52
|
-
sp.out_dir.mkdir(parents=True, exist_ok=True)
|
|
53
|
-
G = build_from_json(merged)
|
|
54
|
-
communities = cluster(G)
|
|
55
|
-
cohesion = score_all(G, communities)
|
|
56
|
-
gods = god_nodes(G)
|
|
57
|
-
surprises = surprising_connections(G, communities)
|
|
58
|
-
labels = {cid: f"Community {cid}" for cid in communities}
|
|
59
|
-
questions = suggest_questions(G, communities, labels)
|
|
60
|
-
tokens = {"input": 0, "output": 0}
|
|
61
|
-
report = generate(
|
|
62
|
-
G, communities, cohesion, labels, gods, surprises,
|
|
63
|
-
{"warning": "okstra-graphify: .okstra scope"},
|
|
64
|
-
tokens, str(sp.corpus), suggested_questions=questions,
|
|
65
|
-
)
|
|
66
|
-
(sp.out_dir / "GRAPH_REPORT.md").write_text(report, encoding="utf-8")
|
|
67
|
-
to_json(G, communities, str(sp.out_dir / "graph.json"))
|
|
68
|
-
to_html(G, communities, str(sp.out_dir / "graph.html"), community_labels=labels or None)
|
|
69
|
-
return sp.out_dir
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _graph_path(project_root: Path) -> Path:
|
|
73
|
-
return resolve_scope(project_root).out_dir / "graph.json"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def _require_graph(project_root: Path) -> Path:
|
|
77
|
-
gp = _graph_path(project_root)
|
|
78
|
-
if not gp.exists():
|
|
79
|
-
raise SystemExit(
|
|
80
|
-
f"okstra-graphify: no graph at {gp}. Run `okstra graphify build` first."
|
|
81
|
-
)
|
|
82
|
-
return gp
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def _load_graph(graph_path: Path):
|
|
86
|
-
from networkx.readwrite import json_graph
|
|
87
|
-
raw = json.loads(Path(graph_path).read_text(encoding="utf-8"))
|
|
88
|
-
try:
|
|
89
|
-
return json_graph.node_link_graph(raw, edges="links")
|
|
90
|
-
except TypeError:
|
|
91
|
-
return json_graph.node_link_graph(raw)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def _run_query(graph_path: Path, question: str, *, budget: int = 2000, use_dfs: bool = False) -> None:
|
|
95
|
-
# 벤더 __main__.py query 핸들러(1092–1149) 미러: 그래프 경로만 스코프로 교체.
|
|
96
|
-
from graphify.serve import _score_nodes, _bfs, _dfs, _subgraph_to_text
|
|
97
|
-
G = _load_graph(graph_path)
|
|
98
|
-
terms = [t.lower() for t in question.split() if len(t) > 2]
|
|
99
|
-
scored = _score_nodes(G, terms)
|
|
100
|
-
if not scored:
|
|
101
|
-
print("No matching nodes found.")
|
|
102
|
-
return
|
|
103
|
-
start = [nid for _, nid in scored[:5]]
|
|
104
|
-
nodes, edges = (_dfs if use_dfs else _bfs)(G, start, depth=2)
|
|
105
|
-
print(_subgraph_to_text(G, nodes, edges, token_budget=budget))
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def _run_path(graph_path: Path, source_label: str, target_label: str) -> None:
|
|
109
|
-
# 벤더 __main__.py path 핸들러(1169–1217) 미러.
|
|
110
|
-
from graphify.serve import _score_nodes
|
|
111
|
-
import networkx as nx
|
|
112
|
-
G = _load_graph(graph_path)
|
|
113
|
-
src_scored = _score_nodes(G, [t.lower() for t in source_label.split()])
|
|
114
|
-
tgt_scored = _score_nodes(G, [t.lower() for t in target_label.split()])
|
|
115
|
-
if not src_scored:
|
|
116
|
-
print(f"No node matching '{source_label}' found.")
|
|
117
|
-
return
|
|
118
|
-
if not tgt_scored:
|
|
119
|
-
print(f"No node matching '{target_label}' found.")
|
|
120
|
-
return
|
|
121
|
-
src_nid, tgt_nid = src_scored[0][1], tgt_scored[0][1]
|
|
122
|
-
try:
|
|
123
|
-
path_nodes = nx.shortest_path(G, src_nid, tgt_nid)
|
|
124
|
-
except (nx.NetworkXNoPath, nx.NodeNotFound):
|
|
125
|
-
print(f"No path found between '{source_label}' and '{target_label}'.")
|
|
126
|
-
return
|
|
127
|
-
hops = len(path_nodes) - 1
|
|
128
|
-
segments = []
|
|
129
|
-
for i in range(len(path_nodes) - 1):
|
|
130
|
-
u, v = path_nodes[i], path_nodes[i + 1]
|
|
131
|
-
edata = G.edges[u, v]
|
|
132
|
-
rel = edata.get("relation", "")
|
|
133
|
-
conf = edata.get("confidence", "")
|
|
134
|
-
conf_str = f" [{conf}]" if conf else ""
|
|
135
|
-
if i == 0:
|
|
136
|
-
segments.append(G.nodes[u].get("label", u))
|
|
137
|
-
segments.append(f"--{rel}{conf_str}--> {G.nodes[v].get('label', v)}")
|
|
138
|
-
print(f"Shortest path ({hops} hops):\n " + " ".join(segments))
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def _run_explain(graph_path: Path, label: str) -> None:
|
|
142
|
-
# 벤더 __main__.py explain 핸들러(1219–1261) 미러.
|
|
143
|
-
from graphify.serve import _find_node
|
|
144
|
-
G = _load_graph(graph_path)
|
|
145
|
-
matches = _find_node(G, label)
|
|
146
|
-
if not matches:
|
|
147
|
-
print(f"No node matching '{label}' found.")
|
|
148
|
-
return
|
|
149
|
-
nid = matches[0]
|
|
150
|
-
d = G.nodes[nid]
|
|
151
|
-
print(f"Node: {d.get('label', nid)}")
|
|
152
|
-
print(f" ID: {nid}")
|
|
153
|
-
print(f" Source: {d.get('source_file', '')} {d.get('source_location', '')}".rstrip())
|
|
154
|
-
print(f" Type: {d.get('file_type', '')}")
|
|
155
|
-
print(f" Community: {d.get('community', '')}")
|
|
156
|
-
print(f" Degree: {G.degree(nid)}")
|
|
157
|
-
neighbors = list(G.neighbors(nid))
|
|
158
|
-
if neighbors:
|
|
159
|
-
print(f"\nConnections ({len(neighbors)}):")
|
|
160
|
-
for nb in sorted(neighbors, key=lambda n: G.degree(n), reverse=True)[:20]:
|
|
161
|
-
edata = G.edges[nid, nb]
|
|
162
|
-
rel = edata.get("relation", "")
|
|
163
|
-
conf = edata.get("confidence", "")
|
|
164
|
-
print(f" --> {G.nodes[nb].get('label', nb)} [{rel}] [{conf}]")
|
|
165
|
-
if len(neighbors) > 20:
|
|
166
|
-
print(f" ... and {len(neighbors) - 20} more")
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def _run_wiki(project_root: Path) -> int:
|
|
170
|
-
# 벤더 wiki.to_wiki(wiki.py:168) 미러 — 그래프에서 커뮤니티/라벨/god-node 를
|
|
171
|
-
# 재구성해 <out_dir>/wiki/ 로 기록한다. assemble 과 동일한 재클러스터 경로.
|
|
172
|
-
from graphify.build import build_from_json
|
|
173
|
-
from graphify.cluster import cluster, score_all
|
|
174
|
-
from graphify.analyze import god_nodes
|
|
175
|
-
from graphify.wiki import to_wiki
|
|
176
|
-
sp = resolve_scope(project_root)
|
|
177
|
-
raw = json.loads((sp.out_dir / "graph.json").read_text(encoding="utf-8"))
|
|
178
|
-
G = build_from_json(raw)
|
|
179
|
-
communities = cluster(G)
|
|
180
|
-
cohesion = score_all(G, communities)
|
|
181
|
-
gods = god_nodes(G)
|
|
182
|
-
labels = {cid: f"Community {cid}" for cid in communities}
|
|
183
|
-
return to_wiki(
|
|
184
|
-
G, communities, str(sp.out_dir / "wiki"),
|
|
185
|
-
community_labels=labels or None, cohesion=cohesion, god_nodes_data=gods,
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def main(argv: list[str]) -> int:
|
|
190
|
-
parser = argparse.ArgumentParser(prog="okstra graphify")
|
|
191
|
-
parser.add_argument(
|
|
192
|
-
"subcmd",
|
|
193
|
-
choices=["build", "query", "path", "explain", "mcp", "wiki"],
|
|
194
|
-
)
|
|
195
|
-
parser.add_argument("rest", nargs="*")
|
|
196
|
-
parser.add_argument("--project-root", required=True, type=Path)
|
|
197
|
-
ns = parser.parse_args(argv)
|
|
198
|
-
root = ns.project_root
|
|
199
|
-
|
|
200
|
-
if ns.subcmd == "build":
|
|
201
|
-
assemble(root)
|
|
202
|
-
return 0
|
|
203
|
-
if ns.subcmd == "mcp":
|
|
204
|
-
from graphify.serve import serve
|
|
205
|
-
serve(str(_require_graph(root)))
|
|
206
|
-
return 0
|
|
207
|
-
if ns.subcmd == "wiki":
|
|
208
|
-
_require_graph(root)
|
|
209
|
-
_run_wiki(root)
|
|
210
|
-
return 0
|
|
211
|
-
|
|
212
|
-
gp = _require_graph(root)
|
|
213
|
-
if ns.subcmd == "query":
|
|
214
|
-
_run_query(gp, " ".join(ns.rest))
|
|
215
|
-
elif ns.subcmd == "path":
|
|
216
|
-
if len(ns.rest) < 2:
|
|
217
|
-
raise SystemExit("usage: okstra graphify path <ConceptA> <ConceptB> --project-root <dir>")
|
|
218
|
-
_run_path(gp, ns.rest[0], ns.rest[1])
|
|
219
|
-
elif ns.subcmd == "explain":
|
|
220
|
-
_run_explain(gp, " ".join(ns.rest))
|
|
221
|
-
return 0
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if __name__ == "__main__":
|
|
225
|
-
raise SystemExit(main(sys.argv[1:]))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.4.23
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"""graphify - extract · build · cluster · analyze · report."""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def __getattr__(name):
|
|
5
|
-
# Lazy imports so `graphify install` works before heavy deps are in place.
|
|
6
|
-
_map = {
|
|
7
|
-
"extract": ("graphify.extract", "extract"),
|
|
8
|
-
"collect_files": ("graphify.extract", "collect_files"),
|
|
9
|
-
"build_from_json": ("graphify.build", "build_from_json"),
|
|
10
|
-
"cluster": ("graphify.cluster", "cluster"),
|
|
11
|
-
"score_all": ("graphify.cluster", "score_all"),
|
|
12
|
-
"cohesion_score": ("graphify.cluster", "cohesion_score"),
|
|
13
|
-
"god_nodes": ("graphify.analyze", "god_nodes"),
|
|
14
|
-
"surprising_connections": ("graphify.analyze", "surprising_connections"),
|
|
15
|
-
"suggest_questions": ("graphify.analyze", "suggest_questions"),
|
|
16
|
-
"generate": ("graphify.report", "generate"),
|
|
17
|
-
"to_json": ("graphify.export", "to_json"),
|
|
18
|
-
"to_html": ("graphify.export", "to_html"),
|
|
19
|
-
"to_svg": ("graphify.export", "to_svg"),
|
|
20
|
-
"to_canvas": ("graphify.export", "to_canvas"),
|
|
21
|
-
"to_wiki": ("graphify.wiki", "to_wiki"),
|
|
22
|
-
}
|
|
23
|
-
if name in _map:
|
|
24
|
-
import importlib
|
|
25
|
-
mod_name, attr = _map[name]
|
|
26
|
-
mod = importlib.import_module(mod_name)
|
|
27
|
-
return getattr(mod, attr)
|
|
28
|
-
raise AttributeError(f"module 'graphify' has no attribute {name!r}")
|