@goondocks/myco 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-run-2NFYMQXW.js → agent-run-I4O2K2CK.js} +4 -4
- package/dist/{agent-tasks-MEIYLXGN.js → agent-tasks-UOW5BQIB.js} +4 -4
- package/dist/{chunk-JMOUFG6Y.js → chunk-44PZCAYS.js} +47 -5
- package/dist/chunk-44PZCAYS.js.map +1 -0
- package/dist/{chunk-JDI4DPWD.js → chunk-C3EGL5JX.js} +632 -145
- package/dist/chunk-C3EGL5JX.js.map +1 -0
- package/dist/{chunk-OW433Q4C.js → chunk-CURS2TNP.js} +44 -3
- package/dist/chunk-CURS2TNP.js.map +1 -0
- package/dist/{chunk-FABWUX5G.js → chunk-DPSLJ242.js} +16 -2
- package/dist/chunk-DPSLJ242.js.map +1 -0
- package/dist/{chunk-DLFDBKEV.js → chunk-LSP5HYOO.js} +17 -14
- package/dist/chunk-LSP5HYOO.js.map +1 -0
- package/dist/{chunk-VOCGURV7.js → chunk-N75GMQGA.js} +3 -3
- package/dist/{chunk-U7GJTVSX.js → chunk-RIDSOQDR.js} +20 -6
- package/dist/chunk-RIDSOQDR.js.map +1 -0
- package/dist/{chunk-KWTOCJLB.js → chunk-TCSVDQF5.js} +1128 -193
- package/dist/chunk-TCSVDQF5.js.map +1 -0
- package/dist/{chunk-55QEICRO.js → chunk-TLK46KKD.js} +2 -2
- package/dist/{chunk-NZI7WBZI.js → chunk-TOER6RNC.js} +21 -1
- package/dist/chunk-TOER6RNC.js.map +1 -0
- package/dist/{chunk-7OYXB2NM.js → chunk-TZAXQKO6.js} +5 -1
- package/dist/chunk-TZAXQKO6.js.map +1 -0
- package/dist/{chunk-EO2RQW4S.js → chunk-W7WENJ6F.js} +2 -2
- package/dist/{chunk-BUIR3JWM.js → chunk-XWOQL4XN.js} +2 -2
- package/dist/{chunk-PFWIPRF6.js → chunk-YZPI2Y3E.js} +2 -2
- package/dist/{cli-IIMBALPV.js → cli-D3TJYJ2U.js} +35 -35
- package/dist/{client-VZCUISHZ.js → client-4LLEXLVK.js} +3 -3
- package/dist/{detect-GEM3NVK6.js → detect-SZ2KDUF4.js} +2 -2
- package/dist/{doctor-QYD34X7Q.js → doctor-KCTXPX5D.js} +6 -6
- package/dist/{executor-NSPRTH4M.js → executor-UYIZC3L5.js} +83 -275
- package/dist/executor-UYIZC3L5.js.map +1 -0
- package/dist/{init-WYYL44KZ.js → init-QFNBKKDC.js} +7 -7
- package/dist/{llm-KEDHK3TQ.js → llm-SMA5ZEAW.js} +2 -2
- package/dist/{main-6PY3ITQ5.js → main-5THODR77.js} +427 -196
- package/dist/main-5THODR77.js.map +1 -0
- package/dist/{open-HRFMJDQX.js → open-7737CSPN.js} +4 -4
- package/dist/{post-compact-HT24YMAN.js → post-compact-2TJ5FPZH.js} +6 -6
- package/dist/{post-tool-use-DENRI5WB.js → post-tool-use-FRTSICC3.js} +5 -5
- package/dist/{post-tool-use-failure-A6SNJX42.js → post-tool-use-failure-KYO2NCNB.js} +6 -6
- package/dist/{pre-compact-3Q4BALCL.js → pre-compact-J6GCJEJR.js} +6 -6
- package/dist/{remove-YB5A6HY2.js → remove-3WZZC7AX.js} +5 -5
- package/dist/{restart-RGDVHELZ.js → restart-HUHEFOXU.js} +5 -5
- package/dist/{search-WOHT3G55.js → search-ZGN3LDXG.js} +5 -5
- package/dist/{server-6SUNYDV7.js → server-PTXLVVEE.js} +3 -3
- package/dist/{session-W3SKRFRV.js → session-7VV3IQMO.js} +5 -5
- package/dist/{session-end-OUTY7AFF.js → session-end-SMU55UCM.js} +5 -5
- package/dist/{session-start-5MB3LFOA.js → session-start-NIMWEOIZ.js} +16 -11
- package/dist/{session-start-5MB3LFOA.js.map → session-start-NIMWEOIZ.js.map} +1 -1
- package/dist/{setup-llm-ZMYGIQX5.js → setup-llm-7S3VPAPN.js} +4 -4
- package/dist/src/agent/definitions/tasks/extract-only.yaml +1 -1
- package/dist/src/agent/definitions/tasks/full-intelligence.yaml +10 -0
- package/dist/src/agent/definitions/tasks/skill-evolve.yaml +163 -49
- package/dist/src/agent/definitions/tasks/skill-generate.yaml +44 -27
- package/dist/src/agent/definitions/tasks/skill-survey.yaml +132 -138
- package/dist/src/agent/definitions/tasks/supersession-sweep.yaml +1 -1
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/src/symbionts/manifests/codex.yaml +45 -7
- package/dist/src/worker/src/index.ts +8 -2
- package/dist/src/worker/src/schema.ts +2 -0
- package/dist/{stats-DGI6B3HX.js → stats-GEOQ2DFF.js} +5 -5
- package/dist/{stop-YGHODSP7.js → stop-7AKYBJJ2.js} +5 -5
- package/dist/{stop-failure-7IJTPJ6W.js → stop-failure-NLE2EURG.js} +6 -6
- package/dist/{subagent-start-ZBQ5PJB5.js → subagent-start-LBNZF2TG.js} +6 -6
- package/dist/{subagent-stop-N2TDQU2D.js → subagent-stop-B2Z5GYAB.js} +6 -6
- package/dist/{task-completed-BDLMRSBB.js → task-completed-PO5TETJ7.js} +6 -6
- package/dist/{team-2ZFGTSIN.js → team-DPNP2RN7.js} +3 -3
- package/dist/ui/assets/{index-DtT9_nlT.js → index-CiI1fwas.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/dist/{update-STLAN7LR.js → update-WBWB5URU.js} +5 -5
- package/dist/{user-prompt-submit-4IBFUYQ3.js → user-prompt-submit-IZJC3NV7.js} +11 -8
- package/dist/user-prompt-submit-IZJC3NV7.js.map +1 -0
- package/dist/{verify-EJYPO7QA.js → verify-FNSP62I3.js} +2 -2
- package/dist/{version-YPBIKH77.js → version-QEVU66NT.js} +2 -2
- package/package.json +7 -7
- package/dist/chunk-7OYXB2NM.js.map +0 -1
- package/dist/chunk-DLFDBKEV.js.map +0 -1
- package/dist/chunk-FABWUX5G.js.map +0 -1
- package/dist/chunk-JDI4DPWD.js.map +0 -1
- package/dist/chunk-JMOUFG6Y.js.map +0 -1
- package/dist/chunk-KWTOCJLB.js.map +0 -1
- package/dist/chunk-NZI7WBZI.js.map +0 -1
- package/dist/chunk-OW433Q4C.js.map +0 -1
- package/dist/chunk-U7GJTVSX.js.map +0 -1
- package/dist/executor-NSPRTH4M.js.map +0 -1
- package/dist/main-6PY3ITQ5.js.map +0 -1
- package/dist/user-prompt-submit-4IBFUYQ3.js.map +0 -1
- /package/dist/{agent-run-2NFYMQXW.js.map → agent-run-I4O2K2CK.js.map} +0 -0
- /package/dist/{agent-tasks-MEIYLXGN.js.map → agent-tasks-UOW5BQIB.js.map} +0 -0
- /package/dist/{chunk-VOCGURV7.js.map → chunk-N75GMQGA.js.map} +0 -0
- /package/dist/{chunk-55QEICRO.js.map → chunk-TLK46KKD.js.map} +0 -0
- /package/dist/{chunk-EO2RQW4S.js.map → chunk-W7WENJ6F.js.map} +0 -0
- /package/dist/{chunk-BUIR3JWM.js.map → chunk-XWOQL4XN.js.map} +0 -0
- /package/dist/{chunk-PFWIPRF6.js.map → chunk-YZPI2Y3E.js.map} +0 -0
- /package/dist/{cli-IIMBALPV.js.map → cli-D3TJYJ2U.js.map} +0 -0
- /package/dist/{client-VZCUISHZ.js.map → client-4LLEXLVK.js.map} +0 -0
- /package/dist/{detect-GEM3NVK6.js.map → detect-SZ2KDUF4.js.map} +0 -0
- /package/dist/{doctor-QYD34X7Q.js.map → doctor-KCTXPX5D.js.map} +0 -0
- /package/dist/{init-WYYL44KZ.js.map → init-QFNBKKDC.js.map} +0 -0
- /package/dist/{llm-KEDHK3TQ.js.map → llm-SMA5ZEAW.js.map} +0 -0
- /package/dist/{open-HRFMJDQX.js.map → open-7737CSPN.js.map} +0 -0
- /package/dist/{post-compact-HT24YMAN.js.map → post-compact-2TJ5FPZH.js.map} +0 -0
- /package/dist/{post-tool-use-DENRI5WB.js.map → post-tool-use-FRTSICC3.js.map} +0 -0
- /package/dist/{post-tool-use-failure-A6SNJX42.js.map → post-tool-use-failure-KYO2NCNB.js.map} +0 -0
- /package/dist/{pre-compact-3Q4BALCL.js.map → pre-compact-J6GCJEJR.js.map} +0 -0
- /package/dist/{remove-YB5A6HY2.js.map → remove-3WZZC7AX.js.map} +0 -0
- /package/dist/{restart-RGDVHELZ.js.map → restart-HUHEFOXU.js.map} +0 -0
- /package/dist/{search-WOHT3G55.js.map → search-ZGN3LDXG.js.map} +0 -0
- /package/dist/{server-6SUNYDV7.js.map → server-PTXLVVEE.js.map} +0 -0
- /package/dist/{session-W3SKRFRV.js.map → session-7VV3IQMO.js.map} +0 -0
- /package/dist/{session-end-OUTY7AFF.js.map → session-end-SMU55UCM.js.map} +0 -0
- /package/dist/{setup-llm-ZMYGIQX5.js.map → setup-llm-7S3VPAPN.js.map} +0 -0
- /package/dist/{stats-DGI6B3HX.js.map → stats-GEOQ2DFF.js.map} +0 -0
- /package/dist/{stop-YGHODSP7.js.map → stop-7AKYBJJ2.js.map} +0 -0
- /package/dist/{stop-failure-7IJTPJ6W.js.map → stop-failure-NLE2EURG.js.map} +0 -0
- /package/dist/{subagent-start-ZBQ5PJB5.js.map → subagent-start-LBNZF2TG.js.map} +0 -0
- /package/dist/{subagent-stop-N2TDQU2D.js.map → subagent-stop-B2Z5GYAB.js.map} +0 -0
- /package/dist/{task-completed-BDLMRSBB.js.map → task-completed-PO5TETJ7.js.map} +0 -0
- /package/dist/{team-2ZFGTSIN.js.map → team-DPNP2RN7.js.map} +0 -0
- /package/dist/{update-STLAN7LR.js.map → update-WBWB5URU.js.map} +0 -0
- /package/dist/{verify-EJYPO7QA.js.map → verify-FNSP62I3.js.map} +0 -0
- /package/dist/{version-YPBIKH77.js.map → version-QEVU66NT.js.map} +0 -0
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
+
DESCRIPTION_DUPLICATE_THRESHOLD,
|
|
3
4
|
SKILL_GENERATE_TASK,
|
|
4
5
|
STATUS_COMPLETED,
|
|
5
6
|
STATUS_FAILED,
|
|
6
7
|
STATUS_RUNNING,
|
|
8
|
+
TOPIC_OVERLAP_THRESHOLD,
|
|
9
|
+
checkFrontmatterPreservation,
|
|
7
10
|
createSporeLineage,
|
|
8
11
|
deleteCandidate,
|
|
9
12
|
deleteSkillRecordCascade,
|
|
13
|
+
descriptionSimilarity,
|
|
10
14
|
errorMessage,
|
|
11
15
|
getCandidate,
|
|
12
16
|
getRunningRunForTask,
|
|
13
17
|
getSkillRecord,
|
|
14
18
|
getSkillRecordByName,
|
|
19
|
+
getStatesForAgent,
|
|
15
20
|
getUnprocessedBatches,
|
|
16
21
|
insertCandidate,
|
|
17
22
|
insertEntity,
|
|
@@ -28,14 +33,17 @@ import {
|
|
|
28
33
|
markBatchProcessed,
|
|
29
34
|
notify,
|
|
30
35
|
resolveRunConfig,
|
|
36
|
+
setState,
|
|
37
|
+
topicOverlapSimilarity,
|
|
31
38
|
updateCandidate,
|
|
32
39
|
updateRunStatus,
|
|
33
40
|
updateSkillRecord,
|
|
34
|
-
upsertDigestExtract
|
|
35
|
-
|
|
41
|
+
upsertDigestExtract,
|
|
42
|
+
validateSkillContent
|
|
43
|
+
} from "./chunk-C3EGL5JX.js";
|
|
36
44
|
import {
|
|
37
45
|
fullTextSearch
|
|
38
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-TOER6RNC.js";
|
|
39
47
|
import "./chunk-RAV5YMRU.js";
|
|
40
48
|
import {
|
|
41
49
|
getDefaultTask,
|
|
@@ -60,17 +68,17 @@ import {
|
|
|
60
68
|
insertSpore,
|
|
61
69
|
listSpores,
|
|
62
70
|
updateSporeStatus
|
|
63
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-TZAXQKO6.js";
|
|
64
72
|
import {
|
|
65
73
|
listSessions,
|
|
66
74
|
updateSession
|
|
67
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-RIDSOQDR.js";
|
|
68
76
|
import "./chunk-O3TRN3RC.js";
|
|
69
77
|
import {
|
|
70
78
|
AGENT_SETTABLE_STATUSES,
|
|
71
79
|
CANDIDATE_STATUS,
|
|
72
80
|
createSchema
|
|
73
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-CURS2TNP.js";
|
|
74
82
|
import "./chunk-2V7HR7HB.js";
|
|
75
83
|
import {
|
|
76
84
|
getDatabase,
|
|
@@ -79,7 +87,7 @@ import {
|
|
|
79
87
|
} from "./chunk-MYX5NCRH.js";
|
|
80
88
|
import {
|
|
81
89
|
getPluginVersion
|
|
82
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-W7WENJ6F.js";
|
|
83
91
|
import {
|
|
84
92
|
findPackageRoot
|
|
85
93
|
} from "./chunk-LPUQPDC2.js";
|
|
@@ -110,46 +118,6 @@ import { createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
|
110
118
|
// src/agent/tools/read-tools.ts
|
|
111
119
|
import { tool } from "@anthropic-ai/claude-agent-sdk";
|
|
112
120
|
|
|
113
|
-
// src/db/queries/agent-state.ts
|
|
114
|
-
var STATE_COLUMNS = [
|
|
115
|
-
"agent_id",
|
|
116
|
-
"key",
|
|
117
|
-
"value",
|
|
118
|
-
"updated_at"
|
|
119
|
-
];
|
|
120
|
-
var SELECT_COLUMNS = STATE_COLUMNS.join(", ");
|
|
121
|
-
function toAgentStateRow(row) {
|
|
122
|
-
return {
|
|
123
|
-
agent_id: row.agent_id,
|
|
124
|
-
key: row.key,
|
|
125
|
-
value: row.value,
|
|
126
|
-
updated_at: row.updated_at
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
function setState(agentId, key, value, updatedAt) {
|
|
130
|
-
const db = getDatabase();
|
|
131
|
-
db.prepare(
|
|
132
|
-
`INSERT INTO agent_state (agent_id, key, value, updated_at)
|
|
133
|
-
VALUES (?, ?, ?, ?)
|
|
134
|
-
ON CONFLICT (agent_id, key) DO UPDATE SET
|
|
135
|
-
value = EXCLUDED.value,
|
|
136
|
-
updated_at = EXCLUDED.updated_at`
|
|
137
|
-
).run(agentId, key, value, updatedAt);
|
|
138
|
-
return toAgentStateRow(
|
|
139
|
-
db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_state WHERE agent_id = ? AND key = ?`).get(agentId, key)
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
function getStatesForAgent(agentId) {
|
|
143
|
-
const db = getDatabase();
|
|
144
|
-
const rows = db.prepare(
|
|
145
|
-
`SELECT ${SELECT_COLUMNS}
|
|
146
|
-
FROM agent_state
|
|
147
|
-
WHERE agent_id = ?
|
|
148
|
-
ORDER BY key ASC`
|
|
149
|
-
).all(agentId);
|
|
150
|
-
return rows.map(toAgentStateRow);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
121
|
// src/agent/tools/types.ts
|
|
154
122
|
function textResult(data) {
|
|
155
123
|
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
@@ -245,10 +213,10 @@ function createReadTools(deps) {
|
|
|
245
213
|
);
|
|
246
214
|
const vaultSearchSemantic = tool(
|
|
247
215
|
"vault_search_semantic",
|
|
248
|
-
"Semantic similarity search across embedded vault content (spores, sessions, plans, artifacts). Best for finding conceptually related content. Returns results ranked by similarity score.",
|
|
216
|
+
"Semantic similarity search across embedded vault content (spores, sessions, plans, artifacts, skill_records). Best for finding conceptually related content. Returns results ranked by similarity score.",
|
|
249
217
|
{
|
|
250
218
|
query: external_exports.string().describe("Search query text"),
|
|
251
|
-
namespace: external_exports.string().optional().describe("Restrict to a content type: spores, sessions, plans, artifacts. Omit to search all."),
|
|
219
|
+
namespace: external_exports.string().optional().describe("Restrict to a content type: spores, sessions, plans, artifacts, skill_records. Omit to search all."),
|
|
252
220
|
limit: external_exports.number().optional().describe("Maximum results to return")
|
|
253
221
|
},
|
|
254
222
|
async (args) => {
|
|
@@ -646,219 +614,8 @@ import crypto2 from "crypto";
|
|
|
646
614
|
import { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from "fs";
|
|
647
615
|
import { resolve } from "path";
|
|
648
616
|
import { tool as tool4 } from "@anthropic-ai/claude-agent-sdk";
|
|
649
|
-
|
|
650
|
-
// src/agent/tools/skill-validator.ts
|
|
651
|
-
var MAX_SKILL_LINES = 500;
|
|
652
|
-
var REQUIRED_FRONTMATTER_FIELDS = ["name", "description", "managed_by", "user-invocable", "allowed-tools"];
|
|
653
|
-
var PROTECTED_FRONTMATTER_FIELDS = ["user-invocable", "allowed-tools"];
|
|
654
|
-
var ALLOWED_CLAUDE_CODE_TOOLS = /* @__PURE__ */ new Set([
|
|
655
|
-
"Read",
|
|
656
|
-
"Edit",
|
|
657
|
-
"Write",
|
|
658
|
-
"MultiEdit",
|
|
659
|
-
"Bash",
|
|
660
|
-
"Grep",
|
|
661
|
-
"Glob",
|
|
662
|
-
"NotebookRead",
|
|
663
|
-
"NotebookEdit",
|
|
664
|
-
"WebFetch",
|
|
665
|
-
"WebSearch",
|
|
666
|
-
"Task",
|
|
667
|
-
"TodoWrite"
|
|
668
|
-
]);
|
|
669
|
-
function extractFrontmatterField(content, field) {
|
|
670
|
-
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
671
|
-
if (!fmMatch) return void 0;
|
|
672
|
-
const match = fmMatch[1].match(new RegExp(`^${field}:\\s*(.+)$`, "m"));
|
|
673
|
-
return match?.[1].trim();
|
|
674
|
-
}
|
|
675
|
-
function parseAllowedTools(rawValue) {
|
|
676
|
-
if (!rawValue) return null;
|
|
677
|
-
let stripped = rawValue.trim();
|
|
678
|
-
if (stripped.length === 0) return null;
|
|
679
|
-
if (stripped.startsWith("[") && stripped.endsWith("]")) {
|
|
680
|
-
stripped = stripped.slice(1, -1).trim();
|
|
681
|
-
}
|
|
682
|
-
if (stripped.length === 0) return null;
|
|
683
|
-
const parts = stripped.split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter((s) => s.length > 0);
|
|
684
|
-
if (parts.length === 0) return null;
|
|
685
|
-
const sentinels = /* @__PURE__ */ new Set(["None", "none", "null", "Null", "~"]);
|
|
686
|
-
if (parts.some((p) => sentinels.has(p))) return null;
|
|
687
|
-
return parts;
|
|
688
|
-
}
|
|
689
|
-
function stemToken(word) {
|
|
690
|
-
let w = word;
|
|
691
|
-
if (w.length > 5 && w.endsWith("ing")) w = w.slice(0, -3);
|
|
692
|
-
else if (w.length > 5 && w.endsWith("ed")) w = w.slice(0, -2);
|
|
693
|
-
if (w.length > 4 && w.endsWith("s")) w = w.slice(0, -1);
|
|
694
|
-
if (w.length > 4 && w.endsWith("e")) w = w.slice(0, -1);
|
|
695
|
-
return w;
|
|
696
|
-
}
|
|
697
|
-
function tokenSet(text) {
|
|
698
|
-
const stopwords = /* @__PURE__ */ new Set([
|
|
699
|
-
"the",
|
|
700
|
-
"a",
|
|
701
|
-
"an",
|
|
702
|
-
"and",
|
|
703
|
-
"or",
|
|
704
|
-
"but",
|
|
705
|
-
"is",
|
|
706
|
-
"are",
|
|
707
|
-
"was",
|
|
708
|
-
"were",
|
|
709
|
-
"be",
|
|
710
|
-
"been",
|
|
711
|
-
"being",
|
|
712
|
-
"have",
|
|
713
|
-
"has",
|
|
714
|
-
"had",
|
|
715
|
-
"do",
|
|
716
|
-
"does",
|
|
717
|
-
"did",
|
|
718
|
-
"will",
|
|
719
|
-
"would",
|
|
720
|
-
"should",
|
|
721
|
-
"could",
|
|
722
|
-
"may",
|
|
723
|
-
"might",
|
|
724
|
-
"must",
|
|
725
|
-
"can",
|
|
726
|
-
"this",
|
|
727
|
-
"that",
|
|
728
|
-
"these",
|
|
729
|
-
"those",
|
|
730
|
-
"with",
|
|
731
|
-
"from",
|
|
732
|
-
"into",
|
|
733
|
-
"onto",
|
|
734
|
-
"for",
|
|
735
|
-
"when",
|
|
736
|
-
"where",
|
|
737
|
-
"which",
|
|
738
|
-
"what",
|
|
739
|
-
"who",
|
|
740
|
-
"how",
|
|
741
|
-
"why",
|
|
742
|
-
"use",
|
|
743
|
-
"uses",
|
|
744
|
-
"used",
|
|
745
|
-
"using",
|
|
746
|
-
"not",
|
|
747
|
-
"also",
|
|
748
|
-
"than",
|
|
749
|
-
"then",
|
|
750
|
-
"ensure",
|
|
751
|
-
"ensures",
|
|
752
|
-
"make",
|
|
753
|
-
"makes"
|
|
754
|
-
]);
|
|
755
|
-
return new Set(
|
|
756
|
-
text.toLowerCase().replace(/[^a-z0-9_\s]/g, " ").split(/\s+/).filter((w) => w.length >= 4 && !stopwords.has(w)).map(stemToken)
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
|
-
function intersectionSize(a, b) {
|
|
760
|
-
let count = 0;
|
|
761
|
-
for (const token of a) {
|
|
762
|
-
if (b.has(token)) count++;
|
|
763
|
-
}
|
|
764
|
-
return count;
|
|
765
|
-
}
|
|
766
|
-
function descriptionSimilarity(a, b) {
|
|
767
|
-
const aTokens = tokenSet(a);
|
|
768
|
-
const bTokens = tokenSet(b);
|
|
769
|
-
if (aTokens.size === 0 || bTokens.size === 0) return 0;
|
|
770
|
-
const intersection = intersectionSize(aTokens, bTokens);
|
|
771
|
-
const union = aTokens.size + bTokens.size - intersection;
|
|
772
|
-
return union === 0 ? 0 : intersection / union;
|
|
773
|
-
}
|
|
774
|
-
function topicOverlapSimilarity(a, b, minTokens = 3) {
|
|
775
|
-
const aTokens = tokenSet(a);
|
|
776
|
-
const bTokens = tokenSet(b);
|
|
777
|
-
if (aTokens.size < minTokens || bTokens.size < minTokens) return 0;
|
|
778
|
-
const intersection = intersectionSize(aTokens, bTokens);
|
|
779
|
-
const smaller = Math.min(aTokens.size, bTokens.size);
|
|
780
|
-
return smaller === 0 ? 0 : intersection / smaller;
|
|
781
|
-
}
|
|
782
|
-
var DESCRIPTION_DUPLICATE_THRESHOLD = 0.4;
|
|
783
|
-
var TOPIC_OVERLAP_THRESHOLD = 0.6;
|
|
784
|
-
function checkFrontmatterPreservation(existing, incoming) {
|
|
785
|
-
const violations = [];
|
|
786
|
-
for (const field of PROTECTED_FRONTMATTER_FIELDS) {
|
|
787
|
-
const oldValue = extractFrontmatterField(existing, field);
|
|
788
|
-
const newValue = extractFrontmatterField(incoming, field);
|
|
789
|
-
if (oldValue !== void 0 && newValue !== void 0 && oldValue !== newValue) {
|
|
790
|
-
violations.push(`${field}: was "${oldValue}", changed to "${newValue}"`);
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
const oldDesc = extractFrontmatterField(existing, "description");
|
|
794
|
-
const newDesc = extractFrontmatterField(incoming, "description");
|
|
795
|
-
if (oldDesc && newDesc && newDesc.length < oldDesc.length * 0.9) {
|
|
796
|
-
violations.push(
|
|
797
|
-
`description shortened from ${oldDesc.length} to ${newDesc.length} chars (${Math.round((1 - newDesc.length / oldDesc.length) * 100)}% reduction). Descriptions are the primary triggering mechanism \u2014 do not shorten them.`
|
|
798
|
-
);
|
|
799
|
-
}
|
|
800
|
-
return violations;
|
|
801
|
-
}
|
|
802
|
-
function validateSkillContent(content, dirName) {
|
|
803
|
-
const issues = [];
|
|
804
|
-
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
805
|
-
if (!fmMatch) {
|
|
806
|
-
issues.push("Missing YAML frontmatter (must start with --- and end with ---)");
|
|
807
|
-
return issues;
|
|
808
|
-
}
|
|
809
|
-
const frontmatter = fmMatch[1];
|
|
810
|
-
for (const field of REQUIRED_FRONTMATTER_FIELDS) {
|
|
811
|
-
if (!frontmatter.includes(`${field}:`)) {
|
|
812
|
-
issues.push(`Missing required frontmatter field: ${field}`);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
|
|
816
|
-
if (nameMatch && !nameMatch[1].trim().startsWith("myco:")) {
|
|
817
|
-
issues.push(`Skill name must start with "myco:" prefix. Got: "${nameMatch[1].trim()}"`);
|
|
818
|
-
}
|
|
819
|
-
const managedMatch = frontmatter.match(/^managed_by:\s*(.+)$/m);
|
|
820
|
-
if (managedMatch && managedMatch[1].trim() !== "myco") {
|
|
821
|
-
issues.push(`managed_by must be "myco". Got: "${managedMatch[1].trim()}"`);
|
|
822
|
-
}
|
|
823
|
-
const allowedToolsMatch = frontmatter.match(/^allowed-tools:\s*(.+)$/m);
|
|
824
|
-
if (allowedToolsMatch) {
|
|
825
|
-
const rawValue = allowedToolsMatch[1].trim();
|
|
826
|
-
if (rawValue.includes("vault_")) {
|
|
827
|
-
issues.push(
|
|
828
|
-
"allowed-tools contains vault agent tool names (vault_*). Skills run in Claude Code sessions -- use Claude Code tool names instead: Read, Edit, Write, Bash, Grep, Glob"
|
|
829
|
-
);
|
|
830
|
-
} else {
|
|
831
|
-
const parsed = parseAllowedTools(rawValue);
|
|
832
|
-
if (parsed === null) {
|
|
833
|
-
issues.push(
|
|
834
|
-
`allowed-tools value is malformed or empty: "${rawValue}". Provide a comma-separated list of Claude Code tools, e.g. "Read, Edit, Write, Bash, Grep, Glob". Use the narrowest set the skill actually needs.`
|
|
835
|
-
);
|
|
836
|
-
} else {
|
|
837
|
-
const unknown = parsed.filter((t) => !ALLOWED_CLAUDE_CODE_TOOLS.has(t));
|
|
838
|
-
if (unknown.length > 0) {
|
|
839
|
-
issues.push(
|
|
840
|
-
`allowed-tools contains unknown tool name(s): ${unknown.join(", ")}. Valid Claude Code tools: ${[...ALLOWED_CLAUDE_CODE_TOOLS].join(", ")}.`
|
|
841
|
-
);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
const listToolLines = frontmatter.match(/^\s+-\s+vault_\w+/gm);
|
|
847
|
-
if (listToolLines) {
|
|
848
|
-
issues.push(
|
|
849
|
-
"allowed-tools contains vault agent tool names (vault_*). Skills run in Claude Code sessions -- use Claude Code tool names instead: Read, Edit, Write, Bash, Grep, Glob"
|
|
850
|
-
);
|
|
851
|
-
}
|
|
852
|
-
const lineCount = content.split("\n").length;
|
|
853
|
-
if (lineCount > MAX_SKILL_LINES) {
|
|
854
|
-
issues.push(`Skill is ${lineCount} lines (max ${MAX_SKILL_LINES})`);
|
|
855
|
-
}
|
|
856
|
-
return issues;
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
// src/agent/tools/skill-tools.ts
|
|
860
617
|
function createSkillTools(deps) {
|
|
861
|
-
const { agentId, machineId, projectRoot, vaultDir, recordTurn } = deps;
|
|
618
|
+
const { agentId, machineId, projectRoot, vaultDir, recordTurn, embeddingManager } = deps;
|
|
862
619
|
function findOverlappingCandidate(newTopic, existing) {
|
|
863
620
|
let best = null;
|
|
864
621
|
for (const candidate of existing) {
|
|
@@ -878,7 +635,7 @@ function createSkillTools(deps) {
|
|
|
878
635
|
const common = `already has an existing candidate with a similar topic: "${match.topic}"`;
|
|
879
636
|
switch (match.status) {
|
|
880
637
|
case CANDIDATE_STATUS.DISMISSED:
|
|
881
|
-
return `
|
|
638
|
+
return `Note: similar to dismissed candidate "${match.topic}". If this is a broader domain that subsumes the dismissed topic, creation is allowed.`;
|
|
882
639
|
case CANDIDATE_STATUS.GENERATED:
|
|
883
640
|
return `Candidate rejected: the vault ${common} that was already fulfilled by a generated skill. Do not re-identify.`;
|
|
884
641
|
case CANDIDATE_STATUS.APPROVED:
|
|
@@ -1072,6 +829,7 @@ function createSkillTools(deps) {
|
|
|
1072
829
|
),
|
|
1073
830
|
source_ids: external_exports.string().optional().describe("JSON array of source spore/entity IDs"),
|
|
1074
831
|
skill_id: external_exports.string().optional().describe("Associated skill record ID (after materialization)"),
|
|
832
|
+
supersedes: external_exports.string().optional().describe("JSON array of skill record names this candidate would replace (for domain-level candidates that subsume existing narrow skills)"),
|
|
1075
833
|
limit: external_exports.number().optional().describe("Maximum candidates to return (for list)")
|
|
1076
834
|
},
|
|
1077
835
|
async (args) => {
|
|
@@ -1095,9 +853,18 @@ function createSkillTools(deps) {
|
|
|
1095
853
|
if (!args.topic || !args.rationale) {
|
|
1096
854
|
return textResult({ error: "topic and rationale are required for create action" });
|
|
1097
855
|
}
|
|
856
|
+
let supersedesNames = [];
|
|
857
|
+
if (args.supersedes) {
|
|
858
|
+
try {
|
|
859
|
+
supersedesNames = JSON.parse(args.supersedes);
|
|
860
|
+
} catch {
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const supersedesSet = new Set(supersedesNames);
|
|
1098
864
|
const activeSkills = listSkillRecords({ agent_id: agentId, status: "active", limit: 100 });
|
|
1099
865
|
const topicLower = args.topic.toLowerCase();
|
|
1100
866
|
const overlapping = activeSkills.filter((s) => {
|
|
867
|
+
if (supersedesSet.has(s.name)) return false;
|
|
1101
868
|
const nameWords = s.name.split("-").filter((w) => w.length > 2);
|
|
1102
869
|
if (nameWords.length < 2) return false;
|
|
1103
870
|
return nameWords.every((w) => topicLower.includes(w));
|
|
@@ -1110,16 +877,21 @@ function createSkillTools(deps) {
|
|
|
1110
877
|
}
|
|
1111
878
|
const allExisting = listCandidates({ agent_id: agentId, limit: 500 });
|
|
1112
879
|
const match = findOverlappingCandidate(args.topic, allExisting);
|
|
880
|
+
let dismissedMatch;
|
|
1113
881
|
if (match) {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
882
|
+
if (match.candidate.status === CANDIDATE_STATUS.DISMISSED) {
|
|
883
|
+
dismissedMatch = match;
|
|
884
|
+
} else {
|
|
885
|
+
return textResult({
|
|
886
|
+
error: candidateOverlapError(match.candidate),
|
|
887
|
+
existing_candidate: {
|
|
888
|
+
id: match.candidate.id,
|
|
889
|
+
status: match.candidate.status,
|
|
890
|
+
topic: match.candidate.topic
|
|
891
|
+
},
|
|
892
|
+
similarity: match.score
|
|
893
|
+
});
|
|
894
|
+
}
|
|
1123
895
|
}
|
|
1124
896
|
const now = epochSeconds();
|
|
1125
897
|
const candidate = insertCandidate({
|
|
@@ -1131,9 +903,18 @@ function createSkillTools(deps) {
|
|
|
1131
903
|
confidence: args.confidence,
|
|
1132
904
|
status: args.status,
|
|
1133
905
|
source_ids: args.source_ids,
|
|
906
|
+
supersedes: args.supersedes,
|
|
1134
907
|
created_at: now,
|
|
1135
908
|
updated_at: now
|
|
1136
909
|
});
|
|
910
|
+
const result = { ...candidate };
|
|
911
|
+
if (dismissedMatch) {
|
|
912
|
+
result.warning = candidateOverlapError(dismissedMatch.candidate);
|
|
913
|
+
result.similar_dismissed_candidate = {
|
|
914
|
+
id: dismissedMatch.candidate.id,
|
|
915
|
+
topic: dismissedMatch.candidate.topic
|
|
916
|
+
};
|
|
917
|
+
}
|
|
1137
918
|
notify(vaultDir, {
|
|
1138
919
|
domain: "skills",
|
|
1139
920
|
type: "skill.surveyed",
|
|
@@ -1142,7 +923,7 @@ function createSkillTools(deps) {
|
|
|
1142
923
|
link: "/skills?tab=candidates",
|
|
1143
924
|
metadata: { candidateId: candidate.id, topic: args.topic }
|
|
1144
925
|
});
|
|
1145
|
-
return textResult(
|
|
926
|
+
return textResult(result);
|
|
1146
927
|
}
|
|
1147
928
|
case "update": {
|
|
1148
929
|
if (!args.id) return textResult({ error: "id is required for update action" });
|
|
@@ -1154,6 +935,7 @@ function createSkillTools(deps) {
|
|
|
1154
935
|
...args.status !== void 0 ? { status: args.status } : {},
|
|
1155
936
|
...args.source_ids !== void 0 ? { source_ids: args.source_ids } : {},
|
|
1156
937
|
...args.skill_id !== void 0 ? { skill_id: args.skill_id } : {},
|
|
938
|
+
...args.supersedes !== void 0 ? { supersedes: args.supersedes } : {},
|
|
1157
939
|
updated_at: now
|
|
1158
940
|
});
|
|
1159
941
|
if (!updated) return textResult({ error: `Candidate not found: ${args.id}` });
|
|
@@ -1173,7 +955,7 @@ function createSkillTools(deps) {
|
|
|
1173
955
|
);
|
|
1174
956
|
const vaultSkillRecords = tool4(
|
|
1175
957
|
"vault_skill_records",
|
|
1176
|
-
"Read, update, and delete skill records (materialized skills on disk). Supports list, get, update, and delete actions.",
|
|
958
|
+
"Read, update, and delete skill records (materialized skills on disk). Supports list, get, update, and delete actions. The get action includes the full SKILL.md file content.",
|
|
1177
959
|
{
|
|
1178
960
|
action: external_exports.enum(["list", "get", "update", "delete"]).describe("Action to perform"),
|
|
1179
961
|
id: external_exports.string().optional().describe("Skill record ID or name (required for get/update/delete)"),
|
|
@@ -1198,7 +980,14 @@ function createSkillTools(deps) {
|
|
|
1198
980
|
if (!args.id) return textResult({ error: "id is required for get action" });
|
|
1199
981
|
const record = getSkillRecord(args.id) ?? getSkillRecordByName(args.id);
|
|
1200
982
|
if (!record) return textResult({ error: `Skill record not found: ${args.id}` });
|
|
1201
|
-
|
|
983
|
+
const result = { ...record };
|
|
984
|
+
if (record.path && projectRoot) {
|
|
985
|
+
try {
|
|
986
|
+
result.content = readFileSync(resolve(projectRoot, record.path), "utf-8");
|
|
987
|
+
} catch {
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
return textResult(result);
|
|
1202
991
|
}
|
|
1203
992
|
case "update": {
|
|
1204
993
|
if (!args.id) return textResult({ error: "id is required for update action" });
|
|
@@ -1219,6 +1008,10 @@ function createSkillTools(deps) {
|
|
|
1219
1008
|
if (!args.id) return textResult({ error: "id is required for delete action" });
|
|
1220
1009
|
const result = deleteSkillRecordCascade(args.id);
|
|
1221
1010
|
if (!result) return textResult({ error: `Skill record not found: ${args.id}` });
|
|
1011
|
+
try {
|
|
1012
|
+
embeddingManager?.onRemoved("skill_records", result.id);
|
|
1013
|
+
} catch {
|
|
1014
|
+
}
|
|
1222
1015
|
const root = projectRoot ?? process.cwd();
|
|
1223
1016
|
if (!/[/\\]|\.\./.test(result.name)) {
|
|
1224
1017
|
const skillDir = resolve(root, ".agents", "skills", result.name);
|
|
@@ -1338,6 +1131,11 @@ function createSkillTools(deps) {
|
|
|
1338
1131
|
recordId: result.id,
|
|
1339
1132
|
generation: result.generation
|
|
1340
1133
|
});
|
|
1134
|
+
embeddingManager?.onContentWritten("skill_records", result.id, args.description, {
|
|
1135
|
+
status: "active",
|
|
1136
|
+
name: args.name
|
|
1137
|
+
}).catch(() => {
|
|
1138
|
+
});
|
|
1341
1139
|
return textResult(result);
|
|
1342
1140
|
}
|
|
1343
1141
|
const priorSkillContent = readFileSync(skillPath, "utf-8");
|
|
@@ -1399,6 +1197,11 @@ function createSkillTools(deps) {
|
|
|
1399
1197
|
recordId,
|
|
1400
1198
|
generation
|
|
1401
1199
|
});
|
|
1200
|
+
embeddingManager?.onContentWritten("skill_records", recordId, args.description, {
|
|
1201
|
+
status: "active",
|
|
1202
|
+
name: args.name
|
|
1203
|
+
}).catch(() => {
|
|
1204
|
+
});
|
|
1402
1205
|
recordTurn("vault_write_skill", args);
|
|
1403
1206
|
return textResult({
|
|
1404
1207
|
id: recordId,
|
|
@@ -1538,6 +1341,11 @@ function createSkillTools(deps) {
|
|
|
1538
1341
|
recordId: result.id,
|
|
1539
1342
|
generation: result.generation
|
|
1540
1343
|
});
|
|
1344
|
+
embeddingManager?.onContentWritten("skill_records", result.id, manifest.description, {
|
|
1345
|
+
status: "active",
|
|
1346
|
+
name: manifest.name
|
|
1347
|
+
}).catch(() => {
|
|
1348
|
+
});
|
|
1541
1349
|
return textResult(result);
|
|
1542
1350
|
},
|
|
1543
1351
|
{ annotations: { openWorldHint: true } }
|
|
@@ -2595,4 +2403,4 @@ export {
|
|
|
2595
2403
|
computeWaves,
|
|
2596
2404
|
runAgent
|
|
2597
2405
|
};
|
|
2598
|
-
//# sourceMappingURL=executor-
|
|
2406
|
+
//# sourceMappingURL=executor-UYIZC3L5.js.map
|