helixevo 0.2.41 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +19 -6
- package/dashboard/app/commands/page.tsx +17 -0
- package/dashboard/app/evolution/page.tsx +58 -37
- package/dashboard/app/guide/page.tsx +35 -1
- package/dashboard/app/network/client.tsx +125 -1
- package/dashboard/app/network/page.tsx +3 -1
- package/dashboard/app/page.tsx +57 -1
- package/dashboard/app/projects/client.tsx +21 -2
- package/dashboard/app/projects/page.tsx +29 -2
- package/dashboard/app/research/client.tsx +67 -1
- package/dashboard/app/research/page.tsx +3 -2
- package/dashboard/lib/data.ts +443 -1
- package/dist/cli.js +532 -109
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -9174,9 +9174,240 @@ var init_skills = __esm(() => {
|
|
|
9174
9174
|
FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
9175
9175
|
});
|
|
9176
9176
|
|
|
9177
|
+
// src/ontology/entities.ts
|
|
9178
|
+
var ONTOLOGY_KERNEL_ENTITY_NAMES;
|
|
9179
|
+
var init_entities = __esm(() => {
|
|
9180
|
+
ONTOLOGY_KERNEL_ENTITY_NAMES = [
|
|
9181
|
+
"ProjectRecord",
|
|
9182
|
+
"SessionRecord",
|
|
9183
|
+
"TaskRecord",
|
|
9184
|
+
"FailureRecord",
|
|
9185
|
+
"PressureSignal",
|
|
9186
|
+
"Capability",
|
|
9187
|
+
"SkillNode",
|
|
9188
|
+
"SkillRelation",
|
|
9189
|
+
"ActivationEvent",
|
|
9190
|
+
"MutationProposal",
|
|
9191
|
+
"TopologyChange",
|
|
9192
|
+
"EvidenceArtifact",
|
|
9193
|
+
"EvaluationResult",
|
|
9194
|
+
"TransferEvent",
|
|
9195
|
+
"GovernanceMode",
|
|
9196
|
+
"HealthMetric",
|
|
9197
|
+
"LineageRecord",
|
|
9198
|
+
"OntologyConcept",
|
|
9199
|
+
"OntologyChangeEvent"
|
|
9200
|
+
];
|
|
9201
|
+
});
|
|
9202
|
+
|
|
9203
|
+
// src/ontology/relations.ts
|
|
9204
|
+
var ONTOLOGY_RELATION_FAMILIES;
|
|
9205
|
+
var init_relations = __esm(() => {
|
|
9206
|
+
ONTOLOGY_RELATION_FAMILIES = [
|
|
9207
|
+
"belongs_to",
|
|
9208
|
+
"derived_from",
|
|
9209
|
+
"replaced_by",
|
|
9210
|
+
"parent_of",
|
|
9211
|
+
"child_of",
|
|
9212
|
+
"specializes",
|
|
9213
|
+
"generalizes_from",
|
|
9214
|
+
"depends_on",
|
|
9215
|
+
"enhances",
|
|
9216
|
+
"conflicts_with",
|
|
9217
|
+
"co_evolves_with",
|
|
9218
|
+
"covers",
|
|
9219
|
+
"activated_for",
|
|
9220
|
+
"suppressed_by",
|
|
9221
|
+
"contributed_to",
|
|
9222
|
+
"competed_with",
|
|
9223
|
+
"triggered_by",
|
|
9224
|
+
"validated_by",
|
|
9225
|
+
"contradicted_by",
|
|
9226
|
+
"survived_in",
|
|
9227
|
+
"requires_review",
|
|
9228
|
+
"proposed_due_to",
|
|
9229
|
+
"benefits",
|
|
9230
|
+
"transferred_to",
|
|
9231
|
+
"refined_by",
|
|
9232
|
+
"promoted_from",
|
|
9233
|
+
"executed_under",
|
|
9234
|
+
"deferred_by",
|
|
9235
|
+
"prioritized_by",
|
|
9236
|
+
"locked_by",
|
|
9237
|
+
"measures",
|
|
9238
|
+
"signals_weakness_in",
|
|
9239
|
+
"suggests_repair_for"
|
|
9240
|
+
];
|
|
9241
|
+
});
|
|
9242
|
+
|
|
9243
|
+
// src/ontology/operations.ts
|
|
9244
|
+
var SKILL_OPERATIONS, TOPOLOGY_OPERATIONS, ONTOLOGY_OPERATIONS, GOVERNANCE_OPERATIONS, ONTOLOGY_MUTATION_OPERATIONS, ONTOLOGY_ALL_OPERATIONS;
|
|
9245
|
+
var init_operations = __esm(() => {
|
|
9246
|
+
SKILL_OPERATIONS = [
|
|
9247
|
+
"create_skill",
|
|
9248
|
+
"edit_skill",
|
|
9249
|
+
"specialize_skill",
|
|
9250
|
+
"generalize_skill",
|
|
9251
|
+
"promote_skill",
|
|
9252
|
+
"demote_skill",
|
|
9253
|
+
"retire_skill"
|
|
9254
|
+
];
|
|
9255
|
+
TOPOLOGY_OPERATIONS = [
|
|
9256
|
+
"merge_skills",
|
|
9257
|
+
"split_skill",
|
|
9258
|
+
"rewire_relation",
|
|
9259
|
+
"prune_branch",
|
|
9260
|
+
"consolidate_cluster"
|
|
9261
|
+
];
|
|
9262
|
+
ONTOLOGY_OPERATIONS = [
|
|
9263
|
+
"hypothesize_concept",
|
|
9264
|
+
"promote_concept",
|
|
9265
|
+
"merge_concepts",
|
|
9266
|
+
"split_concept",
|
|
9267
|
+
"deprecate_concept",
|
|
9268
|
+
"refine_relation_subtype",
|
|
9269
|
+
"add_invariant",
|
|
9270
|
+
"migrate_mapping"
|
|
9271
|
+
];
|
|
9272
|
+
GOVERNANCE_OPERATIONS = [
|
|
9273
|
+
"change_mode",
|
|
9274
|
+
"adjust_plasticity_regime",
|
|
9275
|
+
"allocate_attention",
|
|
9276
|
+
"defer_change",
|
|
9277
|
+
"require_review"
|
|
9278
|
+
];
|
|
9279
|
+
ONTOLOGY_MUTATION_OPERATIONS = [
|
|
9280
|
+
...SKILL_OPERATIONS,
|
|
9281
|
+
...TOPOLOGY_OPERATIONS
|
|
9282
|
+
];
|
|
9283
|
+
ONTOLOGY_ALL_OPERATIONS = [
|
|
9284
|
+
...SKILL_OPERATIONS,
|
|
9285
|
+
...TOPOLOGY_OPERATIONS,
|
|
9286
|
+
...ONTOLOGY_OPERATIONS,
|
|
9287
|
+
...GOVERNANCE_OPERATIONS
|
|
9288
|
+
];
|
|
9289
|
+
});
|
|
9290
|
+
|
|
9291
|
+
// src/ontology/invariants.ts
|
|
9292
|
+
var ONTOLOGY_INVARIANTS;
|
|
9293
|
+
var init_invariants = __esm(() => {
|
|
9294
|
+
ONTOLOGY_INVARIANTS = [
|
|
9295
|
+
{
|
|
9296
|
+
id: "accepted-change-requires-evidence",
|
|
9297
|
+
description: "Every accepted change must reference evidence."
|
|
9298
|
+
},
|
|
9299
|
+
{
|
|
9300
|
+
id: "specialist-requires-local-context",
|
|
9301
|
+
description: "Every specialist skill must be linked to a project or local context."
|
|
9302
|
+
},
|
|
9303
|
+
{
|
|
9304
|
+
id: "promotion-requires-repeated-evidence",
|
|
9305
|
+
description: "Every promotion toward generalist intelligence must cite repeated cross-project or repeated-context evidence."
|
|
9306
|
+
},
|
|
9307
|
+
{
|
|
9308
|
+
id: "relation-requires-family-and-confidence",
|
|
9309
|
+
description: "Every skill relation must declare a relation family and confidence source."
|
|
9310
|
+
},
|
|
9311
|
+
{
|
|
9312
|
+
id: "topology-change-preserves-lineage",
|
|
9313
|
+
description: "Every topology change must preserve or explicitly rewrite lineage."
|
|
9314
|
+
},
|
|
9315
|
+
{
|
|
9316
|
+
id: "deprecated-state-remains-recoverable",
|
|
9317
|
+
description: "Every deprecated skill or concept must remain recoverable through lineage."
|
|
9318
|
+
},
|
|
9319
|
+
{
|
|
9320
|
+
id: "ontology-promotion-requires-migration",
|
|
9321
|
+
description: "Every ontology promotion must include a migration mapping."
|
|
9322
|
+
},
|
|
9323
|
+
{
|
|
9324
|
+
id: "frontier-concepts-stay-provisional",
|
|
9325
|
+
description: "Every frontier concept remains provisional until promoted through review."
|
|
9326
|
+
},
|
|
9327
|
+
{
|
|
9328
|
+
id: "transfer-requires-source-and-target",
|
|
9329
|
+
description: "Every transfer claim must identify source and target contexts."
|
|
9330
|
+
},
|
|
9331
|
+
{
|
|
9332
|
+
id: "high-risk-topology-change-requires-validation",
|
|
9333
|
+
description: "Every accepted high-risk topology change must have replay or equivalent validation."
|
|
9334
|
+
}
|
|
9335
|
+
];
|
|
9336
|
+
});
|
|
9337
|
+
|
|
9338
|
+
// src/ontology/events.ts
|
|
9339
|
+
var ONTOLOGY_EVENT_TYPES;
|
|
9340
|
+
var init_events = __esm(() => {
|
|
9341
|
+
ONTOLOGY_EVENT_TYPES = [
|
|
9342
|
+
"failure_captured",
|
|
9343
|
+
"pressure_detected",
|
|
9344
|
+
"skill_activated",
|
|
9345
|
+
"skill_suppressed",
|
|
9346
|
+
"capability_gap_detected",
|
|
9347
|
+
"mutation_proposed",
|
|
9348
|
+
"mutation_accepted",
|
|
9349
|
+
"mutation_rejected",
|
|
9350
|
+
"topology_changed",
|
|
9351
|
+
"transfer_realized",
|
|
9352
|
+
"replay_completed",
|
|
9353
|
+
"regression_completed",
|
|
9354
|
+
"canary_completed",
|
|
9355
|
+
"rollback_triggered",
|
|
9356
|
+
"concept_hypothesized",
|
|
9357
|
+
"concept_promoted",
|
|
9358
|
+
"concept_rejected",
|
|
9359
|
+
"concept_merged",
|
|
9360
|
+
"concept_split",
|
|
9361
|
+
"governance_changed"
|
|
9362
|
+
];
|
|
9363
|
+
});
|
|
9364
|
+
|
|
9365
|
+
// src/ontology/spec.ts
|
|
9366
|
+
var ONTOLOGY_SPEC_VERSION = "0.1.0", ONTOLOGY_KERNEL_PILLARS, ONTOLOGY_LAYERS, ONTOLOGY_V0_SPEC;
|
|
9367
|
+
var init_spec = __esm(() => {
|
|
9368
|
+
init_entities();
|
|
9369
|
+
init_events();
|
|
9370
|
+
init_invariants();
|
|
9371
|
+
init_operations();
|
|
9372
|
+
init_relations();
|
|
9373
|
+
ONTOLOGY_KERNEL_PILLARS = [
|
|
9374
|
+
"Operational World",
|
|
9375
|
+
"Perception / Pressure",
|
|
9376
|
+
"Working Memory / Activation",
|
|
9377
|
+
"Long-Term Memory",
|
|
9378
|
+
"Plasticity / Topology",
|
|
9379
|
+
"Evidence / Immune System",
|
|
9380
|
+
"Executive / Governance",
|
|
9381
|
+
"Metacognition / Health",
|
|
9382
|
+
"Time / Lineage"
|
|
9383
|
+
];
|
|
9384
|
+
ONTOLOGY_LAYERS = ["kernel", "extension", "frontier", "vocabulary"];
|
|
9385
|
+
ONTOLOGY_V0_SPEC = {
|
|
9386
|
+
version: ONTOLOGY_SPEC_VERSION,
|
|
9387
|
+
pillars: [...ONTOLOGY_KERNEL_PILLARS],
|
|
9388
|
+
layers: [...ONTOLOGY_LAYERS],
|
|
9389
|
+
entityNames: [...ONTOLOGY_KERNEL_ENTITY_NAMES],
|
|
9390
|
+
relationFamilies: [...ONTOLOGY_RELATION_FAMILIES],
|
|
9391
|
+
mutationOperations: [...ONTOLOGY_MUTATION_OPERATIONS],
|
|
9392
|
+
operations: [...ONTOLOGY_ALL_OPERATIONS],
|
|
9393
|
+
invariantIds: ONTOLOGY_INVARIANTS.map((invariant) => invariant.id),
|
|
9394
|
+
eventTypes: [...ONTOLOGY_EVENT_TYPES]
|
|
9395
|
+
};
|
|
9396
|
+
});
|
|
9397
|
+
|
|
9398
|
+
// src/ontology/index.ts
|
|
9399
|
+
var init_ontology = __esm(() => {
|
|
9400
|
+
init_entities();
|
|
9401
|
+
init_relations();
|
|
9402
|
+
init_operations();
|
|
9403
|
+
init_invariants();
|
|
9404
|
+
init_events();
|
|
9405
|
+
init_spec();
|
|
9406
|
+
});
|
|
9407
|
+
|
|
9177
9408
|
// src/utils/data.ts
|
|
9178
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, appendFileSync, existsSync as existsSync3 } from "node:fs";
|
|
9179
|
-
import { dirname } from "node:path";
|
|
9409
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, appendFileSync, existsSync as existsSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
9410
|
+
import { dirname, join as join3 } from "node:path";
|
|
9180
9411
|
function readJsonl(filename) {
|
|
9181
9412
|
const path = getDataPath(filename);
|
|
9182
9413
|
if (!existsSync3(path))
|
|
@@ -9246,19 +9477,45 @@ function loadSkillGraph() {
|
|
|
9246
9477
|
function saveSkillGraph(graph) {
|
|
9247
9478
|
writeJson("skill-graph.json", graph);
|
|
9248
9479
|
}
|
|
9480
|
+
function appendEvolutionArtifact(artifact) {
|
|
9481
|
+
appendJsonl("evolution-artifacts.jsonl", artifact);
|
|
9482
|
+
}
|
|
9483
|
+
function appendActivationTrace(trace) {
|
|
9484
|
+
appendJsonl("activation-traces.jsonl", trace);
|
|
9485
|
+
}
|
|
9486
|
+
function appendPressureSignal(signal) {
|
|
9487
|
+
appendJsonl("pressure-signals.jsonl", signal);
|
|
9488
|
+
}
|
|
9249
9489
|
var init_data = __esm(() => {
|
|
9490
|
+
init_ontology();
|
|
9250
9491
|
init_config();
|
|
9251
9492
|
});
|
|
9252
9493
|
|
|
9253
9494
|
// src/utils/llm.ts
|
|
9254
9495
|
import { spawn } from "node:child_process";
|
|
9255
|
-
function
|
|
9496
|
+
function buildClaudeEnv({ dropOauthToken }) {
|
|
9497
|
+
const env = { ...process.env };
|
|
9498
|
+
if (dropOauthToken) {
|
|
9499
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
9500
|
+
}
|
|
9501
|
+
return env;
|
|
9502
|
+
}
|
|
9503
|
+
function runClaudeOnce(prompt, args, env) {
|
|
9256
9504
|
return new Promise((resolve, reject) => {
|
|
9257
9505
|
const proc = spawn("claude", args, {
|
|
9258
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
9506
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
9507
|
+
env
|
|
9259
9508
|
});
|
|
9260
9509
|
let stdout = "";
|
|
9261
9510
|
let stderr = "";
|
|
9511
|
+
let settled = false;
|
|
9512
|
+
const timeout = setTimeout(() => {
|
|
9513
|
+
proc.kill();
|
|
9514
|
+
if (!settled) {
|
|
9515
|
+
settled = true;
|
|
9516
|
+
reject(new Error("claude call timed out after 180s"));
|
|
9517
|
+
}
|
|
9518
|
+
}, 180000);
|
|
9262
9519
|
proc.stdout.on("data", (data) => {
|
|
9263
9520
|
stdout += data.toString();
|
|
9264
9521
|
});
|
|
@@ -9266,23 +9523,42 @@ function runClaude(prompt, args) {
|
|
|
9266
9523
|
stderr += data.toString();
|
|
9267
9524
|
});
|
|
9268
9525
|
proc.on("close", (code) => {
|
|
9526
|
+
clearTimeout(timeout);
|
|
9527
|
+
if (settled)
|
|
9528
|
+
return;
|
|
9529
|
+
settled = true;
|
|
9269
9530
|
if (code !== 0) {
|
|
9270
|
-
|
|
9531
|
+
const output = (stderr || stdout).slice(0, 500);
|
|
9532
|
+
reject(new Error(`claude exited with code ${code}: ${output}`));
|
|
9271
9533
|
} else {
|
|
9272
9534
|
resolve(stdout.trim());
|
|
9273
9535
|
}
|
|
9274
9536
|
});
|
|
9275
9537
|
proc.on("error", (err) => {
|
|
9538
|
+
clearTimeout(timeout);
|
|
9539
|
+
if (settled)
|
|
9540
|
+
return;
|
|
9541
|
+
settled = true;
|
|
9276
9542
|
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
9277
9543
|
});
|
|
9278
9544
|
proc.stdin.write(prompt);
|
|
9279
9545
|
proc.stdin.end();
|
|
9280
|
-
setTimeout(() => {
|
|
9281
|
-
proc.kill();
|
|
9282
|
-
reject(new Error("claude call timed out after 180s"));
|
|
9283
|
-
}, 180000);
|
|
9284
9546
|
});
|
|
9285
9547
|
}
|
|
9548
|
+
function isRetryableClaudeAuthError(error) {
|
|
9549
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
9550
|
+
return CLAUDE_AUTH_ERROR_PATTERNS.some((pattern) => message.includes(pattern));
|
|
9551
|
+
}
|
|
9552
|
+
async function runClaude(prompt, args) {
|
|
9553
|
+
try {
|
|
9554
|
+
return await runClaudeOnce(prompt, args, buildClaudeEnv({ dropOauthToken: false }));
|
|
9555
|
+
} catch (error) {
|
|
9556
|
+
if (!process.env.CLAUDE_CODE_OAUTH_TOKEN || !isRetryableClaudeAuthError(error)) {
|
|
9557
|
+
throw error;
|
|
9558
|
+
}
|
|
9559
|
+
return runClaudeOnce(prompt, args, buildClaudeEnv({ dropOauthToken: true }));
|
|
9560
|
+
}
|
|
9561
|
+
}
|
|
9286
9562
|
async function chat(options) {
|
|
9287
9563
|
const config = loadConfig();
|
|
9288
9564
|
const model = options.model ?? config.model;
|
|
@@ -9334,8 +9610,14 @@ async function searchWeb(query) {
|
|
|
9334
9610
|
];
|
|
9335
9611
|
return runClaude(query, args);
|
|
9336
9612
|
}
|
|
9613
|
+
var CLAUDE_AUTH_ERROR_PATTERNS;
|
|
9337
9614
|
var init_llm = __esm(() => {
|
|
9338
9615
|
init_config();
|
|
9616
|
+
CLAUDE_AUTH_ERROR_PATTERNS = [
|
|
9617
|
+
"OAuth token has expired",
|
|
9618
|
+
"authentication_error",
|
|
9619
|
+
"Failed to authenticate"
|
|
9620
|
+
];
|
|
9339
9621
|
});
|
|
9340
9622
|
|
|
9341
9623
|
// src/core/network-health.ts
|
|
@@ -9576,7 +9858,7 @@ init_config();
|
|
|
9576
9858
|
init_skills();
|
|
9577
9859
|
init_data();
|
|
9578
9860
|
init_llm();
|
|
9579
|
-
import { join as
|
|
9861
|
+
import { join as join5 } from "node:path";
|
|
9580
9862
|
import { homedir as homedir2 } from "node:os";
|
|
9581
9863
|
import { existsSync as existsSync4, cpSync } from "node:fs";
|
|
9582
9864
|
|
|
@@ -9607,10 +9889,10 @@ Return JSON:
|
|
|
9607
9889
|
|
|
9608
9890
|
// src/version.ts
|
|
9609
9891
|
import { createRequire as createRequire2 } from "node:module";
|
|
9610
|
-
import { join as
|
|
9892
|
+
import { join as join4, dirname as dirname2 } from "node:path";
|
|
9611
9893
|
import { fileURLToPath } from "node:url";
|
|
9612
9894
|
var require2 = createRequire2(import.meta.url);
|
|
9613
|
-
var pkg = require2(
|
|
9895
|
+
var pkg = require2(join4(dirname2(fileURLToPath(import.meta.url)), "..", "package.json"));
|
|
9614
9896
|
var VERSION = pkg.version;
|
|
9615
9897
|
|
|
9616
9898
|
// src/commands/init.ts
|
|
@@ -9621,22 +9903,22 @@ async function initCommand(options) {
|
|
|
9621
9903
|
const generalDir = getGeneralSkillsPath();
|
|
9622
9904
|
ensureDir(sgDir);
|
|
9623
9905
|
ensureDir(generalDir);
|
|
9624
|
-
if (!existsSync4(
|
|
9906
|
+
if (!existsSync4(join5(sgDir, "config.json"))) {
|
|
9625
9907
|
saveConfig(DEFAULT_CONFIG);
|
|
9626
9908
|
console.log(" ✓ Created config.json");
|
|
9627
9909
|
}
|
|
9628
9910
|
const defaultPaths = [
|
|
9629
|
-
|
|
9630
|
-
|
|
9911
|
+
join5(homedir2(), ".agents", "skills"),
|
|
9912
|
+
join5(homedir2(), ".craft-agent", "workspaces")
|
|
9631
9913
|
];
|
|
9632
9914
|
const scanPaths = options.skillsPaths ?? defaultPaths;
|
|
9633
9915
|
const expandedPaths = [];
|
|
9634
9916
|
for (const p of scanPaths) {
|
|
9635
9917
|
if (p.includes("workspaces") && existsSync4(p)) {
|
|
9636
|
-
const { readdirSync:
|
|
9637
|
-
const workspaces =
|
|
9918
|
+
const { readdirSync: readdirSync3 } = await import("node:fs");
|
|
9919
|
+
const workspaces = readdirSync3(p, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("."));
|
|
9638
9920
|
for (const ws of workspaces) {
|
|
9639
|
-
const skillsDir =
|
|
9921
|
+
const skillsDir = join5(p, ws.name, "skills");
|
|
9640
9922
|
if (existsSync4(skillsDir))
|
|
9641
9923
|
expandedPaths.push(skillsDir);
|
|
9642
9924
|
}
|
|
@@ -9649,7 +9931,7 @@ async function initCommand(options) {
|
|
|
9649
9931
|
`);
|
|
9650
9932
|
let imported = 0;
|
|
9651
9933
|
for (const skill of existingSkills) {
|
|
9652
|
-
const targetDir =
|
|
9934
|
+
const targetDir = join5(generalDir, skill.slug);
|
|
9653
9935
|
if (existsSync4(targetDir)) {
|
|
9654
9936
|
console.log(` → ${skill.slug}: already exists, skipping`);
|
|
9655
9937
|
continue;
|
|
@@ -9747,19 +10029,57 @@ async function captureCommand(sessionPath, options) {
|
|
|
9747
10029
|
}
|
|
9748
10030
|
const project = options.project ?? output.project;
|
|
9749
10031
|
for (const f of output.failures) {
|
|
10032
|
+
const timestamp = new Date().toISOString();
|
|
10033
|
+
const failureId = `f_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
|
|
10034
|
+
const activationTraceId = `activation_${failureId}`;
|
|
10035
|
+
const pressureSignalId = `pressure_${failureId}`;
|
|
9750
10036
|
const record = {
|
|
9751
|
-
id:
|
|
10037
|
+
id: failureId,
|
|
9752
10038
|
sessionId,
|
|
9753
|
-
timestamp
|
|
10039
|
+
timestamp,
|
|
9754
10040
|
project,
|
|
9755
10041
|
userRequest: f.userRequest,
|
|
9756
10042
|
agentAction: f.agentAction,
|
|
9757
10043
|
correction: f.correction,
|
|
9758
10044
|
correctionType: f.correctionType,
|
|
9759
10045
|
skillsActive: f.skillsActive,
|
|
9760
|
-
skillsRelevant: f.skillsActive
|
|
10046
|
+
skillsRelevant: f.skillsActive,
|
|
10047
|
+
activationTraceId,
|
|
10048
|
+
pressureSignals: [pressureSignalId]
|
|
10049
|
+
};
|
|
10050
|
+
const activationTrace = {
|
|
10051
|
+
id: activationTraceId,
|
|
10052
|
+
timestamp,
|
|
10053
|
+
provenance: "capture-derived",
|
|
10054
|
+
sourceId: failureId,
|
|
10055
|
+
projectId: project ?? undefined,
|
|
10056
|
+
sessionId,
|
|
10057
|
+
activatedSkillIds: f.skillsActive,
|
|
10058
|
+
relevantSkillIds: f.skillsActive,
|
|
10059
|
+
reasonSummary: `${f.correctionType} correction captured from session review`,
|
|
10060
|
+
contextSummary: f.correction,
|
|
10061
|
+
relatedFailureId: failureId,
|
|
10062
|
+
traceVersion: "0.1.0"
|
|
10063
|
+
};
|
|
10064
|
+
const pressureSignal = {
|
|
10065
|
+
id: pressureSignalId,
|
|
10066
|
+
kind: `correction:${f.correctionType}`,
|
|
10067
|
+
provenance: "failure-native",
|
|
10068
|
+
sourceType: "failure",
|
|
10069
|
+
sourceId: failureId,
|
|
10070
|
+
projectId: project ?? undefined,
|
|
10071
|
+
detectedAt: timestamp,
|
|
10072
|
+
severity: f.correctionType === "manual_edit" ? 0.95 : f.correctionType === "mode_switch" ? 0.9 : f.correctionType === "retry" ? 0.72 : 0.65,
|
|
10073
|
+
priority: f.correctionType === "manual_edit" || f.correctionType === "mode_switch" ? "high" : f.correctionType === "retry" ? "medium" : "low",
|
|
10074
|
+
description: f.correction,
|
|
10075
|
+
relatedFailureId: failureId,
|
|
10076
|
+
relatedActivationTraceId: activationTraceId,
|
|
10077
|
+
skillIds: f.skillsActive,
|
|
10078
|
+
status: "open"
|
|
9761
10079
|
};
|
|
9762
10080
|
appendFailure(record);
|
|
10081
|
+
appendActivationTrace(activationTrace);
|
|
10082
|
+
appendPressureSignal(pressureSignal);
|
|
9763
10083
|
console.log(` ✓ Captured: "${f.correction.slice(0, 60)}..."`);
|
|
9764
10084
|
}
|
|
9765
10085
|
console.log(`
|
|
@@ -9805,7 +10125,7 @@ init_config();
|
|
|
9805
10125
|
init_data();
|
|
9806
10126
|
init_skills();
|
|
9807
10127
|
init_llm();
|
|
9808
|
-
import { join as
|
|
10128
|
+
import { join as join8 } from "node:path";
|
|
9809
10129
|
|
|
9810
10130
|
// src/prompts/cluster.ts
|
|
9811
10131
|
function buildClusterPrompt(failures, skills, graph) {
|
|
@@ -10216,11 +10536,11 @@ Return JSON: { "score": <number>, "reason": "<one sentence>" }`;
|
|
|
10216
10536
|
// src/core/canary.ts
|
|
10217
10537
|
init_config();
|
|
10218
10538
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync6, cpSync as cpSync2, rmSync } from "node:fs";
|
|
10219
|
-
import { join as
|
|
10220
|
-
var CANARY_DIR =
|
|
10221
|
-
var BACKUPS_DIR =
|
|
10539
|
+
import { join as join6 } from "node:path";
|
|
10540
|
+
var CANARY_DIR = join6(getHelixDir(), "canary");
|
|
10541
|
+
var BACKUPS_DIR = join6(getHelixDir(), "backups");
|
|
10222
10542
|
function getRegistryPath() {
|
|
10223
|
-
return
|
|
10543
|
+
return join6(getHelixDir(), "canary-registry.json");
|
|
10224
10544
|
}
|
|
10225
10545
|
function loadRegistry() {
|
|
10226
10546
|
const path = getRegistryPath();
|
|
@@ -10233,7 +10553,7 @@ function saveRegistry(registry) {
|
|
|
10233
10553
|
}
|
|
10234
10554
|
function backupSkill(skillPath, slug, version) {
|
|
10235
10555
|
ensureDir(BACKUPS_DIR);
|
|
10236
|
-
const backupPath =
|
|
10556
|
+
const backupPath = join6(BACKUPS_DIR, `${slug}_${version}_${Date.now()}`);
|
|
10237
10557
|
if (existsSync6(skillPath)) {
|
|
10238
10558
|
cpSync2(skillPath, backupPath, { recursive: true });
|
|
10239
10559
|
}
|
|
@@ -10315,7 +10635,7 @@ init_config();
|
|
|
10315
10635
|
init_skills();
|
|
10316
10636
|
init_data();
|
|
10317
10637
|
init_llm();
|
|
10318
|
-
import { join as
|
|
10638
|
+
import { join as join7 } from "node:path";
|
|
10319
10639
|
async function autoGeneralize(candidates, verbose = false, dryRun = false) {
|
|
10320
10640
|
const created = [];
|
|
10321
10641
|
const skipped = [];
|
|
@@ -10384,7 +10704,7 @@ Keep it focused and actionable. No filler.`
|
|
|
10384
10704
|
meta.lastEvolved = new Date().toISOString();
|
|
10385
10705
|
meta.tags = [...meta.tags ?? [], "auto-generalized"];
|
|
10386
10706
|
meta.enhances = candidate.sourceSkills;
|
|
10387
|
-
const skillDir =
|
|
10707
|
+
const skillDir = join7(getGeneralSkillsPath(), candidate.suggestedName);
|
|
10388
10708
|
writeSkill(skillDir, meta, content);
|
|
10389
10709
|
created.push(candidate.suggestedName);
|
|
10390
10710
|
console.log(` ✓ Created: ${candidate.suggestedName} (domain layer)`);
|
|
@@ -10489,8 +10809,10 @@ async function evolveCommand(options) {
|
|
|
10489
10809
|
console.log();
|
|
10490
10810
|
}
|
|
10491
10811
|
const generation = getCurrentGeneration() + 1;
|
|
10812
|
+
const iterationId = generateIterationId();
|
|
10492
10813
|
const proposals = [];
|
|
10493
10814
|
const failureClusters = [];
|
|
10815
|
+
const artifacts = [];
|
|
10494
10816
|
let proposalCount = 0;
|
|
10495
10817
|
for (const cluster of clusters.clusters) {
|
|
10496
10818
|
if (proposalCount >= maxProposals)
|
|
@@ -10589,10 +10911,40 @@ async function evolveCommand(options) {
|
|
|
10589
10911
|
outcomeReason: !consensus ? `Rejected: only ${passCount}/3 judges passed` : !passedRegression ? `Rejected: regression ${(regressionResult.passRate * 100).toFixed(0)}% < ${(config.quality.regressionPassRate * 100).toFixed(0)}% threshold` : `Accepted: ${passCount}/3 judges + ${(regressionResult.passRate * 100).toFixed(0)}% regression`,
|
|
10590
10912
|
relatedProposals: proposalOutput.relatedIterations
|
|
10591
10913
|
};
|
|
10914
|
+
const artifactCreatedAt = new Date().toISOString();
|
|
10915
|
+
artifacts.push({
|
|
10916
|
+
id: `artifact_${proposalId}`,
|
|
10917
|
+
createdAt: artifactCreatedAt,
|
|
10918
|
+
artifactType: "evolution",
|
|
10919
|
+
provenance: "native-evolution",
|
|
10920
|
+
sourceId: proposalId,
|
|
10921
|
+
iterationId,
|
|
10922
|
+
proposalId,
|
|
10923
|
+
title: `${skillSlug} · ${proposalOutput.action}`,
|
|
10924
|
+
summary: proposalOutput.diff,
|
|
10925
|
+
targetSkill: skillSlug,
|
|
10926
|
+
operation: proposalOutput.action,
|
|
10927
|
+
outcome: proposal.outcome,
|
|
10928
|
+
clusterType: cluster.type,
|
|
10929
|
+
trigger: "manual",
|
|
10930
|
+
judgeScores: {
|
|
10931
|
+
taskCompletion: judge1.score,
|
|
10932
|
+
correctionAlignment: judge2.score,
|
|
10933
|
+
sideEffectCheck: judge3.score
|
|
10934
|
+
},
|
|
10935
|
+
regression: regressionResult,
|
|
10936
|
+
metrics: {
|
|
10937
|
+
averageJudgeScore: avgScore,
|
|
10938
|
+
taskCompletion: judge1.score,
|
|
10939
|
+
correctionAlignment: judge2.score,
|
|
10940
|
+
sideEffectCheck: judge3.score,
|
|
10941
|
+
regressionPassRate: regressionResult.passRate
|
|
10942
|
+
}
|
|
10943
|
+
});
|
|
10592
10944
|
if (finalAccepted && !dryRun) {
|
|
10593
10945
|
const { meta, content } = parseSkillMd(proposalOutput.proposedSkillMd);
|
|
10594
10946
|
const skillSlug2 = proposalOutput.targetSkill ?? proposal.targetSkill;
|
|
10595
|
-
const skillDir =
|
|
10947
|
+
const skillDir = join8(getGeneralSkillsPath(), skillSlug2);
|
|
10596
10948
|
meta.generation = generation;
|
|
10597
10949
|
meta.score = avgScore;
|
|
10598
10950
|
meta.lastEvolved = new Date().toISOString();
|
|
@@ -10639,15 +10991,21 @@ async function evolveCommand(options) {
|
|
|
10639
10991
|
proposals.push(proposal);
|
|
10640
10992
|
proposalCount++;
|
|
10641
10993
|
}
|
|
10994
|
+
const iterationTimestamp = new Date().toISOString();
|
|
10642
10995
|
const iteration = {
|
|
10643
|
-
id:
|
|
10644
|
-
timestamp:
|
|
10996
|
+
id: iterationId,
|
|
10997
|
+
timestamp: iterationTimestamp,
|
|
10645
10998
|
trigger: "manual",
|
|
10646
10999
|
failureCount: batch.length,
|
|
10647
11000
|
failureClusters,
|
|
10648
11001
|
proposals
|
|
10649
11002
|
};
|
|
10650
11003
|
addIteration(iteration);
|
|
11004
|
+
if (!dryRun) {
|
|
11005
|
+
for (const artifact of artifacts) {
|
|
11006
|
+
appendEvolutionArtifact(artifact);
|
|
11007
|
+
}
|
|
11008
|
+
}
|
|
10651
11009
|
if (hasGraph) {
|
|
10652
11010
|
const accepted2 = proposals.filter((p) => p.outcome === "accepted");
|
|
10653
11011
|
if (accepted2.length > 0) {
|
|
@@ -10705,9 +11063,9 @@ init_skills();
|
|
|
10705
11063
|
// src/core/knowledge-buffer.ts
|
|
10706
11064
|
init_config();
|
|
10707
11065
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync7 } from "node:fs";
|
|
10708
|
-
import { join as
|
|
10709
|
-
var BUFFER_PATH = () =>
|
|
10710
|
-
var DRAFTS_DIR = () =>
|
|
11066
|
+
import { join as join9 } from "node:path";
|
|
11067
|
+
var BUFFER_PATH = () => join9(getHelixDir(), "knowledge-buffer.json");
|
|
11068
|
+
var DRAFTS_DIR = () => join9(getHelixDir(), "drafts");
|
|
10711
11069
|
var MAX_DISCOVERIES = 50;
|
|
10712
11070
|
var MAX_DRAFTS = 10;
|
|
10713
11071
|
var DECAY_RATE = 0.1;
|
|
@@ -10764,9 +11122,9 @@ function saveDraft(draft) {
|
|
|
10764
11122
|
existing.avgScore = draft.avgScore;
|
|
10765
11123
|
existing.iteration++;
|
|
10766
11124
|
existing.lastIterated = new Date().toISOString();
|
|
10767
|
-
const draftDir =
|
|
11125
|
+
const draftDir = join9(DRAFTS_DIR(), draft.skillName);
|
|
10768
11126
|
ensureDir(draftDir);
|
|
10769
|
-
writeFileSync5(
|
|
11127
|
+
writeFileSync5(join9(draftDir, "SKILL.md"), draft.skillMd);
|
|
10770
11128
|
}
|
|
10771
11129
|
} else {
|
|
10772
11130
|
buffer.drafts.push({
|
|
@@ -10780,9 +11138,9 @@ function saveDraft(draft) {
|
|
|
10780
11138
|
iteration: 1,
|
|
10781
11139
|
lastIterated: new Date().toISOString()
|
|
10782
11140
|
});
|
|
10783
|
-
const draftDir =
|
|
11141
|
+
const draftDir = join9(DRAFTS_DIR(), draft.skillName);
|
|
10784
11142
|
ensureDir(draftDir);
|
|
10785
|
-
writeFileSync5(
|
|
11143
|
+
writeFileSync5(join9(draftDir, "SKILL.md"), draft.skillMd);
|
|
10786
11144
|
}
|
|
10787
11145
|
trimAndSave(buffer);
|
|
10788
11146
|
}
|
|
@@ -10882,7 +11240,7 @@ async function statusCommand() {
|
|
|
10882
11240
|
init_data();
|
|
10883
11241
|
init_skills();
|
|
10884
11242
|
import { writeFileSync as writeFileSync6 } from "node:fs";
|
|
10885
|
-
import { join as
|
|
11243
|
+
import { join as join10 } from "node:path";
|
|
10886
11244
|
init_config();
|
|
10887
11245
|
async function reportCommand(options) {
|
|
10888
11246
|
const days = parseInt(options.days ?? "1");
|
|
@@ -10966,8 +11324,8 @@ async function reportCommand(options) {
|
|
|
10966
11324
|
report += `- **${s.slug}**${evolved}
|
|
10967
11325
|
`;
|
|
10968
11326
|
}
|
|
10969
|
-
const outputPath = options.output ??
|
|
10970
|
-
ensureDir(
|
|
11327
|
+
const outputPath = options.output ?? join10(getHelixDir(), "reports", `${date}.md`);
|
|
11328
|
+
ensureDir(join10(getHelixDir(), "reports"));
|
|
10971
11329
|
writeFileSync6(outputPath, report);
|
|
10972
11330
|
console.log(report);
|
|
10973
11331
|
console.log(`
|
|
@@ -10978,7 +11336,7 @@ async function reportCommand(options) {
|
|
|
10978
11336
|
init_config();
|
|
10979
11337
|
init_skills();
|
|
10980
11338
|
init_llm();
|
|
10981
|
-
import { join as
|
|
11339
|
+
import { join as join11 } from "node:path";
|
|
10982
11340
|
async function generalizeCommand(options) {
|
|
10983
11341
|
const verbose = options.verbose ?? false;
|
|
10984
11342
|
const dryRun = options.dryRun ?? false;
|
|
@@ -11041,7 +11399,7 @@ async function generalizeCommand(options) {
|
|
|
11041
11399
|
meta.generation = 1;
|
|
11042
11400
|
meta.score = candidate.confidence;
|
|
11043
11401
|
meta.lastEvolved = new Date().toISOString();
|
|
11044
|
-
const skillDir =
|
|
11402
|
+
const skillDir = join11(getGeneralSkillsPath(), candidate.suggestedName);
|
|
11045
11403
|
writeSkill(skillDir, meta, content);
|
|
11046
11404
|
console.log(` ✓ Created: ${candidate.suggestedName} (${candidate.suggestedLayer} layer)
|
|
11047
11405
|
`);
|
|
@@ -11149,7 +11507,7 @@ Return JSON:
|
|
|
11149
11507
|
init_data();
|
|
11150
11508
|
init_skills();
|
|
11151
11509
|
init_llm();
|
|
11152
|
-
import { join as
|
|
11510
|
+
import { join as join12 } from "node:path";
|
|
11153
11511
|
async function specializeCommand(options) {
|
|
11154
11512
|
const verbose = options.verbose ?? false;
|
|
11155
11513
|
const dryRun = options.dryRun ?? false;
|
|
@@ -11220,8 +11578,8 @@ async function specializeCommand(options) {
|
|
|
11220
11578
|
meta.generation = 1;
|
|
11221
11579
|
meta.score = candidate.confidence;
|
|
11222
11580
|
meta.lastEvolved = new Date().toISOString();
|
|
11223
|
-
const projectSkillsDir =
|
|
11224
|
-
const skillDir =
|
|
11581
|
+
const projectSkillsDir = join12(process.cwd(), ".helix", "skills");
|
|
11582
|
+
const skillDir = join12(projectSkillsDir, candidate.suggestedName);
|
|
11225
11583
|
writeSkill(skillDir, meta, content);
|
|
11226
11584
|
console.log(` ✓ Created: ${candidate.suggestedName} (project layer, parent: ${candidate.domainSkill})
|
|
11227
11585
|
`);
|
|
@@ -11318,10 +11676,11 @@ Return JSON:
|
|
|
11318
11676
|
// src/commands/graph.ts
|
|
11319
11677
|
import { writeFileSync as writeFileSync8 } from "node:fs";
|
|
11320
11678
|
import { execSync } from "node:child_process";
|
|
11321
|
-
import { join as
|
|
11679
|
+
import { join as join14 } from "node:path";
|
|
11322
11680
|
import { tmpdir } from "node:os";
|
|
11323
11681
|
|
|
11324
11682
|
// src/core/network.ts
|
|
11683
|
+
init_ontology();
|
|
11325
11684
|
init_skills();
|
|
11326
11685
|
init_data();
|
|
11327
11686
|
init_config();
|
|
@@ -11371,7 +11730,12 @@ async function fullRebuild(verbose) {
|
|
|
11371
11730
|
status: "active",
|
|
11372
11731
|
tags: s.meta.tags ?? [],
|
|
11373
11732
|
failureCount: s.meta.failureCount ?? 0,
|
|
11374
|
-
lastEvolved: s.meta.lastEvolved ?? ""
|
|
11733
|
+
lastEvolved: s.meta.lastEvolved ?? "",
|
|
11734
|
+
cognitiveRole: s.meta.cognitiveRole,
|
|
11735
|
+
stabilityState: s.meta.stabilityState,
|
|
11736
|
+
plasticityState: s.meta.plasticityState,
|
|
11737
|
+
capabilities: s.meta.capabilities,
|
|
11738
|
+
lineageId: s.meta.lineageId
|
|
11375
11739
|
}));
|
|
11376
11740
|
const edges = [];
|
|
11377
11741
|
for (const s of skills) {
|
|
@@ -11399,6 +11763,7 @@ async function fullRebuild(verbose) {
|
|
|
11399
11763
|
const clusters = clusterSkills(nodes, edges);
|
|
11400
11764
|
const graph = {
|
|
11401
11765
|
updated: new Date().toISOString(),
|
|
11766
|
+
ontologyVersion: ONTOLOGY_SPEC_VERSION,
|
|
11402
11767
|
nodes,
|
|
11403
11768
|
edges: deduplicateEdges(edges),
|
|
11404
11769
|
clusters
|
|
@@ -11671,29 +12036,29 @@ function detectMergeCandidates(enhances, coEvolves, skills) {
|
|
|
11671
12036
|
init_data();
|
|
11672
12037
|
init_skills();
|
|
11673
12038
|
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync3 } from "node:fs";
|
|
11674
|
-
import { join as
|
|
12039
|
+
import { join as join13 } from "node:path";
|
|
11675
12040
|
function syncToObsidian(vaultPath, verbose = false) {
|
|
11676
12041
|
const graph = loadSkillGraph();
|
|
11677
12042
|
const skills = loadAllGeneralSkills();
|
|
11678
|
-
const skillsDir =
|
|
11679
|
-
const reportsDir =
|
|
12043
|
+
const skillsDir = join13(vaultPath, "Skills");
|
|
12044
|
+
const reportsDir = join13(vaultPath, "Reports");
|
|
11680
12045
|
mkdirSync3(skillsDir, { recursive: true });
|
|
11681
12046
|
mkdirSync3(reportsDir, { recursive: true });
|
|
11682
12047
|
for (const node of graph.nodes) {
|
|
11683
12048
|
const skill = skills.find((s) => s.slug === node.id);
|
|
11684
12049
|
const note = generateSkillNote(node, graph.edges, skill ?? undefined);
|
|
11685
|
-
const notePath =
|
|
12050
|
+
const notePath = join13(skillsDir, `${node.id}.md`);
|
|
11686
12051
|
writeFileSync7(notePath, note);
|
|
11687
12052
|
if (verbose)
|
|
11688
12053
|
console.log(` ✓ ${node.id}.md`);
|
|
11689
12054
|
}
|
|
11690
12055
|
const indexNote = generateIndexNote(graph);
|
|
11691
|
-
writeFileSync7(
|
|
12056
|
+
writeFileSync7(join13(vaultPath, "HelixEvo Index.md"), indexNote);
|
|
11692
12057
|
const recent = getRecentIterations(7);
|
|
11693
12058
|
if (recent.length > 0) {
|
|
11694
12059
|
const report = generateEvolutionReport(recent);
|
|
11695
12060
|
const date = new Date().toISOString().slice(0, 10);
|
|
11696
|
-
writeFileSync7(
|
|
12061
|
+
writeFileSync7(join13(reportsDir, `Evolution ${date}.md`), report);
|
|
11697
12062
|
}
|
|
11698
12063
|
console.log(` ✓ Synced ${graph.nodes.length} skills to ${vaultPath}`);
|
|
11699
12064
|
}
|
|
@@ -12052,7 +12417,7 @@ ${mermaidCode}
|
|
|
12052
12417
|
});
|
|
12053
12418
|
</script>
|
|
12054
12419
|
</body></html>`;
|
|
12055
|
-
const htmlPath =
|
|
12420
|
+
const htmlPath = join14(tmpdir(), "helix-network.html");
|
|
12056
12421
|
writeFileSync8(htmlPath, html);
|
|
12057
12422
|
execSync(`open "${htmlPath}"`);
|
|
12058
12423
|
console.log(` ✓ Opened in browser`);
|
|
@@ -12117,7 +12482,7 @@ function renderScoreBar(score) {
|
|
|
12117
12482
|
init_config();
|
|
12118
12483
|
init_skills();
|
|
12119
12484
|
init_llm();
|
|
12120
|
-
import { join as
|
|
12485
|
+
import { join as join15 } from "node:path";
|
|
12121
12486
|
import { readFileSync as readFileSync7, existsSync as existsSync9 } from "node:fs";
|
|
12122
12487
|
async function researchCommand(options) {
|
|
12123
12488
|
const verbose = options.verbose ?? false;
|
|
@@ -12233,7 +12598,7 @@ Only include discoveries that are NOT already covered by current skills.`
|
|
|
12233
12598
|
meta.score = result.avgScore / 10;
|
|
12234
12599
|
meta.lastEvolved = new Date().toISOString();
|
|
12235
12600
|
meta.tags = [...meta.tags ?? [], "research-discovered"];
|
|
12236
|
-
const skillDir =
|
|
12601
|
+
const skillDir = join15(getGeneralSkillsPath(), hypothesis.skillName);
|
|
12237
12602
|
writeSkill(skillDir, meta, content);
|
|
12238
12603
|
console.log(` ✓ Created: ${hypothesis.skillName} (from research)
|
|
12239
12604
|
`);
|
|
@@ -12281,7 +12646,7 @@ async function understandGoals(projectPath, skills) {
|
|
|
12281
12646
|
const paths = projectPath ? [projectPath] : [process.cwd()];
|
|
12282
12647
|
for (const p of paths) {
|
|
12283
12648
|
for (const file of ["README.md", "CLAUDE.md", "package.json", ".agents/AGENTS.md"]) {
|
|
12284
|
-
const fullPath =
|
|
12649
|
+
const fullPath = join15(p, file);
|
|
12285
12650
|
if (existsSync9(fullPath)) {
|
|
12286
12651
|
const content = readFileSync7(fullPath, "utf-8").slice(0, 2000);
|
|
12287
12652
|
context.push(`## ${file}
|
|
@@ -12443,8 +12808,8 @@ ${replay.slice(0, 800)}`
|
|
|
12443
12808
|
|
|
12444
12809
|
// src/commands/dashboard.ts
|
|
12445
12810
|
import { execSync as execSync2, spawn as spawn2 } from "node:child_process";
|
|
12446
|
-
import { join as
|
|
12447
|
-
import { existsSync as existsSync11, cpSync as cpSync3, mkdirSync as mkdirSync5, readdirSync as
|
|
12811
|
+
import { join as join17, dirname as dirname3 } from "node:path";
|
|
12812
|
+
import { existsSync as existsSync11, cpSync as cpSync3, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync as readFileSync9, rmSync as rmSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
12448
12813
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
12449
12814
|
import { homedir as homedir4 } from "node:os";
|
|
12450
12815
|
init_skills();
|
|
@@ -12452,10 +12817,10 @@ init_data();
|
|
|
12452
12817
|
|
|
12453
12818
|
// src/utils/update-check.ts
|
|
12454
12819
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync9, existsSync as existsSync10, mkdirSync as mkdirSync4 } from "node:fs";
|
|
12455
|
-
import { join as
|
|
12820
|
+
import { join as join16 } from "node:path";
|
|
12456
12821
|
import { homedir as homedir3 } from "node:os";
|
|
12457
|
-
var HELIX_DIR2 =
|
|
12458
|
-
var CACHE_PATH =
|
|
12822
|
+
var HELIX_DIR2 = join16(homedir3(), ".helix");
|
|
12823
|
+
var CACHE_PATH = join16(HELIX_DIR2, "update-check.json");
|
|
12459
12824
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
12460
12825
|
var REGISTRY_URL = "https://registry.npmjs.org/helixevo/latest";
|
|
12461
12826
|
function readCache() {
|
|
@@ -12555,7 +12920,7 @@ function printUpdateBanner(currentVersion, latestVersion) {
|
|
|
12555
12920
|
|
|
12556
12921
|
// src/commands/dashboard.ts
|
|
12557
12922
|
var __filename = "/Users/tianchichen/Documents/GitHub/helixevo/src/commands/dashboard.ts";
|
|
12558
|
-
var HELIX_DASHBOARD_DIR =
|
|
12923
|
+
var HELIX_DASHBOARD_DIR = join17(homedir4(), ".helix", "dashboard");
|
|
12559
12924
|
var DASHBOARD_SKIP_AUTO_UPDATE_ENV = "HELIXEVO_DASHBOARD_SKIP_AUTO_UPDATE";
|
|
12560
12925
|
async function dashboardCommand(options) {
|
|
12561
12926
|
if (options.autoUpdate !== false && process.env[DASHBOARD_SKIP_AUTO_UPDATE_ENV] !== "1" && !findDevDashboard()) {
|
|
@@ -12572,7 +12937,7 @@ async function dashboardCommand(options) {
|
|
|
12572
12937
|
console.error(" cd helixevo/dashboard && npm install && npx next dev --port 3847");
|
|
12573
12938
|
process.exit(1);
|
|
12574
12939
|
}
|
|
12575
|
-
if (!existsSync11(
|
|
12940
|
+
if (!existsSync11(join17(dir, "node_modules"))) {
|
|
12576
12941
|
console.log(" Installing dashboard dependencies...");
|
|
12577
12942
|
try {
|
|
12578
12943
|
execSync2("npm install --no-audit --no-fund", { cwd: dir, stdio: "inherit" });
|
|
@@ -12585,7 +12950,7 @@ async function dashboardCommand(options) {
|
|
|
12585
12950
|
}
|
|
12586
12951
|
ensureSkillGraph();
|
|
12587
12952
|
if (options.background) {
|
|
12588
|
-
const logFile =
|
|
12953
|
+
const logFile = join17(homedir4(), ".helix", "dashboard.log");
|
|
12589
12954
|
const out = __require("fs").openSync(logFile, "a");
|
|
12590
12955
|
const err = __require("fs").openSync(logFile, "a");
|
|
12591
12956
|
let currentVersion2 = VERSION;
|
|
@@ -12599,7 +12964,7 @@ async function dashboardCommand(options) {
|
|
|
12599
12964
|
detached: true
|
|
12600
12965
|
});
|
|
12601
12966
|
child.unref();
|
|
12602
|
-
writeFileSync10(
|
|
12967
|
+
writeFileSync10(join17(homedir4(), ".helix", "dashboard.pid"), String(child.pid));
|
|
12603
12968
|
console.log(` \uD83C\uDF10 HelixEvo Dashboard v${currentVersion2} running in background`);
|
|
12604
12969
|
console.log(` http://localhost:3847`);
|
|
12605
12970
|
console.log(` Logs: ${logFile}`);
|
|
@@ -12688,7 +13053,7 @@ function launchDashboard(dir, openBrowser) {
|
|
|
12688
13053
|
\uD83D\uDD04 Restarting dashboard after update...
|
|
12689
13054
|
`);
|
|
12690
13055
|
setTimeout(() => {
|
|
12691
|
-
const nextCache =
|
|
13056
|
+
const nextCache = join17(dir, ".next");
|
|
12692
13057
|
if (existsSync11(nextCache)) {
|
|
12693
13058
|
try {
|
|
12694
13059
|
rmSync2(nextCache, { recursive: true });
|
|
@@ -12715,20 +13080,20 @@ function prepareDashboard() {
|
|
|
12715
13080
|
const npmSource = findNpmDashboard();
|
|
12716
13081
|
if (npmSource)
|
|
12717
13082
|
return copyToHelix(npmSource);
|
|
12718
|
-
if (existsSync11(
|
|
13083
|
+
if (existsSync11(join17(HELIX_DASHBOARD_DIR, "package.json"))) {
|
|
12719
13084
|
return HELIX_DASHBOARD_DIR;
|
|
12720
13085
|
}
|
|
12721
13086
|
return null;
|
|
12722
13087
|
}
|
|
12723
13088
|
function findDevDashboard() {
|
|
12724
13089
|
const candidates = [
|
|
12725
|
-
|
|
13090
|
+
join17(process.cwd(), "dashboard")
|
|
12726
13091
|
];
|
|
12727
13092
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
12728
|
-
candidates.push(
|
|
12729
|
-
candidates.push(
|
|
13093
|
+
candidates.push(join17(home, "Documents", "GitHub", "helixevo", "dashboard"));
|
|
13094
|
+
candidates.push(join17(home, "Documents", "GitHub", "skillgraph", "dashboard"));
|
|
12730
13095
|
for (const dir of candidates) {
|
|
12731
|
-
if (existsSync11(
|
|
13096
|
+
if (existsSync11(join17(dir, "package.json")) && !dir.includes("node_modules")) {
|
|
12732
13097
|
return dir;
|
|
12733
13098
|
}
|
|
12734
13099
|
}
|
|
@@ -12739,15 +13104,15 @@ function findNpmDashboard() {
|
|
|
12739
13104
|
try {
|
|
12740
13105
|
const thisFile = typeof __filename !== "undefined" ? __filename : fileURLToPath2(import.meta.url);
|
|
12741
13106
|
const pkgRoot = dirname3(dirname3(thisFile));
|
|
12742
|
-
candidates.push(
|
|
13107
|
+
candidates.push(join17(pkgRoot, "dashboard"));
|
|
12743
13108
|
} catch {}
|
|
12744
13109
|
try {
|
|
12745
13110
|
const globalPrefix = execSync2("npm prefix -g", { encoding: "utf-8" }).trim();
|
|
12746
|
-
candidates.push(
|
|
12747
|
-
candidates.push(
|
|
13111
|
+
candidates.push(join17(globalPrefix, "lib", "node_modules", "helixevo", "dashboard"));
|
|
13112
|
+
candidates.push(join17(globalPrefix, "node_modules", "helixevo", "dashboard"));
|
|
12748
13113
|
} catch {}
|
|
12749
13114
|
for (const dir of candidates) {
|
|
12750
|
-
if (existsSync11(
|
|
13115
|
+
if (existsSync11(join17(dir, "package.json"))) {
|
|
12751
13116
|
return dir;
|
|
12752
13117
|
}
|
|
12753
13118
|
}
|
|
@@ -12755,7 +13120,7 @@ function findNpmDashboard() {
|
|
|
12755
13120
|
}
|
|
12756
13121
|
function getInstalledDashboardVersion() {
|
|
12757
13122
|
try {
|
|
12758
|
-
const versionFile =
|
|
13123
|
+
const versionFile = join17(HELIX_DASHBOARD_DIR, ".helixevo-version");
|
|
12759
13124
|
if (!existsSync11(versionFile))
|
|
12760
13125
|
return null;
|
|
12761
13126
|
return readFileSync9(versionFile, "utf-8").trim();
|
|
@@ -12766,7 +13131,7 @@ function getInstalledDashboardVersion() {
|
|
|
12766
13131
|
function copyToHelix(sourceDir) {
|
|
12767
13132
|
let sourceVersion = VERSION;
|
|
12768
13133
|
try {
|
|
12769
|
-
const srcRoot =
|
|
13134
|
+
const srcRoot = join17(sourceDir, "..", "package.json");
|
|
12770
13135
|
const pkg2 = JSON.parse(readFileSync9(srcRoot, "utf-8"));
|
|
12771
13136
|
if (pkg2.name === "helixevo" && pkg2.version)
|
|
12772
13137
|
sourceVersion = pkg2.version;
|
|
@@ -12783,34 +13148,34 @@ function copyToHelix(sourceDir) {
|
|
|
12783
13148
|
mkdirSync5(HELIX_DASHBOARD_DIR, { recursive: true });
|
|
12784
13149
|
let depsChanged = true;
|
|
12785
13150
|
try {
|
|
12786
|
-
const srcDeps = readFileSync9(
|
|
12787
|
-
const dstDeps = readFileSync9(
|
|
13151
|
+
const srcDeps = readFileSync9(join17(sourceDir, "package.json"), "utf-8");
|
|
13152
|
+
const dstDeps = readFileSync9(join17(HELIX_DASHBOARD_DIR, "package.json"), "utf-8");
|
|
12788
13153
|
const srcPkg = JSON.parse(srcDeps);
|
|
12789
13154
|
const dstPkg = JSON.parse(dstDeps);
|
|
12790
13155
|
depsChanged = JSON.stringify(srcPkg.dependencies) !== JSON.stringify(dstPkg.dependencies) || JSON.stringify(srcPkg.devDependencies) !== JSON.stringify(dstPkg.devDependencies);
|
|
12791
13156
|
} catch {
|
|
12792
13157
|
depsChanged = true;
|
|
12793
13158
|
}
|
|
12794
|
-
const items =
|
|
13159
|
+
const items = readdirSync3(sourceDir, { withFileTypes: true });
|
|
12795
13160
|
for (const item of items) {
|
|
12796
13161
|
if (item.name === "node_modules" || item.name === ".next" || item.name === "package-lock.json" || item.name === ".env.local")
|
|
12797
13162
|
continue;
|
|
12798
|
-
const src =
|
|
12799
|
-
const dest =
|
|
13163
|
+
const src = join17(sourceDir, item.name);
|
|
13164
|
+
const dest = join17(HELIX_DASHBOARD_DIR, item.name);
|
|
12800
13165
|
cpSync3(src, dest, { recursive: true });
|
|
12801
13166
|
}
|
|
12802
13167
|
if (depsChanged) {
|
|
12803
|
-
const oldModules =
|
|
13168
|
+
const oldModules = join17(HELIX_DASHBOARD_DIR, "node_modules");
|
|
12804
13169
|
if (existsSync11(oldModules))
|
|
12805
13170
|
rmSync2(oldModules, { recursive: true });
|
|
12806
|
-
const oldLock =
|
|
13171
|
+
const oldLock = join17(HELIX_DASHBOARD_DIR, "package-lock.json");
|
|
12807
13172
|
if (existsSync11(oldLock))
|
|
12808
13173
|
rmSync2(oldLock);
|
|
12809
13174
|
}
|
|
12810
|
-
const nextCache =
|
|
13175
|
+
const nextCache = join17(HELIX_DASHBOARD_DIR, ".next");
|
|
12811
13176
|
if (existsSync11(nextCache))
|
|
12812
13177
|
rmSync2(nextCache, { recursive: true });
|
|
12813
|
-
writeFileSync10(
|
|
13178
|
+
writeFileSync10(join17(HELIX_DASHBOARD_DIR, ".helixevo-version"), sourceVersion);
|
|
12814
13179
|
return HELIX_DASHBOARD_DIR;
|
|
12815
13180
|
}
|
|
12816
13181
|
function ensureSkillGraph() {
|
|
@@ -12852,7 +13217,7 @@ function ensureSkillGraph() {
|
|
|
12852
13217
|
}
|
|
12853
13218
|
|
|
12854
13219
|
// src/commands/watch.ts
|
|
12855
|
-
import { join as
|
|
13220
|
+
import { join as join19 } from "node:path";
|
|
12856
13221
|
import { existsSync as existsSync14 } from "node:fs";
|
|
12857
13222
|
|
|
12858
13223
|
// src/core/auto-capture.ts
|
|
@@ -12999,9 +13364,9 @@ init_data();
|
|
|
12999
13364
|
init_config();
|
|
13000
13365
|
init_data();
|
|
13001
13366
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync11, existsSync as existsSync13 } from "node:fs";
|
|
13002
|
-
import { join as
|
|
13367
|
+
import { join as join18 } from "node:path";
|
|
13003
13368
|
function getMetricsPath() {
|
|
13004
|
-
return
|
|
13369
|
+
return join18(getHelixDir(), "metrics.json");
|
|
13005
13370
|
}
|
|
13006
13371
|
function loadMetrics() {
|
|
13007
13372
|
const path = getMetricsPath();
|
|
@@ -13188,7 +13553,7 @@ async function watchCommand(options) {
|
|
|
13188
13553
|
const verbose = options.verbose ?? false;
|
|
13189
13554
|
const autoEvolve = options.evolve !== false;
|
|
13190
13555
|
const project = options.project ?? null;
|
|
13191
|
-
const eventsPath = options.events ??
|
|
13556
|
+
const eventsPath = options.events ?? join19(process.cwd(), "events.jsonl");
|
|
13192
13557
|
console.log(`\uD83E\uDDEC HelixEvo Watch Mode — Always-On Learning
|
|
13193
13558
|
`);
|
|
13194
13559
|
console.log(` Events: ${eventsPath}`);
|
|
@@ -13343,10 +13708,12 @@ async function metricsCommand(options) {
|
|
|
13343
13708
|
}
|
|
13344
13709
|
|
|
13345
13710
|
// src/commands/project-setup.ts
|
|
13711
|
+
init_data();
|
|
13346
13712
|
init_skills();
|
|
13347
13713
|
init_llm();
|
|
13348
|
-
import { join as
|
|
13349
|
-
import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync12, mkdirSync as mkdirSync6, readdirSync as
|
|
13714
|
+
import { isAbsolute, join as join20, normalize, resolve } from "node:path";
|
|
13715
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync12, mkdirSync as mkdirSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
13716
|
+
import { homedir as homedir5 } from "node:os";
|
|
13350
13717
|
|
|
13351
13718
|
// src/prompts/project-analysis.ts
|
|
13352
13719
|
function buildProjectAnalysisPrompt(projectContext, skills) {
|
|
@@ -13410,6 +13777,23 @@ Return JSON:
|
|
|
13410
13777
|
|
|
13411
13778
|
// src/commands/project-setup.ts
|
|
13412
13779
|
init_config();
|
|
13780
|
+
function stripTrailingSeparator(path) {
|
|
13781
|
+
if (path.length <= 1)
|
|
13782
|
+
return path;
|
|
13783
|
+
return path.replace(/[\\/]+$/, "") || path;
|
|
13784
|
+
}
|
|
13785
|
+
function expandHomePath(path) {
|
|
13786
|
+
if (path === "~")
|
|
13787
|
+
return homedir5();
|
|
13788
|
+
if (path.startsWith("~/"))
|
|
13789
|
+
return join20(homedir5(), path.slice(2));
|
|
13790
|
+
return path;
|
|
13791
|
+
}
|
|
13792
|
+
function normalizeProjectPath(projectPath) {
|
|
13793
|
+
const expanded = expandHomePath(projectPath.trim());
|
|
13794
|
+
const resolvedPath = isAbsolute(expanded) ? normalize(expanded) : resolve(process.cwd(), expanded);
|
|
13795
|
+
return stripTrailingSeparator(resolvedPath);
|
|
13796
|
+
}
|
|
13413
13797
|
function readProjectContext(projectPath) {
|
|
13414
13798
|
const contextFiles = [];
|
|
13415
13799
|
const filesToRead = [
|
|
@@ -13427,7 +13811,7 @@ function readProjectContext(projectPath) {
|
|
|
13427
13811
|
"Dockerfile"
|
|
13428
13812
|
];
|
|
13429
13813
|
for (const f of filesToRead) {
|
|
13430
|
-
const p =
|
|
13814
|
+
const p = join20(projectPath, f);
|
|
13431
13815
|
if (existsSync15(p)) {
|
|
13432
13816
|
try {
|
|
13433
13817
|
const content = readFileSync12(p, "utf-8");
|
|
@@ -13437,23 +13821,23 @@ function readProjectContext(projectPath) {
|
|
|
13437
13821
|
}
|
|
13438
13822
|
let dirStructure = "";
|
|
13439
13823
|
try {
|
|
13440
|
-
const items =
|
|
13824
|
+
const items = readdirSync4(projectPath, { withFileTypes: true }).filter((d) => !d.name.startsWith(".") && d.name !== "node_modules" && d.name !== "__pycache__").slice(0, 30);
|
|
13441
13825
|
dirStructure = items.map((d) => `${d.isDirectory() ? "\uD83D\uDCC1" : "\uD83D\uDCC4"} ${d.name}`).join(`
|
|
13442
13826
|
`);
|
|
13443
13827
|
} catch {}
|
|
13444
13828
|
let srcStructure = "";
|
|
13445
|
-
const srcDir =
|
|
13829
|
+
const srcDir = join20(projectPath, "src");
|
|
13446
13830
|
if (existsSync15(srcDir)) {
|
|
13447
13831
|
try {
|
|
13448
13832
|
const scanDir = (dir, prefix, depth) => {
|
|
13449
13833
|
if (depth > 2)
|
|
13450
13834
|
return [];
|
|
13451
13835
|
const lines = [];
|
|
13452
|
-
const items =
|
|
13836
|
+
const items = readdirSync4(dir, { withFileTypes: true }).filter((d) => !d.name.startsWith(".")).slice(0, 20);
|
|
13453
13837
|
for (const item of items) {
|
|
13454
13838
|
lines.push(`${prefix}${item.isDirectory() ? "\uD83D\uDCC1" : "\uD83D\uDCC4"} ${item.name}`);
|
|
13455
13839
|
if (item.isDirectory()) {
|
|
13456
|
-
lines.push(...scanDir(
|
|
13840
|
+
lines.push(...scanDir(join20(dir, item.name), prefix + " ", depth + 1));
|
|
13457
13841
|
}
|
|
13458
13842
|
}
|
|
13459
13843
|
return lines;
|
|
@@ -13487,17 +13871,17 @@ ${f.content}
|
|
|
13487
13871
|
return context;
|
|
13488
13872
|
}
|
|
13489
13873
|
function getProjectsDir() {
|
|
13490
|
-
return
|
|
13874
|
+
return join20(getHelixDir(), "projects");
|
|
13491
13875
|
}
|
|
13492
13876
|
function saveProjectProfile(profile) {
|
|
13493
|
-
const dir =
|
|
13877
|
+
const dir = join20(getProjectsDir(), profile.name);
|
|
13494
13878
|
mkdirSync6(dir, { recursive: true });
|
|
13495
|
-
writeFileSync12(
|
|
13879
|
+
writeFileSync12(join20(dir, "profile.json"), JSON.stringify(profile, null, 2));
|
|
13496
13880
|
}
|
|
13497
13881
|
async function projectSetupCommand(projectPath, options) {
|
|
13498
13882
|
const verbose = options.verbose ?? false;
|
|
13499
13883
|
const dryRun = options.dryRun ?? false;
|
|
13500
|
-
const resolvedPath =
|
|
13884
|
+
const resolvedPath = normalizeProjectPath(projectPath);
|
|
13501
13885
|
if (!existsSync15(resolvedPath)) {
|
|
13502
13886
|
console.error(` ✗ Path not found: ${resolvedPath}`);
|
|
13503
13887
|
process.exit(1);
|
|
@@ -13557,19 +13941,58 @@ async function projectSetupCommand(projectPath, options) {
|
|
|
13557
13941
|
}
|
|
13558
13942
|
}
|
|
13559
13943
|
if (!dryRun) {
|
|
13944
|
+
const analyzedAt = new Date().toISOString();
|
|
13560
13945
|
const profile = {
|
|
13561
13946
|
name: analysis.name,
|
|
13562
13947
|
path: resolvedPath,
|
|
13563
13948
|
description: analysis.description,
|
|
13564
13949
|
techStack: analysis.techStack,
|
|
13565
13950
|
domains: analysis.domains,
|
|
13566
|
-
analyzedAt
|
|
13951
|
+
analyzedAt,
|
|
13567
13952
|
matchedSkills: analysis.matchedSkills,
|
|
13568
13953
|
gaps: analysis.gaps,
|
|
13569
13954
|
recommendations: analysis.recommendations,
|
|
13570
13955
|
status: "analyzed"
|
|
13571
13956
|
};
|
|
13572
13957
|
saveProjectProfile(profile);
|
|
13958
|
+
const activationTraceId = `activation_project_${analysis.name}_${Date.now()}`;
|
|
13959
|
+
const activationTrace = {
|
|
13960
|
+
id: activationTraceId,
|
|
13961
|
+
timestamp: analyzedAt,
|
|
13962
|
+
provenance: "project-analysis",
|
|
13963
|
+
sourceId: resolvedPath,
|
|
13964
|
+
projectId: analysis.name,
|
|
13965
|
+
projectPath: resolvedPath,
|
|
13966
|
+
activatedSkillIds: analysis.matchedSkills.map((skill) => skill.slug),
|
|
13967
|
+
relevantSkillIds: analysis.matchedSkills.map((skill) => skill.slug),
|
|
13968
|
+
reasonSummary: "project-analysis skill match and capability scan",
|
|
13969
|
+
contextSummary: analysis.description,
|
|
13970
|
+
gapAreas: analysis.gaps.map((gap) => gap.area),
|
|
13971
|
+
recommendations: analysis.recommendations,
|
|
13972
|
+
traceVersion: "0.1.0"
|
|
13973
|
+
};
|
|
13974
|
+
appendActivationTrace(activationTrace);
|
|
13975
|
+
analysis.gaps.forEach((gap, index) => {
|
|
13976
|
+
const signal = {
|
|
13977
|
+
id: `pressure_project_${analysis.name}_${index}_${Date.now()}`,
|
|
13978
|
+
kind: `gap:${gap.area}`,
|
|
13979
|
+
provenance: "project-analysis-native",
|
|
13980
|
+
sourceType: "project-analysis",
|
|
13981
|
+
sourceId: resolvedPath,
|
|
13982
|
+
projectId: analysis.name,
|
|
13983
|
+
projectPath: resolvedPath,
|
|
13984
|
+
detectedAt: analyzedAt,
|
|
13985
|
+
severity: gap.priority === "high" ? 0.95 : gap.priority === "medium" ? 0.75 : 0.55,
|
|
13986
|
+
priority: gap.priority,
|
|
13987
|
+
capability: gap.area,
|
|
13988
|
+
description: gap.description,
|
|
13989
|
+
suggestedAction: gap.suggestedAction,
|
|
13990
|
+
relatedActivationTraceId: activationTraceId,
|
|
13991
|
+
skillIds: analysis.matchedSkills.map((skill) => skill.slug),
|
|
13992
|
+
status: "open"
|
|
13993
|
+
};
|
|
13994
|
+
appendPressureSignal(signal);
|
|
13995
|
+
});
|
|
13573
13996
|
console.log(`
|
|
13574
13997
|
✓ Project profile saved to ~/.helix/projects/${analysis.name}/`);
|
|
13575
13998
|
console.log(` Next: Run "helixevo specialize --project ${analysis.name}" to create project-specific skills`);
|
|
@@ -13584,8 +14007,8 @@ async function projectSetupCommand(projectPath, options) {
|
|
|
13584
14007
|
}
|
|
13585
14008
|
|
|
13586
14009
|
// src/cli.ts
|
|
13587
|
-
import { join as
|
|
13588
|
-
import { homedir as
|
|
14010
|
+
import { join as join21 } from "node:path";
|
|
14011
|
+
import { homedir as homedir6 } from "node:os";
|
|
13589
14012
|
import { existsSync as existsSync16, readFileSync as readFileSync13, rmSync as rmSync3 } from "node:fs";
|
|
13590
14013
|
var program2 = new Command;
|
|
13591
14014
|
program2.name("helixevo").description("Self-evolving skill ecosystem for AI agents").version(VERSION).addHelpText("after", `
|
|
@@ -13616,7 +14039,7 @@ program2.command("graph").description("Skill network [--mermaid] [--obsidian <pa
|
|
|
13616
14039
|
program2.command("research").description("Proactive research via web [--project <path>] [--dry-run] [--verbose]").option("--project <path>", "Project path for goal extraction").option("--dry-run", "Show discoveries without creating skills").option("--verbose", "Show detailed research steps").option("--max-hypotheses <n>", "Max hypotheses to test", "3").action(researchCommand);
|
|
13617
14040
|
program2.command("dashboard").description("Open web dashboard at http://localhost:3847").option("--background", "Run in background (detach from terminal)").option("--stop", "Stop a background dashboard").option("--no-auto-update", "Skip automatic update check before launching the dashboard").action(async (options) => {
|
|
13618
14041
|
if (options.stop) {
|
|
13619
|
-
const pidFile =
|
|
14042
|
+
const pidFile = join21(homedir6(), ".helix", "dashboard.pid");
|
|
13620
14043
|
if (existsSync16(pidFile)) {
|
|
13621
14044
|
const pid = parseInt(readFileSync13(pidFile, "utf-8").trim());
|
|
13622
14045
|
try {
|