@iowarp/clio-coder 0.3.6 → 0.3.8
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 +59 -0
- package/README.md +22 -6
- package/dist/{acp-2BEHC4DL.js → acp-U67UHUK2.js} +14 -14
- package/dist/{agents-LNNFTM53.js → agents-YU6SGALZ.js} +42 -35
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-5ZPJOIVG.js} +32 -24
- package/dist/builtins-C6JMZVV6.js +17 -0
- package/dist/{chunk-E25LMLRW.js → chunk-26LEYJZH.js} +2 -2
- package/dist/{chunk-TSHXZTOQ.js → chunk-2HEJ2F35.js} +5 -5
- package/dist/{chunk-PBTHKCPN.js → chunk-2HFZQUHL.js} +7 -7
- package/dist/{chunk-FO5ZOVUY.js → chunk-3BINW3FP.js} +5 -5
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CKXWIANG.js → chunk-4SPRNWDE.js} +18 -16
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-XF5N4U5A.js → chunk-5DHKRSMQ.js} +9 -8
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-EKY57CSP.js → chunk-5H3GB5BO.js} +68 -772
- package/dist/{chunk-6XXKFVSN.js → chunk-5Q2VVUKB.js} +4 -4
- package/dist/{chunk-DJVECN66.js → chunk-7RFXX52T.js} +295 -3705
- package/dist/{chunk-ZXF4XRKW.js → chunk-7RGZWPB6.js} +158 -8
- package/dist/{chunk-FYYLNIL5.js → chunk-A2NJGIB3.js} +2 -2
- package/dist/{chunk-XXQNGV4M.js → chunk-A3WNZD3P.js} +548 -72
- package/dist/{chunk-VEZEGCGW.js → chunk-B5CSFE7B.js} +23 -21
- package/dist/{chunk-2SFS6XQE.js → chunk-DGSYXYMX.js} +3 -2
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-ZWLZP4ZT.js → chunk-DYIM5TJT.js} +98 -12
- package/dist/{chunk-QKMUKYO7.js → chunk-E77JEWSD.js} +270 -125
- package/dist/{chunk-LYF7OHWH.js → chunk-EMYUUSFG.js} +12 -467
- package/dist/{chunk-4VP4KH3K.js → chunk-EQ63NRB7.js} +8 -8
- package/dist/chunk-FBVTI2TJ.js +518 -0
- package/dist/{chunk-R46L2BIR.js → chunk-FHJEP5SW.js} +19 -25
- package/dist/{chunk-WR67VIZY.js → chunk-GN57SG4G.js} +66 -8
- package/dist/{chunk-RD5U66HV.js → chunk-GPIEI3LY.js} +9 -9
- package/dist/{chunk-PCZJO5TI.js → chunk-GU2UIAFZ.js} +13 -178
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/chunk-H7IXIC72.js +103 -0
- package/dist/{chunk-3BPUFZDL.js → chunk-HLE42MG7.js} +3 -3
- package/dist/{chunk-24I7BN55.js → chunk-IFBNV6H6.js} +3 -3
- package/dist/{chunk-QNQHSOLF.js → chunk-IGWKHNIQ.js} +114 -55
- package/dist/chunk-IIZWH4XA.js +172 -0
- package/dist/{chunk-AD2SYQYC.js → chunk-IJ7RPIYJ.js} +124 -6
- package/dist/chunk-J3YUBZWY.js +382 -0
- package/dist/{chunk-5JGRAMKL.js → chunk-JOZYP4GM.js} +8 -6
- package/dist/{chunk-OH3TOQTB.js → chunk-K4XHGFR5.js} +751 -15
- package/dist/{chunk-EYPA3EGJ.js → chunk-KTYTFRMB.js} +178 -14
- package/dist/chunk-LU7P4LHA.js +33 -0
- package/dist/chunk-ME6CCNFO.js +108 -0
- package/dist/chunk-MXKJU4JB.js +1100 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-N22QMJKY.js} +21 -18
- package/dist/chunk-NMPKI6XL.js +3006 -0
- package/dist/chunk-NUGM5KR6.js +165 -0
- package/dist/{chunk-22NAGB7X.js → chunk-P43ETTHK.js} +5 -94
- package/dist/{chunk-NILBFAPG.js → chunk-PMDBGQSJ.js} +2 -2
- package/dist/chunk-PT7HYKEM.js +165 -0
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-GEYXPTRF.js → chunk-RWSI4YD7.js} +2 -2
- package/dist/{chunk-4BPJXDWC.js → chunk-TANS5ZJS.js} +35 -19
- package/dist/{verifiers-NCBTHHN2.js → chunk-TB5666IT.js} +67 -324
- package/dist/{chunk-QM3F2GKX.js → chunk-TLQJPP24.js} +7927 -8088
- package/dist/{chunk-G7MUEIGA.js → chunk-TT36MB5S.js} +2 -1
- package/dist/chunk-TTHACPOM.js +961 -0
- package/dist/{chunk-6US73PDB.js → chunk-TYPGUK6W.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-U6MBIEMB.js} +554 -209
- package/dist/chunk-VAWNZU7Z.js +242 -0
- package/dist/{chunk-IR4CFBFN.js → chunk-VCBR6CU7.js} +12 -12
- package/dist/{chunk-WHJYKASB.js → chunk-VHN4MY6O.js} +2 -2
- package/dist/{chunk-XYDYPRZI.js → chunk-VWZOAB7K.js} +10 -10
- package/dist/{chunk-ZRGEBJ4T.js → chunk-WLFILSD5.js} +48 -48
- package/dist/{chunk-K7T3E2SR.js → chunk-WNIJTQQK.js} +12 -11
- package/dist/{chunk-CYQKWTG3.js → chunk-WSB3FPX7.js} +68 -20
- package/dist/{chunk-KHSFENX2.js → chunk-WWCZ5F23.js} +116 -14
- package/dist/{chunk-XE2VEJHX.js → chunk-WXY7KU3G.js} +2 -2
- package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
- package/dist/{chunk-KOHPCX4K.js → chunk-XWSF374K.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-YS5VLNH5.js} +10 -10
- package/dist/{chunk-ZZMN5OM4.js → chunk-ZNLWCMVZ.js} +2 -2
- package/dist/{chunk-WHGPSPT5.js → chunk-ZVJ5BLO2.js} +2 -2
- package/dist/cli/index.js +33 -31
- package/dist/{clio-M2KGYUFZ.js → clio-QVTYJ57A.js} +10 -10
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +5 -5
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-5TTYYX6G.js → components-ZFA3SAER.js} +9 -9
- package/dist/{config-XUUYQIWO.js → config-LW5IJFQN.js} +65 -55
- package/dist/{configure-IHJ7YOMV.js → configure-7XIZCOU4.js} +29 -24
- package/dist/{context-75MIWW3U.js → context-L3WL3X7K.js} +54 -43
- package/dist/{context-ZQ7SIFJV.js → context-N52ZA626.js} +30 -14
- package/dist/{context-74JLXAWD.js → context-Y6Y7QPR6.js} +12 -12
- package/dist/{context-clear-GYKWNUML.js → context-clear-MBQRLSDQ.js} +54 -43
- package/dist/{context-index-SSR5ECNE.js → context-index-HVMFQHK3.js} +5 -5
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-GS6DSO7F.js} +18 -18
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-22ZCNOM3.js} +367 -79
- package/dist/{docs-6FZSCG5B.js → docs-7LQ23DLM.js} +9 -9
- package/dist/{doctor-SVJ5BZCW.js → doctor-M7YEDGAE.js} +27 -23
- package/dist/{eval-CG6LLBLD.js → eval-BEC2WHDA.js} +73 -20
- package/dist/{evidence-ZYFIEN42.js → evidence-REJUMSKM.js} +70 -59
- package/dist/{evolve-QGEXEMDW.js → evolve-PY5ZBA5K.js} +50 -39
- package/dist/{extensions-ADGNCJJD.js → extensions-HVKU65YU.js} +7 -7
- package/dist/{fleet-S5R4ZOQY.js → fleet-7WZEWRFA.js} +236 -377
- package/dist/fleet-commands-UVHWM76J.js +70 -0
- package/dist/fleet-graph-6ULH7PES.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-J53T6CCE.js} +5 -5
- package/dist/fleet-validate-72PC4SLA.js +79 -0
- package/dist/{init-5DRU55YR.js → init-OG3TPGQG.js} +69 -57
- package/dist/library-CNTMPLRF.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-6IS7F275.js} +52 -41
- package/dist/{models-ZPOLRU2C.js → models-ENRJDA5W.js} +37 -31
- package/dist/{monitor-US5F5YGZ.js → monitor-XLDVO7TN.js} +79 -42
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-6KSPYRHA.js} +4126 -762
- package/dist/{paths-E7KYAQWE.js → paths-DBXMZMDU.js} +6 -6
- package/dist/registry-LG64LTF4.js +11 -0
- package/dist/{reset-KZ652EK6.js → reset-RZ4ER727.js} +12 -12
- package/dist/{run-SRNBKDWD.js → run-Y2CNK5RU.js} +89 -76
- package/dist/{share-CGZE33UP.js → share-A55GYP6Z.js} +37 -13
- package/dist/{skills-S2X4DLY5.js → skills-ALC5J6AT.js} +29 -13
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-JPBEBYQU.js} +60 -48
- package/dist/support-MIETYA5E.js +38 -0
- package/dist/{targets-54SWINWB.js → targets-VGNXIR3S.js} +46 -36
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WOBR64YA.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-ZJF5H5ZN.js} +9 -9
- package/dist/{upgrade-JKAR27XC.js → upgrade-FUSUAGHR.js} +31 -28
- package/dist/{usage-MSAWCLX4.js → usage-N4MKVHKD.js} +140 -68
- package/dist/verifiers-YAWOJ3H2.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-LTDHYBGY.js} +10 -9
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-6M7GHTBJ.js} +75 -62
- package/dist/worker/entry.js +67 -57
- 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 +11 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +83 -3
- package/docs/configuration-and-targets.md +86 -4
- 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 +74 -10
- 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 +228 -16
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +22 -2
- 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 +56 -9
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +4 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +83 -65
- 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 -2
- package/src/cli/argv.ts +5 -0
- package/src/cli/configure.ts +107 -23
- package/src/cli/doctor.ts +5 -1
- package/src/cli/evidence.ts +30 -25
- 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 +111 -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/shared.ts +1 -0
- package/src/cli/targets.ts +4 -1
- package/src/cli/usage.ts +111 -19
- package/src/cli/validate-model.ts +60 -5
- package/src/core/bus-events.ts +29 -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/core/path-boundary.ts +100 -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/extension.ts +2 -11
- package/src/domains/agents/fleet-contract.ts +304 -24
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +7 -1
- package/src/domains/agents/registry.ts +73 -5
- package/src/domains/agents/result-contract.ts +360 -15
- package/src/domains/agents/write-boundary.ts +15 -50
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/project-rules.ts +51 -1
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/assignment-reconcile.ts +22 -5
- package/src/domains/dispatch/assignment-store.ts +151 -14
- 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 +48 -0
- package/src/domains/dispatch/delegation-plan.ts +164 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +12 -2
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +412 -74
- 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 +791 -0
- package/src/domains/dispatch/gate-role-prompts.ts +47 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +41 -1
- package/src/domains/dispatch/intent-requirements.ts +40 -0
- package/src/domains/dispatch/intent.ts +235 -0
- package/src/domains/dispatch/path-scope.ts +370 -0
- package/src/domains/dispatch/receipt-integrity.ts +9 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +64 -12
- package/src/domains/dispatch/validation.ts +69 -6
- package/src/domains/dispatch/write-boundary-enforcer.ts +45 -0
- package/src/domains/dispatch/write-boundary.ts +201 -22
- package/src/domains/eval/metrics/evidence.ts +79 -2
- package/src/domains/eval/runners/clio-run.ts +12 -2
- package/src/domains/evidence/build.ts +69 -11
- package/src/domains/evidence/index.ts +21 -0
- package/src/domains/evidence/provenance.ts +46 -11
- package/src/domains/evidence/trust-projection.ts +274 -0
- package/src/domains/evidence/trust-status.ts +155 -18
- package/src/domains/evidence/types.ts +4 -0
- package/src/domains/extensions/discovery.ts +88 -1
- package/src/domains/extensions/resources.ts +20 -8
- package/src/domains/extensions/state.ts +6 -2
- package/src/domains/extensions/types.ts +4 -1
- package/src/domains/lifecycle/doctor.ts +140 -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/prompts/contract.ts +3 -5
- package/src/domains/providers/extension.ts +30 -2
- package/src/domains/resources/common-loader.ts +3 -0
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/prompts/loader.ts +119 -14
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/policy-engine.ts +5 -5
- package/src/domains/safety/run-effects.ts +64 -1
- package/src/domains/safety/scope.ts +7 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/server.ts +4 -1
- package/src/engine/prompt-templates.ts +18 -1
- package/src/engine/worker-runtime.ts +6 -3
- 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 +311 -17
- 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 +23 -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 +221 -30
- 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 +439 -7
- 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/view/artifacts.ts +42 -9
- package/src/interactive/view/view-overlay.ts +15 -3
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-receipts.ts +14 -2
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +15 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +251 -18
- package/src/tools/dispatch-arguments.ts +84 -1
- package/src/tools/dispatch-plan.ts +165 -6
- package/src/tools/dispatch-runner.ts +364 -23
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +29 -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 +21 -14
- package/src/worker/spec-contract.ts +3 -1
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -1,32 +1,565 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
+
parseAgentRecipeSchema
|
|
4
|
+
} from "./chunk-FBVTI2TJ.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-TANS5ZJS.js";
|
|
8
14
|
import {
|
|
9
15
|
COMPAT_RESOURCE_PRECEDENCE,
|
|
10
16
|
defaultScopedResourceRoots,
|
|
11
|
-
readRootEntries,
|
|
12
17
|
sourceInfoForRoot,
|
|
13
18
|
splitYamlFrontmatter,
|
|
14
19
|
stringField
|
|
15
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-DGSYXYMX.js";
|
|
21
|
+
import {
|
|
22
|
+
parseFleetContract,
|
|
23
|
+
parseFrontmatter
|
|
24
|
+
} from "./chunk-E77JEWSD.js";
|
|
25
|
+
import {
|
|
26
|
+
assertAgentSpecPolicy,
|
|
27
|
+
normalizeAgentSpec
|
|
28
|
+
} from "./chunk-AOCYTWAV.js";
|
|
16
29
|
import {
|
|
17
30
|
INTEROP_AGENT_KINDS
|
|
18
31
|
} from "./chunk-IHXBNWMM.js";
|
|
32
|
+
import {
|
|
33
|
+
runCommandVector
|
|
34
|
+
} from "./chunk-B5CSFE7B.js";
|
|
35
|
+
import {
|
|
36
|
+
readSettings,
|
|
37
|
+
updateSettings
|
|
38
|
+
} from "./chunk-IJ7RPIYJ.js";
|
|
19
39
|
import {
|
|
20
40
|
expandConfigPath
|
|
21
41
|
} from "./chunk-SST6Z5JA.js";
|
|
22
42
|
import {
|
|
23
43
|
require_dist
|
|
24
44
|
} from "./chunk-APJ265NV.js";
|
|
45
|
+
import {
|
|
46
|
+
clioConfigDir
|
|
47
|
+
} from "./chunk-BNAZZHFG.js";
|
|
48
|
+
import {
|
|
49
|
+
safeResourceWrite
|
|
50
|
+
} from "./chunk-WEPFGWHJ.js";
|
|
25
51
|
import {
|
|
26
52
|
__toESM,
|
|
27
53
|
init_esm_shims
|
|
28
54
|
} from "./chunk-3R73A4XB.js";
|
|
29
55
|
|
|
56
|
+
// src/domains/resources/library.ts
|
|
57
|
+
init_esm_shims();
|
|
58
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
59
|
+
import { createHash } from "node:crypto";
|
|
60
|
+
import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
61
|
+
import path2 from "node:path";
|
|
62
|
+
|
|
63
|
+
// src/domains/resources/prompts/loader.ts
|
|
64
|
+
init_esm_shims();
|
|
65
|
+
import { lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs";
|
|
66
|
+
import { homedir } from "node:os";
|
|
67
|
+
import path from "node:path";
|
|
68
|
+
|
|
69
|
+
// src/engine/prompt-templates.ts
|
|
70
|
+
init_esm_shims();
|
|
71
|
+
import { parseCommandArgs, substituteArgs as substituteParsedArgs } from "@earendil-works/pi-agent-core";
|
|
72
|
+
var RAW_ARGUMENTS_PLACEHOLDER = /\$ARGUMENTS/g;
|
|
73
|
+
function substituteArgs(content, args, rawArguments) {
|
|
74
|
+
if (rawArguments === void 0) return substituteParsedArgs(content, args);
|
|
75
|
+
return content.split(RAW_ARGUMENTS_PLACEHOLDER).map((segment) => substituteParsedArgs(segment, args)).join(rawArguments);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/domains/resources/collision.ts
|
|
79
|
+
init_esm_shims();
|
|
80
|
+
var SCOPE_RANK = {
|
|
81
|
+
package: 0,
|
|
82
|
+
user: 1,
|
|
83
|
+
project: 2,
|
|
84
|
+
cli: 3
|
|
85
|
+
};
|
|
86
|
+
function rankOf(info) {
|
|
87
|
+
return info.precedence ?? SCOPE_RANK[info.scope];
|
|
88
|
+
}
|
|
89
|
+
function compareCandidates(a, b) {
|
|
90
|
+
const rankDelta = rankOf(a.source) - rankOf(b.source);
|
|
91
|
+
if (rankDelta !== 0) return rankDelta;
|
|
92
|
+
return a.source.path.localeCompare(b.source.path);
|
|
93
|
+
}
|
|
94
|
+
function resolveResourceCollisions(candidates) {
|
|
95
|
+
const byName = /* @__PURE__ */ new Map();
|
|
96
|
+
for (const candidate of candidates) {
|
|
97
|
+
const key = candidate.name.trim();
|
|
98
|
+
if (key.length === 0) continue;
|
|
99
|
+
const list = byName.get(key) ?? [];
|
|
100
|
+
list.push(candidate);
|
|
101
|
+
byName.set(key, list);
|
|
102
|
+
}
|
|
103
|
+
const winners = [];
|
|
104
|
+
const diagnostics = [];
|
|
105
|
+
for (const [name, entries] of byName.entries()) {
|
|
106
|
+
const sorted = [...entries].sort(compareCandidates);
|
|
107
|
+
const winner = sorted[sorted.length - 1];
|
|
108
|
+
if (!winner) continue;
|
|
109
|
+
winners.push(winner.value);
|
|
110
|
+
for (const loser of sorted.slice(0, -1)) {
|
|
111
|
+
diagnostics.push({
|
|
112
|
+
type: "collision",
|
|
113
|
+
message: `${name} from ${winner.source.scope} overrides ${loser.source.scope}`,
|
|
114
|
+
path: loser.source.path,
|
|
115
|
+
collision: {
|
|
116
|
+
name,
|
|
117
|
+
winnerPath: winner.source.path,
|
|
118
|
+
loserPath: loser.source.path,
|
|
119
|
+
winnerScope: winner.source.scope,
|
|
120
|
+
loserScope: loser.source.scope
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { winners, diagnostics };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/domains/resources/prompts/loader.ts
|
|
129
|
+
function defaultPromptTemplateRoots(input = {}) {
|
|
130
|
+
const cwd = input.cwd ?? process.cwd();
|
|
131
|
+
const home = input.home ?? homedir();
|
|
132
|
+
const trustProject = projectCompatTrusted(input.trustProjectCompatRoots);
|
|
133
|
+
const compat = [];
|
|
134
|
+
for (const kind of INTEROP_AGENT_KINDS) {
|
|
135
|
+
if (kind.userPromptRoot !== void 0) {
|
|
136
|
+
compat.push({
|
|
137
|
+
path: path.join(home, kind.userPromptRoot),
|
|
138
|
+
scope: "user",
|
|
139
|
+
source: `${kind.id}-user`,
|
|
140
|
+
precedence: COMPAT_RESOURCE_PRECEDENCE.userCompat,
|
|
141
|
+
trusted: true
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (kind.projectPromptRoot !== void 0) {
|
|
145
|
+
compat.push({
|
|
146
|
+
path: path.join(cwd, kind.projectPromptRoot),
|
|
147
|
+
scope: "project",
|
|
148
|
+
source: `${kind.id}-project`,
|
|
149
|
+
precedence: COMPAT_RESOURCE_PRECEDENCE.projectCompat,
|
|
150
|
+
trusted: trustProject
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return [...defaultScopedResourceRoots("prompts", cwd), ...compat];
|
|
155
|
+
}
|
|
156
|
+
function splitOptionalFrontmatter(raw, filePath, diagnostics) {
|
|
157
|
+
const split = splitYamlFrontmatter(raw);
|
|
158
|
+
if (split.ok) return split;
|
|
159
|
+
if (split.reason === "missing") return { frontmatter: {}, body: raw };
|
|
160
|
+
const message = split.reason === "missing closing delimiter" ? "prompt template frontmatter is missing a closing delimiter; treating the file as plain markdown" : split.reason === "must be a YAML object" ? "prompt template frontmatter must be a YAML object" : `prompt template frontmatter is ${split.reason}`;
|
|
161
|
+
diagnostics.push({ type: "warning", message, path: filePath });
|
|
162
|
+
return { frontmatter: {}, body: split.body };
|
|
163
|
+
}
|
|
164
|
+
function fallbackDescription(body) {
|
|
165
|
+
const line = body.split(/\r?\n/).map((entry) => entry.trim()).find((entry) => entry.length > 0);
|
|
166
|
+
if (!line) return "Prompt template";
|
|
167
|
+
const normalized = line.replace(/^#{1,6}\s+/, "");
|
|
168
|
+
return normalized.length > 60 ? `${normalized.slice(0, 57)}...` : normalized;
|
|
169
|
+
}
|
|
170
|
+
var EXTENSION_ROOT_REFERENCE = /\$\{extensionRoot\}(\/[A-Za-z0-9._~%+@/-]*)?/g;
|
|
171
|
+
var EXTENSION_ROOT_TOKEN = "${extensionRoot}";
|
|
172
|
+
function contained(root, candidate) {
|
|
173
|
+
const relative = path.relative(root, candidate);
|
|
174
|
+
return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative);
|
|
175
|
+
}
|
|
176
|
+
function resolveExtensionReferences(body, root, filePath, diagnostics) {
|
|
177
|
+
if (root.rootPath === void 0 || !body.includes(EXTENSION_ROOT_TOKEN)) return body;
|
|
178
|
+
let canonicalRoot;
|
|
179
|
+
try {
|
|
180
|
+
canonicalRoot = realpathSync(root.rootPath);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
diagnostics.push({
|
|
183
|
+
type: "warning",
|
|
184
|
+
message: `extension root could not be resolved: ${error instanceof Error ? error.message : String(error)}`,
|
|
185
|
+
path: filePath
|
|
186
|
+
});
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
let invalid = null;
|
|
190
|
+
const resolved = body.replace(EXTENSION_ROOT_REFERENCE, (reference, suffix) => {
|
|
191
|
+
const candidate = path.resolve(canonicalRoot, `.${suffix ?? ""}`);
|
|
192
|
+
try {
|
|
193
|
+
const canonicalCandidate = realpathSync(candidate);
|
|
194
|
+
if (!contained(canonicalRoot, canonicalCandidate)) invalid = reference;
|
|
195
|
+
} catch {
|
|
196
|
+
invalid = reference;
|
|
197
|
+
}
|
|
198
|
+
return candidate;
|
|
199
|
+
});
|
|
200
|
+
if (invalid !== null) {
|
|
201
|
+
diagnostics.push({
|
|
202
|
+
type: "warning",
|
|
203
|
+
message: `prompt template has an unresolved or escaping extension reference: ${invalid}`,
|
|
204
|
+
path: filePath
|
|
205
|
+
});
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
return resolved;
|
|
209
|
+
}
|
|
210
|
+
function loadPromptFile(filePath, root, diagnostics) {
|
|
211
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
212
|
+
if (ext !== ".md") return null;
|
|
213
|
+
let raw;
|
|
214
|
+
try {
|
|
215
|
+
raw = readFileSync(filePath, "utf8");
|
|
216
|
+
} catch (err) {
|
|
217
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
218
|
+
diagnostics.push({ type: "warning", message: `prompt template could not be read: ${reason}`, path: filePath });
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
const relativePath = path.relative(root.path, filePath);
|
|
222
|
+
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePath)) {
|
|
223
|
+
diagnostics.push({ type: "warning", message: "prompt template escaped its discovery root", path: filePath });
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const name = relativePath.slice(0, -ext.length).split(path.sep).join(":");
|
|
227
|
+
if (name.trim().length === 0) return null;
|
|
228
|
+
const { frontmatter, body } = splitOptionalFrontmatter(raw, filePath, diagnostics);
|
|
229
|
+
const resolvedBody = resolveExtensionReferences(body, root, filePath, diagnostics);
|
|
230
|
+
if (resolvedBody === null) return null;
|
|
231
|
+
const description = stringField(frontmatter, "description") ?? fallbackDescription(resolvedBody);
|
|
232
|
+
const argumentHint = stringField(frontmatter, "argument-hint") ?? stringField(frontmatter, "argumentHint");
|
|
233
|
+
const sourceInfo = sourceInfoForRoot(root, filePath);
|
|
234
|
+
const template = {
|
|
235
|
+
name,
|
|
236
|
+
description,
|
|
237
|
+
content: resolvedBody.trim(),
|
|
238
|
+
filePath,
|
|
239
|
+
sourceInfo,
|
|
240
|
+
trusted: root.trusted !== false
|
|
241
|
+
};
|
|
242
|
+
if (argumentHint) template.argumentHint = argumentHint;
|
|
243
|
+
return { name, value: template, source: sourceInfo };
|
|
244
|
+
}
|
|
245
|
+
function loadPromptRoot(root, diagnostics) {
|
|
246
|
+
const candidates = [];
|
|
247
|
+
const pending = [root.path];
|
|
248
|
+
while (pending.length > 0) {
|
|
249
|
+
const directory = pending.pop();
|
|
250
|
+
if (!directory) continue;
|
|
251
|
+
let entries;
|
|
252
|
+
try {
|
|
253
|
+
const stat = lstatSync(directory);
|
|
254
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
255
|
+
diagnostics.push({
|
|
256
|
+
type: "warning",
|
|
257
|
+
message: "prompt template root contains a non-directory or symbolic link",
|
|
258
|
+
path: directory
|
|
259
|
+
});
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
entries = readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if (error.code === "ENOENT") continue;
|
|
265
|
+
diagnostics.push({
|
|
266
|
+
type: "warning",
|
|
267
|
+
message: `prompt template directory could not be read: ${error instanceof Error ? error.message : String(error)}`,
|
|
268
|
+
path: directory
|
|
269
|
+
});
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
for (const entry of [...entries].reverse()) {
|
|
273
|
+
const filePath = path.join(directory, entry.name);
|
|
274
|
+
if (entry.isSymbolicLink()) {
|
|
275
|
+
diagnostics.push({ type: "warning", message: "prompt template symbolic link was ignored", path: filePath });
|
|
276
|
+
} else if (entry.isDirectory()) {
|
|
277
|
+
pending.push(filePath);
|
|
278
|
+
} else if (entry.isFile()) {
|
|
279
|
+
const candidate = loadPromptFile(filePath, root, diagnostics);
|
|
280
|
+
if (candidate) candidates.push(candidate);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return candidates;
|
|
285
|
+
}
|
|
286
|
+
function loadPromptTemplates(input = {}) {
|
|
287
|
+
const roots = input.roots ?? defaultPromptTemplateRoots(input);
|
|
288
|
+
const diagnostics = [];
|
|
289
|
+
const candidates = roots.flatMap((root) => loadPromptRoot(root, diagnostics));
|
|
290
|
+
const resolved = resolveResourceCollisions(candidates);
|
|
291
|
+
const items = [];
|
|
292
|
+
for (const template of resolved.winners) {
|
|
293
|
+
if (input.reservedNames?.has(template.name) === true) {
|
|
294
|
+
diagnostics.push({
|
|
295
|
+
type: "collision",
|
|
296
|
+
message: `prompt template /${template.name} conflicts with the built-in slash command /${template.name} and was ignored`,
|
|
297
|
+
path: template.filePath
|
|
298
|
+
});
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
items.push(template);
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
items: items.sort((a, b) => a.name.localeCompare(b.name)),
|
|
305
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics]
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function parsePromptCommand(input) {
|
|
309
|
+
const framed = input.trimStart();
|
|
310
|
+
if (!framed.startsWith("/")) return null;
|
|
311
|
+
const withoutSlash = framed.slice(1);
|
|
312
|
+
const separator = withoutSlash.search(/\s/);
|
|
313
|
+
const name = separator === -1 ? withoutSlash : withoutSlash.slice(0, separator);
|
|
314
|
+
if (name.length === 0 || name.includes("/")) return null;
|
|
315
|
+
const delimiterWidth = separator !== -1 && withoutSlash.slice(separator, separator + 2) === "\r\n" ? 2 : 1;
|
|
316
|
+
const rest = separator === -1 ? "" : withoutSlash.slice(separator + delimiterWidth);
|
|
317
|
+
return { name, rest };
|
|
318
|
+
}
|
|
319
|
+
function expandPromptTemplateInput(input, templates) {
|
|
320
|
+
const command = parsePromptCommand(input);
|
|
321
|
+
if (!command) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
|
|
322
|
+
const template = templates.items.find((entry) => entry.name === command.name);
|
|
323
|
+
if (!template) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
|
|
324
|
+
if (!template.trusted) {
|
|
325
|
+
const message = `prompt template ${template.name} comes from an untrusted project root; set skills.trustProjectCompatRoots to use it`;
|
|
326
|
+
return {
|
|
327
|
+
expanded: false,
|
|
328
|
+
text: input,
|
|
329
|
+
args: [],
|
|
330
|
+
diagnostics: [...templates.diagnostics, { type: "warning", message, path: template.filePath }],
|
|
331
|
+
refusal: { template, message }
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
const args = parseCommandArgs(command.rest);
|
|
335
|
+
return {
|
|
336
|
+
expanded: true,
|
|
337
|
+
text: substituteArgs(template.content, args, command.rest),
|
|
338
|
+
args,
|
|
339
|
+
template,
|
|
340
|
+
diagnostics: templates.diagnostics
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// src/domains/resources/library.ts
|
|
345
|
+
function isRecord(value) {
|
|
346
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
347
|
+
}
|
|
348
|
+
function catalogPath() {
|
|
349
|
+
const configured = readSettings().library.catalog;
|
|
350
|
+
return path2.resolve(configured ?? path2.join(clioConfigDir(), "library.yaml"));
|
|
351
|
+
}
|
|
352
|
+
function parseCatalog(filePath, diagnostics) {
|
|
353
|
+
if (!existsSync(filePath)) return [];
|
|
354
|
+
try {
|
|
355
|
+
const raw = readFileSync2(filePath, "utf8");
|
|
356
|
+
const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : (0, import_yaml.parse)(raw);
|
|
357
|
+
const rows = Array.isArray(parsed) ? parsed : isRecord(parsed) && Array.isArray(parsed.skills) ? parsed.skills : [];
|
|
358
|
+
return rows.flatMap((value) => {
|
|
359
|
+
if (!isRecord(value) || typeof value.name !== "string" || typeof value.description !== "string" || typeof value.sourceUrl !== "string") {
|
|
360
|
+
diagnostics.push(`library catalog entry malformed: ${filePath}`);
|
|
361
|
+
return [];
|
|
362
|
+
}
|
|
363
|
+
const kind = value.kind === void 0 || value.kind === "skill" ? "skill" : value.kind === "agent" || value.kind === "prompt" || value.kind === "fleet" ? value.kind : "skill";
|
|
364
|
+
if (value.kind !== void 0 && !["skill", "agent", "prompt", "fleet"].includes(String(value.kind))) {
|
|
365
|
+
diagnostics.push(`library catalog entry has unsupported kind: ${value.name}`);
|
|
366
|
+
return [];
|
|
367
|
+
}
|
|
368
|
+
if (value.requires !== void 0 && (!Array.isArray(value.requires) || value.requires.some((item) => typeof item !== "string"))) {
|
|
369
|
+
diagnostics.push(`library_requirement_malformed: ${value.name}`);
|
|
370
|
+
return [];
|
|
371
|
+
}
|
|
372
|
+
const sourceUrl = /^(?:https?:\/\/|git@)/.test(value.sourceUrl) ? value.sourceUrl : path2.resolve(path2.dirname(filePath), value.sourceUrl);
|
|
373
|
+
const requires = Array.isArray(value.requires) ? value.requires.filter((item) => typeof item === "string") : void 0;
|
|
374
|
+
return [
|
|
375
|
+
{
|
|
376
|
+
kind,
|
|
377
|
+
name: value.name.trim(),
|
|
378
|
+
description: value.description.trim(),
|
|
379
|
+
sourceUrl,
|
|
380
|
+
origin: "index",
|
|
381
|
+
...typeof value.version === "string" ? { version: value.version } : {},
|
|
382
|
+
...requires ? { requires } : {}
|
|
383
|
+
}
|
|
384
|
+
];
|
|
385
|
+
});
|
|
386
|
+
} catch (error) {
|
|
387
|
+
diagnostics.push(`library catalog unreadable: ${error instanceof Error ? error.message : String(error)}`);
|
|
388
|
+
return [];
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function libraryEntryRef(entry) {
|
|
392
|
+
return `${entry.kind}:${entry.name}`;
|
|
393
|
+
}
|
|
394
|
+
function discoverLibrary(options = {}) {
|
|
395
|
+
const marketplace = discoverMarketplaceSkills({
|
|
396
|
+
...options.marketplace ?? {},
|
|
397
|
+
...options.cwd ? { cwd: options.cwd } : {}
|
|
398
|
+
});
|
|
399
|
+
const diagnostics = [...marketplace.diagnostics.filter((item) => !item.includes("no local skill marketplace"))];
|
|
400
|
+
const privatePath = catalogPath();
|
|
401
|
+
const primary = options.catalog ? parseCatalog(path2.resolve(options.catalog), diagnostics) : [];
|
|
402
|
+
const privateEntries = parseCatalog(privatePath, diagnostics);
|
|
403
|
+
const byRef = /* @__PURE__ */ new Map();
|
|
404
|
+
for (const entry of [...marketplace.skills, ...primary, ...privateEntries]) byRef.set(libraryEntryRef(entry), entry);
|
|
405
|
+
const refusals = {};
|
|
406
|
+
const entries = [...byRef.values()].filter((entry) => {
|
|
407
|
+
try {
|
|
408
|
+
resolveLibraryRequirements(entry, [...byRef.values()]);
|
|
409
|
+
return true;
|
|
410
|
+
} catch (error) {
|
|
411
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
412
|
+
refusals[libraryEntryRef(entry)] = message;
|
|
413
|
+
if (!diagnostics.includes(message)) diagnostics.push(message);
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
return {
|
|
418
|
+
entries: entries.sort((a, b) => libraryEntryRef(a).localeCompare(libraryEntryRef(b))),
|
|
419
|
+
diagnostics,
|
|
420
|
+
refusals
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
var REQUIREMENT_PATTERN = /^(skill|agent|prompt|fleet):([A-Za-z0-9][A-Za-z0-9._-]*)$/;
|
|
424
|
+
function resolveLibraryRequirements(entry, catalog) {
|
|
425
|
+
const byRef = new Map(catalog.map((item) => [libraryEntryRef(item), item]));
|
|
426
|
+
const ordered = [];
|
|
427
|
+
const visiting = [];
|
|
428
|
+
const visited = /* @__PURE__ */ new Set();
|
|
429
|
+
const visit = (current) => {
|
|
430
|
+
const currentRef = libraryEntryRef(current);
|
|
431
|
+
if (visited.has(currentRef)) return;
|
|
432
|
+
const cycleAt = visiting.indexOf(currentRef);
|
|
433
|
+
if (cycleAt >= 0)
|
|
434
|
+
throw new Error(`library_requirement_cycle: ${[...visiting.slice(cycleAt), currentRef].join(" -> ")}`);
|
|
435
|
+
visiting.push(currentRef);
|
|
436
|
+
for (const requirement of current.requires ?? []) {
|
|
437
|
+
if (!REQUIREMENT_PATTERN.test(requirement)) throw new Error("library_requirement_malformed");
|
|
438
|
+
const dependency = byRef.get(requirement);
|
|
439
|
+
if (!dependency) throw new Error(`library_requirement_missing: ${requirement}`);
|
|
440
|
+
visit(dependency);
|
|
441
|
+
}
|
|
442
|
+
visiting.pop();
|
|
443
|
+
visited.add(currentRef);
|
|
444
|
+
ordered.push(current);
|
|
445
|
+
};
|
|
446
|
+
visit(entry);
|
|
447
|
+
return ordered;
|
|
448
|
+
}
|
|
449
|
+
function sourceFile(entry) {
|
|
450
|
+
const source = path2.resolve(entry.sourceUrl);
|
|
451
|
+
if (entry.kind === "skill") return source;
|
|
452
|
+
if (!existsSync(source)) throw new Error(`library source path does not exist: ${source}`);
|
|
453
|
+
return source;
|
|
454
|
+
}
|
|
455
|
+
function validateEntry(entry, raw, filePath) {
|
|
456
|
+
if (entry.kind === "fleet") {
|
|
457
|
+
parseFleetContract(raw, filePath);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (entry.kind === "agent") {
|
|
461
|
+
const parsed = parseFrontmatter(raw, filePath);
|
|
462
|
+
const recipe = parseAgentRecipeSchema({ id: entry.name, source: "user", filepath: filePath, ...parsed });
|
|
463
|
+
assertAgentSpecPolicy(normalizeAgentSpec(recipe));
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (entry.kind === "prompt") {
|
|
467
|
+
const loaded = loadPromptTemplates({ roots: [{ path: path2.dirname(filePath), scope: "user", source: "library" }] });
|
|
468
|
+
if (!loaded.items.some((item) => item.filePath === filePath))
|
|
469
|
+
throw new Error(`prompt template is malformed: ${filePath}`);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function libraryInstallPath(entry) {
|
|
473
|
+
if (entry.kind === "skill") return path2.join(clioConfigDir(), "skills", entry.name, "SKILL.md");
|
|
474
|
+
const root = entry.kind === "agent" ? "agents" : entry.kind === "fleet" ? "fleets" : "prompts";
|
|
475
|
+
return path2.join(clioConfigDir(), root, `${entry.name}.md`);
|
|
476
|
+
}
|
|
477
|
+
function readLibraryPins() {
|
|
478
|
+
const pinPath = path2.join(clioConfigDir(), "library-pins.yaml");
|
|
479
|
+
if (!existsSync(pinPath)) return {};
|
|
480
|
+
const parsed = (0, import_yaml.parse)(readFileSync2(pinPath, "utf8"));
|
|
481
|
+
return isRecord(parsed) ? parsed : {};
|
|
482
|
+
}
|
|
483
|
+
function libraryEntryInstalled(entry) {
|
|
484
|
+
return readLibraryPins()[libraryEntryRef(entry)] !== void 0 || existsSync(libraryInstallPath(entry));
|
|
485
|
+
}
|
|
486
|
+
function libraryEntryPin(entry) {
|
|
487
|
+
return readLibraryPins()[libraryEntryRef(entry)];
|
|
488
|
+
}
|
|
489
|
+
function classifyLibraryRequirements(entry, catalog) {
|
|
490
|
+
const ordered = resolveLibraryRequirements(entry, catalog).slice(0, -1);
|
|
491
|
+
const satisfied = ordered.filter((requirement) => libraryEntryInstalled(requirement));
|
|
492
|
+
const satisfiedRefs = new Set(satisfied.map(libraryEntryRef));
|
|
493
|
+
return {
|
|
494
|
+
ordered,
|
|
495
|
+
satisfied,
|
|
496
|
+
unsatisfied: ordered.filter((requirement) => !satisfiedRefs.has(libraryEntryRef(requirement)))
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
function planLibraryInstall(entry) {
|
|
500
|
+
if (entry.kind === "skill") {
|
|
501
|
+
const source2 = sourceFile(entry);
|
|
502
|
+
const file = statSync(source2).isDirectory() ? path2.join(source2, "SKILL.md") : source2;
|
|
503
|
+
const raw2 = readFileSync2(file);
|
|
504
|
+
return {
|
|
505
|
+
entry,
|
|
506
|
+
path: libraryInstallPath(entry),
|
|
507
|
+
sha256: normalizedSkillHash(raw2.toString("utf8"))
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
const source = sourceFile(entry);
|
|
511
|
+
const raw = readFileSync2(source, "utf8");
|
|
512
|
+
validateEntry(entry, raw, source);
|
|
513
|
+
return {
|
|
514
|
+
entry,
|
|
515
|
+
path: libraryInstallPath(entry),
|
|
516
|
+
sha256: createHash("sha256").update(raw).digest("hex")
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function recordPin(plan) {
|
|
520
|
+
const pinPath = path2.join(clioConfigDir(), "library-pins.yaml");
|
|
521
|
+
const pins = readLibraryPins();
|
|
522
|
+
pins[libraryEntryRef(plan.entry)] = { sha256: plan.sha256, sourceUrl: plan.entry.sourceUrl };
|
|
523
|
+
safeResourceWrite(pinPath, (0, import_yaml.stringify)(Object.fromEntries(Object.entries(pins).sort())), { encoding: "utf8" });
|
|
524
|
+
}
|
|
525
|
+
function installLibraryPlan(plan) {
|
|
526
|
+
if (existsSync(plan.path)) throw new Error(`library destination already exists: ${plan.path}`);
|
|
527
|
+
if (plan.entry.kind === "skill") installSkill({ source: plan.entry.sourceUrl, scope: "user", name: plan.entry.name });
|
|
528
|
+
else safeResourceWrite(plan.path, readFileSync2(sourceFile(plan.entry)));
|
|
529
|
+
recordPin(plan);
|
|
530
|
+
}
|
|
531
|
+
function confirmedRemote() {
|
|
532
|
+
const settings = readSettings().library;
|
|
533
|
+
if (!settings.remote || settings.remote !== settings.confirmedRemote) throw new Error("library_remote_unconfirmed");
|
|
534
|
+
return settings.remote;
|
|
535
|
+
}
|
|
536
|
+
function confirmLibraryRemote(url) {
|
|
537
|
+
const current = readSettings().library.remote;
|
|
538
|
+
if (current !== null && current !== url) throw new Error("library_remote_mismatch");
|
|
539
|
+
updateSettings((settings) => {
|
|
540
|
+
if (settings.library.remote === null) settings.library.remote = url;
|
|
541
|
+
settings.library.confirmedRemote = url;
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
async function syncLibrary(direction, runner = runCommandVector) {
|
|
545
|
+
const settings = readSettings().library;
|
|
546
|
+
if (!settings.sync) throw new Error("library_sync_disabled");
|
|
547
|
+
const remote = confirmedRemote();
|
|
548
|
+
const cwd = path2.dirname(catalogPath());
|
|
549
|
+
const remoteResult = await runner("git", ["remote", "get-url", "library"], { cwd, workspaceRoot: cwd });
|
|
550
|
+
if (remoteResult.exitCode !== 0 || remoteResult.stdout.trim() !== remote)
|
|
551
|
+
throw new Error("library_remote_unconfirmed");
|
|
552
|
+
if (direction === "sync") {
|
|
553
|
+
const fetched = await runner("git", ["fetch", "library"], { cwd, workspaceRoot: cwd });
|
|
554
|
+
if (fetched.exitCode !== 0) throw new Error(fetched.stderr.trim() || "library sync failed");
|
|
555
|
+
const advanced = await runner("git", ["merge", "--ff-only", "FETCH_HEAD"], { cwd, workspaceRoot: cwd });
|
|
556
|
+
if (advanced.exitCode !== 0) throw new Error(advanced.stderr.trim() || "library sync failed");
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
const result = await runner("git", ["push", "library"], { cwd, workspaceRoot: cwd });
|
|
560
|
+
if (result.exitCode !== 0) throw new Error(result.stderr.trim() || `library ${direction} failed`);
|
|
561
|
+
}
|
|
562
|
+
|
|
30
563
|
// src/domains/resources/skills/evals.ts
|
|
31
564
|
init_esm_shims();
|
|
32
565
|
var SCENARIO_HEADING = /^##\s+([A-Z])(\d+)\s*[-:–—]\s*(.+?)\s*$/;
|
|
@@ -158,23 +691,23 @@ function extractExpected(block) {
|
|
|
158
691
|
|
|
159
692
|
// src/domains/resources/skills/provenance-pin.ts
|
|
160
693
|
init_esm_shims();
|
|
161
|
-
var
|
|
162
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
163
|
-
import
|
|
694
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
695
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
696
|
+
import path3 from "node:path";
|
|
164
697
|
var SKILL_PIN_MANIFEST_FILENAME = "registry.yaml";
|
|
165
698
|
function isPlainObject(value) {
|
|
166
699
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
167
700
|
}
|
|
168
701
|
function resolveSkillPinManifestPath(cwd) {
|
|
169
702
|
const fromEnv = process.env.CLIO_CODER_SKILL_CATALOG_DIR;
|
|
170
|
-
const catalogDir = fromEnv && fromEnv.trim().length > 0 ?
|
|
171
|
-
const manifestPath =
|
|
172
|
-
return
|
|
703
|
+
const catalogDir = fromEnv && fromEnv.trim().length > 0 ? path3.resolve(fromEnv.trim()) : path3.join(cwd, "skills");
|
|
704
|
+
const manifestPath = path3.join(catalogDir, SKILL_PIN_MANIFEST_FILENAME);
|
|
705
|
+
return existsSync2(manifestPath) ? manifestPath : null;
|
|
173
706
|
}
|
|
174
707
|
function loadSkillPinManifest(manifestPath) {
|
|
175
708
|
let parsed;
|
|
176
709
|
try {
|
|
177
|
-
parsed =
|
|
710
|
+
parsed = import_yaml2.default.parse(readFileSync3(manifestPath, "utf8"));
|
|
178
711
|
} catch {
|
|
179
712
|
return null;
|
|
180
713
|
}
|
|
@@ -224,204 +757,6 @@ init_esm_shims();
|
|
|
224
757
|
|
|
225
758
|
// src/domains/resources/loader.ts
|
|
226
759
|
init_esm_shims();
|
|
227
|
-
|
|
228
|
-
// src/domains/resources/prompts/loader.ts
|
|
229
|
-
init_esm_shims();
|
|
230
|
-
import { readFileSync as readFileSync2 } from "node:fs";
|
|
231
|
-
import { homedir } from "node:os";
|
|
232
|
-
import path2 from "node:path";
|
|
233
|
-
|
|
234
|
-
// src/engine/prompt-templates.ts
|
|
235
|
-
init_esm_shims();
|
|
236
|
-
import { parseCommandArgs, substituteArgs } from "@earendil-works/pi-agent-core";
|
|
237
|
-
|
|
238
|
-
// src/domains/resources/collision.ts
|
|
239
|
-
init_esm_shims();
|
|
240
|
-
var SCOPE_RANK = {
|
|
241
|
-
package: 0,
|
|
242
|
-
user: 1,
|
|
243
|
-
project: 2,
|
|
244
|
-
cli: 3
|
|
245
|
-
};
|
|
246
|
-
function rankOf(info) {
|
|
247
|
-
return info.precedence ?? SCOPE_RANK[info.scope];
|
|
248
|
-
}
|
|
249
|
-
function compareCandidates(a, b) {
|
|
250
|
-
const rankDelta = rankOf(a.source) - rankOf(b.source);
|
|
251
|
-
if (rankDelta !== 0) return rankDelta;
|
|
252
|
-
return a.source.path.localeCompare(b.source.path);
|
|
253
|
-
}
|
|
254
|
-
function resolveResourceCollisions(candidates) {
|
|
255
|
-
const byName = /* @__PURE__ */ new Map();
|
|
256
|
-
for (const candidate of candidates) {
|
|
257
|
-
const key = candidate.name.trim();
|
|
258
|
-
if (key.length === 0) continue;
|
|
259
|
-
const list = byName.get(key) ?? [];
|
|
260
|
-
list.push(candidate);
|
|
261
|
-
byName.set(key, list);
|
|
262
|
-
}
|
|
263
|
-
const winners = [];
|
|
264
|
-
const diagnostics = [];
|
|
265
|
-
for (const [name, entries] of byName.entries()) {
|
|
266
|
-
const sorted = [...entries].sort(compareCandidates);
|
|
267
|
-
const winner = sorted[sorted.length - 1];
|
|
268
|
-
if (!winner) continue;
|
|
269
|
-
winners.push(winner.value);
|
|
270
|
-
for (const loser of sorted.slice(0, -1)) {
|
|
271
|
-
diagnostics.push({
|
|
272
|
-
type: "collision",
|
|
273
|
-
message: `${name} from ${winner.source.scope} overrides ${loser.source.scope}`,
|
|
274
|
-
path: loser.source.path,
|
|
275
|
-
collision: {
|
|
276
|
-
name,
|
|
277
|
-
winnerPath: winner.source.path,
|
|
278
|
-
loserPath: loser.source.path,
|
|
279
|
-
winnerScope: winner.source.scope,
|
|
280
|
-
loserScope: loser.source.scope
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return { winners, diagnostics };
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// src/domains/resources/prompts/loader.ts
|
|
289
|
-
function defaultPromptTemplateRoots(input = {}) {
|
|
290
|
-
const cwd = input.cwd ?? process.cwd();
|
|
291
|
-
const home = input.home ?? homedir();
|
|
292
|
-
const trustProject = projectCompatTrusted(input.trustProjectCompatRoots);
|
|
293
|
-
const compat = [];
|
|
294
|
-
for (const kind of INTEROP_AGENT_KINDS) {
|
|
295
|
-
if (kind.userPromptRoot !== void 0) {
|
|
296
|
-
compat.push({
|
|
297
|
-
path: path2.join(home, kind.userPromptRoot),
|
|
298
|
-
scope: "user",
|
|
299
|
-
source: `${kind.id}-user`,
|
|
300
|
-
precedence: COMPAT_RESOURCE_PRECEDENCE.userCompat,
|
|
301
|
-
trusted: true
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
if (kind.projectPromptRoot !== void 0) {
|
|
305
|
-
compat.push({
|
|
306
|
-
path: path2.join(cwd, kind.projectPromptRoot),
|
|
307
|
-
scope: "project",
|
|
308
|
-
source: `${kind.id}-project`,
|
|
309
|
-
precedence: COMPAT_RESOURCE_PRECEDENCE.projectCompat,
|
|
310
|
-
trusted: trustProject
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return [...defaultScopedResourceRoots("prompts", cwd), ...compat];
|
|
315
|
-
}
|
|
316
|
-
function splitOptionalFrontmatter(raw, filePath, diagnostics) {
|
|
317
|
-
const split = splitYamlFrontmatter(raw);
|
|
318
|
-
if (split.ok) return split;
|
|
319
|
-
if (split.reason === "missing") return { frontmatter: {}, body: raw };
|
|
320
|
-
const message = split.reason === "missing closing delimiter" ? "prompt template frontmatter is missing a closing delimiter; treating the file as plain markdown" : split.reason === "must be a YAML object" ? "prompt template frontmatter must be a YAML object" : `prompt template frontmatter is ${split.reason}`;
|
|
321
|
-
diagnostics.push({ type: "warning", message, path: filePath });
|
|
322
|
-
return { frontmatter: {}, body: split.body };
|
|
323
|
-
}
|
|
324
|
-
function fallbackDescription(body) {
|
|
325
|
-
const line = body.split(/\r?\n/).map((entry) => entry.trim()).find((entry) => entry.length > 0);
|
|
326
|
-
if (!line) return "Prompt template";
|
|
327
|
-
const normalized = line.replace(/^#{1,6}\s+/, "");
|
|
328
|
-
return normalized.length > 60 ? `${normalized.slice(0, 57)}...` : normalized;
|
|
329
|
-
}
|
|
330
|
-
function loadPromptFile(filePath, root, diagnostics) {
|
|
331
|
-
const ext = path2.extname(filePath).toLowerCase();
|
|
332
|
-
if (ext !== ".md") return null;
|
|
333
|
-
let raw;
|
|
334
|
-
try {
|
|
335
|
-
raw = readFileSync2(filePath, "utf8");
|
|
336
|
-
} catch (err) {
|
|
337
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
338
|
-
diagnostics.push({ type: "warning", message: `prompt template could not be read: ${reason}`, path: filePath });
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
const name = path2.basename(filePath, ext);
|
|
342
|
-
if (name.trim().length === 0) return null;
|
|
343
|
-
const { frontmatter, body } = splitOptionalFrontmatter(raw, filePath, diagnostics);
|
|
344
|
-
const description = stringField(frontmatter, "description") ?? fallbackDescription(body);
|
|
345
|
-
const argumentHint = stringField(frontmatter, "argument-hint") ?? stringField(frontmatter, "argumentHint");
|
|
346
|
-
const sourceInfo = sourceInfoForRoot(root, filePath);
|
|
347
|
-
const template = {
|
|
348
|
-
name,
|
|
349
|
-
description,
|
|
350
|
-
content: body.trim(),
|
|
351
|
-
filePath,
|
|
352
|
-
sourceInfo,
|
|
353
|
-
trusted: root.trusted !== false
|
|
354
|
-
};
|
|
355
|
-
if (argumentHint) template.argumentHint = argumentHint;
|
|
356
|
-
return { name, value: template, source: sourceInfo };
|
|
357
|
-
}
|
|
358
|
-
function loadPromptRoot(root, diagnostics) {
|
|
359
|
-
const candidates = [];
|
|
360
|
-
for (const entry of readRootEntries(root, "prompt template", diagnostics)) {
|
|
361
|
-
if (!entry.isFile()) continue;
|
|
362
|
-
const candidate = loadPromptFile(path2.join(root.path, entry.name), root, diagnostics);
|
|
363
|
-
if (candidate) candidates.push(candidate);
|
|
364
|
-
}
|
|
365
|
-
return candidates;
|
|
366
|
-
}
|
|
367
|
-
function loadPromptTemplates(input = {}) {
|
|
368
|
-
const roots = input.roots ?? defaultPromptTemplateRoots(input);
|
|
369
|
-
const diagnostics = [];
|
|
370
|
-
const candidates = roots.flatMap((root) => loadPromptRoot(root, diagnostics));
|
|
371
|
-
const resolved = resolveResourceCollisions(candidates);
|
|
372
|
-
const items = [];
|
|
373
|
-
for (const template of resolved.winners) {
|
|
374
|
-
if (input.reservedNames?.has(template.name) === true) {
|
|
375
|
-
diagnostics.push({
|
|
376
|
-
type: "collision",
|
|
377
|
-
message: `prompt template /${template.name} conflicts with the built-in slash command /${template.name} and was ignored`,
|
|
378
|
-
path: template.filePath
|
|
379
|
-
});
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
items.push(template);
|
|
383
|
-
}
|
|
384
|
-
return {
|
|
385
|
-
items: items.sort((a, b) => a.name.localeCompare(b.name)),
|
|
386
|
-
diagnostics: [...diagnostics, ...resolved.diagnostics]
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
function parsePromptCommand(input) {
|
|
390
|
-
const trimmed = input.trim();
|
|
391
|
-
if (!trimmed.startsWith("/")) return null;
|
|
392
|
-
const withoutSlash = trimmed.slice(1);
|
|
393
|
-
const separator = withoutSlash.search(/\s/);
|
|
394
|
-
const name = separator === -1 ? withoutSlash : withoutSlash.slice(0, separator);
|
|
395
|
-
if (name.length === 0 || name.includes("/")) return null;
|
|
396
|
-
const rest = separator === -1 ? "" : withoutSlash.slice(separator).trim();
|
|
397
|
-
return { name, rest };
|
|
398
|
-
}
|
|
399
|
-
function expandPromptTemplateInput(input, templates) {
|
|
400
|
-
const command = parsePromptCommand(input);
|
|
401
|
-
if (!command) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
|
|
402
|
-
const template = templates.items.find((entry) => entry.name === command.name);
|
|
403
|
-
if (!template) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
|
|
404
|
-
if (!template.trusted) {
|
|
405
|
-
const message = `prompt template ${template.name} comes from an untrusted project root; set skills.trustProjectCompatRoots to use it`;
|
|
406
|
-
return {
|
|
407
|
-
expanded: false,
|
|
408
|
-
text: input,
|
|
409
|
-
args: [],
|
|
410
|
-
diagnostics: [...templates.diagnostics, { type: "warning", message, path: template.filePath }],
|
|
411
|
-
refusal: { template, message }
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
const args = parseCommandArgs(command.rest);
|
|
415
|
-
return {
|
|
416
|
-
expanded: true,
|
|
417
|
-
text: substituteArgs(template.content, args),
|
|
418
|
-
args,
|
|
419
|
-
template,
|
|
420
|
-
diagnostics: templates.diagnostics
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// src/domains/resources/loader.ts
|
|
425
760
|
function createResourcesLoader(options = {}) {
|
|
426
761
|
const defaultCwd = options.cwd ?? process.cwd();
|
|
427
762
|
const skillOptions2 = () => options.skills?.() ?? {};
|
|
@@ -527,9 +862,19 @@ function createResourcesDomainModule(options = {}) {
|
|
|
527
862
|
}
|
|
528
863
|
|
|
529
864
|
export {
|
|
865
|
+
libraryEntryRef,
|
|
866
|
+
discoverLibrary,
|
|
867
|
+
libraryInstallPath,
|
|
868
|
+
libraryEntryInstalled,
|
|
869
|
+
libraryEntryPin,
|
|
870
|
+
classifyLibraryRequirements,
|
|
871
|
+
planLibraryInstall,
|
|
872
|
+
installLibraryPlan,
|
|
873
|
+
confirmLibraryRemote,
|
|
874
|
+
syncLibrary,
|
|
530
875
|
parseSkillEvals,
|
|
531
876
|
checkSkillDrift,
|
|
532
877
|
ResourcesDomainModule,
|
|
533
878
|
createResourcesDomainModule
|
|
534
879
|
};
|
|
535
|
-
//# sourceMappingURL=chunk-
|
|
880
|
+
//# sourceMappingURL=chunk-U6MBIEMB.js.map
|