studiograph 1.1.3 → 1.2.0-beta.2
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 +2 -8
- package/dist/agent/orchestrator.js +56 -11
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/system.md +28 -10
- 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/{bundled/enrich-entities.md → enrich-entities.md} +12 -0
- package/dist/agent/skills/entity-schema.md +502 -0
- package/dist/agent/skills/obsidian-source-setup.md +246 -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 +11 -1
- package/dist/agent/tools/graph-tools.js +90 -29
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/load-skill.d.ts +1 -1
- package/dist/agent/tools/load-skill.js +1 -1
- package/dist/agent/tools/load-skill.js.map +1 -1
- 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/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/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/connector.js +10 -2
- package/dist/cli/commands/connector.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +4 -6
- package/dist/cli/commands/deploy.js +262 -112
- package/dist/cli/commands/deploy.js.map +1 -1
- 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/init.js +21 -203
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.js +23 -3
- package/dist/cli/commands/join.js.map +1 -1
- 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.js +11 -7
- package/dist/cli/commands/provision.js.map +1 -1
- package/dist/cli/commands/r2.js +8 -2
- 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/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 +285 -55
- 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 +36 -5
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/index.js +31 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/scaffolding.d.ts +2 -1
- package/dist/cli/scaffolding.js +36 -22
- package/dist/cli/scaffolding.js.map +1 -1
- 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 +4 -8
- package/dist/core/graph.js +145 -96
- package/dist/core/graph.js.map +1 -1
- package/dist/core/migration-runner.d.ts +4 -1
- package/dist/core/migration-runner.js +14 -3
- package/dist/core/migration-runner.js.map +1 -1
- package/dist/core/types.d.ts +0 -3
- package/dist/core/types.js +0 -2
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +6 -0
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/workspace.d.ts +13 -5
- package/dist/core/workspace.js +110 -33
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/connector-manager.d.ts +7 -3
- package/dist/mcp/connector-manager.js +61 -16
- package/dist/mcp/connector-manager.js.map +1 -1
- 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 +3 -1
- package/dist/mcp/connectors/definitions.js +19 -127
- package/dist/mcp/connectors/definitions.js.map +1 -1
- 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/server/index.js +14 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/plugin-loader.d.ts +7 -0
- package/dist/server/plugin-loader.js +54 -2
- package/dist/server/plugin-loader.js.map +1 -1
- package/dist/services/github-provisioner.d.ts +8 -3
- package/dist/services/github-provisioner.js +35 -8
- package/dist/services/github-provisioner.js.map +1 -1
- package/dist/services/lint-service.js +8 -1
- package/dist/services/lint-service.js.map +1 -1
- package/dist/services/markdown.js +3 -3
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/memory-service.d.ts +1 -1
- package/dist/services/memory-service.js +2 -3
- 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 +354 -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 +11 -0
- package/dist/services/vector-service.js +42 -0
- package/dist/services/vector-service.js.map +1 -1
- 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/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 +16 -7
- /package/dist/agent/skills/{bundled/gather-context.md → gather-context.md} +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const pipedrive = {
|
|
2
|
+
connector: 'pipedrive',
|
|
3
|
+
defaultMappings: [
|
|
4
|
+
{
|
|
5
|
+
source_type: 'deal',
|
|
6
|
+
entity_type: 'project',
|
|
7
|
+
target_repo: 'projects',
|
|
8
|
+
extraction_mode: 'structured',
|
|
9
|
+
id_from: 'title',
|
|
10
|
+
field_map: {
|
|
11
|
+
'title': 'name',
|
|
12
|
+
'org_name': { field: 'client', transform: 'wikilink' },
|
|
13
|
+
'add_time': { field: 'start_date', transform: 'date-iso' },
|
|
14
|
+
'expected_close_date': { field: 'target_completion', transform: 'date-iso' },
|
|
15
|
+
'person_name': { field: 'team', transform: 'wikilink-array' },
|
|
16
|
+
},
|
|
17
|
+
status_map: {
|
|
18
|
+
'won': 'completed',
|
|
19
|
+
'lost': 'archived',
|
|
20
|
+
'open': 'active',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
source_type: 'person',
|
|
25
|
+
entity_type: 'person',
|
|
26
|
+
target_repo: 'people',
|
|
27
|
+
extraction_mode: 'structured',
|
|
28
|
+
id_from: 'name',
|
|
29
|
+
field_map: {
|
|
30
|
+
'name': 'name',
|
|
31
|
+
'email[0].value': 'email',
|
|
32
|
+
'org_id.name': { field: 'organization', transform: 'wikilink' },
|
|
33
|
+
'postal_address_locality': 'location',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
source_type: 'organization',
|
|
38
|
+
entity_type: 'client',
|
|
39
|
+
target_repo: 'clients',
|
|
40
|
+
extraction_mode: 'structured',
|
|
41
|
+
id_from: 'name',
|
|
42
|
+
field_map: {
|
|
43
|
+
'name': 'name',
|
|
44
|
+
'address_formatted_address': 'location',
|
|
45
|
+
'industry': 'industry',
|
|
46
|
+
'website': 'website',
|
|
47
|
+
'add_time': { field: 'relationship_start', transform: 'date-iso' },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=pipedrive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipedrive.js","sourceRoot":"","sources":["../../../../src/services/sync/source-definitions/pipedrive.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAqB;IACzC,SAAS,EAAE,WAAW;IACtB,eAAe,EAAE;QACf;YACE,WAAW,EAAE,MAAM;YACnB,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,UAAU;YACvB,eAAe,EAAE,YAAY;YAE7B,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE;gBACT,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE;gBACtD,UAAU,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE;gBAC1D,qBAAqB,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,UAAU,EAAE;gBAC5E,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE;aAC9D;YACD,UAAU,EAAE;gBACV,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,QAAQ;aACjB;SACF;QACD;YACE,WAAW,EAAE,QAAQ;YACrB,WAAW,EAAE,QAAQ;YACrB,WAAW,EAAE,QAAQ;YACrB,eAAe,EAAE,YAAY;YAE7B,OAAO,EAAE,MAAM;YACf,SAAS,EAAE;gBACT,MAAM,EAAE,MAAM;gBACd,gBAAgB,EAAE,OAAO;gBACzB,aAAa,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE;gBAC/D,yBAAyB,EAAE,UAAU;aACtC;SACF;QACD;YACE,WAAW,EAAE,cAAc;YAC3B,WAAW,EAAE,QAAQ;YACrB,WAAW,EAAE,SAAS;YACtB,eAAe,EAAE,YAAY;YAE7B,OAAO,EAAE,MAAM;YACf,SAAS,EAAE;gBACT,MAAM,EAAE,MAAM;gBACd,2BAA2B,EAAE,UAAU;gBACvC,UAAU,EAAE,UAAU;gBACtB,SAAS,EAAE,SAAS;gBACpB,UAAU,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,UAAU,EAAE;aACnE;SACF;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StagingManager
|
|
3
|
+
*
|
|
4
|
+
* Write/read staging files at .studiograph/staging/.
|
|
5
|
+
* Mirrors repo structure: .studiograph/staging/<repo>/<id>.md
|
|
6
|
+
*
|
|
7
|
+
* Staging files are standard markdown with YAML frontmatter.
|
|
8
|
+
* _action, _confidence, _sources, _notes are included in frontmatter.
|
|
9
|
+
*/
|
|
10
|
+
import type { ReconciliationMatch } from './types.js';
|
|
11
|
+
export interface StagingFile {
|
|
12
|
+
path: string;
|
|
13
|
+
repo: string;
|
|
14
|
+
entity_type: string;
|
|
15
|
+
entity_id: string;
|
|
16
|
+
frontmatter: Record<string, any>;
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class StagingManager {
|
|
20
|
+
private stagingDir;
|
|
21
|
+
private markdownService;
|
|
22
|
+
constructor(workspacePath: string);
|
|
23
|
+
/**
|
|
24
|
+
* Write reconciled matches as markdown files to staging.
|
|
25
|
+
*/
|
|
26
|
+
writeStaging(matches: ReconciliationMatch[]): {
|
|
27
|
+
written: number;
|
|
28
|
+
skipped: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Read all staging files.
|
|
32
|
+
*/
|
|
33
|
+
readStaging(): StagingFile[];
|
|
34
|
+
/**
|
|
35
|
+
* Clear all staging files.
|
|
36
|
+
*/
|
|
37
|
+
clear(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Check if staging has any files.
|
|
40
|
+
*/
|
|
41
|
+
hasStaging(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Get staging summary.
|
|
44
|
+
*/
|
|
45
|
+
getSummary(): {
|
|
46
|
+
total: number;
|
|
47
|
+
creates: number;
|
|
48
|
+
updates: number;
|
|
49
|
+
skips: number;
|
|
50
|
+
byType: Record<string, number>;
|
|
51
|
+
};
|
|
52
|
+
private listDirs;
|
|
53
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StagingManager
|
|
3
|
+
*
|
|
4
|
+
* Write/read staging files at .studiograph/staging/.
|
|
5
|
+
* Mirrors repo structure: .studiograph/staging/<repo>/<id>.md
|
|
6
|
+
*
|
|
7
|
+
* Staging files are standard markdown with YAML frontmatter.
|
|
8
|
+
* _action, _confidence, _sources, _notes are included in frontmatter.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, mkdirSync, readdirSync, rmSync, statSync } from 'fs';
|
|
11
|
+
import { join, basename } from 'path';
|
|
12
|
+
import { MarkdownService } from '../../services/markdown.js';
|
|
13
|
+
export class StagingManager {
|
|
14
|
+
stagingDir;
|
|
15
|
+
markdownService;
|
|
16
|
+
constructor(workspacePath) {
|
|
17
|
+
this.stagingDir = join(workspacePath, '.studiograph', 'staging');
|
|
18
|
+
this.markdownService = new MarkdownService();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Write reconciled matches as markdown files to staging.
|
|
22
|
+
*/
|
|
23
|
+
writeStaging(matches) {
|
|
24
|
+
let written = 0;
|
|
25
|
+
let skipped = 0;
|
|
26
|
+
for (const match of matches) {
|
|
27
|
+
const dir = join(this.stagingDir, match.target_repo);
|
|
28
|
+
mkdirSync(dir, { recursive: true });
|
|
29
|
+
const filePath = join(dir, `${match.entity_id}.md`);
|
|
30
|
+
// Build frontmatter with staging metadata
|
|
31
|
+
const frontmatter = {
|
|
32
|
+
_action: match.action,
|
|
33
|
+
_confidence: Math.round(match.confidence * 100) / 100,
|
|
34
|
+
_sources: match.records.map(r => r.source_ref),
|
|
35
|
+
_notes: match.notes,
|
|
36
|
+
...(match.field_sources ? { _field_sources: match.field_sources } : {}),
|
|
37
|
+
...(match.co_locate ? { _co_locate: match.co_locate } : {}),
|
|
38
|
+
...(match.write_mode ? { _write_mode: match.write_mode } : {}),
|
|
39
|
+
...match.merged_frontmatter,
|
|
40
|
+
};
|
|
41
|
+
this.markdownService.writeFile(filePath, {
|
|
42
|
+
frontmatter,
|
|
43
|
+
content: match.merged_content,
|
|
44
|
+
wikilinks: [],
|
|
45
|
+
});
|
|
46
|
+
written++;
|
|
47
|
+
}
|
|
48
|
+
return { written, skipped };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Read all staging files.
|
|
52
|
+
*/
|
|
53
|
+
readStaging() {
|
|
54
|
+
if (!existsSync(this.stagingDir))
|
|
55
|
+
return [];
|
|
56
|
+
const files = [];
|
|
57
|
+
// Walk: staging/<repo>/<id>.md
|
|
58
|
+
const repos = this.listDirs(this.stagingDir);
|
|
59
|
+
for (const repo of repos) {
|
|
60
|
+
const repoDir = join(this.stagingDir, repo);
|
|
61
|
+
const mdFiles = readdirSync(repoDir).filter(f => f.endsWith('.md'));
|
|
62
|
+
for (const file of mdFiles) {
|
|
63
|
+
const filePath = join(repoDir, file);
|
|
64
|
+
try {
|
|
65
|
+
const doc = this.markdownService.parseFile(filePath);
|
|
66
|
+
const entityType = doc.frontmatter.entity_type ?? repo;
|
|
67
|
+
files.push({
|
|
68
|
+
path: filePath,
|
|
69
|
+
repo,
|
|
70
|
+
entity_type: entityType,
|
|
71
|
+
entity_id: basename(file, '.md'),
|
|
72
|
+
frontmatter: doc.frontmatter,
|
|
73
|
+
content: doc.content,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.warn(`Warning: failed to parse staging file ${filePath}: ${err instanceof Error ? err.message : 'unknown error'}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return files;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Clear all staging files.
|
|
85
|
+
*/
|
|
86
|
+
clear() {
|
|
87
|
+
if (existsSync(this.stagingDir)) {
|
|
88
|
+
rmSync(this.stagingDir, { recursive: true, force: true });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if staging has any files.
|
|
93
|
+
*/
|
|
94
|
+
hasStaging() {
|
|
95
|
+
return this.readStaging().length > 0;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get staging summary.
|
|
99
|
+
*/
|
|
100
|
+
getSummary() {
|
|
101
|
+
const files = this.readStaging();
|
|
102
|
+
const byType = {};
|
|
103
|
+
let creates = 0;
|
|
104
|
+
let updates = 0;
|
|
105
|
+
let skips = 0;
|
|
106
|
+
for (const file of files) {
|
|
107
|
+
const action = file.frontmatter._action;
|
|
108
|
+
if (action === 'create')
|
|
109
|
+
creates++;
|
|
110
|
+
else if (action === 'update')
|
|
111
|
+
updates++;
|
|
112
|
+
else if (action === 'skip')
|
|
113
|
+
skips++;
|
|
114
|
+
byType[file.entity_type] = (byType[file.entity_type] ?? 0) + 1;
|
|
115
|
+
}
|
|
116
|
+
return { total: files.length, creates, updates, skips, byType };
|
|
117
|
+
}
|
|
118
|
+
listDirs(dir) {
|
|
119
|
+
if (!existsSync(dir))
|
|
120
|
+
return [];
|
|
121
|
+
return readdirSync(dir).filter(f => {
|
|
122
|
+
try {
|
|
123
|
+
return statSync(join(dir, f)).isDirectory();
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../../src/services/sync/staging.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StructuredExtractor
|
|
3
|
+
*
|
|
4
|
+
* Generic field-map-driven extractor for structured API sources.
|
|
5
|
+
* No source-specific code — the field map in the source config drives everything.
|
|
6
|
+
*/
|
|
7
|
+
import { SyncMCPClient } from './mcp-client.js';
|
|
8
|
+
import { SyncStateManager } from './sync-state.js';
|
|
9
|
+
import type { SourceConfig, EntityMapping, ExtractedRecord, FieldTransform } from './types.js';
|
|
10
|
+
export declare class StructuredExtractor {
|
|
11
|
+
private client;
|
|
12
|
+
private sourceConfig;
|
|
13
|
+
private syncState;
|
|
14
|
+
constructor(client: SyncMCPClient, sourceConfig: SourceConfig, syncState: SyncStateManager);
|
|
15
|
+
/**
|
|
16
|
+
* Extract entities for one mapping.
|
|
17
|
+
*
|
|
18
|
+
* Handles:
|
|
19
|
+
* - Pagination (loops through pages until no more data)
|
|
20
|
+
* - Detail fetching (calls get tool per record when mapping.fetch_details is set)
|
|
21
|
+
* - Incremental sync (passes updated_after cursor)
|
|
22
|
+
*/
|
|
23
|
+
extract(mapping: EntityMapping, incremental?: boolean, onProgress?: (msg: string) => void): Promise<ExtractedRecord[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Apply field map to one source record.
|
|
26
|
+
*/
|
|
27
|
+
mapRecord(record: Record<string, any>, mapping: EntityMapping): ExtractedRecord | null;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve nested paths like "org_id.name" or "email[0].value".
|
|
30
|
+
*/
|
|
31
|
+
resolveFieldPath(record: Record<string, any>, path: string): any;
|
|
32
|
+
/**
|
|
33
|
+
* Generate entity_id from the id_from field.
|
|
34
|
+
*/
|
|
35
|
+
generateEntityId(record: Record<string, any>, mapping: EntityMapping): string | null;
|
|
36
|
+
private applyTransform;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve nested field paths like "org_id.name" or "email[0].value".
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveFieldPath(record: Record<string, any>, path: string): any;
|
|
42
|
+
/**
|
|
43
|
+
* Apply a field transform to a value.
|
|
44
|
+
*/
|
|
45
|
+
export declare function applyTransform(value: any, transform: FieldTransform['transform']): any;
|
|
46
|
+
/**
|
|
47
|
+
* Convert a string to kebab-case entity ID.
|
|
48
|
+
*/
|
|
49
|
+
export declare function slugify(str: string): string;
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StructuredExtractor
|
|
3
|
+
*
|
|
4
|
+
* Generic field-map-driven extractor for structured API sources.
|
|
5
|
+
* No source-specific code — the field map in the source config drives everything.
|
|
6
|
+
*/
|
|
7
|
+
import { nameQuality } from './name-quality.js';
|
|
8
|
+
export class StructuredExtractor {
|
|
9
|
+
client;
|
|
10
|
+
sourceConfig;
|
|
11
|
+
syncState;
|
|
12
|
+
constructor(client, sourceConfig, syncState) {
|
|
13
|
+
this.client = client;
|
|
14
|
+
this.sourceConfig = sourceConfig;
|
|
15
|
+
this.syncState = syncState;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract entities for one mapping.
|
|
19
|
+
*
|
|
20
|
+
* Handles:
|
|
21
|
+
* - Pagination (loops through pages until no more data)
|
|
22
|
+
* - Detail fetching (calls get tool per record when mapping.fetch_details is set)
|
|
23
|
+
* - Incremental sync (passes updated_after cursor)
|
|
24
|
+
*/
|
|
25
|
+
async extract(mapping, incremental = false, onProgress) {
|
|
26
|
+
if (mapping.extraction_mode !== 'structured')
|
|
27
|
+
return [];
|
|
28
|
+
// Support explicit list_tool override for servers with non-standard tool names
|
|
29
|
+
const listTool = mapping.list_tool ?? this.client.findListTool(mapping.source_type);
|
|
30
|
+
if (!listTool) {
|
|
31
|
+
throw new Error(`No list tool found for source type "${mapping.source_type}"`);
|
|
32
|
+
}
|
|
33
|
+
// Phase 1: List all records (paginating until exhausted)
|
|
34
|
+
// Support array of list_params for APIs that need multiple calls
|
|
35
|
+
// (e.g. Asana archived: false + archived: true)
|
|
36
|
+
const paramSets = Array.isArray(mapping.list_params)
|
|
37
|
+
? mapping.list_params
|
|
38
|
+
: [mapping.list_params ?? {}];
|
|
39
|
+
let allRawRecords = [];
|
|
40
|
+
for (const baseParams of paramSets) {
|
|
41
|
+
let pageStart = 0;
|
|
42
|
+
let hasMore = true;
|
|
43
|
+
while (hasMore) {
|
|
44
|
+
const args = { ...baseParams };
|
|
45
|
+
if (typeof pageStart === 'string') {
|
|
46
|
+
// Cursor-based pagination (Linear, etc.)
|
|
47
|
+
args.cursor = pageStart;
|
|
48
|
+
}
|
|
49
|
+
else if (pageStart > 0) {
|
|
50
|
+
// Offset-based pagination (Pipedrive, etc.)
|
|
51
|
+
args.start = pageStart;
|
|
52
|
+
}
|
|
53
|
+
if (mapping.list_limit)
|
|
54
|
+
args.limit = mapping.list_limit;
|
|
55
|
+
if (incremental) {
|
|
56
|
+
const lastSync = this.syncState.getLastSync(this.sourceConfig.name);
|
|
57
|
+
if (lastSync)
|
|
58
|
+
args.updated_after = lastSync;
|
|
59
|
+
}
|
|
60
|
+
const raw = await this.client.callTool(listTool, Object.keys(args).length > 0 ? args : undefined);
|
|
61
|
+
let records;
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(raw);
|
|
65
|
+
records = Array.isArray(parsed)
|
|
66
|
+
? parsed
|
|
67
|
+
: (parsed.data ?? parsed.files ?? parsed.documents ?? parsed.results ?? parsed.items ?? findFirstArray(parsed) ?? []);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (onProgress)
|
|
71
|
+
onProgress(` Warning: failed to parse list response — ${err instanceof Error ? err.message : 'invalid JSON'}`);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
allRawRecords.push(...records);
|
|
75
|
+
// Pagination: support multiple styles
|
|
76
|
+
const pagination = parsed.additional_data?.pagination;
|
|
77
|
+
if (pagination?.more_items_in_collection && pagination.next_start != null) {
|
|
78
|
+
// Pipedrive-style offset pagination
|
|
79
|
+
pageStart = pagination.next_start;
|
|
80
|
+
}
|
|
81
|
+
else if (parsed.hasNextPage && parsed.cursor) {
|
|
82
|
+
// Cursor-based pagination (Linear, etc.)
|
|
83
|
+
pageStart = parsed.cursor;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
hasMore = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Phase 2: Fetch full details per record if configured
|
|
91
|
+
if (mapping.fetch_details && allRawRecords.length > 0) {
|
|
92
|
+
// Support explicit read_tool override for servers with non-standard tool names
|
|
93
|
+
const getTool = mapping.read_tool ?? this.client.findGetTool(mapping.source_type);
|
|
94
|
+
if (getTool) {
|
|
95
|
+
const idParam = this.client.getToolIdParam(getTool);
|
|
96
|
+
const detailed = [];
|
|
97
|
+
const total = allRawRecords.length;
|
|
98
|
+
for (let i = 0; i < total; i++) {
|
|
99
|
+
const record = allRawRecords[i];
|
|
100
|
+
const id = record.id ?? record.ID ?? record.gid;
|
|
101
|
+
if (!id) {
|
|
102
|
+
detailed.push(record);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
if (onProgress && (i + 1) % 10 === 0) {
|
|
107
|
+
onProgress(` Fetching details: ${i + 1}/${total}`);
|
|
108
|
+
}
|
|
109
|
+
const detailRaw = await this.client.callTool(getTool, { [idParam]: id });
|
|
110
|
+
const parsed = JSON.parse(detailRaw);
|
|
111
|
+
// Handle various wrapper formats
|
|
112
|
+
const detail = parsed.data ?? parsed.document ?? parsed;
|
|
113
|
+
detailed.push(detail);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
if (onProgress)
|
|
117
|
+
onProgress(` Warning: detail fetch failed for record ${id} — ${err instanceof Error ? err.message : 'unknown error'}`);
|
|
118
|
+
detailed.push(record); // fall back to list data on error
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
allRawRecords = detailed;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Phase 3: Map records to ExtractedRecords
|
|
125
|
+
const results = [];
|
|
126
|
+
let mapErrors = 0;
|
|
127
|
+
for (const record of allRawRecords) {
|
|
128
|
+
try {
|
|
129
|
+
const extracted = this.mapRecord(record, mapping);
|
|
130
|
+
if (extracted)
|
|
131
|
+
results.push(extracted);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
mapErrors++;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (mapErrors > 0 && onProgress) {
|
|
138
|
+
onProgress(` Warning: ${mapErrors} record(s) skipped due to mapping errors`);
|
|
139
|
+
}
|
|
140
|
+
// Phase 4: Fetch body content per record via a separate tool (e.g. readGoogleDoc)
|
|
141
|
+
if (mapping.content_tool && results.length > 0) {
|
|
142
|
+
const ct = mapping.content_tool;
|
|
143
|
+
const total = results.length;
|
|
144
|
+
for (let i = 0; i < total; i++) {
|
|
145
|
+
const rec = results[i];
|
|
146
|
+
const rawRecord = allRawRecords[i];
|
|
147
|
+
const docId = resolveFieldPath(rawRecord, ct.id_from ?? 'id');
|
|
148
|
+
if (!docId)
|
|
149
|
+
continue;
|
|
150
|
+
try {
|
|
151
|
+
if (onProgress && (i + 1) % 10 === 0) {
|
|
152
|
+
onProgress(` Fetching content: ${i + 1}/${total}`);
|
|
153
|
+
}
|
|
154
|
+
const contentRaw = await this.client.callTool(ct.tool, {
|
|
155
|
+
[ct.id_param]: docId,
|
|
156
|
+
...ct.extra_args,
|
|
157
|
+
});
|
|
158
|
+
// Use raw text, or extract from JSON wrapper
|
|
159
|
+
let body;
|
|
160
|
+
try {
|
|
161
|
+
const parsed = JSON.parse(contentRaw);
|
|
162
|
+
body = parsed.text ?? parsed.content ?? parsed.markdown ?? contentRaw;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
body = contentRaw;
|
|
166
|
+
}
|
|
167
|
+
// Strip leading "---" (horizontal rule) which gray-matter
|
|
168
|
+
// would interpret as a second frontmatter delimiter
|
|
169
|
+
rec.content = body.replace(/^---\n/, '').trimStart();
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
// non-fatal — entity still gets metadata without body
|
|
173
|
+
if (onProgress)
|
|
174
|
+
onProgress(` Warning: content fetch failed for ${rec.entity_id} — ${err instanceof Error ? err.message : 'unknown error'}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return results;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Apply field map to one source record.
|
|
182
|
+
*/
|
|
183
|
+
mapRecord(record, mapping) {
|
|
184
|
+
if (!mapping.field_map)
|
|
185
|
+
return null;
|
|
186
|
+
const frontmatter = {
|
|
187
|
+
entity_type: mapping.entity_type,
|
|
188
|
+
};
|
|
189
|
+
// Apply field map
|
|
190
|
+
for (const [sourcePath, target] of Object.entries(mapping.field_map)) {
|
|
191
|
+
const sourceValue = this.resolveFieldPath(record, sourcePath);
|
|
192
|
+
if (sourceValue === undefined || sourceValue === null)
|
|
193
|
+
continue;
|
|
194
|
+
if (typeof target === 'string') {
|
|
195
|
+
frontmatter[target] = sourceValue;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// FieldTransform object
|
|
199
|
+
const transform = target;
|
|
200
|
+
let valueToTransform = sourceValue;
|
|
201
|
+
// Extract subfield from each array element before transforming
|
|
202
|
+
if (transform.subfield && Array.isArray(valueToTransform)) {
|
|
203
|
+
valueToTransform = valueToTransform
|
|
204
|
+
.map(item => this.resolveFieldPath(item, transform.subfield))
|
|
205
|
+
.filter(v => v !== undefined && v !== null);
|
|
206
|
+
}
|
|
207
|
+
frontmatter[transform.field] = this.applyTransform(valueToTransform, transform.transform);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Apply status map
|
|
211
|
+
if (mapping.status_map && record.status) {
|
|
212
|
+
const mappedStatus = mapping.status_map[String(record.status).toLowerCase()];
|
|
213
|
+
if (mappedStatus) {
|
|
214
|
+
frontmatter.status = mappedStatus;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Generate entity_id
|
|
218
|
+
const entityId = this.generateEntityId(record, mapping);
|
|
219
|
+
if (!entityId)
|
|
220
|
+
return null;
|
|
221
|
+
frontmatter.entity_id = entityId;
|
|
222
|
+
// Resolve content from a source field if configured
|
|
223
|
+
let content = '';
|
|
224
|
+
if (mapping.content_from) {
|
|
225
|
+
const raw = this.resolveFieldPath(record, mapping.content_from);
|
|
226
|
+
if (raw)
|
|
227
|
+
content = String(raw);
|
|
228
|
+
}
|
|
229
|
+
// Generate source ref for provenance
|
|
230
|
+
const sourceRef = `${mapping.source_type}/${record.id ?? record.ID ?? record.gid ?? entityId}`;
|
|
231
|
+
// Apply name quality penalty
|
|
232
|
+
const name = frontmatter.name ?? frontmatter.title ?? '';
|
|
233
|
+
const quality = nameQuality(String(name), mapping.entity_type);
|
|
234
|
+
const confidence = 0.9 * quality;
|
|
235
|
+
return {
|
|
236
|
+
entity_type: mapping.entity_type,
|
|
237
|
+
entity_id: entityId,
|
|
238
|
+
target_repo: mapping.target_repo,
|
|
239
|
+
frontmatter,
|
|
240
|
+
content,
|
|
241
|
+
source_name: this.sourceConfig.name,
|
|
242
|
+
source_ref: sourceRef,
|
|
243
|
+
confidence,
|
|
244
|
+
...(mapping.co_locate ? { co_locate: mapping.co_locate } : {}),
|
|
245
|
+
...(mapping.write_mode ? { write_mode: mapping.write_mode } : {}),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Resolve nested paths like "org_id.name" or "email[0].value".
|
|
250
|
+
*/
|
|
251
|
+
resolveFieldPath(record, path) {
|
|
252
|
+
return resolveFieldPath(record, path);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Generate entity_id from the id_from field.
|
|
256
|
+
*/
|
|
257
|
+
generateEntityId(record, mapping) {
|
|
258
|
+
const idField = mapping.id_from ?? 'title';
|
|
259
|
+
const raw = this.resolveFieldPath(record, idField);
|
|
260
|
+
if (!raw)
|
|
261
|
+
return null;
|
|
262
|
+
return slugify(String(raw));
|
|
263
|
+
}
|
|
264
|
+
applyTransform(value, transform) {
|
|
265
|
+
return applyTransform(value, transform);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Resolve nested field paths like "org_id.name" or "email[0].value".
|
|
270
|
+
*/
|
|
271
|
+
export function resolveFieldPath(record, path) {
|
|
272
|
+
const parts = path.split('.');
|
|
273
|
+
let current = record;
|
|
274
|
+
for (const part of parts) {
|
|
275
|
+
if (current === undefined || current === null)
|
|
276
|
+
return undefined;
|
|
277
|
+
// Handle array index: field[0]
|
|
278
|
+
const arrayMatch = part.match(/^(.+)\[(\d+)\]$/);
|
|
279
|
+
if (arrayMatch) {
|
|
280
|
+
current = current[arrayMatch[1]];
|
|
281
|
+
if (Array.isArray(current)) {
|
|
282
|
+
current = current[parseInt(arrayMatch[2], 10)];
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
current = current[part];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return current;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Apply a field transform to a value.
|
|
296
|
+
*/
|
|
297
|
+
export function applyTransform(value, transform) {
|
|
298
|
+
switch (transform) {
|
|
299
|
+
case 'direct':
|
|
300
|
+
return value;
|
|
301
|
+
case 'kebab-case':
|
|
302
|
+
return slugify(String(value));
|
|
303
|
+
case 'date-iso':
|
|
304
|
+
try {
|
|
305
|
+
return new Date(value).toISOString().split('T')[0];
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
return String(value);
|
|
309
|
+
}
|
|
310
|
+
case 'wikilink':
|
|
311
|
+
return `[[${slugify(String(value))}]]`;
|
|
312
|
+
case 'wikilink-array':
|
|
313
|
+
if (Array.isArray(value)) {
|
|
314
|
+
return value.map(v => `[[${slugify(String(v))}]]`);
|
|
315
|
+
}
|
|
316
|
+
return [`[[${slugify(String(value))}]]`];
|
|
317
|
+
default:
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Find the first array value in an object.
|
|
323
|
+
* Handles APIs that return { issues: [...] }, { projects: [...] }, etc.
|
|
324
|
+
*/
|
|
325
|
+
function findFirstArray(obj) {
|
|
326
|
+
for (const value of Object.values(obj)) {
|
|
327
|
+
if (Array.isArray(value))
|
|
328
|
+
return value;
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Convert a string to kebab-case entity ID.
|
|
334
|
+
*/
|
|
335
|
+
export function slugify(str) {
|
|
336
|
+
return str
|
|
337
|
+
.toLowerCase()
|
|
338
|
+
.replace(/&/g, 'and')
|
|
339
|
+
.replace(/[^a-z0-9\s_-]/g, '')
|
|
340
|
+
.replace(/[\s_]+/g, '-')
|
|
341
|
+
.replace(/-{2,}/g, '-')
|
|
342
|
+
.replace(/^-+|-+$/g, '');
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=structured-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured-extractor.js","sourceRoot":"","sources":["../../../src/services/sync/structured-extractor.ts"],"names":[],"mappings":"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"}
|