@c4a/daemon 0.4.12-alpha.2 → 0.4.12-beta.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 +805 -64
- package/package.json +3 -2
- package/scheduler/index.js +14061 -0
package/index.js
CHANGED
|
@@ -8794,6 +8794,7 @@ var RelationType;
|
|
|
8794
8794
|
RelationType2["Triggers"] = "TRIGGERS";
|
|
8795
8795
|
RelationType2["References"] = "REFERENCES";
|
|
8796
8796
|
RelationType2["Corresponds"] = "CORRESPONDS";
|
|
8797
|
+
RelationType2["Mentions"] = "MENTIONS";
|
|
8797
8798
|
})(RelationType ||= {});
|
|
8798
8799
|
var AtomField;
|
|
8799
8800
|
((AtomField2) => {
|
|
@@ -8811,6 +8812,7 @@ var AtomField;
|
|
|
8811
8812
|
AtomField2["Constraints"] = "constraints";
|
|
8812
8813
|
AtomField2["Comparisons"] = "comparisons";
|
|
8813
8814
|
AtomField2["Boundaries"] = "boundaries";
|
|
8815
|
+
AtomField2["Claims"] = "claims";
|
|
8814
8816
|
})(AtomField ||= {});
|
|
8815
8817
|
var Kind;
|
|
8816
8818
|
((Kind2) => {
|
|
@@ -8823,6 +8825,161 @@ var Perspective;
|
|
|
8823
8825
|
Perspective2["Business"] = "business";
|
|
8824
8826
|
Perspective2["Technical"] = "technical";
|
|
8825
8827
|
})(Perspective ||= {});
|
|
8828
|
+
// ../core/src/types/edgeSyncRules.ts
|
|
8829
|
+
var EDGE_SYNC_RULES = [
|
|
8830
|
+
{
|
|
8831
|
+
field: "container_id",
|
|
8832
|
+
sourceEntityType: "component" /* Component */,
|
|
8833
|
+
edgeType: "CONTAINS" /* Contains */,
|
|
8834
|
+
direction: "reverse",
|
|
8835
|
+
writeGraph: true
|
|
8836
|
+
},
|
|
8837
|
+
{
|
|
8838
|
+
field: "system_id",
|
|
8839
|
+
sourceEntityType: "container" /* Container */,
|
|
8840
|
+
edgeType: "CONTAINS" /* Contains */,
|
|
8841
|
+
direction: "reverse",
|
|
8842
|
+
writeGraph: true
|
|
8843
|
+
},
|
|
8844
|
+
{
|
|
8845
|
+
field: "ref_sor",
|
|
8846
|
+
sourceEntityType: "sor" /* SoR */,
|
|
8847
|
+
edgeType: "REFERENCES" /* References */,
|
|
8848
|
+
direction: "forward",
|
|
8849
|
+
writeGraph: true
|
|
8850
|
+
},
|
|
8851
|
+
{
|
|
8852
|
+
field: "product_refs",
|
|
8853
|
+
sourceEntityType: "epic" /* Epic */,
|
|
8854
|
+
edgeType: "REFERENCES" /* References */,
|
|
8855
|
+
direction: "forward",
|
|
8856
|
+
writeGraph: true
|
|
8857
|
+
},
|
|
8858
|
+
{
|
|
8859
|
+
field: "atoms.entities.ref",
|
|
8860
|
+
sourceEntityType: "any",
|
|
8861
|
+
edgeType: "MENTIONS" /* Mentions */,
|
|
8862
|
+
direction: "forward",
|
|
8863
|
+
writeGraph: true
|
|
8864
|
+
},
|
|
8865
|
+
{
|
|
8866
|
+
field: "atoms.behaviors.ref",
|
|
8867
|
+
sourceEntityType: "any",
|
|
8868
|
+
edgeType: "MENTIONS" /* Mentions */,
|
|
8869
|
+
direction: "forward",
|
|
8870
|
+
writeGraph: true
|
|
8871
|
+
},
|
|
8872
|
+
{
|
|
8873
|
+
field: "product_id",
|
|
8874
|
+
sourceEntityType: "sor" /* SoR */,
|
|
8875
|
+
edgeType: null,
|
|
8876
|
+
direction: "forward",
|
|
8877
|
+
writeGraph: false
|
|
8878
|
+
},
|
|
8879
|
+
{
|
|
8880
|
+
field: "process_id",
|
|
8881
|
+
sourceEntityType: "sor" /* SoR */,
|
|
8882
|
+
edgeType: "PRODUCES" /* Produces */,
|
|
8883
|
+
direction: "reverse",
|
|
8884
|
+
writeGraph: true
|
|
8885
|
+
}
|
|
8886
|
+
];
|
|
8887
|
+
// ../core/src/types/serverConfig.ts
|
|
8888
|
+
var DEFAULT_SERVER_CONFIG = {
|
|
8889
|
+
server: {
|
|
8890
|
+
port: 5100,
|
|
8891
|
+
host: "::"
|
|
8892
|
+
},
|
|
8893
|
+
git_hosts: [],
|
|
8894
|
+
daemon_scheduler: {
|
|
8895
|
+
enabled: true,
|
|
8896
|
+
host: "localhost",
|
|
8897
|
+
port: 5110,
|
|
8898
|
+
workspace: "./data/daemon-workspace",
|
|
8899
|
+
max_daemons: 20
|
|
8900
|
+
},
|
|
8901
|
+
doc_db: {
|
|
8902
|
+
provider: "sqlite",
|
|
8903
|
+
sqlite: {
|
|
8904
|
+
path: "./data/c4a.db"
|
|
8905
|
+
},
|
|
8906
|
+
mongodb: {
|
|
8907
|
+
uri: "mongodb://localhost:27017/c4a?directConnection=true",
|
|
8908
|
+
database: "c4a"
|
|
8909
|
+
}
|
|
8910
|
+
},
|
|
8911
|
+
graph_db: {
|
|
8912
|
+
provider: "neo4j",
|
|
8913
|
+
neo4j: {
|
|
8914
|
+
uri: "bolt://localhost:7687",
|
|
8915
|
+
username: "neo4j",
|
|
8916
|
+
password: ""
|
|
8917
|
+
},
|
|
8918
|
+
nebulagraph: {
|
|
8919
|
+
uri: "localhost:9669",
|
|
8920
|
+
username: "root",
|
|
8921
|
+
password: "nebula",
|
|
8922
|
+
space: "c4a"
|
|
8923
|
+
},
|
|
8924
|
+
duckdb: {
|
|
8925
|
+
path: "./data/c4a-graph.duckdb"
|
|
8926
|
+
}
|
|
8927
|
+
},
|
|
8928
|
+
vector_db: {
|
|
8929
|
+
provider: "lancedb",
|
|
8930
|
+
collection_prefix: "c4a_",
|
|
8931
|
+
qdrant: {
|
|
8932
|
+
url: "http://localhost:6333",
|
|
8933
|
+
api_key: ""
|
|
8934
|
+
},
|
|
8935
|
+
milvus: {
|
|
8936
|
+
address: "localhost:19530"
|
|
8937
|
+
},
|
|
8938
|
+
lancedb: {
|
|
8939
|
+
path: "./data/lancedb"
|
|
8940
|
+
}
|
|
8941
|
+
},
|
|
8942
|
+
llm: {
|
|
8943
|
+
provider: "openai",
|
|
8944
|
+
openai: {
|
|
8945
|
+
api_key: "",
|
|
8946
|
+
base_url: "",
|
|
8947
|
+
default_model: "gpt-5.3-codex"
|
|
8948
|
+
},
|
|
8949
|
+
anthropic: {
|
|
8950
|
+
api_key: "",
|
|
8951
|
+
base_url: "",
|
|
8952
|
+
default_model: "claude-opus-4-6"
|
|
8953
|
+
},
|
|
8954
|
+
google: {
|
|
8955
|
+
api_key: "",
|
|
8956
|
+
base_url: "",
|
|
8957
|
+
default_model: "gemini-3-pro-preview"
|
|
8958
|
+
}
|
|
8959
|
+
},
|
|
8960
|
+
embedding: {
|
|
8961
|
+
provider: "huggingface",
|
|
8962
|
+
huggingface: {
|
|
8963
|
+
model_id: "Xenova/all-MiniLM-L6-v2",
|
|
8964
|
+
dtype: "q8",
|
|
8965
|
+
cache_dir: "./models/embedding"
|
|
8966
|
+
},
|
|
8967
|
+
xenova: {
|
|
8968
|
+
model_id: "Xenova/bge-m3",
|
|
8969
|
+
dtype: "q8",
|
|
8970
|
+
cache_dir: "./models/embedding"
|
|
8971
|
+
},
|
|
8972
|
+
openai: {
|
|
8973
|
+
api_key: "",
|
|
8974
|
+
base_url: "",
|
|
8975
|
+
model_id: "text-embedding-3-small"
|
|
8976
|
+
},
|
|
8977
|
+
google: {
|
|
8978
|
+
api_key: "",
|
|
8979
|
+
model_id: "text-embedding-004"
|
|
8980
|
+
}
|
|
8981
|
+
}
|
|
8982
|
+
};
|
|
8826
8983
|
// ../core/src/types/daemon.ts
|
|
8827
8984
|
var CODE_PACKAGE_FILES = new Set([
|
|
8828
8985
|
"package.json",
|
|
@@ -12867,7 +13024,7 @@ var atomFieldSchema = exports_external.enum(Object.values(AtomField));
|
|
|
12867
13024
|
var kindSchema = exports_external.enum(Object.values(Kind));
|
|
12868
13025
|
var scopeSchema = exports_external.literal("project");
|
|
12869
13026
|
var perspectiveSchema = exports_external.enum(Object.values(Perspective));
|
|
12870
|
-
var
|
|
13027
|
+
var extractionConfidenceSchema = exports_external.object({
|
|
12871
13028
|
structural: exports_external.number().min(0).max(1),
|
|
12872
13029
|
semantic: exports_external.number().min(0).max(1)
|
|
12873
13030
|
});
|
|
@@ -12875,13 +13032,29 @@ var metadataSchema = exports_external.object({
|
|
|
12875
13032
|
created_at: exports_external.string().datetime(),
|
|
12876
13033
|
updated_at: exports_external.string().datetime(),
|
|
12877
13034
|
version_tag: exports_external.string().optional(),
|
|
12878
|
-
|
|
12879
|
-
|
|
13035
|
+
extraction_confidence: extractionConfidenceSchema.optional(),
|
|
13036
|
+
confidence: exports_external.number().min(0).max(1).optional(),
|
|
13037
|
+
aliases: exports_external.array(exports_external.string()).optional(),
|
|
13038
|
+
rank: exports_external.number().optional(),
|
|
13039
|
+
community_id: exports_external.string().optional(),
|
|
13040
|
+
community_level: exports_external.number().optional()
|
|
13041
|
+
});
|
|
13042
|
+
var entityRefPointerSchema = exports_external.string().regex(/^ref:entity:.+$/, "must be a ref pointer in format ref:entity:<id>");
|
|
13043
|
+
var sourceRefSpanSchema = exports_external.object({
|
|
13044
|
+
start: exports_external.number().int().min(1),
|
|
13045
|
+
end: exports_external.number().int().min(1)
|
|
13046
|
+
});
|
|
13047
|
+
var sourceRefSchema = exports_external.object({
|
|
13048
|
+
ref: exports_external.string(),
|
|
13049
|
+
span: sourceRefSpanSchema.optional()
|
|
13050
|
+
});
|
|
13051
|
+
var sourceRefsSchema = exports_external.array(sourceRefSchema).optional();
|
|
12880
13052
|
// ../core/src/schemas/atomsSchema.ts
|
|
12881
13053
|
var confidenceAtomSchema = exports_external.number().min(0).max(1).optional();
|
|
12882
13054
|
var entityAtomSchema = exports_external.object({
|
|
12883
13055
|
name: exports_external.string(),
|
|
12884
13056
|
kind: kindSchema.optional(),
|
|
13057
|
+
ref: exports_external.string().optional(),
|
|
12885
13058
|
confidence: confidenceAtomSchema
|
|
12886
13059
|
});
|
|
12887
13060
|
var relationAtomSchema = exports_external.object({
|
|
@@ -12895,6 +13068,8 @@ var behaviorAtomSchema = exports_external.object({
|
|
|
12895
13068
|
name: exports_external.string(),
|
|
12896
13069
|
signature: exports_external.string().optional(),
|
|
12897
13070
|
description: exports_external.string().optional(),
|
|
13071
|
+
performed_by: exports_external.array(exports_external.string()).optional(),
|
|
13072
|
+
ref: exports_external.string().optional(),
|
|
12898
13073
|
confidence: confidenceAtomSchema
|
|
12899
13074
|
});
|
|
12900
13075
|
var attributeAtomSchema = exports_external.object({
|
|
@@ -12935,6 +13110,7 @@ var decisionPhaseSchema = exports_external.object({
|
|
|
12935
13110
|
rationale: exports_external.string().optional()
|
|
12936
13111
|
});
|
|
12937
13112
|
var decisionAtomSchema = exports_external.object({
|
|
13113
|
+
name: exports_external.string().optional(),
|
|
12938
13114
|
description: exports_external.string(),
|
|
12939
13115
|
rationale: exports_external.string(),
|
|
12940
13116
|
alternatives: exports_external.array(exports_external.string()).optional(),
|
|
@@ -12957,9 +13133,9 @@ var metricAtomSchema = exports_external.object({
|
|
|
12957
13133
|
});
|
|
12958
13134
|
var roleAtomSchema = exports_external.object({
|
|
12959
13135
|
name: exports_external.string(),
|
|
12960
|
-
kind: exports_external.enum(["
|
|
13136
|
+
kind: exports_external.enum(["human", "team", "persona"]),
|
|
12961
13137
|
performs: exports_external.array(exports_external.string()).optional(),
|
|
12962
|
-
|
|
13138
|
+
description: exports_external.string().optional()
|
|
12963
13139
|
});
|
|
12964
13140
|
var constraintAtomSchema = exports_external.object({
|
|
12965
13141
|
description: exports_external.string(),
|
|
@@ -12990,6 +13166,16 @@ var comparisonAtomSchema = exports_external.object({
|
|
|
12990
13166
|
decision_ref: exports_external.string().optional(),
|
|
12991
13167
|
confidence: confidenceAtomSchema
|
|
12992
13168
|
});
|
|
13169
|
+
var claimAtomSchema = exports_external.object({
|
|
13170
|
+
claim_type: exports_external.string(),
|
|
13171
|
+
description: exports_external.string(),
|
|
13172
|
+
status: exports_external.enum(["active", "deprecated", "proposed"]),
|
|
13173
|
+
valid_from: exports_external.string(),
|
|
13174
|
+
valid_until: exports_external.string().optional(),
|
|
13175
|
+
session_ref: exports_external.string().optional(),
|
|
13176
|
+
changed_by: exports_external.string(),
|
|
13177
|
+
confidence: confidenceAtomSchema
|
|
13178
|
+
});
|
|
12993
13179
|
var dataAtomsSchema = exports_external.object({
|
|
12994
13180
|
entities: exports_external.array(entityAtomSchema).optional(),
|
|
12995
13181
|
relations: exports_external.array(relationAtomSchema).optional(),
|
|
@@ -13004,31 +13190,115 @@ var dataAtomsSchema = exports_external.object({
|
|
|
13004
13190
|
roles: exports_external.array(roleAtomSchema).optional(),
|
|
13005
13191
|
constraints: exports_external.array(constraintAtomSchema).optional(),
|
|
13006
13192
|
comparisons: exports_external.array(comparisonAtomSchema).optional(),
|
|
13007
|
-
boundaries: exports_external.array(boundaryAtomSchema).optional()
|
|
13193
|
+
boundaries: exports_external.array(boundaryAtomSchema).optional(),
|
|
13194
|
+
claims: exports_external.array(claimAtomSchema).optional()
|
|
13008
13195
|
}).superRefine((atoms2, ctx) => {
|
|
13009
|
-
if (!atoms2.transitions || atoms2.transitions.length === 0) {
|
|
13010
|
-
return;
|
|
13011
|
-
}
|
|
13012
13196
|
const stateValues = new Set;
|
|
13197
|
+
const stateNames = new Set;
|
|
13013
13198
|
for (const state of atoms2.states ?? []) {
|
|
13199
|
+
stateNames.add(state.name);
|
|
13014
13200
|
for (const value of state.values) {
|
|
13015
13201
|
stateValues.add(value);
|
|
13016
13202
|
}
|
|
13017
13203
|
}
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13204
|
+
const behaviorNames = new Set;
|
|
13205
|
+
for (const behavior of atoms2.behaviors ?? []) {
|
|
13206
|
+
behaviorNames.add(behavior.name);
|
|
13207
|
+
}
|
|
13208
|
+
const roleNames = new Set;
|
|
13209
|
+
for (const role of atoms2.roles ?? []) {
|
|
13210
|
+
roleNames.add(role.name);
|
|
13211
|
+
}
|
|
13212
|
+
const eventNames = new Set;
|
|
13213
|
+
for (const event of atoms2.events ?? []) {
|
|
13214
|
+
eventNames.add(event.name);
|
|
13215
|
+
}
|
|
13216
|
+
const metricNames = new Set;
|
|
13217
|
+
for (const metric of atoms2.metrics ?? []) {
|
|
13218
|
+
metricNames.add(metric.name);
|
|
13219
|
+
}
|
|
13220
|
+
if (atoms2.transitions && atoms2.transitions.length > 0) {
|
|
13221
|
+
for (const transition of atoms2.transitions) {
|
|
13222
|
+
if (!stateValues.has(transition.from)) {
|
|
13223
|
+
ctx.addIssue({
|
|
13224
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13225
|
+
path: ["transitions"],
|
|
13226
|
+
message: `transition.from references unknown state: ${transition.from}`
|
|
13227
|
+
});
|
|
13228
|
+
}
|
|
13229
|
+
if (!stateValues.has(transition.to)) {
|
|
13230
|
+
ctx.addIssue({
|
|
13231
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13232
|
+
path: ["transitions"],
|
|
13233
|
+
message: `transition.to references unknown state: ${transition.to}`
|
|
13234
|
+
});
|
|
13235
|
+
}
|
|
13236
|
+
const hasEvents = eventNames.size > 0;
|
|
13237
|
+
const hasBehaviors = behaviorNames.size > 0;
|
|
13238
|
+
if (hasEvents || hasBehaviors) {
|
|
13239
|
+
const triggerMatchesEvent = hasEvents && eventNames.has(transition.trigger);
|
|
13240
|
+
const triggerMatchesBehavior = hasBehaviors && behaviorNames.has(transition.trigger);
|
|
13241
|
+
if (!triggerMatchesEvent && !triggerMatchesBehavior) {
|
|
13242
|
+
ctx.addIssue({
|
|
13243
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13244
|
+
path: ["transitions"],
|
|
13245
|
+
message: `transition.trigger references unknown event/behavior: ${transition.trigger}`
|
|
13246
|
+
});
|
|
13247
|
+
}
|
|
13248
|
+
}
|
|
13025
13249
|
}
|
|
13026
|
-
|
|
13027
|
-
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13250
|
+
}
|
|
13251
|
+
if (atoms2.roles && atoms2.roles.length > 0) {
|
|
13252
|
+
for (const [index, role] of atoms2.roles.entries()) {
|
|
13253
|
+
for (const perform of role.performs ?? []) {
|
|
13254
|
+
if (!behaviorNames.has(perform)) {
|
|
13255
|
+
ctx.addIssue({
|
|
13256
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13257
|
+
path: ["roles", index, "performs"],
|
|
13258
|
+
message: `role.performs references unknown behavior: ${perform}`
|
|
13259
|
+
});
|
|
13260
|
+
}
|
|
13261
|
+
}
|
|
13262
|
+
}
|
|
13263
|
+
}
|
|
13264
|
+
if (atoms2.behaviors && atoms2.behaviors.length > 0) {
|
|
13265
|
+
for (const [index, behavior] of atoms2.behaviors.entries()) {
|
|
13266
|
+
for (const performer of behavior.performed_by ?? []) {
|
|
13267
|
+
if (!roleNames.has(performer)) {
|
|
13268
|
+
ctx.addIssue({
|
|
13269
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13270
|
+
path: ["behaviors", index, "performed_by"],
|
|
13271
|
+
message: `behavior.performed_by references unknown role: ${performer}`
|
|
13272
|
+
});
|
|
13273
|
+
}
|
|
13274
|
+
}
|
|
13275
|
+
}
|
|
13276
|
+
}
|
|
13277
|
+
if (atoms2.rules && atoms2.rules.length > 0) {
|
|
13278
|
+
const allowedDependsOn = new Set([...stateNames, ...metricNames]);
|
|
13279
|
+
for (const [index, rule] of atoms2.rules.entries()) {
|
|
13280
|
+
for (const dependency of rule.depends_on ?? []) {
|
|
13281
|
+
if (!allowedDependsOn.has(dependency)) {
|
|
13282
|
+
ctx.addIssue({
|
|
13283
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13284
|
+
path: ["rules", index, "depends_on"],
|
|
13285
|
+
message: `rule.depends_on references unknown state/metric: ${dependency}`
|
|
13286
|
+
});
|
|
13287
|
+
}
|
|
13288
|
+
}
|
|
13289
|
+
}
|
|
13290
|
+
}
|
|
13291
|
+
if (atoms2.events && atoms2.events.length > 0) {
|
|
13292
|
+
for (const [index, event] of atoms2.events.entries()) {
|
|
13293
|
+
for (const behaviorName of event.trigger_for ?? []) {
|
|
13294
|
+
if (!behaviorNames.has(behaviorName)) {
|
|
13295
|
+
ctx.addIssue({
|
|
13296
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13297
|
+
path: ["events", index, "trigger_for"],
|
|
13298
|
+
message: `event.trigger_for references unknown behavior: ${behaviorName}`
|
|
13299
|
+
});
|
|
13300
|
+
}
|
|
13301
|
+
}
|
|
13032
13302
|
}
|
|
13033
13303
|
}
|
|
13034
13304
|
});
|
|
@@ -13044,7 +13314,8 @@ var atomsWhitelistByEntityType = {
|
|
|
13044
13314
|
"states" /* States */,
|
|
13045
13315
|
"rules" /* Rules */,
|
|
13046
13316
|
"transitions" /* Transitions */,
|
|
13047
|
-
"events" /* Events
|
|
13317
|
+
"events" /* Events */,
|
|
13318
|
+
"claims" /* Claims */
|
|
13048
13319
|
]),
|
|
13049
13320
|
["process" /* Process */]: new Set,
|
|
13050
13321
|
["sor" /* SoR */]: new Set([
|
|
@@ -13060,7 +13331,8 @@ var atomsWhitelistByEntityType = {
|
|
|
13060
13331
|
"metrics" /* Metrics */,
|
|
13061
13332
|
"roles" /* Roles */,
|
|
13062
13333
|
"constraints" /* Constraints */,
|
|
13063
|
-
"comparisons" /* Comparisons
|
|
13334
|
+
"comparisons" /* Comparisons */,
|
|
13335
|
+
"claims" /* Claims */
|
|
13064
13336
|
]),
|
|
13065
13337
|
["contract" /* Contract */]: new Set,
|
|
13066
13338
|
["epic" /* Epic */]: new Set([
|
|
@@ -13068,7 +13340,8 @@ var atomsWhitelistByEntityType = {
|
|
|
13068
13340
|
"metrics" /* Metrics */,
|
|
13069
13341
|
"roles" /* Roles */,
|
|
13070
13342
|
"constraints" /* Constraints */,
|
|
13071
|
-
"comparisons" /* Comparisons
|
|
13343
|
+
"comparisons" /* Comparisons */,
|
|
13344
|
+
"claims" /* Claims */
|
|
13072
13345
|
]),
|
|
13073
13346
|
["document" /* Document */]: new Set
|
|
13074
13347
|
};
|
|
@@ -13093,7 +13366,8 @@ var baseEntitySchema = exports_external.object({
|
|
|
13093
13366
|
kind: kindSchema,
|
|
13094
13367
|
scope: scopeSchema,
|
|
13095
13368
|
perspective: perspectiveSchema,
|
|
13096
|
-
metadata: metadataSchema
|
|
13369
|
+
metadata: metadataSchema,
|
|
13370
|
+
source_refs: sourceRefsSchema
|
|
13097
13371
|
});
|
|
13098
13372
|
var productDataSchema = exports_external.object({
|
|
13099
13373
|
description: exports_external.string().optional(),
|
|
@@ -13107,7 +13381,8 @@ var productEntitySchema = baseEntitySchema.extend({
|
|
|
13107
13381
|
});
|
|
13108
13382
|
var systemDataSchema = exports_external.object({
|
|
13109
13383
|
description: exports_external.string().optional(),
|
|
13110
|
-
corresponds_to: exports_external.string().optional()
|
|
13384
|
+
corresponds_to: exports_external.string().optional(),
|
|
13385
|
+
atoms: exports_external.undefined().optional()
|
|
13111
13386
|
});
|
|
13112
13387
|
var systemEntitySchema = baseEntitySchema.extend({
|
|
13113
13388
|
type: exports_external.literal("system" /* System */),
|
|
@@ -13153,9 +13428,10 @@ var sorEntitySchema = baseEntitySchema.extend({
|
|
|
13153
13428
|
data: sorDataSchema
|
|
13154
13429
|
});
|
|
13155
13430
|
var contractDataSchema = exports_external.object({
|
|
13156
|
-
format: exports_external.enum(["openapi", "asyncapi", "proto"]),
|
|
13431
|
+
format: exports_external.enum(["openapi", "asyncapi", "proto", "graphql", "custom"]),
|
|
13157
13432
|
spec: exports_external.string(),
|
|
13158
|
-
|
|
13433
|
+
version: exports_external.string().optional(),
|
|
13434
|
+
description: exports_external.string().optional()
|
|
13159
13435
|
});
|
|
13160
13436
|
var contractEntitySchema = baseEntitySchema.extend({
|
|
13161
13437
|
type: exports_external.literal("contract" /* Contract */),
|
|
@@ -13163,7 +13439,7 @@ var contractEntitySchema = baseEntitySchema.extend({
|
|
|
13163
13439
|
});
|
|
13164
13440
|
var epicDataSchema = exports_external.object({
|
|
13165
13441
|
description: exports_external.string().optional(),
|
|
13166
|
-
product_refs: exports_external.array(
|
|
13442
|
+
product_refs: exports_external.array(entityRefPointerSchema).optional(),
|
|
13167
13443
|
atoms: dataAtomsSchema.optional()
|
|
13168
13444
|
});
|
|
13169
13445
|
var epicEntitySchema = baseEntitySchema.extend({
|
|
@@ -13239,18 +13515,45 @@ var entitySchema = exports_external.discriminatedUnion("type", [
|
|
|
13239
13515
|
});
|
|
13240
13516
|
}
|
|
13241
13517
|
}
|
|
13518
|
+
if (entity2.type === "sor" /* SoR */ && entity2.data.atoms) {
|
|
13519
|
+
const { constraints, rules } = entity2.data.atoms;
|
|
13520
|
+
const hasConstraints = Array.isArray(constraints) && constraints.length > 0;
|
|
13521
|
+
const hasRules = Array.isArray(rules) && rules.length > 0;
|
|
13522
|
+
if (!hasConstraints && !hasRules) {
|
|
13523
|
+
ctx.addIssue({
|
|
13524
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13525
|
+
path: ["data", "atoms"],
|
|
13526
|
+
message: "SoR must have at least one constraint or rule"
|
|
13527
|
+
});
|
|
13528
|
+
}
|
|
13529
|
+
}
|
|
13530
|
+
if (entity2.type === "epic" /* Epic */ && entity2.data.atoms) {
|
|
13531
|
+
const { decisions } = entity2.data.atoms;
|
|
13532
|
+
const hasDecisions = Array.isArray(decisions) && decisions.length > 0;
|
|
13533
|
+
if (!hasDecisions) {
|
|
13534
|
+
ctx.addIssue({
|
|
13535
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13536
|
+
path: ["data", "atoms"],
|
|
13537
|
+
message: "Epic must have at least one decision"
|
|
13538
|
+
});
|
|
13539
|
+
}
|
|
13540
|
+
}
|
|
13242
13541
|
});
|
|
13243
13542
|
// ../core/src/schemas/relationSchema.ts
|
|
13244
13543
|
var relationDataSchema = exports_external.object({
|
|
13245
|
-
description: exports_external.string().optional()
|
|
13544
|
+
description: exports_external.string().optional(),
|
|
13545
|
+
_source: exports_external.literal("field_sync").optional()
|
|
13246
13546
|
});
|
|
13247
13547
|
var relationSchema = exports_external.object({
|
|
13248
13548
|
id: exports_external.string(),
|
|
13249
13549
|
type: relationTypeSchema,
|
|
13250
13550
|
from: exports_external.string(),
|
|
13251
13551
|
to: exports_external.string(),
|
|
13552
|
+
weight: exports_external.number().optional(),
|
|
13553
|
+
confidence: exports_external.number().min(0).max(1).optional(),
|
|
13252
13554
|
data: relationDataSchema.optional(),
|
|
13253
|
-
metadata: metadataSchema.optional()
|
|
13555
|
+
metadata: metadataSchema.optional(),
|
|
13556
|
+
source_refs: sourceRefsSchema
|
|
13254
13557
|
});
|
|
13255
13558
|
// ../core/src/errors/httpStatus.ts
|
|
13256
13559
|
var ERROR_CODE_HTTP_STATUS = {
|
|
@@ -13288,6 +13591,25 @@ var ERROR_CODE_HTTP_STATUS = {
|
|
|
13288
13591
|
var import_yaml = __toESM(require_dist(), 1);
|
|
13289
13592
|
// ../core/src/constants.ts
|
|
13290
13593
|
var DAEMON_HEARTBEAT_INTERVAL = 30000;
|
|
13594
|
+
var CLOUD_DAEMON_IDLE_TIMEOUT = 300000;
|
|
13595
|
+
// ../core/src/fileTypes.ts
|
|
13596
|
+
var INDEXABLE_CODE_EXTENSIONS = new Set([".ts", ".tsx"]);
|
|
13597
|
+
var INDEXABLE_DOC_EXTENSIONS = new Set([".md"]);
|
|
13598
|
+
var INDEXABLE_EXTENSIONS = new Set([
|
|
13599
|
+
...INDEXABLE_CODE_EXTENSIONS,
|
|
13600
|
+
...INDEXABLE_DOC_EXTENSIONS
|
|
13601
|
+
]);
|
|
13602
|
+
var UPLOAD_ALLOWED_EXTENSIONS = new Set([
|
|
13603
|
+
".md",
|
|
13604
|
+
".doc",
|
|
13605
|
+
".docx",
|
|
13606
|
+
".pdf",
|
|
13607
|
+
".ppt",
|
|
13608
|
+
".pptx",
|
|
13609
|
+
".txt"
|
|
13610
|
+
]);
|
|
13611
|
+
var TEXT_EXTENSIONS = new Set([".md", ".txt"]);
|
|
13612
|
+
var UPLOAD_MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
13291
13613
|
// src/handlers/utils.ts
|
|
13292
13614
|
import path2 from "node:path";
|
|
13293
13615
|
|
|
@@ -13367,18 +13689,22 @@ function resolveServerUrl(input) {
|
|
|
13367
13689
|
}
|
|
13368
13690
|
const isLocal = host.startsWith("localhost") || host.startsWith("127.0.0.1") || host.startsWith("0.0.0.0");
|
|
13369
13691
|
const protocol = isLocal ? "ws" : "wss";
|
|
13370
|
-
const base2 = host.replace(
|
|
13692
|
+
const base2 = host.replace(/\/+$/, "");
|
|
13371
13693
|
return `${protocol}://${base2}${WS_DAEMON_PATH}`;
|
|
13372
13694
|
}
|
|
13373
|
-
var parseAllowedPaths = (input) => {
|
|
13695
|
+
var parseAllowedPaths = (input, extraPath) => {
|
|
13374
13696
|
if (!input) {
|
|
13375
|
-
return ["*"];
|
|
13697
|
+
return extraPath ? ["*", extraPath] : ["*"];
|
|
13376
13698
|
}
|
|
13377
13699
|
const parts = input.split(",").map((s) => s.trim()).filter(Boolean);
|
|
13378
13700
|
if (parts.includes("*")) {
|
|
13379
|
-
return ["*"];
|
|
13701
|
+
return extraPath ? ["*", extraPath] : ["*"];
|
|
13702
|
+
}
|
|
13703
|
+
const normalized = normalizeAllowedPaths(parts);
|
|
13704
|
+
if (extraPath && !normalized.includes("*")) {
|
|
13705
|
+
normalized.push(extraPath);
|
|
13380
13706
|
}
|
|
13381
|
-
return normalizeAllowedPaths(
|
|
13707
|
+
return normalizeAllowedPaths(normalized);
|
|
13382
13708
|
};
|
|
13383
13709
|
|
|
13384
13710
|
// src/handshake.ts
|
|
@@ -13411,8 +13737,8 @@ var readPackageVersion = (packageRoot = getPackageRoot()) => {
|
|
|
13411
13737
|
const parsed = JSON.parse(raw);
|
|
13412
13738
|
return parsed.version ?? "0.0.0";
|
|
13413
13739
|
};
|
|
13414
|
-
var buildHandshakePayload = (allowedPaths) => {
|
|
13415
|
-
const machineId = os.hostname();
|
|
13740
|
+
var buildHandshakePayload = (allowedPaths, machineIdOverride) => {
|
|
13741
|
+
const machineId = machineIdOverride?.trim() || os.hostname();
|
|
13416
13742
|
return {
|
|
13417
13743
|
machine_id: machineId,
|
|
13418
13744
|
machine_name: machineId,
|
|
@@ -13499,7 +13825,8 @@ var matchesFilter = (filePath, include) => {
|
|
|
13499
13825
|
if (CODE_PACKAGE_FILES.has(lower))
|
|
13500
13826
|
return true;
|
|
13501
13827
|
} else if (filter === "docs") {
|
|
13502
|
-
|
|
13828
|
+
const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
|
|
13829
|
+
if (INDEXABLE_DOC_EXTENSIONS.has(ext))
|
|
13503
13830
|
return true;
|
|
13504
13831
|
} else if (filter.startsWith(".")) {
|
|
13505
13832
|
if (filePath.toLowerCase().endsWith(filter.toLowerCase()))
|
|
@@ -13694,12 +14021,41 @@ var createFsReadFileHandler = (allowedPaths) => async (params) => {
|
|
|
13694
14021
|
// src/handlers/fsRepoStatus.ts
|
|
13695
14022
|
var REPO_STATUS_CACHE_TTL_MS = 1e4;
|
|
13696
14023
|
var repoStatusCache = new Map;
|
|
14024
|
+
var parseForEachRef = (raw) => {
|
|
14025
|
+
const entries = [];
|
|
14026
|
+
for (const line of raw.split(`
|
|
14027
|
+
`)) {
|
|
14028
|
+
if (!line.trim())
|
|
14029
|
+
continue;
|
|
14030
|
+
const [name, commit] = line.split(" ");
|
|
14031
|
+
if (name && commit)
|
|
14032
|
+
entries.push({ name, commit });
|
|
14033
|
+
}
|
|
14034
|
+
return entries;
|
|
14035
|
+
};
|
|
14036
|
+
var parseLogOutput = (raw) => {
|
|
14037
|
+
const entries = [];
|
|
14038
|
+
for (const line of raw.split(`
|
|
14039
|
+
`)) {
|
|
14040
|
+
if (!line.trim())
|
|
14041
|
+
continue;
|
|
14042
|
+
const spaceIdx = line.indexOf(" ");
|
|
14043
|
+
if (spaceIdx === -1) {
|
|
14044
|
+
entries.push({ hash: line.trim(), message: "" });
|
|
14045
|
+
} else {
|
|
14046
|
+
entries.push({ hash: line.slice(0, spaceIdx), message: line.slice(spaceIdx + 1) });
|
|
14047
|
+
}
|
|
14048
|
+
}
|
|
14049
|
+
return entries;
|
|
14050
|
+
};
|
|
13697
14051
|
var createFsRepoStatusHandler = (allowedPaths) => async (params) => {
|
|
13698
14052
|
const now = Date.now();
|
|
13699
14053
|
const payload = params;
|
|
13700
14054
|
const rawPath = ensureString(payload?.path, "path");
|
|
14055
|
+
const requestedBranch = typeof payload?.branch === "string" ? payload.branch : "";
|
|
13701
14056
|
const targetPath = assertAllowedPath(rawPath, allowedPaths);
|
|
13702
|
-
const
|
|
14057
|
+
const cacheKey = `${targetPath}:${requestedBranch}`;
|
|
14058
|
+
const cached = repoStatusCache.get(cacheKey);
|
|
13703
14059
|
if (cached?.value && cached.expiresAt > now) {
|
|
13704
14060
|
return cached.value;
|
|
13705
14061
|
}
|
|
@@ -13707,26 +14063,36 @@ var createFsRepoStatusHandler = (allowedPaths) => async (params) => {
|
|
|
13707
14063
|
return cached.inflight;
|
|
13708
14064
|
}
|
|
13709
14065
|
const inflight = (async () => {
|
|
13710
|
-
const [branch, headHash, remoteResult] = await Promise.all([
|
|
14066
|
+
const [branch, headHash, remoteResult, branchesRaw, tagsRaw] = await Promise.all([
|
|
13711
14067
|
runGit(["rev-parse", "--abbrev-ref", "HEAD"], targetPath),
|
|
13712
14068
|
runGit(["rev-parse", "HEAD"], targetPath),
|
|
13713
|
-
tryRunGit(["config", "--get", "remote.origin.url"], targetPath)
|
|
14069
|
+
tryRunGit(["config", "--get", "remote.origin.url"], targetPath),
|
|
14070
|
+
runGit(["for-each-ref", "refs/heads", "--format=%(refname:short) %(objectname)"], targetPath),
|
|
14071
|
+
runGit(["for-each-ref", "refs/tags", "--format=%(refname:short) %(objectname)"], targetPath)
|
|
13714
14072
|
]);
|
|
13715
14073
|
const dirtyResult = await tryRunGit(["diff-index", "--quiet", "HEAD", "--"], targetPath);
|
|
14074
|
+
const branches = parseForEachRef(branchesRaw);
|
|
14075
|
+
const tags = parseForEachRef(tagsRaw);
|
|
14076
|
+
const logBranch = requestedBranch || branch;
|
|
14077
|
+
const logResult = await tryRunGit(["log", logBranch, "--format=%H %s", "-n", "30"], targetPath);
|
|
14078
|
+
const commits = logResult.ok ? parseLogOutput(logResult.stdout) : [];
|
|
13716
14079
|
return {
|
|
13717
14080
|
branch,
|
|
13718
14081
|
head_hash: headHash,
|
|
13719
14082
|
is_dirty: !dirtyResult.ok,
|
|
13720
|
-
remote_url: remoteResult.ok ? remoteResult.stdout.trim() || undefined : undefined
|
|
14083
|
+
remote_url: remoteResult.ok ? remoteResult.stdout.trim() || undefined : undefined,
|
|
14084
|
+
branches,
|
|
14085
|
+
tags,
|
|
14086
|
+
commits
|
|
13721
14087
|
};
|
|
13722
14088
|
})();
|
|
13723
|
-
repoStatusCache.set(
|
|
14089
|
+
repoStatusCache.set(cacheKey, { expiresAt: now + REPO_STATUS_CACHE_TTL_MS, inflight });
|
|
13724
14090
|
try {
|
|
13725
14091
|
const value = await inflight;
|
|
13726
|
-
repoStatusCache.set(
|
|
14092
|
+
repoStatusCache.set(cacheKey, { expiresAt: Date.now() + REPO_STATUS_CACHE_TTL_MS, value });
|
|
13727
14093
|
return value;
|
|
13728
14094
|
} finally {
|
|
13729
|
-
const entry = repoStatusCache.get(
|
|
14095
|
+
const entry = repoStatusCache.get(cacheKey);
|
|
13730
14096
|
if (entry?.inflight) {
|
|
13731
14097
|
delete entry.inflight;
|
|
13732
14098
|
}
|
|
@@ -13734,8 +14100,6 @@ var createFsRepoStatusHandler = (allowedPaths) => async (params) => {
|
|
|
13734
14100
|
};
|
|
13735
14101
|
|
|
13736
14102
|
// src/handlers/fsRepoScan.ts
|
|
13737
|
-
import { readFile as readFile4 } from "node:fs/promises";
|
|
13738
|
-
import path7 from "node:path";
|
|
13739
14103
|
var DEFAULT_INCLUDE2 = ["manifests", "docs"];
|
|
13740
14104
|
var matchesFilter2 = (filePath, include) => {
|
|
13741
14105
|
if (include.includes("*"))
|
|
@@ -13747,7 +14111,8 @@ var matchesFilter2 = (filePath, include) => {
|
|
|
13747
14111
|
if (CODE_PACKAGE_FILES.has(lower))
|
|
13748
14112
|
return true;
|
|
13749
14113
|
} else if (filter === "docs") {
|
|
13750
|
-
|
|
14114
|
+
const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
|
|
14115
|
+
if (INDEXABLE_DOC_EXTENSIONS.has(ext))
|
|
13751
14116
|
return true;
|
|
13752
14117
|
} else if (filter.startsWith(".")) {
|
|
13753
14118
|
if (filePath.toLowerCase().endsWith(filter.toLowerCase()))
|
|
@@ -13796,8 +14161,7 @@ var createFsRepoScanHandler = (allowedPaths) => async (params) => {
|
|
|
13796
14161
|
if (!fileName || !CODE_PACKAGE_FILES.has(fileName.toLowerCase()))
|
|
13797
14162
|
continue;
|
|
13798
14163
|
try {
|
|
13799
|
-
const
|
|
13800
|
-
const content = await readFile4(fullPath, "utf-8");
|
|
14164
|
+
const content = await runGit(["show", `${hash2}:${file.path}`], targetPath);
|
|
13801
14165
|
if (!isValidManifest(file.path, content))
|
|
13802
14166
|
continue;
|
|
13803
14167
|
manifests.push({ path: file.path, content });
|
|
@@ -13838,8 +14202,362 @@ var createFsRepoTreeHandler = (allowedPaths) => async (params) => {
|
|
|
13838
14202
|
return { files };
|
|
13839
14203
|
};
|
|
13840
14204
|
|
|
14205
|
+
// src/handlers/configSetAuth.ts
|
|
14206
|
+
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
|
14207
|
+
|
|
14208
|
+
// src/handlers/vcsUtils.ts
|
|
14209
|
+
import { execFile as execFile2, spawn } from "node:child_process";
|
|
14210
|
+
import path7 from "node:path";
|
|
14211
|
+
var stripAuthFromUrl = (rawUrl) => {
|
|
14212
|
+
try {
|
|
14213
|
+
const parsed = new URL(rawUrl);
|
|
14214
|
+
if (parsed.username || parsed.password) {
|
|
14215
|
+
parsed.username = "";
|
|
14216
|
+
parsed.password = "";
|
|
14217
|
+
}
|
|
14218
|
+
return `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
|
|
14219
|
+
} catch {
|
|
14220
|
+
return rawUrl;
|
|
14221
|
+
}
|
|
14222
|
+
};
|
|
14223
|
+
var gitConfigPath = (workDir) => path7.join(workDir, ".git-daemon.config");
|
|
14224
|
+
var gitCredentialsPath = (workDir) => path7.join(workDir, ".git-daemon.credentials");
|
|
14225
|
+
var createGitEnv = (workDir) => {
|
|
14226
|
+
const base2 = {
|
|
14227
|
+
...process.env,
|
|
14228
|
+
LANG: "C",
|
|
14229
|
+
LC_ALL: "C",
|
|
14230
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
14231
|
+
};
|
|
14232
|
+
if (!workDir)
|
|
14233
|
+
return base2;
|
|
14234
|
+
return { ...base2, GIT_CONFIG_GLOBAL: gitConfigPath(workDir) };
|
|
14235
|
+
};
|
|
14236
|
+
var parseGitVersion = (raw) => {
|
|
14237
|
+
const match = raw.match(/git version (\d+)\.(\d+)\.(\d+)/i);
|
|
14238
|
+
if (!match)
|
|
14239
|
+
return null;
|
|
14240
|
+
return {
|
|
14241
|
+
major: Number(match[1]),
|
|
14242
|
+
minor: Number(match[2]),
|
|
14243
|
+
patch: Number(match[3])
|
|
14244
|
+
};
|
|
14245
|
+
};
|
|
14246
|
+
var isGitVersionAtLeast = (version, target) => {
|
|
14247
|
+
if (version.major !== target.major)
|
|
14248
|
+
return version.major > target.major;
|
|
14249
|
+
if (version.minor !== target.minor)
|
|
14250
|
+
return version.minor > target.minor;
|
|
14251
|
+
return version.patch >= target.patch;
|
|
14252
|
+
};
|
|
14253
|
+
var getGitVersion = async (env) => new Promise((resolve) => {
|
|
14254
|
+
execFile2("git", ["--version"], { env }, (error, stdout) => {
|
|
14255
|
+
if (error) {
|
|
14256
|
+
console.log(`[getGitVersion] execFile error: ${error.message}`);
|
|
14257
|
+
return resolve(null);
|
|
14258
|
+
}
|
|
14259
|
+
const raw = stdout.trim();
|
|
14260
|
+
const parsed = parseGitVersion(raw);
|
|
14261
|
+
console.log(`[getGitVersion] raw="${raw}" parsed=${JSON.stringify(parsed)}`);
|
|
14262
|
+
resolve(parsed);
|
|
14263
|
+
});
|
|
14264
|
+
});
|
|
14265
|
+
var EXEC_GIT_MAX_BUFFER = 20 * 1024 * 1024;
|
|
14266
|
+
var execGit = async (args, options = {}) => new Promise((resolve, reject) => {
|
|
14267
|
+
execFile2("git", args, { cwd: options.cwd, env: options.env, maxBuffer: EXEC_GIT_MAX_BUFFER }, (error, stdout, stderr) => {
|
|
14268
|
+
if (error) {
|
|
14269
|
+
reject(error);
|
|
14270
|
+
return;
|
|
14271
|
+
}
|
|
14272
|
+
resolve({ stdout: stdout.toString(), stderr: stderr.toString() });
|
|
14273
|
+
});
|
|
14274
|
+
});
|
|
14275
|
+
var GIT_PROGRESS_RE = /(Enumerating|Receiving|Counting|Compressing|Resolving) (?:objects|deltas):\s+(\d+)%\s*(?:\([^)]*\))?/;
|
|
14276
|
+
var GIT_PHASE_WEIGHTS = {
|
|
14277
|
+
Enumerating: [0, 3],
|
|
14278
|
+
Counting: [3, 6],
|
|
14279
|
+
Compressing: [6, 10],
|
|
14280
|
+
Receiving: [10, 90],
|
|
14281
|
+
Resolving: [90, 100]
|
|
14282
|
+
};
|
|
14283
|
+
var weightedPercent = (phase, rawPercent) => {
|
|
14284
|
+
const [start, end] = GIT_PHASE_WEIGHTS[phase] ?? [0, 100];
|
|
14285
|
+
return Math.round(start + rawPercent / 100 * (end - start));
|
|
14286
|
+
};
|
|
14287
|
+
var runGitWithProgress = async (args, options) => new Promise((resolve, reject) => {
|
|
14288
|
+
console.log(`[runGitWithProgress] spawn: git ${args.join(" ")}`);
|
|
14289
|
+
const child = spawn("git", args, {
|
|
14290
|
+
cwd: options.cwd,
|
|
14291
|
+
env: options.env,
|
|
14292
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
14293
|
+
});
|
|
14294
|
+
let lastWeighted = null;
|
|
14295
|
+
let stderrBuf = "";
|
|
14296
|
+
child.stderr.on("data", (chunk) => {
|
|
14297
|
+
const text = chunk.toString();
|
|
14298
|
+
stderrBuf += text;
|
|
14299
|
+
const lines = stderrBuf.split(/[\r\n]+/);
|
|
14300
|
+
stderrBuf = lines.pop() ?? "";
|
|
14301
|
+
for (const line of lines) {
|
|
14302
|
+
const trimmed = line.trim();
|
|
14303
|
+
if (!trimmed)
|
|
14304
|
+
continue;
|
|
14305
|
+
options.onStderr?.(trimmed);
|
|
14306
|
+
const match = trimmed.match(GIT_PROGRESS_RE);
|
|
14307
|
+
if (match) {
|
|
14308
|
+
const phase = match[1];
|
|
14309
|
+
const raw = Number(match[2]);
|
|
14310
|
+
if (!Number.isNaN(raw)) {
|
|
14311
|
+
const weighted = weightedPercent(phase, raw);
|
|
14312
|
+
if (weighted !== lastWeighted) {
|
|
14313
|
+
lastWeighted = weighted;
|
|
14314
|
+
options.onProgress?.({ percent: weighted, label: trimmed });
|
|
14315
|
+
}
|
|
14316
|
+
}
|
|
14317
|
+
}
|
|
14318
|
+
}
|
|
14319
|
+
});
|
|
14320
|
+
child.on("error", (error) => {
|
|
14321
|
+
reject(error);
|
|
14322
|
+
});
|
|
14323
|
+
child.on("close", (code) => {
|
|
14324
|
+
if (stderrBuf.trim()) {
|
|
14325
|
+
options.onStderr?.(stderrBuf.trim());
|
|
14326
|
+
}
|
|
14327
|
+
if (code === 0) {
|
|
14328
|
+
console.log("[runGitWithProgress] finished successfully");
|
|
14329
|
+
resolve();
|
|
14330
|
+
} else {
|
|
14331
|
+
reject(new Error(`git ${args.join(" ")} failed with code ${code}`));
|
|
14332
|
+
}
|
|
14333
|
+
});
|
|
14334
|
+
});
|
|
14335
|
+
|
|
14336
|
+
// src/handlers/configSetAuth.ts
|
|
14337
|
+
var ensureWorkDir = (workDir) => {
|
|
14338
|
+
if (!workDir) {
|
|
14339
|
+
throw new RpcError(JSON_RPC_ERROR_CODES.INVALID_PARAMS, "Work dir not configured");
|
|
14340
|
+
}
|
|
14341
|
+
return workDir;
|
|
14342
|
+
};
|
|
14343
|
+
var formatCredentialLines = (hosts) => hosts.map((host) => {
|
|
14344
|
+
const authUser = host.auth_user ?? "oauth2";
|
|
14345
|
+
return `https://${authUser}:${host.token}@${host.host}`;
|
|
14346
|
+
});
|
|
14347
|
+
var createConfigSetAuthHandler = (workDir) => async (params, _context) => {
|
|
14348
|
+
const payload = params;
|
|
14349
|
+
const hosts = Array.isArray(payload?.hosts) ? payload.hosts : null;
|
|
14350
|
+
if (!hosts) {
|
|
14351
|
+
throw new RpcError(JSON_RPC_ERROR_CODES.INVALID_PARAMS, "Invalid hosts");
|
|
14352
|
+
}
|
|
14353
|
+
for (const entry of hosts) {
|
|
14354
|
+
ensureString(entry?.host, "host");
|
|
14355
|
+
ensureString(entry?.auth_user, "auth_user");
|
|
14356
|
+
ensureString(entry?.token, "token");
|
|
14357
|
+
}
|
|
14358
|
+
const rootDir = ensureWorkDir(workDir);
|
|
14359
|
+
await mkdir(rootDir, { recursive: true });
|
|
14360
|
+
const configPath = gitConfigPath(rootDir);
|
|
14361
|
+
const credentialsPath = gitCredentialsPath(rootDir);
|
|
14362
|
+
const configContent = `[credential]
|
|
14363
|
+
helper = store --file ${credentialsPath}
|
|
14364
|
+
`;
|
|
14365
|
+
await writeFile(configPath, configContent, "utf-8");
|
|
14366
|
+
const lines = formatCredentialLines(hosts);
|
|
14367
|
+
await writeFile(credentialsPath, `${lines.join(`
|
|
14368
|
+
`)}
|
|
14369
|
+
`, "utf-8");
|
|
14370
|
+
await chmod(credentialsPath, 384);
|
|
14371
|
+
return { ok: true };
|
|
14372
|
+
};
|
|
14373
|
+
|
|
14374
|
+
// src/handlers/vcsClone.ts
|
|
14375
|
+
import { mkdir as mkdir2, rename, rm } from "node:fs/promises";
|
|
14376
|
+
import path8 from "node:path";
|
|
14377
|
+
var MIN_GIT_VERSION = { major: 2, minor: 5, patch: 0 };
|
|
14378
|
+
var ensureWorkDir2 = (workDir) => {
|
|
14379
|
+
if (!workDir) {
|
|
14380
|
+
throw new RpcError(JSON_RPC_ERROR_CODES.INVALID_PARAMS, "Work dir not configured");
|
|
14381
|
+
}
|
|
14382
|
+
return workDir;
|
|
14383
|
+
};
|
|
14384
|
+
var extractRepoNameFromUrl = (url) => {
|
|
14385
|
+
try {
|
|
14386
|
+
const parsed = new URL(url);
|
|
14387
|
+
const name = parsed.pathname.split("/").filter(Boolean).pop() ?? "repo";
|
|
14388
|
+
return name.replace(/\.git$/i, "") || "repo";
|
|
14389
|
+
} catch {
|
|
14390
|
+
return "repo";
|
|
14391
|
+
}
|
|
14392
|
+
};
|
|
14393
|
+
var getRepoDir = (workDir, repoName) => path8.join(workDir, "repos", repoName);
|
|
14394
|
+
var notifyProgress = (notify, percent, detail) => {
|
|
14395
|
+
if (!notify)
|
|
14396
|
+
return;
|
|
14397
|
+
const payload = {
|
|
14398
|
+
stage: "cloning",
|
|
14399
|
+
label: "cloning",
|
|
14400
|
+
percent,
|
|
14401
|
+
...detail ? { detail } : {}
|
|
14402
|
+
};
|
|
14403
|
+
notify("task/progress", payload);
|
|
14404
|
+
};
|
|
14405
|
+
var getRemoteUrl = async (repoDir, env) => {
|
|
14406
|
+
try {
|
|
14407
|
+
const result = await execGit(["-C", repoDir, "config", "--get", "remote.origin.url"], { env });
|
|
14408
|
+
const url = result.stdout.trim();
|
|
14409
|
+
return url.length > 0 ? url : null;
|
|
14410
|
+
} catch {
|
|
14411
|
+
return null;
|
|
14412
|
+
}
|
|
14413
|
+
};
|
|
14414
|
+
var getHeadCommit = async (repoDir, env) => {
|
|
14415
|
+
const result = await execGit(["-C", repoDir, "rev-parse", "HEAD"], { env });
|
|
14416
|
+
return result.stdout.trim();
|
|
14417
|
+
};
|
|
14418
|
+
var createVcsCloneHandler = (workDir) => async (params, context) => {
|
|
14419
|
+
const payload = params;
|
|
14420
|
+
const url = ensureString(payload?.url, "url");
|
|
14421
|
+
const ref = payload?.ref;
|
|
14422
|
+
const commit = payload?.commit;
|
|
14423
|
+
if (ref !== undefined) {
|
|
14424
|
+
ensureString(ref, "ref");
|
|
14425
|
+
}
|
|
14426
|
+
if (commit !== undefined) {
|
|
14427
|
+
ensureString(commit, "commit");
|
|
14428
|
+
}
|
|
14429
|
+
const rootDir = ensureWorkDir2(workDir);
|
|
14430
|
+
const repoName = payload?.repo_name || extractRepoNameFromUrl(url);
|
|
14431
|
+
const repoDir = getRepoDir(rootDir, repoName);
|
|
14432
|
+
const env = createGitEnv(rootDir);
|
|
14433
|
+
if (commit) {
|
|
14434
|
+
const version = await getGitVersion(env);
|
|
14435
|
+
console.log(`[vcs/clone] git version check: parsed=${JSON.stringify(version)}, env.PATH=${env?.PATH ?? process.env.PATH}`);
|
|
14436
|
+
if (!version || !isGitVersionAtLeast(version, MIN_GIT_VERSION)) {
|
|
14437
|
+
const current = version ? `${version.major}.${version.minor}.${version.patch}` : "unknown";
|
|
14438
|
+
throw new RpcError(JSON_RPC_ERROR_CODES.INVALID_PARAMS, `Commit hash checkout requires Git 2.5+, current version: ${current}. Please use branch/tag selection instead.`);
|
|
14439
|
+
}
|
|
14440
|
+
}
|
|
14441
|
+
await mkdir2(rootDir, { recursive: true });
|
|
14442
|
+
const legacyRepoDir = path8.join(rootDir, "repo");
|
|
14443
|
+
const hasNewDir = await execGit(["-C", repoDir, "rev-parse", "--git-dir"], { env }).then(() => true).catch(() => false);
|
|
14444
|
+
if (!hasNewDir) {
|
|
14445
|
+
const hasLegacy = await execGit(["-C", legacyRepoDir, "rev-parse", "--git-dir"], { env }).then(() => true).catch(() => false);
|
|
14446
|
+
if (hasLegacy) {
|
|
14447
|
+
const legacyRemote = await getRemoteUrl(legacyRepoDir, env);
|
|
14448
|
+
if (legacyRemote && stripAuthFromUrl(legacyRemote) === stripAuthFromUrl(url)) {
|
|
14449
|
+
await mkdir2(path8.dirname(repoDir), { recursive: true });
|
|
14450
|
+
await rename(legacyRepoDir, repoDir);
|
|
14451
|
+
}
|
|
14452
|
+
}
|
|
14453
|
+
}
|
|
14454
|
+
const hasGitDir = await execGit(["-C", repoDir, "rev-parse", "--git-dir"], { env }).then(() => true).catch(() => false);
|
|
14455
|
+
if (hasGitDir) {
|
|
14456
|
+
const remoteUrl = await getRemoteUrl(repoDir, env);
|
|
14457
|
+
if (remoteUrl && stripAuthFromUrl(remoteUrl) === stripAuthFromUrl(url)) {
|
|
14458
|
+
if (commit) {
|
|
14459
|
+
await runGitWithProgress(["-C", repoDir, "fetch", "--depth=1", "--progress", "origin", commit], {
|
|
14460
|
+
env,
|
|
14461
|
+
onProgress: ({ percent, label }) => notifyProgress(context?.notify, percent, label),
|
|
14462
|
+
onStderr: (text) => console.log(`[vcs/clone] git: ${text}`)
|
|
14463
|
+
});
|
|
14464
|
+
await execGit(["-C", repoDir, "checkout", commit], { env });
|
|
14465
|
+
} else {
|
|
14466
|
+
const refToUse = ref ?? "HEAD";
|
|
14467
|
+
await runGitWithProgress(["-C", repoDir, "fetch", "--depth=1", "--progress", "origin", refToUse], {
|
|
14468
|
+
env,
|
|
14469
|
+
onProgress: ({ percent, label }) => notifyProgress(context?.notify, percent, label),
|
|
14470
|
+
onStderr: (text) => console.log(`[vcs/clone] git: ${text}`)
|
|
14471
|
+
});
|
|
14472
|
+
await execGit(["-C", repoDir, "checkout", "FETCH_HEAD"], { env });
|
|
14473
|
+
}
|
|
14474
|
+
} else {
|
|
14475
|
+
await rm(repoDir, { recursive: true, force: true });
|
|
14476
|
+
}
|
|
14477
|
+
}
|
|
14478
|
+
const repoExists = await execGit(["-C", repoDir, "rev-parse", "--git-dir"], { env }).then(() => true).catch(() => false);
|
|
14479
|
+
if (!repoExists) {
|
|
14480
|
+
if (commit) {
|
|
14481
|
+
await mkdir2(repoDir, { recursive: true });
|
|
14482
|
+
await execGit(["-C", repoDir, "init"], { env });
|
|
14483
|
+
await execGit(["-C", repoDir, "remote", "add", "origin", url], { env });
|
|
14484
|
+
await runGitWithProgress(["-C", repoDir, "fetch", "--depth=1", "--progress", "origin", commit], {
|
|
14485
|
+
env,
|
|
14486
|
+
onProgress: ({ percent, label }) => notifyProgress(context?.notify, percent, label),
|
|
14487
|
+
onStderr: (text) => console.log(`[vcs/clone] git: ${text}`)
|
|
14488
|
+
});
|
|
14489
|
+
await execGit(["-C", repoDir, "checkout", commit], { env });
|
|
14490
|
+
} else if (ref) {
|
|
14491
|
+
await runGitWithProgress(["clone", "--depth=1", "--branch", ref, "--progress", url, repoDir], {
|
|
14492
|
+
env,
|
|
14493
|
+
onProgress: ({ percent, label }) => notifyProgress(context?.notify, percent, label),
|
|
14494
|
+
onStderr: (text) => console.log(`[vcs/clone] git: ${text}`)
|
|
14495
|
+
});
|
|
14496
|
+
} else {
|
|
14497
|
+
await runGitWithProgress(["clone", "--depth=1", "--progress", url, repoDir], {
|
|
14498
|
+
env,
|
|
14499
|
+
onProgress: ({ percent, label }) => notifyProgress(context?.notify, percent, label),
|
|
14500
|
+
onStderr: (text) => console.log(`[vcs/clone] git: ${text}`)
|
|
14501
|
+
});
|
|
14502
|
+
}
|
|
14503
|
+
}
|
|
14504
|
+
const commitHash = await getHeadCommit(repoDir, env);
|
|
14505
|
+
return { path: repoDir, commit_hash: commitHash };
|
|
14506
|
+
};
|
|
14507
|
+
|
|
14508
|
+
// src/handlers/vcsRefs.ts
|
|
14509
|
+
var parseLsRemoteOutput = (raw) => {
|
|
14510
|
+
const entries = [];
|
|
14511
|
+
const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
14512
|
+
for (const line of lines) {
|
|
14513
|
+
if (line.startsWith("ref: "))
|
|
14514
|
+
continue;
|
|
14515
|
+
const [commit, ref] = line.split(/\s+/);
|
|
14516
|
+
if (!commit || !ref)
|
|
14517
|
+
continue;
|
|
14518
|
+
if (ref.endsWith("^{}"))
|
|
14519
|
+
continue;
|
|
14520
|
+
entries.push({ name: ref, commit });
|
|
14521
|
+
}
|
|
14522
|
+
return entries;
|
|
14523
|
+
};
|
|
14524
|
+
var extractDefaultBranch = (raw) => {
|
|
14525
|
+
const line = raw.split(/\r?\n/).find((item) => item.startsWith("ref: "));
|
|
14526
|
+
if (!line)
|
|
14527
|
+
return null;
|
|
14528
|
+
const match = line.match(/^ref: refs\/heads\/(.+?)\s+HEAD/);
|
|
14529
|
+
return match?.[1] ?? null;
|
|
14530
|
+
};
|
|
14531
|
+
var splitRefs = (entries) => {
|
|
14532
|
+
const branches = [];
|
|
14533
|
+
const tags = [];
|
|
14534
|
+
for (const entry of entries) {
|
|
14535
|
+
if (entry.name.startsWith("refs/heads/")) {
|
|
14536
|
+
branches.push({ name: entry.name.replace("refs/heads/", ""), commit: entry.commit });
|
|
14537
|
+
} else if (entry.name.startsWith("refs/tags/")) {
|
|
14538
|
+
tags.push({ name: entry.name.replace("refs/tags/", ""), commit: entry.commit });
|
|
14539
|
+
}
|
|
14540
|
+
}
|
|
14541
|
+
return { branches, tags };
|
|
14542
|
+
};
|
|
14543
|
+
var createVcsRefsHandler = (workDir) => async (params, _context) => {
|
|
14544
|
+
const payload = params;
|
|
14545
|
+
const url = ensureString(payload?.url, "url");
|
|
14546
|
+
const env = createGitEnv(workDir);
|
|
14547
|
+
try {
|
|
14548
|
+
const out = await execGit(["ls-remote", "--symref", url, "HEAD", "refs/heads/*", "refs/tags/*"], { env });
|
|
14549
|
+
const defaultBranch = extractDefaultBranch(out.stdout) ?? "HEAD";
|
|
14550
|
+
const parsed = parseLsRemoteOutput(out.stdout);
|
|
14551
|
+
const { branches, tags } = splitRefs(parsed);
|
|
14552
|
+
return { branches, tags, default: defaultBranch };
|
|
14553
|
+
} catch (error) {
|
|
14554
|
+
const message = error instanceof Error ? error.message : "Failed to list refs";
|
|
14555
|
+
throw new RpcError(JSON_RPC_ERROR_CODES.INTERNAL_ERROR, message);
|
|
14556
|
+
}
|
|
14557
|
+
};
|
|
14558
|
+
|
|
13841
14559
|
// src/handlers/index.ts
|
|
13842
|
-
var
|
|
14560
|
+
var createDaemonHandlers = (allowedPaths, workDir) => ({
|
|
13843
14561
|
"fs/listTree": createFsListTreeHandler(allowedPaths),
|
|
13844
14562
|
"fs/dirScan": createFsDirScanHandler(allowedPaths),
|
|
13845
14563
|
"fs/exists": createFsExistsHandler(allowedPaths),
|
|
@@ -13849,7 +14567,10 @@ var createFsHandlers = (allowedPaths) => ({
|
|
|
13849
14567
|
"fs/repoStatus": createFsRepoStatusHandler(allowedPaths),
|
|
13850
14568
|
"fs/commitExists": createFsCommitExistsHandler(allowedPaths),
|
|
13851
14569
|
"fs/repoTree": createFsRepoTreeHandler(allowedPaths),
|
|
13852
|
-
"fs/repoScan": createFsRepoScanHandler(allowedPaths)
|
|
14570
|
+
"fs/repoScan": createFsRepoScanHandler(allowedPaths),
|
|
14571
|
+
"config/setAuth": createConfigSetAuthHandler(workDir),
|
|
14572
|
+
"vcs/clone": createVcsCloneHandler(workDir),
|
|
14573
|
+
"vcs/refs": createVcsRefsHandler(workDir)
|
|
13853
14574
|
});
|
|
13854
14575
|
|
|
13855
14576
|
// src/rpcHandler.ts
|
|
@@ -13869,8 +14590,10 @@ var buildError = (code, message, data) => ({
|
|
|
13869
14590
|
|
|
13870
14591
|
class RpcHandler {
|
|
13871
14592
|
handlers;
|
|
13872
|
-
|
|
14593
|
+
context;
|
|
14594
|
+
constructor(handlers, context = {}) {
|
|
13873
14595
|
this.handlers = new Map(Object.entries(handlers));
|
|
14596
|
+
this.context = context;
|
|
13874
14597
|
}
|
|
13875
14598
|
async handleMessage(raw) {
|
|
13876
14599
|
let payload;
|
|
@@ -13909,7 +14632,7 @@ class RpcHandler {
|
|
|
13909
14632
|
};
|
|
13910
14633
|
}
|
|
13911
14634
|
try {
|
|
13912
|
-
const result = await handler(request.params);
|
|
14635
|
+
const result = await handler(request.params, this.context);
|
|
13913
14636
|
if (request.id === undefined) {
|
|
13914
14637
|
return null;
|
|
13915
14638
|
}
|
|
@@ -13942,6 +14665,7 @@ class WebSocketClient {
|
|
|
13942
14665
|
onError;
|
|
13943
14666
|
reconnectMinDelayMs;
|
|
13944
14667
|
reconnectMaxDelayMs;
|
|
14668
|
+
maxReconnectAttempts;
|
|
13945
14669
|
socket = null;
|
|
13946
14670
|
shouldReconnect = true;
|
|
13947
14671
|
reconnectAttempt = 0;
|
|
@@ -13955,6 +14679,7 @@ class WebSocketClient {
|
|
|
13955
14679
|
this.onError = options.onError;
|
|
13956
14680
|
this.reconnectMinDelayMs = options.reconnectMinDelayMs ?? 1000;
|
|
13957
14681
|
this.reconnectMaxDelayMs = options.reconnectMaxDelayMs ?? 30000;
|
|
14682
|
+
this.maxReconnectAttempts = options.maxReconnectAttempts ?? 64;
|
|
13958
14683
|
}
|
|
13959
14684
|
connect() {
|
|
13960
14685
|
this.shouldReconnect = true;
|
|
@@ -14066,6 +14791,11 @@ class WebSocketClient {
|
|
|
14066
14791
|
this.socket.send(JSON.stringify(response));
|
|
14067
14792
|
}
|
|
14068
14793
|
scheduleReconnect() {
|
|
14794
|
+
if (this.maxReconnectAttempts > 0 && this.reconnectAttempt >= this.maxReconnectAttempts) {
|
|
14795
|
+
console.error(`[WebSocketClient] Max reconnect attempts (${this.maxReconnectAttempts}) reached, giving up`);
|
|
14796
|
+
this.shouldReconnect = false;
|
|
14797
|
+
return;
|
|
14798
|
+
}
|
|
14069
14799
|
const delay = Math.min(this.reconnectMaxDelayMs, this.reconnectMinDelayMs * 2 ** this.reconnectAttempt);
|
|
14070
14800
|
this.reconnectAttempt += 1;
|
|
14071
14801
|
setTimeout(() => {
|
|
@@ -14085,7 +14815,7 @@ class WebSocketClient {
|
|
|
14085
14815
|
|
|
14086
14816
|
// src/index.ts
|
|
14087
14817
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
14088
|
-
import { join, dirname } from "node:path";
|
|
14818
|
+
import { join, dirname, resolve } from "node:path";
|
|
14089
14819
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
14090
14820
|
function readVersion() {
|
|
14091
14821
|
try {
|
|
@@ -14101,13 +14831,24 @@ function readVersion() {
|
|
|
14101
14831
|
return "unknown";
|
|
14102
14832
|
}
|
|
14103
14833
|
var program2 = new Command;
|
|
14104
|
-
program2.name("c4a-daemon").description("C4A daemon for local filesystem access").version(readVersion(), "-V, --version").option("--server <host>", "Server host (e.g. localhost:5100, example.com/prefix)", DEFAULT_SERVER_HOST).option("--allow <paths>", "Comma-separated allowed paths (default: all directories)").parse(process.argv);
|
|
14834
|
+
program2.name("c4a-daemon").description("C4A daemon for local filesystem access").version(readVersion(), "-V, --version").option("--server <host>", "Server host (e.g. localhost:5100, example.com/prefix)", DEFAULT_SERVER_HOST).option("--allow <paths>", "Comma-separated allowed paths (default: all directories)").option("--machine-id <id>", "Override daemon machine id (default: hostname)").option("--work-dir <dir>", "Working directory for daemon operations").parse(process.argv);
|
|
14105
14835
|
var options = program2.opts();
|
|
14106
14836
|
var serverUrl = resolveServerUrl(options.server);
|
|
14107
|
-
var
|
|
14837
|
+
var resolvedWorkDir = options.workDir ? resolve(options.workDir) : undefined;
|
|
14838
|
+
var allowedPaths = parseAllowedPaths(options.allow, resolvedWorkDir);
|
|
14108
14839
|
console.log(`Server: ${serverUrl}`);
|
|
14109
14840
|
console.log(`Allowed: ${allowedPaths.join(", ")}`);
|
|
14110
|
-
|
|
14841
|
+
if (resolvedWorkDir) {
|
|
14842
|
+
console.log(`WorkDir: ${resolvedWorkDir}`);
|
|
14843
|
+
}
|
|
14844
|
+
var client;
|
|
14845
|
+
var rpcHandler = new RpcHandler(createDaemonHandlers(allowedPaths, resolvedWorkDir), {
|
|
14846
|
+
notify: (method, params) => {
|
|
14847
|
+
try {
|
|
14848
|
+
client.sendNotification(method, params);
|
|
14849
|
+
} catch {}
|
|
14850
|
+
}
|
|
14851
|
+
});
|
|
14111
14852
|
var heartbeatTimer = null;
|
|
14112
14853
|
var stopHeartbeat = () => {
|
|
14113
14854
|
if (heartbeatTimer) {
|
|
@@ -14115,18 +14856,18 @@ var stopHeartbeat = () => {
|
|
|
14115
14856
|
heartbeatTimer = null;
|
|
14116
14857
|
}
|
|
14117
14858
|
};
|
|
14118
|
-
var startHeartbeat = (
|
|
14859
|
+
var startHeartbeat = (client2, machineId) => {
|
|
14119
14860
|
stopHeartbeat();
|
|
14120
14861
|
heartbeatTimer = setInterval(() => {
|
|
14121
|
-
|
|
14862
|
+
client2.sendNotification("daemon/heartbeat", { machine_id: machineId, timestamp: Date.now() });
|
|
14122
14863
|
}, DAEMON_HEARTBEAT_INTERVAL);
|
|
14123
14864
|
};
|
|
14124
|
-
|
|
14865
|
+
client = new WebSocketClient({
|
|
14125
14866
|
url: serverUrl,
|
|
14126
14867
|
onRequest: (request) => rpcHandler.handleRequest(request),
|
|
14127
14868
|
onOpen: async () => {
|
|
14128
14869
|
try {
|
|
14129
|
-
const handshakePayload = buildHandshakePayload(allowedPaths);
|
|
14870
|
+
const handshakePayload = buildHandshakePayload(allowedPaths, options.machineId);
|
|
14130
14871
|
const response = await client.sendRpcRequest("daemon/handshake", handshakePayload);
|
|
14131
14872
|
if ("error" in response) {
|
|
14132
14873
|
console.error(`Handshake error: ${response.error.message}`);
|