@iowarp/clio-coder 0.3.6 → 0.3.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/CHANGELOG.md +28 -0
- package/README.md +16 -5
- package/dist/{acp-2BEHC4DL.js → acp-SK4MD6MM.js} +10 -10
- package/dist/{agents-LNNFTM53.js → agents-2FN2K6ME.js} +30 -25
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-QIYZWM5I.js} +13 -13
- package/dist/{chunk-KHSFENX2.js → chunk-3HAPLH5M.js} +10 -10
- package/dist/{chunk-24I7BN55.js → chunk-465YSENW.js} +2 -2
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CYQKWTG3.js → chunk-4DWFMQDR.js} +4 -4
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-K7T3E2SR.js → chunk-5UJ6ECTS.js} +10 -9
- package/dist/{chunk-6US73PDB.js → chunk-6M7VS3J3.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-6TUKSZVF.js} +5 -5
- package/dist/{chunk-5JGRAMKL.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-R46L2BIR.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-XXQNGV4M.js → chunk-CEYBNUGC.js} +243 -63
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-DMD2AGVS.js} +5 -4
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-XF5N4U5A.js → chunk-EBEFWSGL.js} +6 -5
- package/dist/{chunk-EYPA3EGJ.js → chunk-EELBMBT6.js} +120 -13
- package/dist/{chunk-CKXWIANG.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-LYF7OHWH.js → chunk-J7PIKKWC.js} +8 -463
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-6XXKFVSN.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-QNQHSOLF.js → chunk-LADCF22A.js} +12 -12
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-XYDYPRZI.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-G7MUEIGA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-EKY57CSP.js → chunk-OBMAI2DP.js} +61 -767
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ZRGEBJ4T.js → chunk-QCTRSGHQ.js} +21 -21
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QM3F2GKX.js → chunk-UUANF5CR.js} +2247 -2096
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-DJVECN66.js → chunk-VQNODYQ4.js} +14 -14
- package/dist/{chunk-3BPUFZDL.js → chunk-VREKEFLL.js} +3 -3
- package/dist/{chunk-PBTHKCPN.js → chunk-WJHBC77E.js} +6 -6
- package/dist/{chunk-XE2VEJHX.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-ZXF4XRKW.js → chunk-XEGB6BCN.js} +157 -7
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-NCBTHHN2.js → chunk-YTYFXUI3.js} +65 -322
- package/dist/{chunk-OH3TOQTB.js → chunk-ZGH7FGS5.js} +13 -7
- package/dist/cli/index.js +32 -30
- package/dist/{clio-M2KGYUFZ.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +3 -3
- package/dist/{components-5TTYYX6G.js → components-F7OEATSO.js} +4 -4
- package/dist/{config-XUUYQIWO.js → config-TRBL3RCF.js} +34 -29
- package/dist/{configure-IHJ7YOMV.js → configure-OLCVPHNM.js} +15 -15
- package/dist/{context-74JLXAWD.js → context-MJIJ6GOX.js} +11 -11
- package/dist/{context-ZQ7SIFJV.js → context-WFPKQSM6.js} +19 -3
- package/dist/{context-75MIWW3U.js → context-XEWE3MOJ.js} +31 -26
- package/dist/{context-clear-GYKWNUML.js → context-clear-KNOS2JPB.js} +31 -26
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-EUXAZI6N.js} +8 -8
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-B7MTOVKL.js} +313 -53
- package/dist/{docs-6FZSCG5B.js → docs-FLJTIDSE.js} +4 -4
- package/dist/{doctor-SVJ5BZCW.js → doctor-RN4YKO2X.js} +14 -14
- package/dist/{eval-CG6LLBLD.js → eval-RUBJVSNQ.js} +8 -7
- package/dist/{evidence-ZYFIEN42.js → evidence-JZNBUOQZ.js} +30 -25
- package/dist/{evolve-QGEXEMDW.js → evolve-FJVC4KKI.js} +30 -25
- package/dist/{extensions-ADGNCJJD.js → extensions-IQL36S7K.js} +4 -4
- package/dist/{fleet-S5R4ZOQY.js → fleet-BDKYJFCP.js} +214 -360
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-5DRU55YR.js → init-LQUB5COQ.js} +44 -37
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-OG6HOYKM.js} +31 -26
- package/dist/{models-ZPOLRU2C.js → models-5ZG5XY7J.js} +21 -20
- package/dist/{monitor-US5F5YGZ.js → monitor-TJ7AMTGB.js} +49 -30
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-WZYB54DM.js} +3827 -581
- package/dist/{paths-E7KYAQWE.js → paths-XUC7GS6E.js} +4 -4
- package/dist/{reset-KZ652EK6.js → reset-PXQT45IY.js} +7 -7
- package/dist/{run-SRNBKDWD.js → run-FQ74YF62.js} +53 -45
- package/dist/{share-CGZE33UP.js → share-FW7SVCL3.js} +33 -9
- package/dist/{skills-S2X4DLY5.js → skills-7E7IRB3R.js} +24 -8
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-LI75W6OK.js} +34 -27
- package/dist/{targets-54SWINWB.js → targets-4CIFKCTW.js} +23 -22
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WUZY7ZV5.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-7FV7IP4E.js} +4 -4
- package/dist/{upgrade-JKAR27XC.js → upgrade-K2HVIVMQ.js} +20 -19
- package/dist/{usage-MSAWCLX4.js → usage-GTZELZQX.js} +116 -49
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-ASIFASCN.js} +45 -37
- package/dist/worker/entry.js +38 -35
- package/docs/README.md +3 -2
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +82 -2
- package/docs/configuration-and-targets.md +79 -2
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +3 -3
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +5 -5
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +197 -10
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +2 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +79 -64
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +1 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +173 -335
- package/src/cli/index.ts +3 -1
- package/src/cli/library.ts +190 -0
- package/src/cli/share.ts +13 -1
- package/src/cli/usage.ts +111 -19
- package/src/core/bus-events.ts +4 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/domains/agents/builtins/architect.md +1 -0
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +13 -1
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/result-contract.ts +235 -1
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +34 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +258 -9
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/receipt-integrity.ts +8 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +51 -6
- package/src/domains/dispatch/validation.ts +66 -6
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +3 -1
- package/src/domains/observability/cost.ts +12 -1
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- package/src/entry/orchestrator.ts +37 -0
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop.ts +235 -1
- package/src/interactive/chat-renderer.ts +22 -0
- package/src/interactive/cost-overlay.ts +31 -3
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +260 -16
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +43 -1
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
- package/src/interactive/overlay-general-openers.ts +190 -1
- package/src/interactive/overlay-key-routing.ts +17 -1
- package/src/interactive/overlay-lifecycle.ts +41 -1
- package/src/interactive/overlay-permission-lifecycle.ts +10 -0
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +432 -5
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-middleware.ts +15 -1
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +7 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +57 -1
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +16 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +61 -1
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +2 -1
- package/src/worker/spec-contract.ts +1 -0
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
+
parseAgentRecipeSchema
|
|
4
|
+
} from "./chunk-UVDSQ6LW.js";
|
|
5
|
+
import {
|
|
6
|
+
discoverMarketplaceSkills,
|
|
3
7
|
expandSkillInvocationInput,
|
|
8
|
+
installSkill,
|
|
4
9
|
loadSkills,
|
|
10
|
+
normalizedSkillHash,
|
|
5
11
|
parsePendingSkillRequests,
|
|
6
12
|
projectCompatTrusted
|
|
7
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-C4JBQ5SR.js";
|
|
8
14
|
import {
|
|
9
15
|
COMPAT_RESOURCE_PRECEDENCE,
|
|
10
16
|
defaultScopedResourceRoots,
|
|
@@ -13,223 +19,53 @@ import {
|
|
|
13
19
|
splitYamlFrontmatter,
|
|
14
20
|
stringField
|
|
15
21
|
} from "./chunk-2SFS6XQE.js";
|
|
22
|
+
import {
|
|
23
|
+
parseFleetContract,
|
|
24
|
+
parseFrontmatter
|
|
25
|
+
} from "./chunk-KCMKRQX4.js";
|
|
26
|
+
import {
|
|
27
|
+
assertAgentSpecPolicy,
|
|
28
|
+
normalizeAgentSpec
|
|
29
|
+
} from "./chunk-AOCYTWAV.js";
|
|
16
30
|
import {
|
|
17
31
|
INTEROP_AGENT_KINDS
|
|
18
32
|
} from "./chunk-IHXBNWMM.js";
|
|
33
|
+
import {
|
|
34
|
+
readSettings,
|
|
35
|
+
updateSettings
|
|
36
|
+
} from "./chunk-UHXRNZ2J.js";
|
|
19
37
|
import {
|
|
20
38
|
expandConfigPath
|
|
21
39
|
} from "./chunk-SST6Z5JA.js";
|
|
40
|
+
import {
|
|
41
|
+
runCommandVector
|
|
42
|
+
} from "./chunk-D4MDIG46.js";
|
|
22
43
|
import {
|
|
23
44
|
require_dist
|
|
24
45
|
} from "./chunk-APJ265NV.js";
|
|
46
|
+
import {
|
|
47
|
+
clioConfigDir
|
|
48
|
+
} from "./chunk-BNAZZHFG.js";
|
|
49
|
+
import {
|
|
50
|
+
safeResourceWrite
|
|
51
|
+
} from "./chunk-WEPFGWHJ.js";
|
|
25
52
|
import {
|
|
26
53
|
__toESM,
|
|
27
54
|
init_esm_shims
|
|
28
55
|
} from "./chunk-3R73A4XB.js";
|
|
29
56
|
|
|
30
|
-
// src/domains/resources/
|
|
31
|
-
init_esm_shims();
|
|
32
|
-
var SCENARIO_HEADING = /^##\s+([A-Z])(\d+)\s*[-:–—]\s*(.+?)\s*$/;
|
|
33
|
-
function parseSkillEvals(markdown) {
|
|
34
|
-
const lines = markdown.split("\n");
|
|
35
|
-
const scenarios = [];
|
|
36
|
-
const diagnostics = [];
|
|
37
|
-
let index = 0;
|
|
38
|
-
while (index < lines.length) {
|
|
39
|
-
const heading = SCENARIO_HEADING.exec(lines[index] ?? "");
|
|
40
|
-
if (heading === null) {
|
|
41
|
-
index += 1;
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
const blockStart = index + 1;
|
|
45
|
-
let blockEnd = blockStart;
|
|
46
|
-
while (blockEnd < lines.length && !/^##\s+/.test(lines[blockEnd] ?? "")) blockEnd += 1;
|
|
47
|
-
const block = lines.slice(blockStart, blockEnd);
|
|
48
|
-
const number = Number.parseInt(heading[2] ?? "", 10);
|
|
49
|
-
const id = `${heading[1] ?? "S"}${number}`;
|
|
50
|
-
const title = heading[3] ?? "";
|
|
51
|
-
const setup = extractSetup(block);
|
|
52
|
-
const fixtureCommands = extractFixtureCommands(block);
|
|
53
|
-
const expected = extractExpected(block);
|
|
54
|
-
if (setup === null) diagnostics.push(`${id} (${title}): no "Setup:" or "Prompt:" paragraph found; scenario skipped`);
|
|
55
|
-
else if (expected.length === 0) diagnostics.push(`${id} (${title}): no "Expected:" bullets found; scenario skipped`);
|
|
56
|
-
else scenarios.push({ id, number, title, setup, ...fixtureCommands ? { fixtureCommands } : {}, expected });
|
|
57
|
-
index = blockEnd;
|
|
58
|
-
}
|
|
59
|
-
return { scenarios, diagnostics };
|
|
60
|
-
}
|
|
61
|
-
function extractSetup(block) {
|
|
62
|
-
return extractLabeledParagraph(block, /^Setup:\s*(.*)$/i) ?? extractLabeledParagraph(block, /^(Prompt:.*)$/i);
|
|
63
|
-
}
|
|
64
|
-
function isScenarioLabel(line) {
|
|
65
|
-
const trimmed = line.trim();
|
|
66
|
-
return /^(Expected|Fixture|Setup commands):/i.test(trimmed) || /^Expected$/i.test(trimmed);
|
|
67
|
-
}
|
|
68
|
-
function extractLabeledParagraph(block, label) {
|
|
69
|
-
for (let i = 0; i < block.length; i += 1) {
|
|
70
|
-
const line = block[i] ?? "";
|
|
71
|
-
const match = label.exec(line.trim());
|
|
72
|
-
if (match === null) continue;
|
|
73
|
-
const parts = [];
|
|
74
|
-
if ((match[1] ?? "").length > 0) parts.push(match[1] ?? "");
|
|
75
|
-
for (let j = i + 1; j < block.length; j += 1) {
|
|
76
|
-
const next = (block[j] ?? "").trim();
|
|
77
|
-
if (next.length === 0) break;
|
|
78
|
-
if (isScenarioLabel(next)) break;
|
|
79
|
-
parts.push(next);
|
|
80
|
-
}
|
|
81
|
-
const setup = parts.join(" ").trim();
|
|
82
|
-
return setup.length > 0 ? setup : null;
|
|
83
|
-
}
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
function extractFixtureCommands(block) {
|
|
87
|
-
for (let i = 0; i < block.length; i += 1) {
|
|
88
|
-
const line = (block[i] ?? "").trim();
|
|
89
|
-
const match = /^(?:Fixture|Setup commands):\s*(.*)$/i.exec(line);
|
|
90
|
-
if (match === null) continue;
|
|
91
|
-
const inline = (match[1] ?? "").trim();
|
|
92
|
-
let cursor = i + 1;
|
|
93
|
-
while (cursor < block.length && (block[cursor] ?? "").trim().length === 0) cursor += 1;
|
|
94
|
-
const first = block[cursor] ?? "";
|
|
95
|
-
const fence = /^```\w*\s*$/.test(first.trim());
|
|
96
|
-
if (fence) {
|
|
97
|
-
const commands2 = [];
|
|
98
|
-
for (let j = cursor + 1; j < block.length; j += 1) {
|
|
99
|
-
const current = block[j] ?? "";
|
|
100
|
-
if (/^```\s*$/.test(current.trim())) {
|
|
101
|
-
const script2 = commands2.join("\n").trim();
|
|
102
|
-
return script2.length > 0 ? script2 : null;
|
|
103
|
-
}
|
|
104
|
-
commands2.push(current);
|
|
105
|
-
}
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
const commands = [];
|
|
109
|
-
if (inline.length > 0) commands.push(inline);
|
|
110
|
-
for (let j = cursor; j < block.length; j += 1) {
|
|
111
|
-
const current = block[j] ?? "";
|
|
112
|
-
const trimmed = current.trim();
|
|
113
|
-
if (trimmed.length === 0) break;
|
|
114
|
-
if (isScenarioLabel(trimmed)) break;
|
|
115
|
-
commands.push(current);
|
|
116
|
-
}
|
|
117
|
-
const script = commands.join("\n").trim();
|
|
118
|
-
return script.length > 0 ? script : null;
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
function extractExpected(block) {
|
|
123
|
-
let start = -1;
|
|
124
|
-
for (let i = 0; i < block.length; i += 1) {
|
|
125
|
-
if (/^Expected:?\s*$/i.test((block[i] ?? "").trim())) {
|
|
126
|
-
start = i + 1;
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (start < 0) return [];
|
|
131
|
-
const bullets = [];
|
|
132
|
-
let current = null;
|
|
133
|
-
for (let i = start; i < block.length; i += 1) {
|
|
134
|
-
const raw = block[i] ?? "";
|
|
135
|
-
const trimmed = raw.trim();
|
|
136
|
-
if (trimmed.length === 0) {
|
|
137
|
-
if (current !== null) {
|
|
138
|
-
bullets.push(current.join(" "));
|
|
139
|
-
current = null;
|
|
140
|
-
}
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
const bullet = /^[-*]\s+(.*)$/.exec(raw);
|
|
144
|
-
if (bullet !== null) {
|
|
145
|
-
if (current !== null) bullets.push(current.join(" "));
|
|
146
|
-
current = [bullet[1] ?? ""];
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
if (current !== null && /^\s+\S/.test(raw)) {
|
|
150
|
-
current.push(trimmed);
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
if (current !== null) bullets.push(current.join(" "));
|
|
156
|
-
return bullets.map((bullet) => bullet.trim()).filter((bullet) => bullet.length > 0);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// src/domains/resources/skills/provenance-pin.ts
|
|
57
|
+
// src/domains/resources/library.ts
|
|
160
58
|
init_esm_shims();
|
|
161
59
|
var import_yaml = __toESM(require_dist(), 1);
|
|
162
|
-
import {
|
|
163
|
-
import
|
|
164
|
-
|
|
165
|
-
function isPlainObject(value) {
|
|
166
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
167
|
-
}
|
|
168
|
-
function resolveSkillPinManifestPath(cwd) {
|
|
169
|
-
const fromEnv = process.env.CLIO_CODER_SKILL_CATALOG_DIR;
|
|
170
|
-
const catalogDir = fromEnv && fromEnv.trim().length > 0 ? path.resolve(fromEnv.trim()) : path.join(cwd, "skills");
|
|
171
|
-
const manifestPath = path.join(catalogDir, SKILL_PIN_MANIFEST_FILENAME);
|
|
172
|
-
return existsSync(manifestPath) ? manifestPath : null;
|
|
173
|
-
}
|
|
174
|
-
function loadSkillPinManifest(manifestPath) {
|
|
175
|
-
let parsed;
|
|
176
|
-
try {
|
|
177
|
-
parsed = import_yaml.default.parse(readFileSync(manifestPath, "utf8"));
|
|
178
|
-
} catch {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
if (!isPlainObject(parsed) || !Array.isArray(parsed.skills)) return null;
|
|
182
|
-
const entries = /* @__PURE__ */ new Map();
|
|
183
|
-
for (const raw of parsed.skills) {
|
|
184
|
-
if (!isPlainObject(raw)) continue;
|
|
185
|
-
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
186
|
-
const sha256 = typeof raw.sha256 === "string" ? raw.sha256.trim().toLowerCase() : "";
|
|
187
|
-
if (name.length === 0 || !/^[0-9a-f]{64}$/.test(sha256)) continue;
|
|
188
|
-
entries.set(name, {
|
|
189
|
-
name,
|
|
190
|
-
version: typeof raw.version === "string" && raw.version.trim().length > 0 ? raw.version.trim() : null,
|
|
191
|
-
sha256
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
return entries;
|
|
195
|
-
}
|
|
196
|
-
function checkSkillDrift(skill, cwd) {
|
|
197
|
-
const actual = skill.normalizedHash.toLowerCase();
|
|
198
|
-
const manifestPath = resolveSkillPinManifestPath(cwd);
|
|
199
|
-
const manifest = manifestPath === null ? null : loadSkillPinManifest(manifestPath);
|
|
200
|
-
const pinned = manifest?.get(skill.name);
|
|
201
|
-
if (pinned !== void 0) {
|
|
202
|
-
return {
|
|
203
|
-
verdict: pinned.sha256 === actual ? "match" : "mismatch",
|
|
204
|
-
authority: "pinned-manifest",
|
|
205
|
-
expected: pinned.sha256
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
const recorded = skill.provenance?.installedHash?.trim().toLowerCase();
|
|
209
|
-
if (recorded !== void 0 && /^[0-9a-f]{64}$/.test(recorded)) {
|
|
210
|
-
return {
|
|
211
|
-
verdict: recorded === actual ? "match" : "mismatch",
|
|
212
|
-
authority: "install-record",
|
|
213
|
-
expected: recorded
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// src/domains/resources/index.ts
|
|
220
|
-
init_esm_shims();
|
|
221
|
-
|
|
222
|
-
// src/domains/resources/extension.ts
|
|
223
|
-
init_esm_shims();
|
|
224
|
-
|
|
225
|
-
// src/domains/resources/loader.ts
|
|
226
|
-
init_esm_shims();
|
|
60
|
+
import { createHash } from "node:crypto";
|
|
61
|
+
import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
62
|
+
import path2 from "node:path";
|
|
227
63
|
|
|
228
64
|
// src/domains/resources/prompts/loader.ts
|
|
229
65
|
init_esm_shims();
|
|
230
|
-
import { readFileSync
|
|
66
|
+
import { readFileSync } from "node:fs";
|
|
231
67
|
import { homedir } from "node:os";
|
|
232
|
-
import
|
|
68
|
+
import path from "node:path";
|
|
233
69
|
|
|
234
70
|
// src/engine/prompt-templates.ts
|
|
235
71
|
init_esm_shims();
|
|
@@ -294,7 +130,7 @@ function defaultPromptTemplateRoots(input = {}) {
|
|
|
294
130
|
for (const kind of INTEROP_AGENT_KINDS) {
|
|
295
131
|
if (kind.userPromptRoot !== void 0) {
|
|
296
132
|
compat.push({
|
|
297
|
-
path:
|
|
133
|
+
path: path.join(home, kind.userPromptRoot),
|
|
298
134
|
scope: "user",
|
|
299
135
|
source: `${kind.id}-user`,
|
|
300
136
|
precedence: COMPAT_RESOURCE_PRECEDENCE.userCompat,
|
|
@@ -303,7 +139,7 @@ function defaultPromptTemplateRoots(input = {}) {
|
|
|
303
139
|
}
|
|
304
140
|
if (kind.projectPromptRoot !== void 0) {
|
|
305
141
|
compat.push({
|
|
306
|
-
path:
|
|
142
|
+
path: path.join(cwd, kind.projectPromptRoot),
|
|
307
143
|
scope: "project",
|
|
308
144
|
source: `${kind.id}-project`,
|
|
309
145
|
precedence: COMPAT_RESOURCE_PRECEDENCE.projectCompat,
|
|
@@ -328,17 +164,17 @@ function fallbackDescription(body) {
|
|
|
328
164
|
return normalized.length > 60 ? `${normalized.slice(0, 57)}...` : normalized;
|
|
329
165
|
}
|
|
330
166
|
function loadPromptFile(filePath, root, diagnostics) {
|
|
331
|
-
const ext =
|
|
167
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
332
168
|
if (ext !== ".md") return null;
|
|
333
169
|
let raw;
|
|
334
170
|
try {
|
|
335
|
-
raw =
|
|
171
|
+
raw = readFileSync(filePath, "utf8");
|
|
336
172
|
} catch (err) {
|
|
337
173
|
const reason = err instanceof Error ? err.message : String(err);
|
|
338
174
|
diagnostics.push({ type: "warning", message: `prompt template could not be read: ${reason}`, path: filePath });
|
|
339
175
|
return null;
|
|
340
176
|
}
|
|
341
|
-
const name =
|
|
177
|
+
const name = path.basename(filePath, ext);
|
|
342
178
|
if (name.trim().length === 0) return null;
|
|
343
179
|
const { frontmatter, body } = splitOptionalFrontmatter(raw, filePath, diagnostics);
|
|
344
180
|
const description = stringField(frontmatter, "description") ?? fallbackDescription(body);
|
|
@@ -359,7 +195,7 @@ function loadPromptRoot(root, diagnostics) {
|
|
|
359
195
|
const candidates = [];
|
|
360
196
|
for (const entry of readRootEntries(root, "prompt template", diagnostics)) {
|
|
361
197
|
if (!entry.isFile()) continue;
|
|
362
|
-
const candidate = loadPromptFile(
|
|
198
|
+
const candidate = loadPromptFile(path.join(root.path, entry.name), root, diagnostics);
|
|
363
199
|
if (candidate) candidates.push(candidate);
|
|
364
200
|
}
|
|
365
201
|
return candidates;
|
|
@@ -421,7 +257,422 @@ function expandPromptTemplateInput(input, templates) {
|
|
|
421
257
|
};
|
|
422
258
|
}
|
|
423
259
|
|
|
260
|
+
// src/domains/resources/library.ts
|
|
261
|
+
function isRecord(value) {
|
|
262
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
263
|
+
}
|
|
264
|
+
function catalogPath() {
|
|
265
|
+
const configured = readSettings().library.catalog;
|
|
266
|
+
return path2.resolve(configured ?? path2.join(clioConfigDir(), "library.yaml"));
|
|
267
|
+
}
|
|
268
|
+
function parseCatalog(filePath, diagnostics) {
|
|
269
|
+
if (!existsSync(filePath)) return [];
|
|
270
|
+
try {
|
|
271
|
+
const raw = readFileSync2(filePath, "utf8");
|
|
272
|
+
const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : (0, import_yaml.parse)(raw);
|
|
273
|
+
const rows = Array.isArray(parsed) ? parsed : isRecord(parsed) && Array.isArray(parsed.skills) ? parsed.skills : [];
|
|
274
|
+
return rows.flatMap((value) => {
|
|
275
|
+
if (!isRecord(value) || typeof value.name !== "string" || typeof value.description !== "string" || typeof value.sourceUrl !== "string") {
|
|
276
|
+
diagnostics.push(`library catalog entry malformed: ${filePath}`);
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
const kind = value.kind === void 0 || value.kind === "skill" ? "skill" : value.kind === "agent" || value.kind === "prompt" || value.kind === "fleet" ? value.kind : "skill";
|
|
280
|
+
if (value.kind !== void 0 && !["skill", "agent", "prompt", "fleet"].includes(String(value.kind))) {
|
|
281
|
+
diagnostics.push(`library catalog entry has unsupported kind: ${value.name}`);
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
if (value.requires !== void 0 && (!Array.isArray(value.requires) || value.requires.some((item) => typeof item !== "string"))) {
|
|
285
|
+
diagnostics.push(`library_requirement_malformed: ${value.name}`);
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
288
|
+
const sourceUrl = /^(?:https?:\/\/|git@)/.test(value.sourceUrl) ? value.sourceUrl : path2.resolve(path2.dirname(filePath), value.sourceUrl);
|
|
289
|
+
const requires = Array.isArray(value.requires) ? value.requires.filter((item) => typeof item === "string") : void 0;
|
|
290
|
+
return [
|
|
291
|
+
{
|
|
292
|
+
kind,
|
|
293
|
+
name: value.name.trim(),
|
|
294
|
+
description: value.description.trim(),
|
|
295
|
+
sourceUrl,
|
|
296
|
+
origin: "index",
|
|
297
|
+
...typeof value.version === "string" ? { version: value.version } : {},
|
|
298
|
+
...requires ? { requires } : {}
|
|
299
|
+
}
|
|
300
|
+
];
|
|
301
|
+
});
|
|
302
|
+
} catch (error) {
|
|
303
|
+
diagnostics.push(`library catalog unreadable: ${error instanceof Error ? error.message : String(error)}`);
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function libraryEntryRef(entry) {
|
|
308
|
+
return `${entry.kind}:${entry.name}`;
|
|
309
|
+
}
|
|
310
|
+
function discoverLibrary(options = {}) {
|
|
311
|
+
const marketplace = discoverMarketplaceSkills({
|
|
312
|
+
...options.marketplace ?? {},
|
|
313
|
+
...options.cwd ? { cwd: options.cwd } : {}
|
|
314
|
+
});
|
|
315
|
+
const diagnostics = [...marketplace.diagnostics.filter((item) => !item.includes("no local skill marketplace"))];
|
|
316
|
+
const privatePath = catalogPath();
|
|
317
|
+
const primary = options.catalog ? parseCatalog(path2.resolve(options.catalog), diagnostics) : [];
|
|
318
|
+
const privateEntries = parseCatalog(privatePath, diagnostics);
|
|
319
|
+
const byRef = /* @__PURE__ */ new Map();
|
|
320
|
+
for (const entry of [...marketplace.skills, ...primary, ...privateEntries]) byRef.set(libraryEntryRef(entry), entry);
|
|
321
|
+
const refusals = {};
|
|
322
|
+
const entries = [...byRef.values()].filter((entry) => {
|
|
323
|
+
try {
|
|
324
|
+
resolveLibraryRequirements(entry, [...byRef.values()]);
|
|
325
|
+
return true;
|
|
326
|
+
} catch (error) {
|
|
327
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
328
|
+
refusals[libraryEntryRef(entry)] = message;
|
|
329
|
+
if (!diagnostics.includes(message)) diagnostics.push(message);
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
return {
|
|
334
|
+
entries: entries.sort((a, b) => libraryEntryRef(a).localeCompare(libraryEntryRef(b))),
|
|
335
|
+
diagnostics,
|
|
336
|
+
refusals
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
var REQUIREMENT_PATTERN = /^(skill|agent|prompt|fleet):([A-Za-z0-9][A-Za-z0-9._-]*)$/;
|
|
340
|
+
function resolveLibraryRequirements(entry, catalog) {
|
|
341
|
+
const byRef = new Map(catalog.map((item) => [libraryEntryRef(item), item]));
|
|
342
|
+
const ordered = [];
|
|
343
|
+
const visiting = [];
|
|
344
|
+
const visited = /* @__PURE__ */ new Set();
|
|
345
|
+
const visit = (current) => {
|
|
346
|
+
const currentRef = libraryEntryRef(current);
|
|
347
|
+
if (visited.has(currentRef)) return;
|
|
348
|
+
const cycleAt = visiting.indexOf(currentRef);
|
|
349
|
+
if (cycleAt >= 0)
|
|
350
|
+
throw new Error(`library_requirement_cycle: ${[...visiting.slice(cycleAt), currentRef].join(" -> ")}`);
|
|
351
|
+
visiting.push(currentRef);
|
|
352
|
+
for (const requirement of current.requires ?? []) {
|
|
353
|
+
if (!REQUIREMENT_PATTERN.test(requirement)) throw new Error("library_requirement_malformed");
|
|
354
|
+
const dependency = byRef.get(requirement);
|
|
355
|
+
if (!dependency) throw new Error(`library_requirement_missing: ${requirement}`);
|
|
356
|
+
visit(dependency);
|
|
357
|
+
}
|
|
358
|
+
visiting.pop();
|
|
359
|
+
visited.add(currentRef);
|
|
360
|
+
ordered.push(current);
|
|
361
|
+
};
|
|
362
|
+
visit(entry);
|
|
363
|
+
return ordered;
|
|
364
|
+
}
|
|
365
|
+
function sourceFile(entry) {
|
|
366
|
+
const source = path2.resolve(entry.sourceUrl);
|
|
367
|
+
if (entry.kind === "skill") return source;
|
|
368
|
+
if (!existsSync(source)) throw new Error(`library source path does not exist: ${source}`);
|
|
369
|
+
return source;
|
|
370
|
+
}
|
|
371
|
+
function validateEntry(entry, raw, filePath) {
|
|
372
|
+
if (entry.kind === "fleet") {
|
|
373
|
+
parseFleetContract(raw, filePath);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (entry.kind === "agent") {
|
|
377
|
+
const parsed = parseFrontmatter(raw, filePath);
|
|
378
|
+
const recipe = parseAgentRecipeSchema({ id: entry.name, source: "user", filepath: filePath, ...parsed });
|
|
379
|
+
assertAgentSpecPolicy(normalizeAgentSpec(recipe));
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if (entry.kind === "prompt") {
|
|
383
|
+
const loaded = loadPromptTemplates({ roots: [{ path: path2.dirname(filePath), scope: "user", source: "library" }] });
|
|
384
|
+
if (!loaded.items.some((item) => item.filePath === filePath))
|
|
385
|
+
throw new Error(`prompt template is malformed: ${filePath}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function libraryInstallPath(entry) {
|
|
389
|
+
if (entry.kind === "skill") return path2.join(clioConfigDir(), "skills", entry.name, "SKILL.md");
|
|
390
|
+
const root = entry.kind === "agent" ? "agents" : entry.kind === "fleet" ? "fleets" : "prompts";
|
|
391
|
+
return path2.join(clioConfigDir(), root, `${entry.name}.md`);
|
|
392
|
+
}
|
|
393
|
+
function readLibraryPins() {
|
|
394
|
+
const pinPath = path2.join(clioConfigDir(), "library-pins.yaml");
|
|
395
|
+
if (!existsSync(pinPath)) return {};
|
|
396
|
+
const parsed = (0, import_yaml.parse)(readFileSync2(pinPath, "utf8"));
|
|
397
|
+
return isRecord(parsed) ? parsed : {};
|
|
398
|
+
}
|
|
399
|
+
function libraryEntryInstalled(entry) {
|
|
400
|
+
return readLibraryPins()[libraryEntryRef(entry)] !== void 0 || existsSync(libraryInstallPath(entry));
|
|
401
|
+
}
|
|
402
|
+
function libraryEntryPin(entry) {
|
|
403
|
+
return readLibraryPins()[libraryEntryRef(entry)];
|
|
404
|
+
}
|
|
405
|
+
function classifyLibraryRequirements(entry, catalog) {
|
|
406
|
+
const ordered = resolveLibraryRequirements(entry, catalog).slice(0, -1);
|
|
407
|
+
const satisfied = ordered.filter((requirement) => libraryEntryInstalled(requirement));
|
|
408
|
+
const satisfiedRefs = new Set(satisfied.map(libraryEntryRef));
|
|
409
|
+
return {
|
|
410
|
+
ordered,
|
|
411
|
+
satisfied,
|
|
412
|
+
unsatisfied: ordered.filter((requirement) => !satisfiedRefs.has(libraryEntryRef(requirement)))
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
function planLibraryInstall(entry) {
|
|
416
|
+
if (entry.kind === "skill") {
|
|
417
|
+
const source2 = sourceFile(entry);
|
|
418
|
+
const file = statSync(source2).isDirectory() ? path2.join(source2, "SKILL.md") : source2;
|
|
419
|
+
const raw2 = readFileSync2(file);
|
|
420
|
+
return {
|
|
421
|
+
entry,
|
|
422
|
+
path: libraryInstallPath(entry),
|
|
423
|
+
sha256: normalizedSkillHash(raw2.toString("utf8"))
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
const source = sourceFile(entry);
|
|
427
|
+
const raw = readFileSync2(source, "utf8");
|
|
428
|
+
validateEntry(entry, raw, source);
|
|
429
|
+
return {
|
|
430
|
+
entry,
|
|
431
|
+
path: libraryInstallPath(entry),
|
|
432
|
+
sha256: createHash("sha256").update(raw).digest("hex")
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function recordPin(plan) {
|
|
436
|
+
const pinPath = path2.join(clioConfigDir(), "library-pins.yaml");
|
|
437
|
+
const pins = readLibraryPins();
|
|
438
|
+
pins[libraryEntryRef(plan.entry)] = { sha256: plan.sha256, sourceUrl: plan.entry.sourceUrl };
|
|
439
|
+
safeResourceWrite(pinPath, (0, import_yaml.stringify)(Object.fromEntries(Object.entries(pins).sort())), { encoding: "utf8" });
|
|
440
|
+
}
|
|
441
|
+
function installLibraryPlan(plan) {
|
|
442
|
+
if (existsSync(plan.path)) throw new Error(`library destination already exists: ${plan.path}`);
|
|
443
|
+
if (plan.entry.kind === "skill") installSkill({ source: plan.entry.sourceUrl, scope: "user", name: plan.entry.name });
|
|
444
|
+
else safeResourceWrite(plan.path, readFileSync2(sourceFile(plan.entry)));
|
|
445
|
+
recordPin(plan);
|
|
446
|
+
}
|
|
447
|
+
function confirmedRemote() {
|
|
448
|
+
const settings = readSettings().library;
|
|
449
|
+
if (!settings.remote || settings.remote !== settings.confirmedRemote) throw new Error("library_remote_unconfirmed");
|
|
450
|
+
return settings.remote;
|
|
451
|
+
}
|
|
452
|
+
function confirmLibraryRemote(url) {
|
|
453
|
+
const current = readSettings().library.remote;
|
|
454
|
+
if (current !== null && current !== url) throw new Error("library_remote_mismatch");
|
|
455
|
+
updateSettings((settings) => {
|
|
456
|
+
if (settings.library.remote === null) settings.library.remote = url;
|
|
457
|
+
settings.library.confirmedRemote = url;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
async function syncLibrary(direction, runner = runCommandVector) {
|
|
461
|
+
const settings = readSettings().library;
|
|
462
|
+
if (!settings.sync) throw new Error("library_sync_disabled");
|
|
463
|
+
const remote = confirmedRemote();
|
|
464
|
+
const cwd = path2.dirname(catalogPath());
|
|
465
|
+
const remoteResult = await runner("git", ["remote", "get-url", "library"], { cwd, workspaceRoot: cwd });
|
|
466
|
+
if (remoteResult.exitCode !== 0 || remoteResult.stdout.trim() !== remote)
|
|
467
|
+
throw new Error("library_remote_unconfirmed");
|
|
468
|
+
if (direction === "sync") {
|
|
469
|
+
const fetched = await runner("git", ["fetch", "library"], { cwd, workspaceRoot: cwd });
|
|
470
|
+
if (fetched.exitCode !== 0) throw new Error(fetched.stderr.trim() || "library sync failed");
|
|
471
|
+
const advanced = await runner("git", ["merge", "--ff-only", "FETCH_HEAD"], { cwd, workspaceRoot: cwd });
|
|
472
|
+
if (advanced.exitCode !== 0) throw new Error(advanced.stderr.trim() || "library sync failed");
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const result = await runner("git", ["push", "library"], { cwd, workspaceRoot: cwd });
|
|
476
|
+
if (result.exitCode !== 0) throw new Error(result.stderr.trim() || `library ${direction} failed`);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// src/domains/resources/skills/evals.ts
|
|
480
|
+
init_esm_shims();
|
|
481
|
+
var SCENARIO_HEADING = /^##\s+([A-Z])(\d+)\s*[-:–—]\s*(.+?)\s*$/;
|
|
482
|
+
function parseSkillEvals(markdown) {
|
|
483
|
+
const lines = markdown.split("\n");
|
|
484
|
+
const scenarios = [];
|
|
485
|
+
const diagnostics = [];
|
|
486
|
+
let index = 0;
|
|
487
|
+
while (index < lines.length) {
|
|
488
|
+
const heading = SCENARIO_HEADING.exec(lines[index] ?? "");
|
|
489
|
+
if (heading === null) {
|
|
490
|
+
index += 1;
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
const blockStart = index + 1;
|
|
494
|
+
let blockEnd = blockStart;
|
|
495
|
+
while (blockEnd < lines.length && !/^##\s+/.test(lines[blockEnd] ?? "")) blockEnd += 1;
|
|
496
|
+
const block = lines.slice(blockStart, blockEnd);
|
|
497
|
+
const number = Number.parseInt(heading[2] ?? "", 10);
|
|
498
|
+
const id = `${heading[1] ?? "S"}${number}`;
|
|
499
|
+
const title = heading[3] ?? "";
|
|
500
|
+
const setup = extractSetup(block);
|
|
501
|
+
const fixtureCommands = extractFixtureCommands(block);
|
|
502
|
+
const expected = extractExpected(block);
|
|
503
|
+
if (setup === null) diagnostics.push(`${id} (${title}): no "Setup:" or "Prompt:" paragraph found; scenario skipped`);
|
|
504
|
+
else if (expected.length === 0) diagnostics.push(`${id} (${title}): no "Expected:" bullets found; scenario skipped`);
|
|
505
|
+
else scenarios.push({ id, number, title, setup, ...fixtureCommands ? { fixtureCommands } : {}, expected });
|
|
506
|
+
index = blockEnd;
|
|
507
|
+
}
|
|
508
|
+
return { scenarios, diagnostics };
|
|
509
|
+
}
|
|
510
|
+
function extractSetup(block) {
|
|
511
|
+
return extractLabeledParagraph(block, /^Setup:\s*(.*)$/i) ?? extractLabeledParagraph(block, /^(Prompt:.*)$/i);
|
|
512
|
+
}
|
|
513
|
+
function isScenarioLabel(line) {
|
|
514
|
+
const trimmed = line.trim();
|
|
515
|
+
return /^(Expected|Fixture|Setup commands):/i.test(trimmed) || /^Expected$/i.test(trimmed);
|
|
516
|
+
}
|
|
517
|
+
function extractLabeledParagraph(block, label) {
|
|
518
|
+
for (let i = 0; i < block.length; i += 1) {
|
|
519
|
+
const line = block[i] ?? "";
|
|
520
|
+
const match = label.exec(line.trim());
|
|
521
|
+
if (match === null) continue;
|
|
522
|
+
const parts = [];
|
|
523
|
+
if ((match[1] ?? "").length > 0) parts.push(match[1] ?? "");
|
|
524
|
+
for (let j = i + 1; j < block.length; j += 1) {
|
|
525
|
+
const next = (block[j] ?? "").trim();
|
|
526
|
+
if (next.length === 0) break;
|
|
527
|
+
if (isScenarioLabel(next)) break;
|
|
528
|
+
parts.push(next);
|
|
529
|
+
}
|
|
530
|
+
const setup = parts.join(" ").trim();
|
|
531
|
+
return setup.length > 0 ? setup : null;
|
|
532
|
+
}
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
function extractFixtureCommands(block) {
|
|
536
|
+
for (let i = 0; i < block.length; i += 1) {
|
|
537
|
+
const line = (block[i] ?? "").trim();
|
|
538
|
+
const match = /^(?:Fixture|Setup commands):\s*(.*)$/i.exec(line);
|
|
539
|
+
if (match === null) continue;
|
|
540
|
+
const inline = (match[1] ?? "").trim();
|
|
541
|
+
let cursor = i + 1;
|
|
542
|
+
while (cursor < block.length && (block[cursor] ?? "").trim().length === 0) cursor += 1;
|
|
543
|
+
const first = block[cursor] ?? "";
|
|
544
|
+
const fence = /^```\w*\s*$/.test(first.trim());
|
|
545
|
+
if (fence) {
|
|
546
|
+
const commands2 = [];
|
|
547
|
+
for (let j = cursor + 1; j < block.length; j += 1) {
|
|
548
|
+
const current = block[j] ?? "";
|
|
549
|
+
if (/^```\s*$/.test(current.trim())) {
|
|
550
|
+
const script2 = commands2.join("\n").trim();
|
|
551
|
+
return script2.length > 0 ? script2 : null;
|
|
552
|
+
}
|
|
553
|
+
commands2.push(current);
|
|
554
|
+
}
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
const commands = [];
|
|
558
|
+
if (inline.length > 0) commands.push(inline);
|
|
559
|
+
for (let j = cursor; j < block.length; j += 1) {
|
|
560
|
+
const current = block[j] ?? "";
|
|
561
|
+
const trimmed = current.trim();
|
|
562
|
+
if (trimmed.length === 0) break;
|
|
563
|
+
if (isScenarioLabel(trimmed)) break;
|
|
564
|
+
commands.push(current);
|
|
565
|
+
}
|
|
566
|
+
const script = commands.join("\n").trim();
|
|
567
|
+
return script.length > 0 ? script : null;
|
|
568
|
+
}
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
function extractExpected(block) {
|
|
572
|
+
let start = -1;
|
|
573
|
+
for (let i = 0; i < block.length; i += 1) {
|
|
574
|
+
if (/^Expected:?\s*$/i.test((block[i] ?? "").trim())) {
|
|
575
|
+
start = i + 1;
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
if (start < 0) return [];
|
|
580
|
+
const bullets = [];
|
|
581
|
+
let current = null;
|
|
582
|
+
for (let i = start; i < block.length; i += 1) {
|
|
583
|
+
const raw = block[i] ?? "";
|
|
584
|
+
const trimmed = raw.trim();
|
|
585
|
+
if (trimmed.length === 0) {
|
|
586
|
+
if (current !== null) {
|
|
587
|
+
bullets.push(current.join(" "));
|
|
588
|
+
current = null;
|
|
589
|
+
}
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const bullet = /^[-*]\s+(.*)$/.exec(raw);
|
|
593
|
+
if (bullet !== null) {
|
|
594
|
+
if (current !== null) bullets.push(current.join(" "));
|
|
595
|
+
current = [bullet[1] ?? ""];
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
if (current !== null && /^\s+\S/.test(raw)) {
|
|
599
|
+
current.push(trimmed);
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
if (current !== null) bullets.push(current.join(" "));
|
|
605
|
+
return bullets.map((bullet) => bullet.trim()).filter((bullet) => bullet.length > 0);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// src/domains/resources/skills/provenance-pin.ts
|
|
609
|
+
init_esm_shims();
|
|
610
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
611
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
612
|
+
import path3 from "node:path";
|
|
613
|
+
var SKILL_PIN_MANIFEST_FILENAME = "registry.yaml";
|
|
614
|
+
function isPlainObject(value) {
|
|
615
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
616
|
+
}
|
|
617
|
+
function resolveSkillPinManifestPath(cwd) {
|
|
618
|
+
const fromEnv = process.env.CLIO_CODER_SKILL_CATALOG_DIR;
|
|
619
|
+
const catalogDir = fromEnv && fromEnv.trim().length > 0 ? path3.resolve(fromEnv.trim()) : path3.join(cwd, "skills");
|
|
620
|
+
const manifestPath = path3.join(catalogDir, SKILL_PIN_MANIFEST_FILENAME);
|
|
621
|
+
return existsSync2(manifestPath) ? manifestPath : null;
|
|
622
|
+
}
|
|
623
|
+
function loadSkillPinManifest(manifestPath) {
|
|
624
|
+
let parsed;
|
|
625
|
+
try {
|
|
626
|
+
parsed = import_yaml2.default.parse(readFileSync3(manifestPath, "utf8"));
|
|
627
|
+
} catch {
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
if (!isPlainObject(parsed) || !Array.isArray(parsed.skills)) return null;
|
|
631
|
+
const entries = /* @__PURE__ */ new Map();
|
|
632
|
+
for (const raw of parsed.skills) {
|
|
633
|
+
if (!isPlainObject(raw)) continue;
|
|
634
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
635
|
+
const sha256 = typeof raw.sha256 === "string" ? raw.sha256.trim().toLowerCase() : "";
|
|
636
|
+
if (name.length === 0 || !/^[0-9a-f]{64}$/.test(sha256)) continue;
|
|
637
|
+
entries.set(name, {
|
|
638
|
+
name,
|
|
639
|
+
version: typeof raw.version === "string" && raw.version.trim().length > 0 ? raw.version.trim() : null,
|
|
640
|
+
sha256
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
return entries;
|
|
644
|
+
}
|
|
645
|
+
function checkSkillDrift(skill, cwd) {
|
|
646
|
+
const actual = skill.normalizedHash.toLowerCase();
|
|
647
|
+
const manifestPath = resolveSkillPinManifestPath(cwd);
|
|
648
|
+
const manifest = manifestPath === null ? null : loadSkillPinManifest(manifestPath);
|
|
649
|
+
const pinned = manifest?.get(skill.name);
|
|
650
|
+
if (pinned !== void 0) {
|
|
651
|
+
return {
|
|
652
|
+
verdict: pinned.sha256 === actual ? "match" : "mismatch",
|
|
653
|
+
authority: "pinned-manifest",
|
|
654
|
+
expected: pinned.sha256
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
const recorded = skill.provenance?.installedHash?.trim().toLowerCase();
|
|
658
|
+
if (recorded !== void 0 && /^[0-9a-f]{64}$/.test(recorded)) {
|
|
659
|
+
return {
|
|
660
|
+
verdict: recorded === actual ? "match" : "mismatch",
|
|
661
|
+
authority: "install-record",
|
|
662
|
+
expected: recorded
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
return null;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/domains/resources/index.ts
|
|
669
|
+
init_esm_shims();
|
|
670
|
+
|
|
671
|
+
// src/domains/resources/extension.ts
|
|
672
|
+
init_esm_shims();
|
|
673
|
+
|
|
424
674
|
// src/domains/resources/loader.ts
|
|
675
|
+
init_esm_shims();
|
|
425
676
|
function createResourcesLoader(options = {}) {
|
|
426
677
|
const defaultCwd = options.cwd ?? process.cwd();
|
|
427
678
|
const skillOptions2 = () => options.skills?.() ?? {};
|
|
@@ -527,9 +778,19 @@ function createResourcesDomainModule(options = {}) {
|
|
|
527
778
|
}
|
|
528
779
|
|
|
529
780
|
export {
|
|
781
|
+
libraryEntryRef,
|
|
782
|
+
discoverLibrary,
|
|
783
|
+
libraryInstallPath,
|
|
784
|
+
libraryEntryInstalled,
|
|
785
|
+
libraryEntryPin,
|
|
786
|
+
classifyLibraryRequirements,
|
|
787
|
+
planLibraryInstall,
|
|
788
|
+
installLibraryPlan,
|
|
789
|
+
confirmLibraryRemote,
|
|
790
|
+
syncLibrary,
|
|
530
791
|
parseSkillEvals,
|
|
531
792
|
checkSkillDrift,
|
|
532
793
|
ResourcesDomainModule,
|
|
533
794
|
createResourcesDomainModule
|
|
534
795
|
};
|
|
535
|
-
//# sourceMappingURL=chunk-
|
|
796
|
+
//# sourceMappingURL=chunk-THKY7CD7.js.map
|