studiograph 1.1.2 → 1.2.0-beta.1
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/LICENSE +191 -0
- package/README.md +301 -10
- package/dist/agent/orchestrator.d.ts +17 -9
- package/dist/agent/orchestrator.js +142 -97
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/system.md +186 -0
- package/dist/agent/skill-loader.d.ts +48 -0
- package/dist/agent/skill-loader.js +166 -0
- package/dist/agent/skill-loader.js.map +1 -0
- package/dist/agent/skills/enrich-entities.md +136 -0
- package/dist/agent/skills/entity-schema.md +502 -0
- package/dist/agent/skills/gather-context.md +46 -0
- package/dist/agent/skills/obsidian-source-setup.md +246 -0
- package/dist/agent/skills/skill-loader.d.ts +48 -0
- package/dist/agent/skills/skill-loader.js +166 -0
- package/dist/agent/skills/skill-loader.js.map +1 -0
- package/dist/agent/skills/sync-configuration.md +144 -0
- package/dist/agent/skills/sync-setup.md +68 -0
- package/dist/agent/tools/connector-tools.d.ts +37 -0
- package/dist/agent/tools/connector-tools.js +132 -0
- package/dist/agent/tools/connector-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +39 -0
- package/dist/agent/tools/fs-tools.js +106 -0
- package/dist/agent/tools/fs-tools.js.map +1 -0
- package/dist/agent/tools/graph-tools.d.ts +30 -2
- package/dist/agent/tools/graph-tools.js +154 -37
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/load-skill.d.ts +42 -0
- package/dist/agent/tools/load-skill.js +45 -0
- package/dist/agent/tools/load-skill.js.map +1 -0
- package/dist/agent/tools/sync-tools.d.ts +25 -0
- package/dist/agent/tools/sync-tools.js +691 -0
- package/dist/agent/tools/sync-tools.js.map +1 -0
- package/dist/agent/tools/tool-loader.d.ts +25 -0
- package/dist/agent/tools/tool-loader.js +73 -0
- package/dist/agent/tools/tool-loader.js.map +1 -0
- package/dist/auth/github.d.ts +11 -8
- package/dist/auth/github.js +56 -75
- package/dist/auth/github.js.map +1 -1
- package/dist/cli/colors.d.ts +54 -0
- package/dist/cli/colors.js +133 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands/app.d.ts +7 -0
- package/dist/cli/commands/app.js +167 -0
- package/dist/cli/commands/app.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +1 -1
- package/dist/cli/commands/auth.js +26 -10
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/clone.d.ts +9 -0
- package/dist/cli/commands/clone.js +167 -0
- package/dist/cli/commands/clone.js.map +1 -0
- package/dist/cli/commands/commit.d.ts +8 -0
- package/dist/cli/commands/commit.js +43 -0
- package/dist/cli/commands/commit.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.js +276 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/connector.d.ts +33 -0
- package/dist/cli/commands/connector.js +178 -0
- package/dist/cli/commands/connector.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +11 -0
- package/dist/cli/commands/deploy.js +153 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/enrich.d.ts +11 -0
- package/dist/cli/commands/enrich.js +135 -0
- package/dist/cli/commands/enrich.js.map +1 -0
- package/dist/cli/commands/graphrag.d.ts +12 -0
- package/dist/cli/commands/graphrag.js +122 -0
- package/dist/cli/commands/graphrag.js.map +1 -0
- package/dist/cli/commands/index.d.ts +15 -0
- package/dist/cli/commands/index.js +117 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.js +110 -210
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.js +89 -24
- package/dist/cli/commands/join.js.map +1 -1
- package/dist/cli/commands/lint.d.ts +8 -0
- package/dist/cli/commands/lint.js +70 -0
- package/dist/cli/commands/lint.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +27 -0
- package/dist/cli/commands/mcp.js +56 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/orphans.d.ts +8 -0
- package/dist/cli/commands/orphans.js +125 -0
- package/dist/cli/commands/orphans.js.map +1 -0
- package/dist/cli/commands/provision.d.ts +8 -0
- package/dist/cli/commands/provision.js +116 -0
- package/dist/cli/commands/provision.js.map +1 -0
- package/dist/cli/commands/r2.d.ts +2 -0
- package/dist/cli/commands/r2.js +87 -6
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/reset.d.ts +12 -0
- package/dist/cli/commands/reset.js +137 -0
- package/dist/cli/commands/reset.js.map +1 -0
- package/dist/cli/commands/review.d.ts +19 -0
- package/dist/cli/commands/review.js +128 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/serve.js +47 -2
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/source.d.ts +16 -0
- package/dist/cli/commands/source.js +159 -0
- package/dist/cli/commands/source.js.map +1 -0
- package/dist/cli/commands/start.js +472 -103
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/sync-entities.d.ts +13 -0
- package/dist/cli/commands/sync-entities.js +242 -0
- package/dist/cli/commands/sync-entities.js.map +1 -0
- package/dist/cli/commands/sync.js +40 -9
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/update.d.ts +8 -0
- package/dist/cli/commands/update.js +155 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.js +114 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/scaffolding.d.ts +10 -0
- package/dist/cli/scaffolding.js +302 -0
- package/dist/cli/scaffolding.js.map +1 -0
- package/dist/cli/setup-wizard.d.ts +30 -0
- package/dist/cli/setup-wizard.js +244 -0
- package/dist/cli/setup-wizard.js.map +1 -0
- package/dist/cli/sync-review-interactive.d.ts +31 -0
- package/dist/cli/sync-review-interactive.js +393 -0
- package/dist/cli/sync-review-interactive.js.map +1 -0
- package/dist/cli/theme.d.ts +31 -0
- package/dist/cli/theme.js +116 -0
- package/dist/cli/theme.js.map +1 -0
- package/dist/core/graph.d.ts +16 -9
- package/dist/core/graph.js +263 -145
- package/dist/core/graph.js.map +1 -1
- package/dist/core/migration-runner.d.ts +42 -0
- package/dist/core/migration-runner.js +232 -0
- package/dist/core/migration-runner.js.map +1 -0
- package/dist/core/migration-types.d.ts +101 -0
- package/dist/core/migration-types.js +21 -0
- package/dist/core/migration-types.js.map +1 -0
- package/dist/core/migrations/20260219-formalize-memory-location.d.ts +2 -0
- package/dist/core/migrations/20260219-formalize-memory-location.js +35 -0
- package/dist/core/migrations/20260219-formalize-memory-location.js.map +1 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +12 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.js +65 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.js.map +1 -0
- package/dist/core/migrations/20260220-add-workspace-readme.d.ts +11 -0
- package/dist/core/migrations/20260220-add-workspace-readme.js +82 -0
- package/dist/core/migrations/20260220-add-workspace-readme.js.map +1 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +9 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js +64 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +1 -0
- package/dist/core/migrations/index.d.ts +11 -0
- package/dist/core/migrations/index.js +23 -0
- package/dist/core/migrations/index.js.map +1 -0
- package/dist/core/schema-registry.d.ts +36 -0
- package/dist/core/schema-registry.js +161 -0
- package/dist/core/schema-registry.js.map +1 -0
- package/dist/core/types.d.ts +242 -3
- package/dist/core/types.js +21 -2
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +16 -0
- package/dist/core/user-config.js +8 -0
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +973 -32
- package/dist/core/validation.js +163 -4
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +26 -2
- package/dist/core/workspace-manager.js +113 -15
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +20 -11
- package/dist/core/workspace.js +123 -34
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/connector-manager.d.ts +65 -0
- package/dist/mcp/connector-manager.js +223 -0
- package/dist/mcp/connector-manager.js.map +1 -0
- package/dist/mcp/connectors/asana.d.ts +2 -0
- package/dist/mcp/connectors/asana.js +20 -0
- package/dist/mcp/connectors/asana.js.map +1 -0
- package/dist/mcp/connectors/definitions.d.ts +45 -0
- package/dist/mcp/connectors/definitions.js +32 -0
- package/dist/mcp/connectors/definitions.js.map +1 -0
- package/dist/mcp/connectors/figma.d.ts +5 -0
- package/dist/mcp/connectors/figma.js +21 -0
- package/dist/mcp/connectors/figma.js.map +1 -0
- package/dist/mcp/connectors/gdrive.d.ts +2 -0
- package/dist/mcp/connectors/gdrive.js +20 -0
- package/dist/mcp/connectors/gdrive.js.map +1 -0
- package/dist/mcp/connectors/granola.d.ts +2 -0
- package/dist/mcp/connectors/granola.js +12 -0
- package/dist/mcp/connectors/granola.js.map +1 -0
- package/dist/mcp/connectors/linear.d.ts +2 -0
- package/dist/mcp/connectors/linear.js +19 -0
- package/dist/mcp/connectors/linear.js.map +1 -0
- package/dist/mcp/connectors/obsidian.d.ts +2 -0
- package/dist/mcp/connectors/obsidian.js +19 -0
- package/dist/mcp/connectors/obsidian.js.map +1 -0
- package/dist/mcp/connectors/pipedrive.d.ts +2 -0
- package/dist/mcp/connectors/pipedrive.js +20 -0
- package/dist/mcp/connectors/pipedrive.js.map +1 -0
- package/dist/mcp/connectors/slack.d.ts +2 -0
- package/dist/mcp/connectors/slack.js +21 -0
- package/dist/mcp/connectors/slack.js.map +1 -0
- package/dist/mcp/oauth-provider.d.ts +41 -0
- package/dist/mcp/oauth-provider.js +160 -0
- package/dist/mcp/oauth-provider.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +28 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +14 -0
- package/dist/mcp/tools.js +172 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/server/index.js +17 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/plugin-loader.d.ts +15 -0
- package/dist/server/plugin-loader.js +68 -2
- package/dist/server/plugin-loader.js.map +1 -1
- package/dist/server/routes/graph-api.js +1 -1
- package/dist/server/routes/graph-api.js.map +1 -1
- package/dist/server/routes/webhook.js +33 -0
- package/dist/server/routes/webhook.js.map +1 -1
- package/dist/services/github-provisioner.d.ts +9 -3
- package/dist/services/github-provisioner.js +46 -8
- package/dist/services/github-provisioner.js.map +1 -1
- package/dist/services/lint-service.d.ts +27 -0
- package/dist/services/lint-service.js +83 -0
- package/dist/services/lint-service.js.map +1 -0
- package/dist/services/markdown.d.ts +9 -0
- package/dist/services/markdown.js +26 -5
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/memory-service.d.ts +1 -2
- package/dist/services/memory-service.js +5 -4
- package/dist/services/memory-service.js.map +1 -1
- package/dist/services/orphan-service.d.ts +31 -0
- package/dist/services/orphan-service.js +100 -0
- package/dist/services/orphan-service.js.map +1 -0
- package/dist/services/sync/commit.d.ts +58 -0
- package/dist/services/sync/commit.js +350 -0
- package/dist/services/sync/commit.js.map +1 -0
- package/dist/services/sync/context-index.d.ts +69 -0
- package/dist/services/sync/context-index.js +280 -0
- package/dist/services/sync/context-index.js.map +1 -0
- package/dist/services/sync/derive.d.ts +34 -0
- package/dist/services/sync/derive.js +164 -0
- package/dist/services/sync/derive.js.map +1 -0
- package/dist/services/sync/enrichment-state.d.ts +31 -0
- package/dist/services/sync/enrichment-state.js +63 -0
- package/dist/services/sync/enrichment-state.js.map +1 -0
- package/dist/services/sync/enrichment.d.ts +25 -0
- package/dist/services/sync/enrichment.js +121 -0
- package/dist/services/sync/enrichment.js.map +1 -0
- package/dist/services/sync/frontmatter-extractor.d.ts +40 -0
- package/dist/services/sync/frontmatter-extractor.js +273 -0
- package/dist/services/sync/frontmatter-extractor.js.map +1 -0
- package/dist/services/sync/graph-match-state.d.ts +33 -0
- package/dist/services/sync/graph-match-state.js +61 -0
- package/dist/services/sync/graph-match-state.js.map +1 -0
- package/dist/services/sync/graph-match.d.ts +53 -0
- package/dist/services/sync/graph-match.js +316 -0
- package/dist/services/sync/graph-match.js.map +1 -0
- package/dist/services/sync/graphrag-client.d.ts +43 -0
- package/dist/services/sync/graphrag-client.js +94 -0
- package/dist/services/sync/graphrag-client.js.map +1 -0
- package/dist/services/sync/graphrag-config.d.ts +16 -0
- package/dist/services/sync/graphrag-config.js +39 -0
- package/dist/services/sync/graphrag-config.js.map +1 -0
- package/dist/services/sync/graphrag-context.d.ts +14 -0
- package/dist/services/sync/graphrag-context.js +109 -0
- package/dist/services/sync/graphrag-context.js.map +1 -0
- package/dist/services/sync/graphrag-indexer.d.ts +30 -0
- package/dist/services/sync/graphrag-indexer.js +358 -0
- package/dist/services/sync/graphrag-indexer.js.map +1 -0
- package/dist/services/sync/llm.d.ts +32 -0
- package/dist/services/sync/llm.js +115 -0
- package/dist/services/sync/llm.js.map +1 -0
- package/dist/services/sync/mcp-client.d.ts +59 -0
- package/dist/services/sync/mcp-client.js +285 -0
- package/dist/services/sync/mcp-client.js.map +1 -0
- package/dist/services/sync/model-factory.d.ts +10 -0
- package/dist/services/sync/model-factory.js +24 -0
- package/dist/services/sync/model-factory.js.map +1 -0
- package/dist/services/sync/name-quality.d.ts +31 -0
- package/dist/services/sync/name-quality.js +60 -0
- package/dist/services/sync/name-quality.js.map +1 -0
- package/dist/services/sync/output-schemas.d.ts +92 -0
- package/dist/services/sync/output-schemas.js +43 -0
- package/dist/services/sync/output-schemas.js.map +1 -0
- package/dist/services/sync/prompts.d.ts +19 -0
- package/dist/services/sync/prompts.js +128 -0
- package/dist/services/sync/prompts.js.map +1 -0
- package/dist/services/sync/reconciler.d.ts +48 -0
- package/dist/services/sync/reconciler.js +295 -0
- package/dist/services/sync/reconciler.js.map +1 -0
- package/dist/services/sync/source-config.d.ts +45 -0
- package/dist/services/sync/source-config.js +208 -0
- package/dist/services/sync/source-config.js.map +1 -0
- package/dist/services/sync/source-definitions/asana.d.ts +15 -0
- package/dist/services/sync/source-definitions/asana.js +48 -0
- package/dist/services/sync/source-definitions/asana.js.map +1 -0
- package/dist/services/sync/source-definitions/definitions.d.ts +21 -0
- package/dist/services/sync/source-definitions/definitions.js +26 -0
- package/dist/services/sync/source-definitions/definitions.js.map +1 -0
- package/dist/services/sync/source-definitions/gdrive.d.ts +16 -0
- package/dist/services/sync/source-definitions/gdrive.js +68 -0
- package/dist/services/sync/source-definitions/gdrive.js.map +1 -0
- package/dist/services/sync/source-definitions/granola.d.ts +2 -0
- package/dist/services/sync/source-definitions/granola.js +28 -0
- package/dist/services/sync/source-definitions/granola.js.map +1 -0
- package/dist/services/sync/source-definitions/linear.d.ts +2 -0
- package/dist/services/sync/source-definitions/linear.js +60 -0
- package/dist/services/sync/source-definitions/linear.js.map +1 -0
- package/dist/services/sync/source-definitions/obsidian.d.ts +2 -0
- package/dist/services/sync/source-definitions/obsidian.js +55 -0
- package/dist/services/sync/source-definitions/obsidian.js.map +1 -0
- package/dist/services/sync/source-definitions/pipedrive.d.ts +2 -0
- package/dist/services/sync/source-definitions/pipedrive.js +52 -0
- package/dist/services/sync/source-definitions/pipedrive.js.map +1 -0
- package/dist/services/sync/staging.d.ts +53 -0
- package/dist/services/sync/staging.js +131 -0
- package/dist/services/sync/staging.js.map +1 -0
- package/dist/services/sync/structured-extractor.d.ts +49 -0
- package/dist/services/sync/structured-extractor.js +344 -0
- package/dist/services/sync/structured-extractor.js.map +1 -0
- package/dist/services/sync/sync-runner.d.ts +32 -0
- package/dist/services/sync/sync-runner.js +195 -0
- package/dist/services/sync/sync-runner.js.map +1 -0
- package/dist/services/sync/sync-state.d.ts +43 -0
- package/dist/services/sync/sync-state.js +154 -0
- package/dist/services/sync/sync-state.js.map +1 -0
- package/dist/services/sync/types.d.ts +203 -0
- package/dist/services/sync/types.js +8 -0
- package/dist/services/sync/types.js.map +1 -0
- package/dist/services/sync/unstructured-extractor.d.ts +29 -0
- package/dist/services/sync/unstructured-extractor.js +197 -0
- package/dist/services/sync/unstructured-extractor.js.map +1 -0
- package/dist/services/vector-service.d.ts +88 -0
- package/dist/services/vector-service.js +322 -0
- package/dist/services/vector-service.js.map +1 -0
- package/dist/utils/git.d.ts +26 -4
- package/dist/utils/git.js +55 -7
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/merge-resolver.d.ts +34 -0
- package/dist/utils/merge-resolver.js +201 -0
- package/dist/utils/merge-resolver.js.map +1 -0
- package/dist/utils/preflight.d.ts +2 -1
- package/dist/utils/preflight.js +8 -1
- package/dist/utils/preflight.js.map +1 -1
- package/dist/utils/version-checker.d.ts +23 -0
- package/dist/utils/version-checker.js +116 -0
- package/dist/utils/version-checker.js.map +1 -0
- package/dist/utils/workspace-config.d.ts +8 -0
- package/dist/utils/workspace-config.js +22 -0
- package/dist/utils/workspace-config.js.map +1 -0
- package/package.json +24 -11
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orphan Entity Detection Service
|
|
3
|
+
*
|
|
4
|
+
* Finds entities with zero inbound wikilink references across the entire graph.
|
|
5
|
+
* These are "orphans" — they exist but nothing points to them.
|
|
6
|
+
*
|
|
7
|
+
* Supports filtering by entity type, minimum age, and actions like
|
|
8
|
+
* tombstoning (sync-state) or deletion.
|
|
9
|
+
*/
|
|
10
|
+
import { MarkdownService, slugifyWikilink } from './markdown.js';
|
|
11
|
+
/**
|
|
12
|
+
* Build a set of all entity IDs that are referenced by at least one wikilink
|
|
13
|
+
* anywhere in the graph. An entity NOT in this set is an orphan.
|
|
14
|
+
*/
|
|
15
|
+
function buildReferencedSet(manager, markdown) {
|
|
16
|
+
const referenced = new Set();
|
|
17
|
+
const allRepos = manager.getAllRepoConfigs();
|
|
18
|
+
for (const repoConfig of allRepos) {
|
|
19
|
+
let graph;
|
|
20
|
+
try {
|
|
21
|
+
graph = manager.getGraph(repoConfig.name);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const entities = graph.list();
|
|
27
|
+
for (const entity of entities) {
|
|
28
|
+
// Collect all wikilinks from this entity's content + frontmatter
|
|
29
|
+
for (const link of entity.document.wikilinks) {
|
|
30
|
+
// Normalize: strip repo prefix if present, then slugify
|
|
31
|
+
const cleanLink = link.split('/').pop() || link;
|
|
32
|
+
referenced.add(cleanLink);
|
|
33
|
+
referenced.add(slugifyWikilink(cleanLink));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return referenced;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Find all orphan entities — entities with zero inbound wikilink references.
|
|
41
|
+
*/
|
|
42
|
+
export function findOrphans(manager, filters) {
|
|
43
|
+
const markdown = new MarkdownService();
|
|
44
|
+
const referenced = buildReferencedSet(manager, markdown);
|
|
45
|
+
const allRepos = manager.getAllRepoConfigs();
|
|
46
|
+
const repos = filters?.repos
|
|
47
|
+
? allRepos.filter(r => filters.repos.includes(r.name))
|
|
48
|
+
: allRepos;
|
|
49
|
+
const entityTypeFilter = filters?.entityTypes
|
|
50
|
+
? new Set(filters.entityTypes)
|
|
51
|
+
: null;
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
const minAgeMs = (filters?.minAgeDays ?? 0) * 86_400_000;
|
|
54
|
+
const orphans = [];
|
|
55
|
+
let totalScanned = 0;
|
|
56
|
+
for (const repoConfig of repos) {
|
|
57
|
+
let graph;
|
|
58
|
+
try {
|
|
59
|
+
graph = manager.getGraph(repoConfig.name);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const entities = graph.list();
|
|
65
|
+
for (const entity of entities) {
|
|
66
|
+
const entityType = entity.data.entity_type;
|
|
67
|
+
// Filter by entity type
|
|
68
|
+
if (entityTypeFilter && !entityTypeFilter.has(entityType))
|
|
69
|
+
continue;
|
|
70
|
+
totalScanned++;
|
|
71
|
+
// Check if this entity is referenced anywhere
|
|
72
|
+
const id = entity.id;
|
|
73
|
+
if (referenced.has(id) || referenced.has(slugifyWikilink(id))) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// Check minimum age
|
|
77
|
+
if (minAgeMs > 0) {
|
|
78
|
+
const createdStr = entity.data.created_at;
|
|
79
|
+
if (createdStr) {
|
|
80
|
+
const createdMs = new Date(createdStr).getTime();
|
|
81
|
+
if (now - createdMs < minAgeMs)
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
orphans.push({
|
|
86
|
+
repo: repoConfig.name,
|
|
87
|
+
entityType,
|
|
88
|
+
entityId: id,
|
|
89
|
+
createdAt: entity.data.created_at,
|
|
90
|
+
name: entity.data.name,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
orphans,
|
|
96
|
+
totalScanned,
|
|
97
|
+
totalOrphans: orphans.length,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=orphan-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orphan-service.js","sourceRoot":"","sources":["../../src/services/orphan-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commit staging files to the graph.
|
|
3
|
+
*
|
|
4
|
+
* Reads staging files, filters out _action: skip, strips _* metadata,
|
|
5
|
+
* and uses MarkdownService to write to repos. Persists provenance to
|
|
6
|
+
* SyncState before stripping. Records explicit skips as tombstones.
|
|
7
|
+
*
|
|
8
|
+
* For updates, performs field-level merge: sync only overwrites fields
|
|
9
|
+
* it owns (tracked via field_origins). User-added fields are preserved.
|
|
10
|
+
*
|
|
11
|
+
* Exports:
|
|
12
|
+
* applyStaging() — write staging → entity files (no git)
|
|
13
|
+
* commitRepos() — git commit across workspace repos
|
|
14
|
+
* commitStaging() — backwards-compatible wrapper (apply + git)
|
|
15
|
+
*/
|
|
16
|
+
export interface CommitResult {
|
|
17
|
+
created: number;
|
|
18
|
+
updated: number;
|
|
19
|
+
skipped: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ApplyResult extends CommitResult {
|
|
22
|
+
/** Per-repo stats for building git commit messages. */
|
|
23
|
+
perRepo: Map<string, {
|
|
24
|
+
created: number;
|
|
25
|
+
updated: number;
|
|
26
|
+
sources: Set<string>;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
export interface CommitOptions {
|
|
30
|
+
force?: boolean;
|
|
31
|
+
noGit?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface CommitReposOptions {
|
|
34
|
+
/** Prefix for the commit message (e.g. "sync", "enrich"). Default: "sync" */
|
|
35
|
+
messagePrefix?: string;
|
|
36
|
+
/** Per-repo stats from applyStaging() — used to build detailed commit messages. */
|
|
37
|
+
perRepo?: Map<string, {
|
|
38
|
+
created: number;
|
|
39
|
+
updated: number;
|
|
40
|
+
sources: Set<string>;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Write staging files to entity files on disk. Does NOT touch git.
|
|
45
|
+
* Handles: dirty tree check, staging read, field-level merge, entity file
|
|
46
|
+
* writes, staging clear, and sync state update.
|
|
47
|
+
*/
|
|
48
|
+
export declare function applyStaging(workspacePath: string, onProgress?: (msg: string) => void, options?: Pick<CommitOptions, 'force'>): Promise<ApplyResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Git commit uncommitted changes across workspace repos.
|
|
51
|
+
* Works after applyStaging(), enrich, or any manual edits.
|
|
52
|
+
*/
|
|
53
|
+
export declare function commitRepos(workspacePath: string, onProgress?: (msg: string) => void, options?: CommitReposOptions): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Write staging files to the graph and optionally git-commit.
|
|
56
|
+
* Backwards-compatible wrapper around applyStaging() + commitRepos().
|
|
57
|
+
*/
|
|
58
|
+
export declare function commitStaging(workspacePath: string, onProgress?: (msg: string) => void, options?: CommitOptions): Promise<CommitResult>;
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commit staging files to the graph.
|
|
3
|
+
*
|
|
4
|
+
* Reads staging files, filters out _action: skip, strips _* metadata,
|
|
5
|
+
* and uses MarkdownService to write to repos. Persists provenance to
|
|
6
|
+
* SyncState before stripping. Records explicit skips as tombstones.
|
|
7
|
+
*
|
|
8
|
+
* For updates, performs field-level merge: sync only overwrites fields
|
|
9
|
+
* it owns (tracked via field_origins). User-added fields are preserved.
|
|
10
|
+
*
|
|
11
|
+
* Exports:
|
|
12
|
+
* applyStaging() — write staging → entity files (no git)
|
|
13
|
+
* commitRepos() — git commit across workspace repos
|
|
14
|
+
* commitStaging() — backwards-compatible wrapper (apply + git)
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
import { spawnSync } from 'child_process';
|
|
19
|
+
import { MarkdownService } from '../../services/markdown.js';
|
|
20
|
+
import { StagingManager } from './staging.js';
|
|
21
|
+
import { SyncStateManager } from './sync-state.js';
|
|
22
|
+
import { gitHasUncommittedChanges, isGitRepo } from '../../utils/git.js';
|
|
23
|
+
import { loadWorkspaceConfig } from '../../utils/workspace-config.js';
|
|
24
|
+
import { Workspace } from '../../core/workspace.js';
|
|
25
|
+
import { RepoType } from '../../core/types.js';
|
|
26
|
+
import { reindexWorkspace } from '../vector-service.js';
|
|
27
|
+
/** Base entity fields that sync always controls. */
|
|
28
|
+
const BASE_FIELDS = new Set([
|
|
29
|
+
'entity_type', 'entity_id', 'updated_at', 'updated_by',
|
|
30
|
+
]);
|
|
31
|
+
// ── applyStaging ──────────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Write staging files to entity files on disk. Does NOT touch git.
|
|
34
|
+
* Handles: dirty tree check, staging read, field-level merge, entity file
|
|
35
|
+
* writes, staging clear, and sync state update.
|
|
36
|
+
*/
|
|
37
|
+
export async function applyStaging(workspacePath, onProgress, options) {
|
|
38
|
+
const log = onProgress ?? (() => { });
|
|
39
|
+
const staging = new StagingManager(workspacePath);
|
|
40
|
+
const syncState = new SyncStateManager(workspacePath);
|
|
41
|
+
const markdown = new MarkdownService();
|
|
42
|
+
const files = staging.readStaging();
|
|
43
|
+
if (files.length === 0) {
|
|
44
|
+
log('No staging files to apply.');
|
|
45
|
+
return { created: 0, updated: 0, skipped: 0, perRepo: new Map() };
|
|
46
|
+
}
|
|
47
|
+
// Load workspace config for repo paths
|
|
48
|
+
const config = loadWorkspaceConfig(workspacePath);
|
|
49
|
+
let repos = config?.repos ?? [];
|
|
50
|
+
// ── Auto-register unknown repos ───────────────────────────────────────
|
|
51
|
+
if (config) {
|
|
52
|
+
const targetRepoNames = new Set(files.filter(f => f.frontmatter._action !== 'skip').map(f => f.repo));
|
|
53
|
+
for (const repoName of targetRepoNames) {
|
|
54
|
+
if (!repos.find((r) => r.name === repoName)) {
|
|
55
|
+
log(` Auto-registering repo: ${repoName}`);
|
|
56
|
+
const workspace = new Workspace(workspacePath);
|
|
57
|
+
await workspace.registerRepo({ name: repoName, type: RepoType.PROJECT });
|
|
58
|
+
// Reload config to pick up new repo
|
|
59
|
+
const updatedConfig = loadWorkspaceConfig(workspacePath);
|
|
60
|
+
repos = updatedConfig?.repos ?? [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ── Dirty working tree check (per-repo) ─────────────────────────────────
|
|
65
|
+
if (!options?.force) {
|
|
66
|
+
const targetRepoPaths = new Set();
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
if (file.frontmatter._action === 'skip')
|
|
69
|
+
continue;
|
|
70
|
+
const repo = repos.find((r) => r.name === file.repo);
|
|
71
|
+
const repoPath = repo ? join(workspacePath, repo.path) : join(workspacePath, file.repo);
|
|
72
|
+
targetRepoPaths.add(repoPath);
|
|
73
|
+
}
|
|
74
|
+
for (const repoPath of targetRepoPaths) {
|
|
75
|
+
if (existsSync(repoPath) && isGitRepo(repoPath) && gitHasUncommittedChanges(repoPath)) {
|
|
76
|
+
const msg = `Uncommitted changes in ${repoPath}. Commit or stash changes first, or use --force.`;
|
|
77
|
+
log(msg);
|
|
78
|
+
throw new Error(msg);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const result = { created: 0, updated: 0, skipped: 0, perRepo: new Map() };
|
|
83
|
+
for (const file of files) {
|
|
84
|
+
const action = file.frontmatter._action;
|
|
85
|
+
const fieldSources = (file.frontmatter._field_sources ?? {});
|
|
86
|
+
// Save provenance before stripping
|
|
87
|
+
const sources = file.frontmatter._sources;
|
|
88
|
+
if (sources && sources.length > 0) {
|
|
89
|
+
for (const sourceRef of sources) {
|
|
90
|
+
const sourceName = sourceRef.split(':')[0] ?? sourceRef.split('/')[0] ?? 'unknown';
|
|
91
|
+
syncState.setEntityMapping(sourceName, file.entity_id, sourceRef);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (action === 'skip') {
|
|
95
|
+
// Track as tombstone if user explicitly changed from create to skip
|
|
96
|
+
syncState.addTombstone(file.entity_id);
|
|
97
|
+
result.skipped++;
|
|
98
|
+
log(` Skipped: ${file.entity_type}/${file.entity_id}`);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Strip staging metadata fields
|
|
102
|
+
const stagedFrontmatter = { ...file.frontmatter };
|
|
103
|
+
const coLocate = stagedFrontmatter._co_locate;
|
|
104
|
+
const writeMode = stagedFrontmatter._write_mode;
|
|
105
|
+
delete stagedFrontmatter._action;
|
|
106
|
+
delete stagedFrontmatter._confidence;
|
|
107
|
+
delete stagedFrontmatter._sources;
|
|
108
|
+
delete stagedFrontmatter._notes;
|
|
109
|
+
delete stagedFrontmatter._field_sources;
|
|
110
|
+
delete stagedFrontmatter._co_locate;
|
|
111
|
+
delete stagedFrontmatter._write_mode;
|
|
112
|
+
// Determine target path
|
|
113
|
+
const repo = repos.find((r) => r.name === file.repo);
|
|
114
|
+
const repoPath = repo ? join(workspacePath, repo.path) : join(workspacePath, file.repo);
|
|
115
|
+
// Git-init new repo directories immediately so they're protected from
|
|
116
|
+
// manual resets or git clean even if workspace_commit isn't called later.
|
|
117
|
+
if (!existsSync(repoPath)) {
|
|
118
|
+
mkdirSync(repoPath, { recursive: true });
|
|
119
|
+
}
|
|
120
|
+
if (!isGitRepo(repoPath)) {
|
|
121
|
+
spawnSync('git', ['init'], { cwd: repoPath, encoding: 'utf-8' });
|
|
122
|
+
const ignorePath = join(repoPath, '.gitignore');
|
|
123
|
+
if (!existsSync(ignorePath)) {
|
|
124
|
+
writeFileSync(ignorePath, '.DS_Store\n*.tmp\n*.log\n', 'utf-8');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
let entityPath;
|
|
128
|
+
if (coLocate) {
|
|
129
|
+
// Co-located sub-content: {repo}/{parentId}/{subfolder}/{entityId}.md
|
|
130
|
+
const parentRef = stagedFrontmatter[coLocate.parent_field];
|
|
131
|
+
if (!parentRef) {
|
|
132
|
+
result.skipped++;
|
|
133
|
+
log(` Skipped: ${file.entity_type}/${file.entity_id} (no ${coLocate.parent_field} assigned)`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const parentId = parentRef.replace(/^\[\[/, '').replace(/\]\]$/, '');
|
|
137
|
+
const subDir = join(repoPath, parentId, coLocate.subfolder);
|
|
138
|
+
mkdirSync(subDir, { recursive: true });
|
|
139
|
+
entityPath = join(subDir, `${file.entity_id}.md`);
|
|
140
|
+
}
|
|
141
|
+
else if (writeMode === 'collection') {
|
|
142
|
+
// Collection mode: {repo}/{entityId}.md (loose file, no subfolder)
|
|
143
|
+
mkdirSync(repoPath, { recursive: true });
|
|
144
|
+
entityPath = join(repoPath, `${file.entity_id}.md`);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// Standard entity: {repo}/{entityId}/main.md
|
|
148
|
+
const entityDir = join(repoPath, file.entity_id);
|
|
149
|
+
mkdirSync(entityDir, { recursive: true });
|
|
150
|
+
entityPath = join(entityDir, 'main.md');
|
|
151
|
+
}
|
|
152
|
+
const now = new Date().toISOString();
|
|
153
|
+
let finalFrontmatter;
|
|
154
|
+
if (action === 'update' && existsSync(entityPath)) {
|
|
155
|
+
// ── Field-level merge ─────────────────────────────────────────────
|
|
156
|
+
const existing = markdown.parseFile(entityPath);
|
|
157
|
+
finalFrontmatter = { ...existing.frontmatter };
|
|
158
|
+
// Overwrite source-owned fields and base fields
|
|
159
|
+
for (const [key, value] of Object.entries(stagedFrontmatter)) {
|
|
160
|
+
if (BASE_FIELDS.has(key) || fieldSources[key]) {
|
|
161
|
+
finalFrontmatter[key] = value;
|
|
162
|
+
}
|
|
163
|
+
else if (finalFrontmatter[key] === undefined) {
|
|
164
|
+
// New field from sync that wasn't on disk — add it
|
|
165
|
+
finalFrontmatter[key] = value;
|
|
166
|
+
}
|
|
167
|
+
// else: field exists on disk and sync doesn't own it → preserve user value
|
|
168
|
+
}
|
|
169
|
+
// Preserve created_at/created_by from existing
|
|
170
|
+
if (existing.frontmatter.created_at)
|
|
171
|
+
finalFrontmatter.created_at = existing.frontmatter.created_at;
|
|
172
|
+
if (existing.frontmatter.created_by)
|
|
173
|
+
finalFrontmatter.created_by = existing.frontmatter.created_by;
|
|
174
|
+
// Always update timestamps
|
|
175
|
+
finalFrontmatter.updated_at = now;
|
|
176
|
+
finalFrontmatter.updated_by = 'sync';
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// ── Create (or update with no existing file) ──────────────────────
|
|
180
|
+
finalFrontmatter = stagedFrontmatter;
|
|
181
|
+
// Add base entity fields if missing
|
|
182
|
+
if (!finalFrontmatter.entity_type)
|
|
183
|
+
finalFrontmatter.entity_type = file.entity_type;
|
|
184
|
+
if (!finalFrontmatter.entity_id)
|
|
185
|
+
finalFrontmatter.entity_id = file.entity_id;
|
|
186
|
+
if (!finalFrontmatter.created_at)
|
|
187
|
+
finalFrontmatter.created_at = now;
|
|
188
|
+
if (!finalFrontmatter.updated_at)
|
|
189
|
+
finalFrontmatter.updated_at = now;
|
|
190
|
+
if (!finalFrontmatter.created_by)
|
|
191
|
+
finalFrontmatter.created_by = 'sync';
|
|
192
|
+
if (!finalFrontmatter.updated_by)
|
|
193
|
+
finalFrontmatter.updated_by = 'sync';
|
|
194
|
+
}
|
|
195
|
+
markdown.writeFile(entityPath, {
|
|
196
|
+
frontmatter: finalFrontmatter,
|
|
197
|
+
content: file.content,
|
|
198
|
+
wikilinks: [],
|
|
199
|
+
});
|
|
200
|
+
// Track per-repo stats for git commit messages
|
|
201
|
+
if (!result.perRepo.has(repoPath)) {
|
|
202
|
+
result.perRepo.set(repoPath, { created: 0, updated: 0, sources: new Set() });
|
|
203
|
+
}
|
|
204
|
+
const repoStats = result.perRepo.get(repoPath);
|
|
205
|
+
const sourceRefs = file.frontmatter._sources;
|
|
206
|
+
if (sourceRefs) {
|
|
207
|
+
for (const ref of sourceRefs) {
|
|
208
|
+
const name = ref.split('/')[0];
|
|
209
|
+
if (name)
|
|
210
|
+
repoStats.sources.add(name);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Persist field origins to sync state
|
|
214
|
+
if (Object.keys(fieldSources).length > 0) {
|
|
215
|
+
// Group field_sources by source name
|
|
216
|
+
const bySource = new Map();
|
|
217
|
+
for (const [field, source] of Object.entries(fieldSources)) {
|
|
218
|
+
if (!bySource.has(source))
|
|
219
|
+
bySource.set(source, {});
|
|
220
|
+
bySource.get(source)[field] = source;
|
|
221
|
+
}
|
|
222
|
+
for (const [sourceName, fields] of bySource) {
|
|
223
|
+
syncState.setFieldOrigins(sourceName, file.entity_id, fields);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (action === 'update') {
|
|
227
|
+
result.updated++;
|
|
228
|
+
repoStats.updated++;
|
|
229
|
+
log(` Updated: ${file.entity_type}/${file.entity_id}`);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
result.created++;
|
|
233
|
+
repoStats.created++;
|
|
234
|
+
log(` Created: ${file.entity_type}/${file.entity_id}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Clear staging after successful apply
|
|
238
|
+
staging.clear();
|
|
239
|
+
log(`\nApply complete: ${result.created} created, ${result.updated} updated, ${result.skipped} skipped`);
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
// ── commitRepos ───────────────────────────────────────────────────────────────
|
|
243
|
+
/**
|
|
244
|
+
* Git commit uncommitted changes across workspace repos.
|
|
245
|
+
* Works after applyStaging(), enrich, or any manual edits.
|
|
246
|
+
*/
|
|
247
|
+
export async function commitRepos(workspacePath, onProgress, options) {
|
|
248
|
+
const log = onProgress ?? (() => { });
|
|
249
|
+
const prefix = options?.messagePrefix ?? 'sync';
|
|
250
|
+
const perRepo = options?.perRepo;
|
|
251
|
+
// ── Reconcile workspace.json with filesystem ────────────────────────
|
|
252
|
+
const workspace = new Workspace(workspacePath);
|
|
253
|
+
if (workspace.isWorkspace()) {
|
|
254
|
+
const { added, removed } = await workspace.reconcileRepos();
|
|
255
|
+
for (const name of added)
|
|
256
|
+
log(` Registered repo: ${name}`);
|
|
257
|
+
for (const name of removed)
|
|
258
|
+
log(` Removed stale repo: ${name}`);
|
|
259
|
+
// Commit .studiograph/ if workspace.json changed
|
|
260
|
+
if (added.length > 0 || removed.length > 0) {
|
|
261
|
+
const sgDir = join(workspacePath, '.studiograph');
|
|
262
|
+
if (isGitRepo(workspacePath) && gitHasUncommittedChanges(workspacePath)) {
|
|
263
|
+
spawnSync('git', ['add', sgDir], { cwd: workspacePath, encoding: 'utf-8' });
|
|
264
|
+
const parts = [];
|
|
265
|
+
if (added.length > 0)
|
|
266
|
+
parts.push(`add ${added.join(', ')}`);
|
|
267
|
+
if (removed.length > 0)
|
|
268
|
+
parts.push(`remove ${removed.join(', ')}`);
|
|
269
|
+
const msg = `workspace: reconcile repos (${parts.join('; ')})`;
|
|
270
|
+
spawnSync('git', ['commit', '-m', msg], { cwd: workspacePath, encoding: 'utf-8' });
|
|
271
|
+
log(` Committed workspace.json update`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const config = loadWorkspaceConfig(workspacePath);
|
|
276
|
+
const repos = config?.repos ?? [];
|
|
277
|
+
for (const repo of repos) {
|
|
278
|
+
const repoPath = join(workspacePath, repo.path);
|
|
279
|
+
if (!existsSync(repoPath))
|
|
280
|
+
continue;
|
|
281
|
+
// Initialize git repo if it doesn't exist yet
|
|
282
|
+
if (!isGitRepo(repoPath)) {
|
|
283
|
+
const init = spawnSync('git', ['init'], { cwd: repoPath, encoding: 'utf-8' });
|
|
284
|
+
if (init.status !== 0) {
|
|
285
|
+
log(` Warning: git init failed in ${repoPath}: ${init.stderr?.trim()}`);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const ignorePath = join(repoPath, '.gitignore');
|
|
289
|
+
if (!existsSync(ignorePath)) {
|
|
290
|
+
writeFileSync(ignorePath, '.DS_Store\n*.tmp\n*.log\n', 'utf-8');
|
|
291
|
+
}
|
|
292
|
+
log(` Git init: ${repo.name}`);
|
|
293
|
+
}
|
|
294
|
+
if (!gitHasUncommittedChanges(repoPath))
|
|
295
|
+
continue;
|
|
296
|
+
// Build commit message
|
|
297
|
+
let commitMsg;
|
|
298
|
+
const stats = perRepo?.get(repoPath);
|
|
299
|
+
if (stats) {
|
|
300
|
+
const parts = [];
|
|
301
|
+
if (stats.created > 0)
|
|
302
|
+
parts.push(`${stats.created} created`);
|
|
303
|
+
if (stats.updated > 0)
|
|
304
|
+
parts.push(`${stats.updated} updated`);
|
|
305
|
+
const from = stats.sources.size > 0 ? ` from ${[...stats.sources].join(', ')}` : '';
|
|
306
|
+
commitMsg = `${prefix}: ${parts.join(', ')}${from}`;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
// Generic message — count changed files from git status
|
|
310
|
+
const status = spawnSync('git', ['status', '--porcelain'], { cwd: repoPath, encoding: 'utf-8' });
|
|
311
|
+
const changedFiles = (status.stdout?.trim().split('\n').filter(Boolean) ?? []).length;
|
|
312
|
+
commitMsg = `${prefix}: ${changedFiles} file${changedFiles === 1 ? '' : 's'} changed`;
|
|
313
|
+
}
|
|
314
|
+
// Stage all changes within this repo directory (relies on .gitignore for exclusions)
|
|
315
|
+
const add = spawnSync('git', ['add', '.'], { cwd: repoPath, encoding: 'utf-8' });
|
|
316
|
+
if (add.status !== 0) {
|
|
317
|
+
log(` Warning: git add failed in ${repoPath}: ${add.stderr?.trim()}`);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
const commit = spawnSync('git', ['commit', '-m', commitMsg], { cwd: repoPath, encoding: 'utf-8' });
|
|
321
|
+
if (commit.status === 0) {
|
|
322
|
+
log(` Git commit: ${repo.name}`);
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
log(` Warning: git commit failed in ${repoPath}: ${commit.stderr?.trim()}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Reindex search after commit (non-fatal)
|
|
329
|
+
try {
|
|
330
|
+
const indexed = await reindexWorkspace(workspacePath, repos, log);
|
|
331
|
+
if (indexed > 0)
|
|
332
|
+
log(` Search index updated (${indexed} entities)`);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// Non-fatal — search may be stale until next manual reindex
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// ── commitStaging (backwards-compatible wrapper) ──────────────────────────────
|
|
339
|
+
/**
|
|
340
|
+
* Write staging files to the graph and optionally git-commit.
|
|
341
|
+
* Backwards-compatible wrapper around applyStaging() + commitRepos().
|
|
342
|
+
*/
|
|
343
|
+
export async function commitStaging(workspacePath, onProgress, options) {
|
|
344
|
+
const applyResult = await applyStaging(workspacePath, onProgress, { force: options?.force });
|
|
345
|
+
if (!options?.noGit) {
|
|
346
|
+
await commitRepos(workspacePath, onProgress, { perRepo: applyResult.perRepo });
|
|
347
|
+
}
|
|
348
|
+
return { created: applyResult.created, updated: applyResult.updated, skipped: applyResult.skipped };
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../../src/services/sync/commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextIndex
|
|
3
|
+
*
|
|
4
|
+
* Cross-source context index for enrichment. Scans all repos for entity
|
|
5
|
+
* references using schema relationship fields and wikilinks.
|
|
6
|
+
*
|
|
7
|
+
* Ranks references by recency, enforces a max_tokens budget, and truncates
|
|
8
|
+
* excess context before the LLM call.
|
|
9
|
+
*/
|
|
10
|
+
import type { SchemaRegistry } from '../../core/schema-registry.js';
|
|
11
|
+
export interface ContextReference {
|
|
12
|
+
entity_id: string;
|
|
13
|
+
entity_type: string;
|
|
14
|
+
field: string;
|
|
15
|
+
repo: string;
|
|
16
|
+
/** ISO date for recency ranking */
|
|
17
|
+
date?: string;
|
|
18
|
+
/** Short summary snippet */
|
|
19
|
+
snippet: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EnrichableEntity {
|
|
22
|
+
entity_id: string;
|
|
23
|
+
entity_type: string;
|
|
24
|
+
repo: string;
|
|
25
|
+
path: string;
|
|
26
|
+
frontmatter: Record<string, any>;
|
|
27
|
+
completeness: number;
|
|
28
|
+
refCount: number;
|
|
29
|
+
}
|
|
30
|
+
export declare class ContextIndex {
|
|
31
|
+
private workspacePath;
|
|
32
|
+
private schemaRegistry;
|
|
33
|
+
private markdownService;
|
|
34
|
+
private references;
|
|
35
|
+
private built;
|
|
36
|
+
constructor(workspacePath: string, schemaRegistry: SchemaRegistry);
|
|
37
|
+
/**
|
|
38
|
+
* Scan all repos for entity references.
|
|
39
|
+
*/
|
|
40
|
+
build(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get all context references for one entity.
|
|
43
|
+
*/
|
|
44
|
+
getReferences(entityId: string): ContextReference[];
|
|
45
|
+
/**
|
|
46
|
+
* Calculate field completeness (0–1) for an entity.
|
|
47
|
+
*/
|
|
48
|
+
getCompleteness(entityType: string, frontmatter: Record<string, any>): number;
|
|
49
|
+
/**
|
|
50
|
+
* Filter to entities worth enriching (low completeness + high context).
|
|
51
|
+
*/
|
|
52
|
+
getEnrichable(minRefs?: number, maxCompleteness?: number): EnrichableEntity[];
|
|
53
|
+
/**
|
|
54
|
+
* Assemble LLM context bundle for one entity.
|
|
55
|
+
* Ranks references by recency, enforces max_tokens budget.
|
|
56
|
+
*/
|
|
57
|
+
assembleContextBundle(entityId: string, entityName: string, maxTokens?: number): string;
|
|
58
|
+
private scanRepo;
|
|
59
|
+
private addReference;
|
|
60
|
+
/**
|
|
61
|
+
* Get relationship fields for an entity type by inspecting schema descriptions.
|
|
62
|
+
*/
|
|
63
|
+
private getRelationshipFields;
|
|
64
|
+
private getDescription;
|
|
65
|
+
private extractEntityId;
|
|
66
|
+
private makeSnippet;
|
|
67
|
+
private findRepoDirs;
|
|
68
|
+
private listSubDirs;
|
|
69
|
+
}
|