@c4a/server-cli 0.4.15-alpha.5 → 0.4.15-alpha.7
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/index.js +105 -17
- package/package.json +1 -1
- package/serve.js +148 -24
- package/web/assets/ContentDetail-C0zfArPg.js +1 -0
- package/web/assets/ContentDetail-DZuam1p0.js +1 -0
- package/web/assets/ContentDetail-qsl_01UW.js +1 -0
- package/web/assets/EntityDetail-BafRMdUD.js +1 -0
- package/web/assets/EntityDetail-C9k4cMVL.js +1 -0
- package/web/assets/EntityDetail-Dssp-tuW.js +1 -0
- package/web/assets/RelationDetail-BK8C5waL.js +1 -0
- package/web/assets/RelationDetail-DH86ysel.js +1 -0
- package/web/assets/RelationDetail-kDhcDsKg.js +1 -0
- package/web/assets/index-BKETuM1m.js +111 -0
- package/web/assets/index-C96WspeJ.css +1 -0
- package/web/assets/index-CMVd9rlp.js +111 -0
- package/web/assets/index-wBO4P6CB.js +111 -0
- package/web/index.html +2 -2
package/index.js
CHANGED
|
@@ -220991,6 +220991,12 @@ class LlmServiceImpl {
|
|
|
220991
220991
|
if (options?.systemPrompt) {
|
|
220992
220992
|
callSettings.system = options.systemPrompt;
|
|
220993
220993
|
}
|
|
220994
|
+
if (options?.jsonMode) {
|
|
220995
|
+
callSettings.providerOptions = {
|
|
220996
|
+
openai: { responseFormat: { type: "json_object" } },
|
|
220997
|
+
anthropic: { responseFormat: { type: "json_object" } }
|
|
220998
|
+
};
|
|
220999
|
+
}
|
|
220994
221000
|
const result = await retry(() => generateText(callSettings), {
|
|
220995
221001
|
shouldRetry: (error40) => isRetryableStatus(getHttpStatus(error40)) || isTimeoutError2(error40)
|
|
220996
221002
|
});
|
|
@@ -221038,6 +221044,12 @@ class LlmServiceImpl {
|
|
|
221038
221044
|
if (options?.systemPrompt) {
|
|
221039
221045
|
callSettings.system = options.systemPrompt;
|
|
221040
221046
|
}
|
|
221047
|
+
if (options?.jsonMode) {
|
|
221048
|
+
callSettings.providerOptions = {
|
|
221049
|
+
openai: { responseFormat: { type: "json_object" } },
|
|
221050
|
+
anthropic: { responseFormat: { type: "json_object" } }
|
|
221051
|
+
};
|
|
221052
|
+
}
|
|
221041
221053
|
const result = await retry(() => Promise.resolve(streamText(callSettings)), {
|
|
221042
221054
|
shouldRetry: (error40) => isRetryableStatus(getHttpStatus(error40)) || isTimeoutError2(error40)
|
|
221043
221055
|
});
|
|
@@ -221856,6 +221868,7 @@ function parseExtractionOutput(raw, schema) {
|
|
|
221856
221868
|
}
|
|
221857
221869
|
parsed = normalizeFlatOutput(parsed);
|
|
221858
221870
|
parsed = stripNulls(parsed);
|
|
221871
|
+
parsed = patchAttributeDefaults(parsed);
|
|
221859
221872
|
const result = schema.safeParse(parsed);
|
|
221860
221873
|
if (!result.success) {
|
|
221861
221874
|
return { success: false, error: result.error };
|
|
@@ -221923,7 +221936,37 @@ function tryParseJson(raw) {
|
|
|
221923
221936
|
return repairAndParse(raw);
|
|
221924
221937
|
}
|
|
221925
221938
|
function repairAndParse(raw) {
|
|
221926
|
-
|
|
221939
|
+
try {
|
|
221940
|
+
return JSON.parse(jsonrepair(raw));
|
|
221941
|
+
} catch {
|
|
221942
|
+
const truncated = truncateToLastCompleteEntry(raw);
|
|
221943
|
+
if (truncated) {
|
|
221944
|
+
return JSON.parse(jsonrepair(truncated));
|
|
221945
|
+
}
|
|
221946
|
+
throw new Error(`JSON repair failed for output of length ${raw.length}`);
|
|
221947
|
+
}
|
|
221948
|
+
}
|
|
221949
|
+
function truncateToLastCompleteEntry(raw) {
|
|
221950
|
+
let text2 = raw.trim();
|
|
221951
|
+
if (text2.startsWith("```")) {
|
|
221952
|
+
const firstNewline = text2.indexOf(`
|
|
221953
|
+
`);
|
|
221954
|
+
text2 = text2.slice(firstNewline + 1);
|
|
221955
|
+
}
|
|
221956
|
+
if (text2.endsWith("```")) {
|
|
221957
|
+
text2 = text2.slice(0, -3);
|
|
221958
|
+
}
|
|
221959
|
+
const pattern = /\}\s*,\s*"P\d+"/g;
|
|
221960
|
+
let lastMatch = null;
|
|
221961
|
+
let m;
|
|
221962
|
+
while ((m = pattern.exec(text2)) !== null) {
|
|
221963
|
+
lastMatch = m;
|
|
221964
|
+
}
|
|
221965
|
+
if (!lastMatch)
|
|
221966
|
+
return null;
|
|
221967
|
+
const cutPos = lastMatch.index + 1;
|
|
221968
|
+
const truncated = text2.slice(0, cutPos) + "}";
|
|
221969
|
+
return truncated;
|
|
221927
221970
|
}
|
|
221928
221971
|
var PARAGRAPH_TAG_RE = /^P\d+$/;
|
|
221929
221972
|
function normalizeFlatOutput(parsed) {
|
|
@@ -221956,6 +221999,43 @@ function stripNulls(value) {
|
|
|
221956
221999
|
}
|
|
221957
222000
|
return value;
|
|
221958
222001
|
}
|
|
222002
|
+
function patchAttributeDefaults(value) {
|
|
222003
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
222004
|
+
return value;
|
|
222005
|
+
const obj = value;
|
|
222006
|
+
if ("paragraphs" in obj && Array.isArray(obj.paragraphs)) {
|
|
222007
|
+
return {
|
|
222008
|
+
...obj,
|
|
222009
|
+
paragraphs: obj.paragraphs.map((p) => {
|
|
222010
|
+
if (!p || typeof p !== "object")
|
|
222011
|
+
return p;
|
|
222012
|
+
const para = p;
|
|
222013
|
+
const atoms2 = para.atoms;
|
|
222014
|
+
if (!atoms2 || typeof atoms2 !== "object")
|
|
222015
|
+
return p;
|
|
222016
|
+
return { ...para, atoms: patchAttrsInAtoms(atoms2) };
|
|
222017
|
+
})
|
|
222018
|
+
};
|
|
222019
|
+
}
|
|
222020
|
+
return value;
|
|
222021
|
+
}
|
|
222022
|
+
function patchAttrsInAtoms(atoms2) {
|
|
222023
|
+
const attrs = atoms2.attributes;
|
|
222024
|
+
if (!Array.isArray(attrs))
|
|
222025
|
+
return atoms2;
|
|
222026
|
+
return {
|
|
222027
|
+
...atoms2,
|
|
222028
|
+
attributes: attrs.map((attr) => {
|
|
222029
|
+
if (!attr || typeof attr !== "object" || Array.isArray(attr))
|
|
222030
|
+
return attr;
|
|
222031
|
+
const a = attr;
|
|
222032
|
+
if (typeof a.type !== "string" || a.type === "") {
|
|
222033
|
+
return { ...a, type: "other" };
|
|
222034
|
+
}
|
|
222035
|
+
return attr;
|
|
222036
|
+
})
|
|
222037
|
+
};
|
|
222038
|
+
}
|
|
221959
222039
|
function isRecord(value) {
|
|
221960
222040
|
return !!value && typeof value === "object" && "key" in value && "value" in value && typeof value.key === "string";
|
|
221961
222041
|
}
|
|
@@ -222212,20 +222292,20 @@ class GleaningExtractor {
|
|
|
222212
222292
|
// ../llm/src/prompts/docAtomAnnotation.ts
|
|
222213
222293
|
init_src();
|
|
222214
222294
|
var DOC_ATOM_DEFS = [
|
|
222215
|
-
["entities", "Named things: systems, services, modules,
|
|
222295
|
+
["entities", "Named things with independent identity — something you can ask questions about ('What does X do?', 'Who owns X?'). Examples: systems, services, modules, APIs, products. If it is a value, address, path, or configuration detail, it is an attribute of an entity, not an entity itself. (NOT people/teams — use roles for those). kind: implementation=internal systems/services, external=third-party dependencies, concept=abstract/not-yet-implemented", entityAtomSchema],
|
|
222216
222296
|
["relations", "Connections between entities", relationAtomSchema],
|
|
222217
222297
|
["behaviors", "Actions/operations: functions, API calls, user actions, workflows", behaviorAtomSchema],
|
|
222218
222298
|
["attributes", "Properties of entities", attributeAtomSchema],
|
|
222219
222299
|
["states", "Possible states of entities", stateAtomSchema],
|
|
222220
|
-
["rules", "
|
|
222300
|
+
["rules", "Conditional business/domain logic: IF condition THEN consequence (e.g., 'IF user not authenticated THEN reject request')", ruleAtomSchema],
|
|
222221
222301
|
["transitions", "State changes: from→to triggered by events or guards", transitionAtomSchema],
|
|
222222
222302
|
["events", "Occurrences that trigger behaviors", eventAtomSchema],
|
|
222223
222303
|
["decisions", "Architectural or business decisions", decisionAtomSchema],
|
|
222224
222304
|
["metrics", "Measurable targets: SLA, throughput, error_rate, with thresholds", metricAtomSchema],
|
|
222225
|
-
["roles", "Actors: human roles, teams, personas that perform behaviors", roleAtomSchema],
|
|
222226
|
-
["constraints", "
|
|
222305
|
+
["roles", "Actors: human roles, teams, personas that perform behaviors. kind: human=individual role, team=group/department, persona=user archetype. System-triggered actions use entity relations, NOT roles", roleAtomSchema],
|
|
222306
|
+
["constraints", "Declarative requirements: 'X must/should/must-not Y' (e.g., 'passwords must be >= 8 chars'). Unlike rules, constraints have no IF-THEN condition — they are unconditional mandates or restrictions", constraintAtomSchema],
|
|
222227
222307
|
["comparisons", "Side-by-side evaluations", comparisonAtomSchema],
|
|
222228
|
-
["boundaries", "
|
|
222308
|
+
["boundaries", "Explicit scope declarations: what is included vs excluded. Only extract when the text explicitly declares scope (e.g., 'this product covers X but NOT Y'). Implicit containment (A runs inside B) is expressed via entity relations, not boundaries", boundaryAtomSchema]
|
|
222229
222309
|
];
|
|
222230
222310
|
function buildAtomTypesBlock() {
|
|
222231
222311
|
return DOC_ATOM_DEFS.map(([name21, desc, schema], i) => {
|
|
@@ -222255,7 +222335,8 @@ Return a single JSON object keyed by paragraph tags. Only include paragraphs tha
|
|
|
222255
222335
|
"relations": [{ "from": "UserService", "to": "Database", "type": "DEPENDS_ON", "confidence": 0.9 }]
|
|
222256
222336
|
},
|
|
222257
222337
|
"P3": {
|
|
222258
|
-
"
|
|
222338
|
+
"constraints": [{ "description": "User must be authenticated before access", "severity": "must", "confidence": 0.9 }],
|
|
222339
|
+
"rules": [{ "description": "Reject request if user is not authenticated", "expression": "IF !user.isAuthenticated THEN reject", "confidence": 0.85 }]
|
|
222259
222340
|
}
|
|
222260
222341
|
}
|
|
222261
222342
|
|
|
@@ -222267,7 +222348,13 @@ Return a single JSON object keyed by paragraph tags. Only include paragraphs tha
|
|
|
222267
222348
|
- **Enum fields MUST use ONLY the listed values.** For example, entity.kind must be one of "implementation"|"external"|"concept" — do NOT use values from other atom types (e.g., do NOT put "team" or "human" in entity.kind; those belong to roles.kind).
|
|
222268
222349
|
- Every atom MUST include a "confidence" field (0.0-1.0) indicating how confident you are in the extraction. Use higher values (0.85-1.0) for explicitly stated facts and lower values (0.5-0.7) for inferred or ambiguous information.
|
|
222269
222350
|
- **Classify correctly:** People, teams, and personas → "roles" (not "entities"). Technical systems, services, modules → "entities".
|
|
222351
|
+
- **Entity naming — extract the subject, not the document:** Entity names should represent the actual system/product/framework being described, not the document itself. If the text says "Next.js is a React framework", the entity is "Next.js" — not "Next.js 官方文档" or "Next.js API 参考". Use names that work as standalone knowledge graph nodes, independent of any document context.
|
|
222270
222352
|
- **Entity reference consistency (CRITICAL):** Every entity name referenced in relation.from, relation.to, behavior.subject, or any other cross-reference field MUST also appear in the "entities" array of the SAME paragraph (or a preceding paragraph in the same chunk). If an entity is mentioned for the first time in a relation, you MUST also extract it as an entity. This ensures no "dangling references" — every name used in relations has a corresponding entity declaration.
|
|
222353
|
+
- **Cross-atom reference consistency:** transitions[].from and transitions[].to values MUST exist in states[].values of the same entity. roles[].performs values MUST match names declared in behaviors[].name.
|
|
222354
|
+
- **Constraints vs rules distinction:** Use "constraints" for unconditional declarative mandates ('X must Y'). Use "rules" for conditional logic ('IF X THEN Y'). Do not mix them — a requirement with no condition is a constraint, a requirement triggered by a condition is a rule. Do NOT invent a rule for every constraint — only create a rule when the text explicitly states conditional logic.
|
|
222355
|
+
- **One statement, multiple atoms:** A single sentence can produce several atom types simultaneously. Do NOT force a choice — extract all that apply. Example: "system uptime must be ≥ 99.9%" → constraint (severity: must) + metric (threshold: "≥ 99.9%").
|
|
222356
|
+
- **Relation types:** Use standard relation types when possible: CONTAINS (parent→child composition), DEPENDS_ON (runtime dependency), IMPLEMENTS (code/component→spec realization), PRODUCES (process→output), TRIGGERS (event/process triggering), REFERENCES (weak cross-reference). Only invent a new type when none of these fit.
|
|
222357
|
+
- **Decisions:** Extract as "decisions" when the text records a deliberate choice between alternatives with rationale (e.g., "we chose X because Y", "after evaluating A/B/C, selected B"). Do not extract routine descriptions as decisions.
|
|
222271
222358
|
- Respond in the same language as the input text (e.g., Chinese input → Chinese descriptions, English input → English descriptions).
|
|
222272
222359
|
- JSON structure keys (tag, atom type names, field names) must always be in English.
|
|
222273
222360
|
- Be thorough: extract ALL relevant atoms from each paragraph.
|
|
@@ -222321,14 +222408,15 @@ var ENTITY_RESOLUTION_SYSTEM_PROMPT = `You are an entity resolution assistant. Y
|
|
|
222321
222408
|
- Prefer the LONGER, more descriptive name as the canonical name
|
|
222322
222409
|
- Do NOT merge names that share a substring but refer to different things
|
|
222323
222410
|
- When uncertain, do NOT merge — add to "ambiguous" instead
|
|
222324
|
-
- Chinese and English names for the same entity SHOULD be merged (e.g. "
|
|
222325
|
-
- Abbreviations should be merged with their full forms (e.g. "
|
|
222411
|
+
- Chinese and English names for the same entity SHOULD be merged (e.g. "Webpack" → "Webpack 打包工具")
|
|
222412
|
+
- Abbreviations should be merged with their full forms (e.g. "K8s" → "Kubernetes")
|
|
222413
|
+
- Document-descriptive names (containing "文档", "参考", "指南" etc.) should be merged to the actual product/system name. The entity is the product, not the document about it
|
|
222326
222414
|
|
|
222327
222415
|
## Task 2: Remove Noise
|
|
222328
|
-
-
|
|
222329
|
-
-
|
|
222330
|
-
- Examples of REAL entities to KEEP: product names (
|
|
222331
|
-
- When uncertain, KEEP the name — only remove if clearly
|
|
222416
|
+
- Apply the **identity test**: a real entity is something you can discuss independently ("What is X?", "How does X work?", "Who owns X?"). Names that fail this test — values, addresses, actions, generic descriptions — are noise.
|
|
222417
|
+
- Remove names that are NOT meaningful named entities: generic words, action descriptions, or things that are attributes/values rather than independent subjects
|
|
222418
|
+
- Examples of REAL entities to KEEP: product names (Next.js, Vite), tools (nvm, Turborepo), services (Nginx, Redis), platforms (Kubernetes, Docker) — these all pass the identity test
|
|
222419
|
+
- When uncertain, KEEP the name — only remove if it clearly fails the identity test
|
|
222332
222420
|
|
|
222333
222421
|
## Output
|
|
222334
222422
|
Valid JSON only. No markdown fences, no explanation.`;
|
|
@@ -222571,7 +222659,7 @@ Each diagram paragraph is tagged with [P0], [P1], etc. You must classify the dia
|
|
|
222571
222659
|
Relation schema: ${relationFields2}
|
|
222572
222660
|
3. Extract action nodes as behaviors (what the process does at each step).
|
|
222573
222661
|
Behavior schema: ${behaviorFields2}
|
|
222574
|
-
4. Extract diamond/
|
|
222662
|
+
4. Extract diamond/condition nodes: if it represents a deliberate choice with rationale → "decisions"; if it represents conditional branching logic (IF-THEN) → "rules".
|
|
222575
222663
|
Decision schema: ${decisionFields}
|
|
222576
222664
|
|
|
222577
222665
|
### Sequence → entities + relations + behaviors + events
|
|
@@ -222604,9 +222692,9 @@ Each diagram paragraph is tagged with [P0], [P1], etc. You must classify the dia
|
|
|
222604
222692
|
Relation schema: ${relationFields2}
|
|
222605
222693
|
|
|
222606
222694
|
### Architecture → entities + relations + constraints
|
|
222607
|
-
1. Extract each system/service/container/component as an entity.
|
|
222695
|
+
1. Extract each system/service/container/component as an entity. Use kind to indicate origin: "implementation" for internal systems/services, "external" for third-party dependencies (databases, cloud services, external APIs).
|
|
222608
222696
|
Entity schema: ${entityFields2}
|
|
222609
|
-
2. Extract connections between components as relations.
|
|
222697
|
+
2. Extract connections between components as relations. Use standard types: CONTAINS (parent→child), DEPENDS_ON (runtime dependency), TRIGGERS (event/process triggering).
|
|
222610
222698
|
Relation schema: ${relationFields2}
|
|
222611
222699
|
3. Extract deployment constraints, technology choices.
|
|
222612
222700
|
Constraint schema: ${constraintFields2}
|
|
@@ -222668,7 +222756,7 @@ Return ONLY a valid JSON object. No markdown fences, no explanation.`;
|
|
|
222668
222756
|
}
|
|
222669
222757
|
var DOC_DIAGRAM_ANNOTATION_SYSTEM_PROMPT = DIAGRAM_SYSTEM_PROMPT;
|
|
222670
222758
|
// ../llm/src/chunking/markdownChunker.ts
|
|
222671
|
-
var DEFAULT_MAX_TOKENS2 =
|
|
222759
|
+
var DEFAULT_MAX_TOKENS2 = 3600;
|
|
222672
222760
|
var DEFAULT_PARAGRAPH_MAX_TOKENS = 500;
|
|
222673
222761
|
function estimateTokens(text2) {
|
|
222674
222762
|
return Math.ceil(text2.length / 4);
|
package/package.json
CHANGED
package/serve.js
CHANGED
|
@@ -194996,6 +194996,12 @@ class LlmServiceImpl {
|
|
|
194996
194996
|
if (options?.systemPrompt) {
|
|
194997
194997
|
callSettings.system = options.systemPrompt;
|
|
194998
194998
|
}
|
|
194999
|
+
if (options?.jsonMode) {
|
|
195000
|
+
callSettings.providerOptions = {
|
|
195001
|
+
openai: { responseFormat: { type: "json_object" } },
|
|
195002
|
+
anthropic: { responseFormat: { type: "json_object" } }
|
|
195003
|
+
};
|
|
195004
|
+
}
|
|
194999
195005
|
const result = await retry(() => generateText(callSettings), {
|
|
195000
195006
|
shouldRetry: (error40) => isRetryableStatus(getHttpStatus(error40)) || isTimeoutError2(error40)
|
|
195001
195007
|
});
|
|
@@ -195043,6 +195049,12 @@ class LlmServiceImpl {
|
|
|
195043
195049
|
if (options?.systemPrompt) {
|
|
195044
195050
|
callSettings.system = options.systemPrompt;
|
|
195045
195051
|
}
|
|
195052
|
+
if (options?.jsonMode) {
|
|
195053
|
+
callSettings.providerOptions = {
|
|
195054
|
+
openai: { responseFormat: { type: "json_object" } },
|
|
195055
|
+
anthropic: { responseFormat: { type: "json_object" } }
|
|
195056
|
+
};
|
|
195057
|
+
}
|
|
195046
195058
|
const result = await retry(() => Promise.resolve(streamText(callSettings)), {
|
|
195047
195059
|
shouldRetry: (error40) => isRetryableStatus(getHttpStatus(error40)) || isTimeoutError2(error40)
|
|
195048
195060
|
});
|
|
@@ -195861,6 +195873,7 @@ function parseExtractionOutput(raw5, schema2) {
|
|
|
195861
195873
|
}
|
|
195862
195874
|
parsed = normalizeFlatOutput(parsed);
|
|
195863
195875
|
parsed = stripNulls(parsed);
|
|
195876
|
+
parsed = patchAttributeDefaults(parsed);
|
|
195864
195877
|
const result = schema2.safeParse(parsed);
|
|
195865
195878
|
if (!result.success) {
|
|
195866
195879
|
return { success: false, error: result.error };
|
|
@@ -195928,7 +195941,37 @@ function tryParseJson(raw5) {
|
|
|
195928
195941
|
return repairAndParse(raw5);
|
|
195929
195942
|
}
|
|
195930
195943
|
function repairAndParse(raw5) {
|
|
195931
|
-
|
|
195944
|
+
try {
|
|
195945
|
+
return JSON.parse(jsonrepair(raw5));
|
|
195946
|
+
} catch {
|
|
195947
|
+
const truncated = truncateToLastCompleteEntry(raw5);
|
|
195948
|
+
if (truncated) {
|
|
195949
|
+
return JSON.parse(jsonrepair(truncated));
|
|
195950
|
+
}
|
|
195951
|
+
throw new Error(`JSON repair failed for output of length ${raw5.length}`);
|
|
195952
|
+
}
|
|
195953
|
+
}
|
|
195954
|
+
function truncateToLastCompleteEntry(raw5) {
|
|
195955
|
+
let text2 = raw5.trim();
|
|
195956
|
+
if (text2.startsWith("```")) {
|
|
195957
|
+
const firstNewline = text2.indexOf(`
|
|
195958
|
+
`);
|
|
195959
|
+
text2 = text2.slice(firstNewline + 1);
|
|
195960
|
+
}
|
|
195961
|
+
if (text2.endsWith("```")) {
|
|
195962
|
+
text2 = text2.slice(0, -3);
|
|
195963
|
+
}
|
|
195964
|
+
const pattern = /\}\s*,\s*"P\d+"/g;
|
|
195965
|
+
let lastMatch = null;
|
|
195966
|
+
let m;
|
|
195967
|
+
while ((m = pattern.exec(text2)) !== null) {
|
|
195968
|
+
lastMatch = m;
|
|
195969
|
+
}
|
|
195970
|
+
if (!lastMatch)
|
|
195971
|
+
return null;
|
|
195972
|
+
const cutPos = lastMatch.index + 1;
|
|
195973
|
+
const truncated = text2.slice(0, cutPos) + "}";
|
|
195974
|
+
return truncated;
|
|
195932
195975
|
}
|
|
195933
195976
|
var PARAGRAPH_TAG_RE = /^P\d+$/;
|
|
195934
195977
|
function normalizeFlatOutput(parsed) {
|
|
@@ -195961,6 +196004,43 @@ function stripNulls(value) {
|
|
|
195961
196004
|
}
|
|
195962
196005
|
return value;
|
|
195963
196006
|
}
|
|
196007
|
+
function patchAttributeDefaults(value) {
|
|
196008
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
196009
|
+
return value;
|
|
196010
|
+
const obj = value;
|
|
196011
|
+
if ("paragraphs" in obj && Array.isArray(obj.paragraphs)) {
|
|
196012
|
+
return {
|
|
196013
|
+
...obj,
|
|
196014
|
+
paragraphs: obj.paragraphs.map((p4) => {
|
|
196015
|
+
if (!p4 || typeof p4 !== "object")
|
|
196016
|
+
return p4;
|
|
196017
|
+
const para = p4;
|
|
196018
|
+
const atoms2 = para.atoms;
|
|
196019
|
+
if (!atoms2 || typeof atoms2 !== "object")
|
|
196020
|
+
return p4;
|
|
196021
|
+
return { ...para, atoms: patchAttrsInAtoms(atoms2) };
|
|
196022
|
+
})
|
|
196023
|
+
};
|
|
196024
|
+
}
|
|
196025
|
+
return value;
|
|
196026
|
+
}
|
|
196027
|
+
function patchAttrsInAtoms(atoms2) {
|
|
196028
|
+
const attrs = atoms2.attributes;
|
|
196029
|
+
if (!Array.isArray(attrs))
|
|
196030
|
+
return atoms2;
|
|
196031
|
+
return {
|
|
196032
|
+
...atoms2,
|
|
196033
|
+
attributes: attrs.map((attr) => {
|
|
196034
|
+
if (!attr || typeof attr !== "object" || Array.isArray(attr))
|
|
196035
|
+
return attr;
|
|
196036
|
+
const a = attr;
|
|
196037
|
+
if (typeof a.type !== "string" || a.type === "") {
|
|
196038
|
+
return { ...a, type: "other" };
|
|
196039
|
+
}
|
|
196040
|
+
return attr;
|
|
196041
|
+
})
|
|
196042
|
+
};
|
|
196043
|
+
}
|
|
195964
196044
|
function isRecord(value) {
|
|
195965
196045
|
return !!value && typeof value === "object" && "key" in value && "value" in value && typeof value.key === "string";
|
|
195966
196046
|
}
|
|
@@ -196217,20 +196297,20 @@ class GleaningExtractor {
|
|
|
196217
196297
|
// ../llm/src/prompts/docAtomAnnotation.ts
|
|
196218
196298
|
init_src();
|
|
196219
196299
|
var DOC_ATOM_DEFS = [
|
|
196220
|
-
["entities", "Named things: systems, services, modules,
|
|
196300
|
+
["entities", "Named things with independent identity — something you can ask questions about ('What does X do?', 'Who owns X?'). Examples: systems, services, modules, APIs, products. If it is a value, address, path, or configuration detail, it is an attribute of an entity, not an entity itself. (NOT people/teams — use roles for those). kind: implementation=internal systems/services, external=third-party dependencies, concept=abstract/not-yet-implemented", entityAtomSchema],
|
|
196221
196301
|
["relations", "Connections between entities", relationAtomSchema],
|
|
196222
196302
|
["behaviors", "Actions/operations: functions, API calls, user actions, workflows", behaviorAtomSchema],
|
|
196223
196303
|
["attributes", "Properties of entities", attributeAtomSchema],
|
|
196224
196304
|
["states", "Possible states of entities", stateAtomSchema],
|
|
196225
|
-
["rules", "
|
|
196305
|
+
["rules", "Conditional business/domain logic: IF condition THEN consequence (e.g., 'IF user not authenticated THEN reject request')", ruleAtomSchema],
|
|
196226
196306
|
["transitions", "State changes: from→to triggered by events or guards", transitionAtomSchema],
|
|
196227
196307
|
["events", "Occurrences that trigger behaviors", eventAtomSchema],
|
|
196228
196308
|
["decisions", "Architectural or business decisions", decisionAtomSchema],
|
|
196229
196309
|
["metrics", "Measurable targets: SLA, throughput, error_rate, with thresholds", metricAtomSchema],
|
|
196230
|
-
["roles", "Actors: human roles, teams, personas that perform behaviors", roleAtomSchema],
|
|
196231
|
-
["constraints", "
|
|
196310
|
+
["roles", "Actors: human roles, teams, personas that perform behaviors. kind: human=individual role, team=group/department, persona=user archetype. System-triggered actions use entity relations, NOT roles", roleAtomSchema],
|
|
196311
|
+
["constraints", "Declarative requirements: 'X must/should/must-not Y' (e.g., 'passwords must be >= 8 chars'). Unlike rules, constraints have no IF-THEN condition — they are unconditional mandates or restrictions", constraintAtomSchema],
|
|
196232
196312
|
["comparisons", "Side-by-side evaluations", comparisonAtomSchema],
|
|
196233
|
-
["boundaries", "
|
|
196313
|
+
["boundaries", "Explicit scope declarations: what is included vs excluded. Only extract when the text explicitly declares scope (e.g., 'this product covers X but NOT Y'). Implicit containment (A runs inside B) is expressed via entity relations, not boundaries", boundaryAtomSchema]
|
|
196234
196314
|
];
|
|
196235
196315
|
function buildAtomTypesBlock() {
|
|
196236
196316
|
return DOC_ATOM_DEFS.map(([name21, desc, schema2], i) => {
|
|
@@ -196260,7 +196340,8 @@ Return a single JSON object keyed by paragraph tags. Only include paragraphs tha
|
|
|
196260
196340
|
"relations": [{ "from": "UserService", "to": "Database", "type": "DEPENDS_ON", "confidence": 0.9 }]
|
|
196261
196341
|
},
|
|
196262
196342
|
"P3": {
|
|
196263
|
-
"
|
|
196343
|
+
"constraints": [{ "description": "User must be authenticated before access", "severity": "must", "confidence": 0.9 }],
|
|
196344
|
+
"rules": [{ "description": "Reject request if user is not authenticated", "expression": "IF !user.isAuthenticated THEN reject", "confidence": 0.85 }]
|
|
196264
196345
|
}
|
|
196265
196346
|
}
|
|
196266
196347
|
|
|
@@ -196272,7 +196353,13 @@ Return a single JSON object keyed by paragraph tags. Only include paragraphs tha
|
|
|
196272
196353
|
- **Enum fields MUST use ONLY the listed values.** For example, entity.kind must be one of "implementation"|"external"|"concept" — do NOT use values from other atom types (e.g., do NOT put "team" or "human" in entity.kind; those belong to roles.kind).
|
|
196273
196354
|
- Every atom MUST include a "confidence" field (0.0-1.0) indicating how confident you are in the extraction. Use higher values (0.85-1.0) for explicitly stated facts and lower values (0.5-0.7) for inferred or ambiguous information.
|
|
196274
196355
|
- **Classify correctly:** People, teams, and personas → "roles" (not "entities"). Technical systems, services, modules → "entities".
|
|
196356
|
+
- **Entity naming — extract the subject, not the document:** Entity names should represent the actual system/product/framework being described, not the document itself. If the text says "Next.js is a React framework", the entity is "Next.js" — not "Next.js 官方文档" or "Next.js API 参考". Use names that work as standalone knowledge graph nodes, independent of any document context.
|
|
196275
196357
|
- **Entity reference consistency (CRITICAL):** Every entity name referenced in relation.from, relation.to, behavior.subject, or any other cross-reference field MUST also appear in the "entities" array of the SAME paragraph (or a preceding paragraph in the same chunk). If an entity is mentioned for the first time in a relation, you MUST also extract it as an entity. This ensures no "dangling references" — every name used in relations has a corresponding entity declaration.
|
|
196358
|
+
- **Cross-atom reference consistency:** transitions[].from and transitions[].to values MUST exist in states[].values of the same entity. roles[].performs values MUST match names declared in behaviors[].name.
|
|
196359
|
+
- **Constraints vs rules distinction:** Use "constraints" for unconditional declarative mandates ('X must Y'). Use "rules" for conditional logic ('IF X THEN Y'). Do not mix them — a requirement with no condition is a constraint, a requirement triggered by a condition is a rule. Do NOT invent a rule for every constraint — only create a rule when the text explicitly states conditional logic.
|
|
196360
|
+
- **One statement, multiple atoms:** A single sentence can produce several atom types simultaneously. Do NOT force a choice — extract all that apply. Example: "system uptime must be ≥ 99.9%" → constraint (severity: must) + metric (threshold: "≥ 99.9%").
|
|
196361
|
+
- **Relation types:** Use standard relation types when possible: CONTAINS (parent→child composition), DEPENDS_ON (runtime dependency), IMPLEMENTS (code/component→spec realization), PRODUCES (process→output), TRIGGERS (event/process triggering), REFERENCES (weak cross-reference). Only invent a new type when none of these fit.
|
|
196362
|
+
- **Decisions:** Extract as "decisions" when the text records a deliberate choice between alternatives with rationale (e.g., "we chose X because Y", "after evaluating A/B/C, selected B"). Do not extract routine descriptions as decisions.
|
|
196276
196363
|
- Respond in the same language as the input text (e.g., Chinese input → Chinese descriptions, English input → English descriptions).
|
|
196277
196364
|
- JSON structure keys (tag, atom type names, field names) must always be in English.
|
|
196278
196365
|
- Be thorough: extract ALL relevant atoms from each paragraph.
|
|
@@ -196326,14 +196413,15 @@ var ENTITY_RESOLUTION_SYSTEM_PROMPT = `You are an entity resolution assistant. Y
|
|
|
196326
196413
|
- Prefer the LONGER, more descriptive name as the canonical name
|
|
196327
196414
|
- Do NOT merge names that share a substring but refer to different things
|
|
196328
196415
|
- When uncertain, do NOT merge — add to "ambiguous" instead
|
|
196329
|
-
- Chinese and English names for the same entity SHOULD be merged (e.g. "
|
|
196330
|
-
- Abbreviations should be merged with their full forms (e.g. "
|
|
196416
|
+
- Chinese and English names for the same entity SHOULD be merged (e.g. "Webpack" → "Webpack 打包工具")
|
|
196417
|
+
- Abbreviations should be merged with their full forms (e.g. "K8s" → "Kubernetes")
|
|
196418
|
+
- Document-descriptive names (containing "文档", "参考", "指南" etc.) should be merged to the actual product/system name. The entity is the product, not the document about it
|
|
196331
196419
|
|
|
196332
196420
|
## Task 2: Remove Noise
|
|
196333
|
-
-
|
|
196334
|
-
-
|
|
196335
|
-
- Examples of REAL entities to KEEP: product names (
|
|
196336
|
-
- When uncertain, KEEP the name — only remove if clearly
|
|
196421
|
+
- Apply the **identity test**: a real entity is something you can discuss independently ("What is X?", "How does X work?", "Who owns X?"). Names that fail this test — values, addresses, actions, generic descriptions — are noise.
|
|
196422
|
+
- Remove names that are NOT meaningful named entities: generic words, action descriptions, or things that are attributes/values rather than independent subjects
|
|
196423
|
+
- Examples of REAL entities to KEEP: product names (Next.js, Vite), tools (nvm, Turborepo), services (Nginx, Redis), platforms (Kubernetes, Docker) — these all pass the identity test
|
|
196424
|
+
- When uncertain, KEEP the name — only remove if it clearly fails the identity test
|
|
196337
196425
|
|
|
196338
196426
|
## Output
|
|
196339
196427
|
Valid JSON only. No markdown fences, no explanation.`;
|
|
@@ -196576,7 +196664,7 @@ Each diagram paragraph is tagged with [P0], [P1], etc. You must classify the dia
|
|
|
196576
196664
|
Relation schema: ${relationFields2}
|
|
196577
196665
|
3. Extract action nodes as behaviors (what the process does at each step).
|
|
196578
196666
|
Behavior schema: ${behaviorFields2}
|
|
196579
|
-
4. Extract diamond/
|
|
196667
|
+
4. Extract diamond/condition nodes: if it represents a deliberate choice with rationale → "decisions"; if it represents conditional branching logic (IF-THEN) → "rules".
|
|
196580
196668
|
Decision schema: ${decisionFields}
|
|
196581
196669
|
|
|
196582
196670
|
### Sequence → entities + relations + behaviors + events
|
|
@@ -196609,9 +196697,9 @@ Each diagram paragraph is tagged with [P0], [P1], etc. You must classify the dia
|
|
|
196609
196697
|
Relation schema: ${relationFields2}
|
|
196610
196698
|
|
|
196611
196699
|
### Architecture → entities + relations + constraints
|
|
196612
|
-
1. Extract each system/service/container/component as an entity.
|
|
196700
|
+
1. Extract each system/service/container/component as an entity. Use kind to indicate origin: "implementation" for internal systems/services, "external" for third-party dependencies (databases, cloud services, external APIs).
|
|
196613
196701
|
Entity schema: ${entityFields2}
|
|
196614
|
-
2. Extract connections between components as relations.
|
|
196702
|
+
2. Extract connections between components as relations. Use standard types: CONTAINS (parent→child), DEPENDS_ON (runtime dependency), TRIGGERS (event/process triggering).
|
|
196615
196703
|
Relation schema: ${relationFields2}
|
|
196616
196704
|
3. Extract deployment constraints, technology choices.
|
|
196617
196705
|
Constraint schema: ${constraintFields2}
|
|
@@ -196673,7 +196761,7 @@ Return ONLY a valid JSON object. No markdown fences, no explanation.`;
|
|
|
196673
196761
|
}
|
|
196674
196762
|
var DOC_DIAGRAM_ANNOTATION_SYSTEM_PROMPT = DIAGRAM_SYSTEM_PROMPT;
|
|
196675
196763
|
// ../llm/src/chunking/markdownChunker.ts
|
|
196676
|
-
var DEFAULT_MAX_TOKENS2 =
|
|
196764
|
+
var DEFAULT_MAX_TOKENS2 = 3600;
|
|
196677
196765
|
var DEFAULT_PARAGRAPH_MAX_TOKENS = 500;
|
|
196678
196766
|
function estimateTokens(text2) {
|
|
196679
196767
|
return Math.ceil(text2.length / 4);
|
|
@@ -197598,7 +197686,8 @@ async function extractTableAtoms(chunk, sections, result, llmService) {
|
|
|
197598
197686
|
const prompt = buildDocTableAnnotationPrompt(tableText);
|
|
197599
197687
|
try {
|
|
197600
197688
|
const res = await llmService.generateText(prompt, {
|
|
197601
|
-
systemPrompt: DOC_TABLE_ANNOTATION_SYSTEM_PROMPT
|
|
197689
|
+
systemPrompt: DOC_TABLE_ANNOTATION_SYSTEM_PROMPT,
|
|
197690
|
+
jsonMode: true
|
|
197602
197691
|
});
|
|
197603
197692
|
const parsed = parseExtractionOutput(res.text, docChunkResultSchema);
|
|
197604
197693
|
if (!parsed.success) {
|
|
@@ -197690,7 +197779,8 @@ async function extractDiagramAtoms(chunk, sections, result, llmService) {
|
|
|
197690
197779
|
const prompt = buildDocDiagramAnnotationPrompt(diagramText);
|
|
197691
197780
|
try {
|
|
197692
197781
|
const res = await llmService.generateText(prompt, {
|
|
197693
|
-
systemPrompt: DOC_DIAGRAM_ANNOTATION_SYSTEM_PROMPT
|
|
197782
|
+
systemPrompt: DOC_DIAGRAM_ANNOTATION_SYSTEM_PROMPT,
|
|
197783
|
+
jsonMode: true
|
|
197694
197784
|
});
|
|
197695
197785
|
const parsed = parseExtractionOutput(res.text, docChunkResultSchema);
|
|
197696
197786
|
if (!parsed.success) {
|
|
@@ -198208,7 +198298,9 @@ ${trimmed}
|
|
|
198208
198298
|
Continue the JSON output from the exact point of truncation. Output ONLY the remaining JSON text.`;
|
|
198209
198299
|
try {
|
|
198210
198300
|
const result = await llmService.generateText(continuationPrompt, {
|
|
198211
|
-
systemPrompt: DOC_ANNOTATION_SYSTEM_PROMPT
|
|
198301
|
+
systemPrompt: DOC_ANNOTATION_SYSTEM_PROMPT,
|
|
198302
|
+
jsonMode: true,
|
|
198303
|
+
maxTokens: 16384
|
|
198212
198304
|
});
|
|
198213
198305
|
const combined = trimmed + result.text.trim();
|
|
198214
198306
|
JSON.parse(jsonrepair(combined));
|
|
@@ -198250,9 +198342,12 @@ async function processChunk(chunk, chunkIndex, llmService, sections, onStep) {
|
|
|
198250
198342
|
const chunkText = injectParagraphTags(chunk, sections);
|
|
198251
198343
|
let llmCalls = 0;
|
|
198252
198344
|
let totalTokens = 0;
|
|
198345
|
+
const DOC_INDEX_MAX_OUTPUT_TOKENS = 16384;
|
|
198253
198346
|
const t1Prompt = buildDocAtomAnnotationPrompt(chunkText);
|
|
198254
198347
|
const t1Result = await llmService.generateText(t1Prompt, {
|
|
198255
|
-
systemPrompt: DOC_ANNOTATION_SYSTEM_PROMPT
|
|
198348
|
+
systemPrompt: DOC_ANNOTATION_SYSTEM_PROMPT,
|
|
198349
|
+
jsonMode: true,
|
|
198350
|
+
maxTokens: DOC_INDEX_MAX_OUTPUT_TOKENS
|
|
198256
198351
|
});
|
|
198257
198352
|
llmCalls++;
|
|
198258
198353
|
totalTokens += t1Result.usage.totalTokens;
|
|
@@ -198262,8 +198357,17 @@ async function processChunk(chunk, chunkIndex, llmService, sections, onStep) {
|
|
|
198262
198357
|
onStep?.("T1 done", llmCalls, totalTokens);
|
|
198263
198358
|
let parseResult = parseExtractionOutput(continued.text, docChunkResultSchema);
|
|
198264
198359
|
if (!parseResult.success) {
|
|
198360
|
+
const rawLen = continued.text.length;
|
|
198265
198361
|
const preview = continued.text.slice(0, 500).replace(/\n/g, "\\n");
|
|
198266
|
-
|
|
198362
|
+
const errMsg = parseResult.error.message.slice(0, 300);
|
|
198363
|
+
const posMatch = errMsg.match(/position\s+(\d+)/);
|
|
198364
|
+
const errContext = posMatch ? continued.text.slice(Math.max(0, +posMatch[1] - 100), +posMatch[1] + 100).replace(/\n/g, "\\n") : "";
|
|
198365
|
+
console.warn(`[docIndexer] chunk ${chunkIndex} T1 strict parse failed, attempting lenient.
|
|
198366
|
+
` + ` Error: ${errMsg}
|
|
198367
|
+
` + ` Output length: ${rawLen} chars | finishReason: ${t1Result.finishReason}
|
|
198368
|
+
` + ` Preview (first 500): ${preview}
|
|
198369
|
+
` + (errContext ? ` Context around error position: ...${errContext}...
|
|
198370
|
+
` : ""));
|
|
198267
198371
|
const lenient = tryLenientParse(continued.text, chunkIndex);
|
|
198268
198372
|
if (lenient) {
|
|
198269
198373
|
parseResult = { success: true, data: lenient };
|
|
@@ -198282,7 +198386,8 @@ async function processChunk(chunk, chunkIndex, llmService, sections, onStep) {
|
|
|
198282
198386
|
extract: async (input) => {
|
|
198283
198387
|
const prompt = buildDocGleaningPrompt(input.chunkText, input.previousResult);
|
|
198284
198388
|
const result = await llmService.generateText(prompt, {
|
|
198285
|
-
systemPrompt: DOC_ANNOTATION_SYSTEM_PROMPT
|
|
198389
|
+
systemPrompt: DOC_ANNOTATION_SYSTEM_PROMPT,
|
|
198390
|
+
jsonMode: true
|
|
198286
198391
|
});
|
|
198287
198392
|
llmCalls++;
|
|
198288
198393
|
totalTokens += result.usage.totalTokens;
|
|
@@ -198512,6 +198617,17 @@ function ensureAtomConfidence(atoms2) {
|
|
|
198512
198617
|
}
|
|
198513
198618
|
}
|
|
198514
198619
|
}
|
|
198620
|
+
function sortAtomsByConfidence(sections) {
|
|
198621
|
+
for (const section of sections) {
|
|
198622
|
+
for (const para of section.paragraphs) {
|
|
198623
|
+
for (const atomList of Object.values(para.atoms)) {
|
|
198624
|
+
if (!Array.isArray(atomList) || atomList.length < 2)
|
|
198625
|
+
continue;
|
|
198626
|
+
atomList.sort((a, b) => (b.confidence ?? 0) - (a.confidence ?? 0));
|
|
198627
|
+
}
|
|
198628
|
+
}
|
|
198629
|
+
}
|
|
198630
|
+
}
|
|
198515
198631
|
function countAtoms(sections) {
|
|
198516
198632
|
const counts = {};
|
|
198517
198633
|
for (const section of sections.values()) {
|
|
@@ -198548,7 +198664,8 @@ async function runEntityResolution(sections, entityNames, llmService, onProgress
|
|
|
198548
198664
|
...noiseCandidates.length > 0 ? { noiseCandidates } : {}
|
|
198549
198665
|
});
|
|
198550
198666
|
const result = await llmService.generateText(prompt, {
|
|
198551
|
-
systemPrompt: ENTITY_RESOLUTION_SYSTEM_PROMPT
|
|
198667
|
+
systemPrompt: ENTITY_RESOLUTION_SYSTEM_PROMPT,
|
|
198668
|
+
jsonMode: true
|
|
198552
198669
|
});
|
|
198553
198670
|
let resolution;
|
|
198554
198671
|
try {
|
|
@@ -198673,7 +198790,13 @@ async function indexDocument(input) {
|
|
|
198673
198790
|
const paragraphs = sortedParaKeys.map((pk) => {
|
|
198674
198791
|
const p4 = section.paragraphs.get(pk);
|
|
198675
198792
|
return { text: p4.text, atoms: p4.atoms };
|
|
198793
|
+
}).filter((p4) => {
|
|
198794
|
+
const hasAtoms = Object.values(p4.atoms).some((arr) => Array.isArray(arr) && arr.length > 0);
|
|
198795
|
+
const hasText = p4.text.replace(/[\s\p{P}\p{S}]/gu, "").length > 0;
|
|
198796
|
+
return hasAtoms || hasText;
|
|
198676
198797
|
});
|
|
198798
|
+
if (paragraphs.length === 0)
|
|
198799
|
+
continue;
|
|
198677
198800
|
digestSections.push({
|
|
198678
198801
|
heading: section.heading,
|
|
198679
198802
|
level: section.level,
|
|
@@ -198704,6 +198827,7 @@ async function indexDocument(input) {
|
|
|
198704
198827
|
totalLlmCalls += resolutionResult.llmCalls;
|
|
198705
198828
|
totalTokens += resolutionResult.totalTokens;
|
|
198706
198829
|
}
|
|
198830
|
+
sortAtomsByConfidence(digestSections);
|
|
198707
198831
|
const atomCounts = countAtoms(sectionsMap);
|
|
198708
198832
|
const paragraphCount = digestSections.reduce((sum, s) => sum + s.paragraphs.length, 0);
|
|
198709
198833
|
if (paragraphCount === 0) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as o,u as m,a as c,j as e,b as d,C as h}from"./index-BKETuM1m.js";const p=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],f=o("arrow-left",p);function j({icon:a,title:t,badges:s,meta:l}){const i=m(),{t:r}=c();return e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"shrink-0",children:a}),e.jsx("h1",{className:"min-w-0 break-all font-mono text-xl font-bold leading-none text-c4a-text-primary",children:t}),s&&s.length>0&&e.jsx("div",{className:"flex items-center gap-1.5 ml-2",children:s.map((n,x)=>e.jsx("span",{children:n},x))})]}),e.jsxs("button",{onClick:()=>i(-1),className:"flex items-center gap-1 text-c4a-text-muted hover:text-c4a-text-primary cursor-pointer transition-colors text-xs font-mono shrink-0 ml-4",children:[e.jsx(f,{size:14}),r("common.back")]})]}),l&&l.length>0&&e.jsx("div",{className:"mt-2 flex flex-wrap items-baseline gap-4 text-xs",children:l.map(n=>e.jsxs("span",{className:"text-c4a-text-muted",children:[n.label,":",e.jsx("span",{className:"text-c4a-text-secondary",children:n.value})]},n.label))})]})}function N(){const{t:a}=c(),{hashId:t}=d();if(!t)return e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:a("common.loading")})});const s=t.length>16?t.slice(0,16)+"…":t;return e.jsxs("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:[e.jsx(j,{icon:e.jsx("span",{children:"📄"}),title:`Content: ${s}`}),e.jsx(h,{hashId:t})]})}export{N as ContentDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as o,u as m,a as c,j as e,b as d,C as h}from"./index-wBO4P6CB.js";const p=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],f=o("arrow-left",p);function j({icon:a,title:t,badges:s,meta:l}){const i=m(),{t:r}=c();return e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"shrink-0",children:a}),e.jsx("h1",{className:"min-w-0 break-all font-mono text-xl font-bold leading-none text-c4a-text-primary",children:t}),s&&s.length>0&&e.jsx("div",{className:"flex items-center gap-1.5 ml-2",children:s.map((n,x)=>e.jsx("span",{children:n},x))})]}),e.jsxs("button",{onClick:()=>i(-1),className:"flex items-center gap-1 text-c4a-text-muted hover:text-c4a-text-primary cursor-pointer transition-colors text-xs font-mono shrink-0 ml-4",children:[e.jsx(f,{size:14}),r("common.back")]})]}),l&&l.length>0&&e.jsx("div",{className:"mt-2 flex flex-wrap items-baseline gap-4 text-xs",children:l.map(n=>e.jsxs("span",{className:"text-c4a-text-muted",children:[n.label,":",e.jsx("span",{className:"text-c4a-text-secondary",children:n.value})]},n.label))})]})}function N(){const{t:a}=c(),{hashId:t}=d();if(!t)return e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:a("common.loading")})});const s=t.length>16?t.slice(0,16)+"…":t;return e.jsxs("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:[e.jsx(j,{icon:e.jsx("span",{children:"📄"}),title:`Content: ${s}`}),e.jsx(h,{hashId:t})]})}export{N as ContentDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as o,u as m,a as c,j as e,b as d,C as h}from"./index-CMVd9rlp.js";const p=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],f=o("arrow-left",p);function j({icon:a,title:t,badges:s,meta:l}){const i=m(),{t:r}=c();return e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"shrink-0",children:a}),e.jsx("h1",{className:"min-w-0 break-all font-mono text-xl font-bold leading-none text-c4a-text-primary",children:t}),s&&s.length>0&&e.jsx("div",{className:"flex items-center gap-1.5 ml-2",children:s.map((n,x)=>e.jsx("span",{children:n},x))})]}),e.jsxs("button",{onClick:()=>i(-1),className:"flex items-center gap-1 text-c4a-text-muted hover:text-c4a-text-primary cursor-pointer transition-colors text-xs font-mono shrink-0 ml-4",children:[e.jsx(f,{size:14}),r("common.back")]})]}),l&&l.length>0&&e.jsx("div",{className:"mt-2 flex flex-wrap items-baseline gap-4 text-xs",children:l.map(n=>e.jsxs("span",{className:"text-c4a-text-muted",children:[n.label,":",e.jsx("span",{className:"text-c4a-text-secondary",children:n.value})]},n.label))})]})}function N(){const{t:a}=c(),{hashId:t}=d();if(!t)return e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:a("common.loading")})});const s=t.length>16?t.slice(0,16)+"…":t;return e.jsxs("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:[e.jsx(j,{icon:e.jsx("span",{children:"📄"}),title:`Content: ${s}`}),e.jsx(h,{hashId:t})]})}export{N as ContentDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as n,b as a,j as e,E as i}from"./index-wBO4P6CB.js";function r(){const{t:s}=n(),{entityId:t}=a();return t?e.jsx("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:e.jsx(i,{entityId:t})}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:s("common.loading")})})}export{r as EntityDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as n,b as a,j as e,E as i}from"./index-BKETuM1m.js";function r(){const{t:s}=n(),{entityId:t}=a();return t?e.jsx("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:e.jsx(i,{entityId:t})}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:s("common.loading")})})}export{r as EntityDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as n,b as a,j as e,E as i}from"./index-CMVd9rlp.js";function r(){const{t:s}=n(),{entityId:t}=a();return t?e.jsx("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:e.jsx(i,{entityId:t})}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:s("common.loading")})})}export{r as EntityDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b as n,j as e,R as l}from"./index-BKETuM1m.js";function r(){const{t:s}=a(),{relationId:t}=n();return t?e.jsx("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:e.jsx(l,{relationId:t})}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:s("common.loading")})})}export{r as RelationDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b as n,j as e,R as l}from"./index-CMVd9rlp.js";function r(){const{t:s}=a(),{relationId:t}=n();return t?e.jsx("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:e.jsx(l,{relationId:t})}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:s("common.loading")})})}export{r as RelationDetail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b as n,j as e,R as l}from"./index-wBO4P6CB.js";function r(){const{t:s}=a(),{relationId:t}=n();return t?e.jsx("div",{className:"flex flex-1 flex-col p-4 md:p-6",children:e.jsx(l,{relationId:t})}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-c4a-text-muted",children:s("common.loading")})})}export{r as RelationDetail};
|