@iowarp/clio-coder 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +407 -0
- package/CODE_OF_CONDUCT.md +21 -0
- package/CONTRIBUTING.md +224 -0
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +798 -0
- package/SECURITY.md +72 -0
- package/assets/clio-coder-logo-128.webp +0 -0
- package/damage-control-rules.yaml +419 -0
- package/dist/acp-UMLFVA3F.js +92 -0
- package/dist/agents-Q4MYPMUW.js +91 -0
- package/dist/auth-O6HYIJ6J.js +521 -0
- package/dist/chunk-262G75JS.js +35 -0
- package/dist/chunk-26BZQOAD.js +1281 -0
- package/dist/chunk-2J63S4SF.js +508 -0
- package/dist/chunk-3DANZDGR.js +717 -0
- package/dist/chunk-4UQA7NCT.js +29 -0
- package/dist/chunk-527KG6XR.js +497 -0
- package/dist/chunk-5LDRNKX2.js +1063 -0
- package/dist/chunk-5N2FG33Q.js +25 -0
- package/dist/chunk-67MTHP2E.js +135 -0
- package/dist/chunk-6CWDTGUC.js +20 -0
- package/dist/chunk-7BHLZB3A.js +2115 -0
- package/dist/chunk-7RBKDI66.js +348 -0
- package/dist/chunk-AMFR5YA3.js +541 -0
- package/dist/chunk-BBUH4VAA.js +1224 -0
- package/dist/chunk-BYEU76JP.js +899 -0
- package/dist/chunk-CLJ5HLUD.js +458 -0
- package/dist/chunk-D5YD55AR.js +116 -0
- package/dist/chunk-DXQNI4PC.js +61 -0
- package/dist/chunk-E3NYWENM.js +1004 -0
- package/dist/chunk-GNGDQYDU.js +34688 -0
- package/dist/chunk-GOTUR54M.js +9 -0
- package/dist/chunk-HBU5MTAM.js +41 -0
- package/dist/chunk-HMYNFFY4.js +28 -0
- package/dist/chunk-JPOWPFCU.js +1010 -0
- package/dist/chunk-JWHCJDCI.js +1215 -0
- package/dist/chunk-KBR4MZZR.js +41 -0
- package/dist/chunk-KKKPTZLM.js +93 -0
- package/dist/chunk-ME6DNWIU.js +66 -0
- package/dist/chunk-NI4DEJMC.js +88 -0
- package/dist/chunk-O4EJEDHO.js +659 -0
- package/dist/chunk-PIDUD6M2.js +31 -0
- package/dist/chunk-PS4PFJQP.js +29459 -0
- package/dist/chunk-QV47YRF4.js +48 -0
- package/dist/chunk-RQDWMVRB.js +279 -0
- package/dist/chunk-TFSSEXL6.js +136 -0
- package/dist/chunk-TKHQ4DGZ.js +8290 -0
- package/dist/chunk-TPOCL34A.js +2876 -0
- package/dist/chunk-UGYAX5YI.js +565 -0
- package/dist/chunk-UHTSULZS.js +461 -0
- package/dist/chunk-UU3R62TT.js +128 -0
- package/dist/chunk-UWIJNAOB.js +3906 -0
- package/dist/chunk-VOO7NYPP.js +914 -0
- package/dist/chunk-VPAWTYLY.js +117 -0
- package/dist/chunk-WD6AJM35.js +1216 -0
- package/dist/chunk-X3BR7HWV.js +115 -0
- package/dist/chunk-X3NE4WVW.js +120 -0
- package/dist/chunk-XNISANGE.js +1395 -0
- package/dist/chunk-XV4ZJ6ZM.js +3177 -0
- package/dist/cli/index.js +236 -0
- package/dist/clio-KIQ5SNDS.js +53 -0
- package/dist/components-JVHMUBEB.js +653 -0
- package/dist/config-ZFCDBMDC.js +372 -0
- package/dist/configure-G4E3A2PG.js +27 -0
- package/dist/context-CDXTP2MP.js +293 -0
- package/dist/context-E3KIFVXI.js +185 -0
- package/dist/context-clear-3F4PLXOS.js +102 -0
- package/dist/context-index-Q7YSYTR3.js +106 -0
- package/dist/docs-YIETIWZI.js +280 -0
- package/dist/doctor-M5HJJZOL.js +61 -0
- package/dist/domains/agents/builtins/architect.md +33 -0
- package/dist/domains/agents/builtins/coder.md +31 -0
- package/dist/domains/agents/builtins/context-bootstrap.md +38 -0
- package/dist/domains/agents/builtins/debugger.md +30 -0
- package/dist/domains/agents/builtins/documenter.md +31 -0
- package/dist/domains/agents/builtins/git-master.md +30 -0
- package/dist/domains/agents/builtins/provenance.md +30 -0
- package/dist/domains/agents/builtins/researcher.md +71 -0
- package/dist/domains/agents/builtins/scout.md +42 -0
- package/dist/domains/agents/builtins/tester.md +31 -0
- package/dist/domains/agents/builtins/verifier.md +30 -0
- package/dist/domains/agents/builtins/wiki-writer.md +41 -0
- package/dist/eval-B3KZZESM.js +2674 -0
- package/dist/evidence-V67CHM35.js +233 -0
- package/dist/evolve-YDZSUQYA.js +518 -0
- package/dist/extensions-SRG7XCAH.js +207 -0
- package/dist/fleet-CA2CRTVG.js +760 -0
- package/dist/fleet-preflight-CLIAX7YR.js +21 -0
- package/dist/init-2OZDJE2D.js +227 -0
- package/dist/memory-3PIQQAKX.js +207 -0
- package/dist/models-DY35XI7Y.js +237 -0
- package/dist/paths-5OMXW7Z4.js +57 -0
- package/dist/preload-KZVHET2B.js +11 -0
- package/dist/reset-PIFYNOS3.js +216 -0
- package/dist/run-3VSPP24F.js +735 -0
- package/dist/share-D36RQCXM.js +241 -0
- package/dist/skills-F2MRLELY.js +445 -0
- package/dist/skills-eval-E2ZTW4PL.js +932 -0
- package/dist/targets-DZMEZAH4.js +977 -0
- package/dist/trace-7NYCUI2J.js +250 -0
- package/dist/uninstall-AD3JWHBB.js +322 -0
- package/dist/upgrade-WYYBKGDY.js +301 -0
- package/dist/usage-ULIDAGFF.js +755 -0
- package/dist/version-ROZ6CZKH.js +16 -0
- package/dist/wiki-generate-PKFIX6OB.js +377 -0
- package/dist/worker/entry.js +1739 -0
- package/docs/README.md +93 -0
- package/docs/acp.md +120 -0
- package/docs/alcf-provider.md +72 -0
- package/docs/architecture.md +172 -0
- package/docs/artifact-versions.md +54 -0
- package/docs/built-in-agents.md +265 -0
- package/docs/capacity-and-scheduling.md +97 -0
- package/docs/commands-and-modes.md +554 -0
- package/docs/config-knobs-audit.md +115 -0
- package/docs/configuration-and-targets.md +812 -0
- package/docs/context-engine.md +236 -0
- package/docs/dispatch-architecture-rationale.md +126 -0
- package/docs/documentation-coverage.md +46 -0
- package/docs/documentation-guide.md +166 -0
- package/docs/environment-variables.md +105 -0
- package/docs/eval-runner.md +205 -0
- package/docs/evals-internal.md +298 -0
- package/docs/evidence-and-memory.md +243 -0
- package/docs/evolution.md +143 -0
- package/docs/exit-codes-and-output.md +74 -0
- package/docs/extensions-and-sharing.md +306 -0
- package/docs/fleet-demo-runbook.md +179 -0
- package/docs/fleet-dispatch.md +591 -0
- package/docs/glossary.md +75 -0
- package/docs/html/agents_blueprint.html +936 -0
- package/docs/html/alcf_blueprint.html +324 -0
- package/docs/html/architecture_blueprint.html +850 -0
- package/docs/html/commands_blueprint.html +794 -0
- package/docs/html/config_knobs_audit_blueprint.html +178 -0
- package/docs/html/configuration_blueprint.html +1080 -0
- package/docs/html/context_blueprint.html +603 -0
- package/docs/html/documentation_blueprint.html +832 -0
- package/docs/html/environment_blueprint.html +404 -0
- package/docs/html/eval_blueprint.html +743 -0
- package/docs/html/evals_internal_blueprint.html +190 -0
- package/docs/html/evolution_blueprint.html +674 -0
- package/docs/html/extensions_blueprint.html +2065 -0
- package/docs/html/fleet_dispatch_blueprint.html +286 -0
- package/docs/html/index.html +919 -0
- package/docs/html/lifecycle_blueprint.html +723 -0
- package/docs/html/memory_blueprint.html +699 -0
- package/docs/html/middleware_blueprint.html +664 -0
- package/docs/html/models_blueprint.html +2366 -0
- package/docs/html/observability_blueprint.html +683 -0
- package/docs/html/provider_adapter_blueprint.html +245 -0
- package/docs/html/safety_blueprint.html +1386 -0
- package/docs/html/shared.css +571 -0
- package/docs/html/shared.js +143 -0
- package/docs/html/skills_blueprint.html +671 -0
- package/docs/html/soak_blueprint.html +182 -0
- package/docs/html/tool_usage_blueprint.html +350 -0
- package/docs/html/tools_blueprint.html +2249 -0
- package/docs/html/trace_blueprint.html +235 -0
- package/docs/html/tui_design_blueprint.html +314 -0
- package/docs/html/validation_blueprint.html +961 -0
- package/docs/html/worker_dispatch_blueprint.html +231 -0
- package/docs/installation-and-lifecycle.md +308 -0
- package/docs/middleware-and-components.md +148 -0
- package/docs/model-catalog.md +189 -0
- package/docs/observability.md +233 -0
- package/docs/proactive-memory.md +452 -0
- package/docs/prompt-envelope-and-tools.md +142 -0
- package/docs/provider-adapter-cookbook.md +148 -0
- package/docs/release-cut-checklist.md +138 -0
- package/docs/safety-model.md +357 -0
- package/docs/scientific-validation.md +105 -0
- package/docs/session-lifecycle.md +156 -0
- package/docs/skills-marketplace.md +46 -0
- package/docs/tool-usage.md +527 -0
- package/docs/trace-store.md +132 -0
- package/docs/troubleshooting.md +33 -0
- package/docs/tui-design.md +239 -0
- package/docs/worker-dispatch-mechanics.md +242 -0
- package/package.json +132 -0
- package/skills/README.md +408 -0
- package/skills/git/commit-crafting/SKILL.md +79 -0
- package/skills/git/commit-crafting/evals.md +92 -0
- package/skills/git/create-pr/SKILL.md +116 -0
- package/skills/git/create-pr/evals.md +114 -0
- package/skills/git/investigate-issue/SKILL.md +139 -0
- package/skills/git/investigate-issue/evals.md +94 -0
- package/skills/git/resolve-merge-conflicts/SKILL.md +96 -0
- package/skills/git/resolve-merge-conflicts/evals.md +58 -0
- package/skills/git/review-changes/SKILL.md +103 -0
- package/skills/git/review-changes/evals.md +85 -0
- package/skills/git/worktree-create/SKILL.md +92 -0
- package/skills/git/worktree-create/evals.md +97 -0
- package/skills/git/worktree-create/references/worktree-setup.md +66 -0
- package/skills/git/worktree-merge/SKILL.md +95 -0
- package/skills/git/worktree-merge/evals.md +114 -0
- package/skills/skill-marketplace.json +261 -0
- package/skills/workflow/cut-it/SKILL.md +86 -0
- package/skills/workflow/cut-it/evals.md +42 -0
- package/src/domains/agents/builtins/architect.md +33 -0
- package/src/domains/agents/builtins/coder.md +31 -0
- package/src/domains/agents/builtins/context-bootstrap.md +38 -0
- package/src/domains/agents/builtins/debugger.md +30 -0
- package/src/domains/agents/builtins/documenter.md +31 -0
- package/src/domains/agents/builtins/git-master.md +30 -0
- package/src/domains/agents/builtins/provenance.md +30 -0
- package/src/domains/agents/builtins/researcher.md +71 -0
- package/src/domains/agents/builtins/scout.md +42 -0
- package/src/domains/agents/builtins/tester.md +31 -0
- package/src/domains/agents/builtins/verifier.md +30 -0
- package/src/domains/agents/builtins/wiki-writer.md +41 -0
- package/src/domains/agents/fleets/build-review.md +34 -0
- package/src/domains/agents/fleets/build-test.md +35 -0
- package/src/domains/agents/fleets/sdlc.md +86 -0
- package/src/domains/prompts/fragments/identity/clio-worker.md +11 -0
- package/src/domains/prompts/fragments/identity/clio.md +26 -0
- package/src/domains/prompts/fragments/operating/contract.md +64 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +14 -0
- package/src/domains/prompts/fragments/safety/full-auto.md +14 -0
- package/src/domains/prompts/fragments/safety/read-only.md +13 -0
- package/src/domains/prompts/fragments/safety/suggest.md +13 -0
- package/src/domains/prompts/fragments/wiki/page.md +75 -0
- package/src/domains/prompts/fragments/wiki/plan.md +48 -0
- package/src/domains/providers/models/cloud-models/alcf.yaml +40 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +993 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safeResourceWrite
|
|
3
|
+
} from "./chunk-VPAWTYLY.js";
|
|
4
|
+
import {
|
|
5
|
+
clioConfigDir
|
|
6
|
+
} from "./chunk-X3NE4WVW.js";
|
|
7
|
+
|
|
8
|
+
// src/domains/extensions/discovery.ts
|
|
9
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
12
|
+
var MANIFEST_NAMES = ["clio-coder-extension.yaml", "clio-coder-extension.yml", "clio-coder-extension.json"];
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function trimString(value) {
|
|
17
|
+
if (typeof value !== "string") return void 0;
|
|
18
|
+
const trimmed = value.trim();
|
|
19
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
20
|
+
}
|
|
21
|
+
function validateId(id) {
|
|
22
|
+
if (id.length > 80) return "id exceeds 80 characters";
|
|
23
|
+
if (!/^[a-z0-9][a-z0-9._-]*[a-z0-9]$/.test(id)) {
|
|
24
|
+
return "id must use lowercase letters, numbers, dots, underscores, or hyphens and start/end alphanumeric";
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
function readJsonOrYaml(filePath) {
|
|
29
|
+
const raw = readFileSync(filePath, "utf8");
|
|
30
|
+
if (filePath.endsWith(".json")) return JSON.parse(raw);
|
|
31
|
+
return parseYaml(raw);
|
|
32
|
+
}
|
|
33
|
+
function normalizeResources(value) {
|
|
34
|
+
if (!isRecord(value)) return {};
|
|
35
|
+
const out = {};
|
|
36
|
+
const skills = trimString(value.skills);
|
|
37
|
+
const prompts = trimString(value.prompts);
|
|
38
|
+
const themes = trimString(value.themes);
|
|
39
|
+
if (skills) out.skills = skills;
|
|
40
|
+
if (prompts) out.prompts = prompts;
|
|
41
|
+
if (themes) out.themes = themes;
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
function stringArray(value) {
|
|
45
|
+
if (!Array.isArray(value)) return void 0;
|
|
46
|
+
const out = value.map((entry) => trimString(entry)).filter((entry) => entry !== void 0);
|
|
47
|
+
return out.length > 0 ? out : void 0;
|
|
48
|
+
}
|
|
49
|
+
function parseExtensionManifest(value, manifestPath) {
|
|
50
|
+
const diagnostics = [];
|
|
51
|
+
if (!isRecord(value)) {
|
|
52
|
+
return { diagnostics: [{ type: "error", message: "extension manifest must be an object", path: manifestPath }] };
|
|
53
|
+
}
|
|
54
|
+
if (value.manifestVersion !== 1) {
|
|
55
|
+
diagnostics.push({ type: "error", message: "manifestVersion must be 1", path: manifestPath });
|
|
56
|
+
}
|
|
57
|
+
const id = trimString(value.id);
|
|
58
|
+
const name = trimString(value.name) ?? id;
|
|
59
|
+
const version = trimString(value.version);
|
|
60
|
+
const description = trimString(value.description);
|
|
61
|
+
if (!id) diagnostics.push({ type: "error", message: "id is required", path: manifestPath });
|
|
62
|
+
else {
|
|
63
|
+
const idError = validateId(id);
|
|
64
|
+
if (idError) diagnostics.push({ type: "error", message: idError, path: manifestPath });
|
|
65
|
+
}
|
|
66
|
+
if (!version) diagnostics.push({ type: "error", message: "version is required", path: manifestPath });
|
|
67
|
+
if (!description) diagnostics.push({ type: "error", message: "description is required", path: manifestPath });
|
|
68
|
+
const resources = normalizeResources(value.resources);
|
|
69
|
+
const tools = stringArray(value.tools);
|
|
70
|
+
const settings = stringArray(value.settings);
|
|
71
|
+
const compatibility = isRecord(value.compatibility) ? { ...trimString(value.compatibility.clio) ? { clio: trimString(value.compatibility.clio) } : {} } : void 0;
|
|
72
|
+
if (!id || !name || !version || !description || diagnostics.some((diag) => diag.type === "error")) {
|
|
73
|
+
return { diagnostics };
|
|
74
|
+
}
|
|
75
|
+
const manifest = {
|
|
76
|
+
manifestVersion: 1,
|
|
77
|
+
id,
|
|
78
|
+
name,
|
|
79
|
+
version,
|
|
80
|
+
description,
|
|
81
|
+
resources
|
|
82
|
+
};
|
|
83
|
+
if (tools) manifest.tools = tools;
|
|
84
|
+
if (settings) manifest.settings = settings;
|
|
85
|
+
if (compatibility && Object.keys(compatibility).length > 0) manifest.compatibility = compatibility;
|
|
86
|
+
return { manifest, diagnostics };
|
|
87
|
+
}
|
|
88
|
+
function findExtensionManifestPath(root) {
|
|
89
|
+
for (const name of MANIFEST_NAMES) {
|
|
90
|
+
const candidate = path.join(root, name);
|
|
91
|
+
try {
|
|
92
|
+
if (statSync(candidate).isFile()) return candidate;
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
function loadManifestFromRoot(root) {
|
|
99
|
+
const manifestPath = findExtensionManifestPath(root);
|
|
100
|
+
if (!manifestPath) {
|
|
101
|
+
return {
|
|
102
|
+
path: root,
|
|
103
|
+
valid: false,
|
|
104
|
+
diagnostics: [{ type: "error", message: "extension manifest not found", path: root }]
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const parsed = parseExtensionManifest(readJsonOrYaml(manifestPath), manifestPath);
|
|
109
|
+
return {
|
|
110
|
+
path: root,
|
|
111
|
+
manifestPath,
|
|
112
|
+
...parsed.manifest ? { manifest: parsed.manifest } : {},
|
|
113
|
+
valid: parsed.manifest !== void 0 && !parsed.diagnostics.some((diag) => diag.type === "error"),
|
|
114
|
+
diagnostics: parsed.diagnostics
|
|
115
|
+
};
|
|
116
|
+
} catch (err) {
|
|
117
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
118
|
+
return {
|
|
119
|
+
path: root,
|
|
120
|
+
manifestPath,
|
|
121
|
+
valid: false,
|
|
122
|
+
diagnostics: [{ type: "error", message: `extension manifest could not be read: ${reason}`, path: manifestPath }]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function discoverExtensionPackages(root) {
|
|
127
|
+
const full = path.resolve(root);
|
|
128
|
+
if (!existsSync(full)) {
|
|
129
|
+
return [{ path: full, valid: false, diagnostics: [{ type: "error", message: "path does not exist", path: full }] }];
|
|
130
|
+
}
|
|
131
|
+
const stat = statSync(full);
|
|
132
|
+
if (!stat.isDirectory()) {
|
|
133
|
+
return [
|
|
134
|
+
{
|
|
135
|
+
path: full,
|
|
136
|
+
valid: false,
|
|
137
|
+
diagnostics: [{ type: "error", message: "extension path is not a directory", path: full }]
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
const direct = loadManifestFromRoot(full);
|
|
142
|
+
if (direct.valid || direct.manifestPath) return [direct];
|
|
143
|
+
const candidates = [];
|
|
144
|
+
for (const entry of readdirSync(full, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
145
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
146
|
+
const child = path.join(full, entry.name);
|
|
147
|
+
const loaded = loadManifestFromRoot(child);
|
|
148
|
+
if (loaded.valid || loaded.manifestPath) candidates.push(loaded);
|
|
149
|
+
}
|
|
150
|
+
const discovered = candidates.length > 0 ? candidates : [direct];
|
|
151
|
+
const ids = /* @__PURE__ */ new Map();
|
|
152
|
+
for (const candidate of discovered) {
|
|
153
|
+
const id = candidate.manifest?.id;
|
|
154
|
+
if (!id) continue;
|
|
155
|
+
const group = ids.get(id) ?? [];
|
|
156
|
+
group.push(candidate);
|
|
157
|
+
ids.set(id, group);
|
|
158
|
+
}
|
|
159
|
+
for (const [id, group] of ids) {
|
|
160
|
+
if (group.length < 2) continue;
|
|
161
|
+
for (const candidate of group) {
|
|
162
|
+
candidate.valid = false;
|
|
163
|
+
candidate.diagnostics.push({
|
|
164
|
+
type: "error",
|
|
165
|
+
message: `duplicate extension id ${id}`,
|
|
166
|
+
path: candidate.manifestPath ?? candidate.path
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return discovered;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// src/domains/extensions/state.ts
|
|
174
|
+
import { cpSync, existsSync as existsSync2, mkdirSync, readdirSync as readdirSync2, readFileSync as readFileSync2, renameSync, rmSync } from "node:fs";
|
|
175
|
+
import path2 from "node:path";
|
|
176
|
+
var DEFAULT_STATE = { version: 1, disabled: [], installed: {} };
|
|
177
|
+
function extensionBaseDir(scope, cwd = process.cwd()) {
|
|
178
|
+
return scope === "user" ? path2.join(clioConfigDir(), "extensions") : path2.join(path2.resolve(cwd), ".clio-coder", "extensions");
|
|
179
|
+
}
|
|
180
|
+
function statePath(scope, cwd = process.cwd()) {
|
|
181
|
+
return path2.join(extensionBaseDir(scope, cwd), "state.json");
|
|
182
|
+
}
|
|
183
|
+
function scopeRank(scope) {
|
|
184
|
+
return scope === "project" ? 2 : 1;
|
|
185
|
+
}
|
|
186
|
+
function readState(scope, cwd = process.cwd()) {
|
|
187
|
+
const filePath = statePath(scope, cwd);
|
|
188
|
+
if (!existsSync2(filePath)) return structuredClone(DEFAULT_STATE);
|
|
189
|
+
try {
|
|
190
|
+
const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
|
|
191
|
+
if (!isRecord(parsed) || parsed.version !== 1) return structuredClone(DEFAULT_STATE);
|
|
192
|
+
const disabled = Array.isArray(parsed.disabled) ? parsed.disabled.filter((entry) => typeof entry === "string") : [];
|
|
193
|
+
const installed = isRecord(parsed.installed) ? Object.fromEntries(
|
|
194
|
+
Object.entries(parsed.installed).flatMap(([id, raw]) => {
|
|
195
|
+
if (!isRecord(raw)) return [];
|
|
196
|
+
const installedAt = trimString(raw.installedAt) ?? (/* @__PURE__ */ new Date(0)).toISOString();
|
|
197
|
+
const source = trimString(raw.source);
|
|
198
|
+
return [[id, { installedAt, ...source ? { source } : {} }]];
|
|
199
|
+
})
|
|
200
|
+
) : {};
|
|
201
|
+
return { version: 1, disabled, installed };
|
|
202
|
+
} catch {
|
|
203
|
+
return structuredClone(DEFAULT_STATE);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function writeState(scope, state, cwd = process.cwd()) {
|
|
207
|
+
const filePath = statePath(scope, cwd);
|
|
208
|
+
safeResourceWrite(filePath, `${JSON.stringify(state, null, 2)}
|
|
209
|
+
`, { encoding: "utf8" });
|
|
210
|
+
}
|
|
211
|
+
function installedFromRoot(root, scope, state) {
|
|
212
|
+
const candidate = loadManifestFromRoot(root);
|
|
213
|
+
const manifest = candidate.manifest;
|
|
214
|
+
if (!manifest || !candidate.manifestPath) return null;
|
|
215
|
+
return {
|
|
216
|
+
id: manifest.id,
|
|
217
|
+
name: manifest.name,
|
|
218
|
+
version: manifest.version,
|
|
219
|
+
description: manifest.description,
|
|
220
|
+
scope,
|
|
221
|
+
rootPath: root,
|
|
222
|
+
manifestPath: candidate.manifestPath,
|
|
223
|
+
enabled: !state.disabled.includes(manifest.id),
|
|
224
|
+
effective: false,
|
|
225
|
+
resources: manifest.resources,
|
|
226
|
+
diagnostics: candidate.diagnostics
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function listScope(scope, cwd = process.cwd()) {
|
|
230
|
+
const base = extensionBaseDir(scope, cwd);
|
|
231
|
+
if (!existsSync2(base)) return [];
|
|
232
|
+
const state = readState(scope, cwd);
|
|
233
|
+
const out = [];
|
|
234
|
+
for (const entry of readdirSync2(base, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
235
|
+
if (!entry.isDirectory()) continue;
|
|
236
|
+
const root = path2.join(base, entry.name);
|
|
237
|
+
const installed = installedFromRoot(root, scope, state);
|
|
238
|
+
if (installed) out.push(installed);
|
|
239
|
+
}
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
function listInstalledExtensions(cwd = process.cwd(), options = {}) {
|
|
243
|
+
const scopes = options.scope ? [options.scope] : ["user", "project"];
|
|
244
|
+
const entries = scopes.flatMap((scope) => listScope(scope, cwd));
|
|
245
|
+
const byId = /* @__PURE__ */ new Map();
|
|
246
|
+
for (const entry of entries) {
|
|
247
|
+
const list = byId.get(entry.id) ?? [];
|
|
248
|
+
list.push(entry);
|
|
249
|
+
byId.set(entry.id, list);
|
|
250
|
+
}
|
|
251
|
+
for (const group of byId.values()) {
|
|
252
|
+
const winner = [...group].sort((a, b) => scopeRank(a.scope) - scopeRank(b.scope)).at(-1);
|
|
253
|
+
for (const entry of group) {
|
|
254
|
+
entry.effective = entry === winner;
|
|
255
|
+
if (!entry.effective && winner) entry.overriddenBy = winner.scope;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const all = options.all === true ? entries : entries.filter((entry) => entry.effective);
|
|
259
|
+
return all.sort((a, b) => {
|
|
260
|
+
const id = a.id.localeCompare(b.id);
|
|
261
|
+
if (id !== 0) return id;
|
|
262
|
+
return scopeRank(a.scope) - scopeRank(b.scope);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
function findInstalled(id, cwd, scope) {
|
|
266
|
+
const entries = listInstalledExtensions(cwd, { ...scope ? { scope } : {}, all: true }).filter(
|
|
267
|
+
(entry) => entry.id === id
|
|
268
|
+
);
|
|
269
|
+
if (entries.length === 0) return null;
|
|
270
|
+
return [...entries].sort((a, b) => scopeRank(a.scope) - scopeRank(b.scope)).at(-1) ?? null;
|
|
271
|
+
}
|
|
272
|
+
function installExtension(sourcePath, options = {}) {
|
|
273
|
+
const scope = options.scope ?? "user";
|
|
274
|
+
const cwd = options.cwd ?? process.cwd();
|
|
275
|
+
const source = path2.resolve(sourcePath);
|
|
276
|
+
const candidate = loadManifestFromRoot(source);
|
|
277
|
+
if (!candidate.manifest) return { diagnostics: candidate.diagnostics };
|
|
278
|
+
const targetRoot = path2.join(extensionBaseDir(scope, cwd), candidate.manifest.id);
|
|
279
|
+
if (existsSync2(targetRoot)) {
|
|
280
|
+
if (!options.force) {
|
|
281
|
+
return {
|
|
282
|
+
diagnostics: [
|
|
283
|
+
{ type: "error", message: `extension ${candidate.manifest.id} is already installed`, path: targetRoot }
|
|
284
|
+
]
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const parent = path2.dirname(targetRoot);
|
|
289
|
+
const stagingRoot = path2.join(parent, `.${candidate.manifest.id}.install-${process.pid}-${Date.now()}`);
|
|
290
|
+
const backupRoot = path2.join(parent, `.${candidate.manifest.id}.backup-${process.pid}-${Date.now()}`);
|
|
291
|
+
let installedReplacement = false;
|
|
292
|
+
let movedExisting = false;
|
|
293
|
+
const state = readState(scope, cwd);
|
|
294
|
+
try {
|
|
295
|
+
mkdirSync(parent, { recursive: true });
|
|
296
|
+
rmSync(stagingRoot, { recursive: true, force: true });
|
|
297
|
+
rmSync(backupRoot, { recursive: true, force: true });
|
|
298
|
+
cpSync(source, stagingRoot, {
|
|
299
|
+
recursive: true,
|
|
300
|
+
filter: (src) => path2.basename(src) !== "state.json"
|
|
301
|
+
});
|
|
302
|
+
if (existsSync2(targetRoot)) {
|
|
303
|
+
renameSync(targetRoot, backupRoot);
|
|
304
|
+
movedExisting = true;
|
|
305
|
+
}
|
|
306
|
+
renameSync(stagingRoot, targetRoot);
|
|
307
|
+
installedReplacement = true;
|
|
308
|
+
state.installed[candidate.manifest.id] = { installedAt: (/* @__PURE__ */ new Date()).toISOString(), source };
|
|
309
|
+
state.disabled = state.disabled.filter((entry) => entry !== candidate.manifest?.id);
|
|
310
|
+
writeState(scope, state, cwd);
|
|
311
|
+
rmSync(backupRoot, { recursive: true, force: true });
|
|
312
|
+
} catch (error) {
|
|
313
|
+
rmSync(stagingRoot, { recursive: true, force: true });
|
|
314
|
+
if (installedReplacement) rmSync(targetRoot, { recursive: true, force: true });
|
|
315
|
+
if (movedExisting && existsSync2(backupRoot) && !existsSync2(targetRoot)) {
|
|
316
|
+
renameSync(backupRoot, targetRoot);
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
diagnostics: [
|
|
320
|
+
{
|
|
321
|
+
type: "error",
|
|
322
|
+
message: `extension ${candidate.manifest.id} install failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
323
|
+
path: targetRoot
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
const installed = findInstalled(candidate.manifest.id, cwd, scope);
|
|
329
|
+
return {
|
|
330
|
+
...installed ? { extension: installed } : {},
|
|
331
|
+
diagnostics: candidate.diagnostics
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function mutateEnabled(id, enabled, options = {}) {
|
|
335
|
+
const cwd = options.cwd ?? process.cwd();
|
|
336
|
+
const target = findInstalled(id, cwd, options.scope);
|
|
337
|
+
if (!target) {
|
|
338
|
+
return { diagnostics: [{ type: "error", message: `extension ${id} is not installed` }] };
|
|
339
|
+
}
|
|
340
|
+
const state = readState(target.scope, cwd);
|
|
341
|
+
if (enabled) state.disabled = state.disabled.filter((entry) => entry !== id);
|
|
342
|
+
else if (!state.disabled.includes(id)) state.disabled.push(id);
|
|
343
|
+
writeState(target.scope, state, cwd);
|
|
344
|
+
const extension = findInstalled(id, cwd, target.scope) ?? void 0;
|
|
345
|
+
return { ...extension ? { extension } : {}, diagnostics: [] };
|
|
346
|
+
}
|
|
347
|
+
function enableExtension(id, options = {}) {
|
|
348
|
+
return mutateEnabled(id, true, options);
|
|
349
|
+
}
|
|
350
|
+
function disableExtension(id, options = {}) {
|
|
351
|
+
return mutateEnabled(id, false, options);
|
|
352
|
+
}
|
|
353
|
+
function removeExtension(id, options = {}) {
|
|
354
|
+
const cwd = options.cwd ?? process.cwd();
|
|
355
|
+
const target = findInstalled(id, cwd, options.scope);
|
|
356
|
+
if (!target) {
|
|
357
|
+
return { diagnostics: [{ type: "error", message: `extension ${id} is not installed` }] };
|
|
358
|
+
}
|
|
359
|
+
rmSync(target.rootPath, { recursive: true, force: true });
|
|
360
|
+
const state = readState(target.scope, cwd);
|
|
361
|
+
Reflect.deleteProperty(state.installed, id);
|
|
362
|
+
state.disabled = state.disabled.filter((entry) => entry !== id);
|
|
363
|
+
writeState(target.scope, state, cwd);
|
|
364
|
+
return { removed: { id, scope: target.scope, path: target.rootPath }, diagnostics: [] };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// src/domains/extensions/resources.ts
|
|
368
|
+
import { statSync as statSync2 } from "node:fs";
|
|
369
|
+
import path3 from "node:path";
|
|
370
|
+
function extensionResourcePath(rootPath, resourcePath) {
|
|
371
|
+
const root = path3.resolve(rootPath);
|
|
372
|
+
const full = path3.resolve(root, resourcePath);
|
|
373
|
+
const relative = path3.relative(root, full);
|
|
374
|
+
if (relative === "" || !relative.startsWith("..") && !path3.isAbsolute(relative)) return full;
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
function enabledExtensionResourceRoots(kind, cwd = process.cwd()) {
|
|
378
|
+
const roots = [];
|
|
379
|
+
for (const entry of listInstalledExtensions(cwd)) {
|
|
380
|
+
if (!entry.enabled || !entry.effective) continue;
|
|
381
|
+
const rel = entry.resources[kind];
|
|
382
|
+
if (!rel) continue;
|
|
383
|
+
const full = extensionResourcePath(entry.rootPath, rel);
|
|
384
|
+
if (!full) continue;
|
|
385
|
+
try {
|
|
386
|
+
if (!statSync2(full).isDirectory()) continue;
|
|
387
|
+
} catch {
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
roots.push({
|
|
391
|
+
id: entry.id,
|
|
392
|
+
scope: entry.scope,
|
|
393
|
+
path: full,
|
|
394
|
+
source: `extension:${entry.scope}:${entry.id}`
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
return roots;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/domains/extensions/extension.ts
|
|
401
|
+
function createExtensionsBundle(_context) {
|
|
402
|
+
const extension = {
|
|
403
|
+
start() {
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
const contract = {
|
|
408
|
+
list(cwd, options = {}) {
|
|
409
|
+
return listInstalledExtensions(cwd, options);
|
|
410
|
+
},
|
|
411
|
+
discover(root) {
|
|
412
|
+
return discoverExtensionPackages(root);
|
|
413
|
+
},
|
|
414
|
+
install(root, options = {}) {
|
|
415
|
+
return installExtension(root, options);
|
|
416
|
+
},
|
|
417
|
+
enable(id, options = {}) {
|
|
418
|
+
return enableExtension(id, options);
|
|
419
|
+
},
|
|
420
|
+
disable(id, options = {}) {
|
|
421
|
+
return disableExtension(id, options);
|
|
422
|
+
},
|
|
423
|
+
remove(id, options = {}) {
|
|
424
|
+
return removeExtension(id, options);
|
|
425
|
+
},
|
|
426
|
+
resourceRoots(kind, cwd) {
|
|
427
|
+
return enabledExtensionResourceRoots(kind, cwd);
|
|
428
|
+
},
|
|
429
|
+
async reload() {
|
|
430
|
+
return void 0;
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
return { extension, contract };
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// src/domains/extensions/manifest.ts
|
|
437
|
+
var ExtensionsManifest = {
|
|
438
|
+
name: "extensions",
|
|
439
|
+
dependsOn: ["config"]
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// src/domains/extensions/index.ts
|
|
443
|
+
var ExtensionsDomainModule = {
|
|
444
|
+
manifest: ExtensionsManifest,
|
|
445
|
+
createExtension: createExtensionsBundle
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
export {
|
|
449
|
+
discoverExtensionPackages,
|
|
450
|
+
listInstalledExtensions,
|
|
451
|
+
installExtension,
|
|
452
|
+
enableExtension,
|
|
453
|
+
disableExtension,
|
|
454
|
+
removeExtension,
|
|
455
|
+
enabledExtensionResourceRoots,
|
|
456
|
+
ExtensionsDomainModule
|
|
457
|
+
};
|
|
458
|
+
//# sourceMappingURL=chunk-CLJ5HLUD.js.map
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// src/core/bus-events.ts
|
|
2
|
+
var BusChannels = {
|
|
3
|
+
SessionStart: "session.start",
|
|
4
|
+
SessionEnd: "session.end",
|
|
5
|
+
SessionParked: "session.parked",
|
|
6
|
+
SessionResumed: "session.resumed",
|
|
7
|
+
DomainLoaded: "domain.loaded",
|
|
8
|
+
DomainFailed: "domain.failed",
|
|
9
|
+
ConfigHotReload: "config.hotReload",
|
|
10
|
+
ConfigNextTurn: "config.nextTurn",
|
|
11
|
+
ConfigRestartRequired: "config.restartRequired",
|
|
12
|
+
ConfigReloadFailed: "config.reloadFailed",
|
|
13
|
+
PermissionRequested: "permission.requested",
|
|
14
|
+
PermissionResolved: "permission.resolved",
|
|
15
|
+
SafetyClassified: "safety.classified",
|
|
16
|
+
SafetyBlocked: "safety.blocked",
|
|
17
|
+
SafetyAllowed: "safety.allowed",
|
|
18
|
+
LoopBlocked: "safety.loopBlocked",
|
|
19
|
+
ToolBudgetExceeded: "safety.toolBudgetExceeded",
|
|
20
|
+
ProviderHealth: "provider.health",
|
|
21
|
+
RuntimeNotice: "runtime.notice",
|
|
22
|
+
DispatchEnqueued: "dispatch.enqueued",
|
|
23
|
+
DispatchStarted: "dispatch.started",
|
|
24
|
+
DispatchProgress: "dispatch.progress",
|
|
25
|
+
DispatchCompleted: "dispatch.completed",
|
|
26
|
+
DispatchFailed: "dispatch.failed",
|
|
27
|
+
CompactionBegin: "compaction.begin",
|
|
28
|
+
CompactionEnd: "compaction.end",
|
|
29
|
+
MiddlewareHookFailed: "middleware.hookFailed",
|
|
30
|
+
ContextActivity: "context.activity",
|
|
31
|
+
ContextWarning: "context.warning",
|
|
32
|
+
ContextPruned: "context.pruned",
|
|
33
|
+
AgentStatusChanged: "agent.status.changed",
|
|
34
|
+
RunAborted: "run.aborted",
|
|
35
|
+
BudgetAlert: "budget.alert",
|
|
36
|
+
ShutdownRequested: "shutdown.requested",
|
|
37
|
+
ShutdownDrained: "shutdown.drained",
|
|
38
|
+
ShutdownTerminated: "shutdown.terminated",
|
|
39
|
+
ShutdownPersisted: "shutdown.persisted"
|
|
40
|
+
};
|
|
41
|
+
var RUN_ABORT_SOURCES = /* @__PURE__ */ new Set([
|
|
42
|
+
"dispatch_abort",
|
|
43
|
+
"dispatch_drain",
|
|
44
|
+
"stream_cancel",
|
|
45
|
+
"loop_guard"
|
|
46
|
+
]);
|
|
47
|
+
function isRunAbortedPayload(value) {
|
|
48
|
+
if (!value || typeof value !== "object") return false;
|
|
49
|
+
const p = value;
|
|
50
|
+
if (typeof p.source !== "string" || !RUN_ABORT_SOURCES.has(p.source)) return false;
|
|
51
|
+
if (p.runId !== null && typeof p.runId !== "string") return false;
|
|
52
|
+
if (p.startedAt !== null && typeof p.startedAt !== "string") return false;
|
|
53
|
+
if (p.elapsedMs !== null && typeof p.elapsedMs !== "number") return false;
|
|
54
|
+
if (p.reason !== void 0 && typeof p.reason !== "string") return false;
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/core/event-bus.ts
|
|
59
|
+
function reportListenerError(channel, error) {
|
|
60
|
+
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
61
|
+
console.error(`[clio:event-bus] Listener crashed on ${channel}: ${message}`);
|
|
62
|
+
}
|
|
63
|
+
function createSafeEventBus() {
|
|
64
|
+
const registry = /* @__PURE__ */ new Map();
|
|
65
|
+
const deliver = (channel, payload) => {
|
|
66
|
+
const ls = registry.get(channel);
|
|
67
|
+
if (!ls) return;
|
|
68
|
+
for (const listener of [...ls]) {
|
|
69
|
+
try {
|
|
70
|
+
const result = listener(payload);
|
|
71
|
+
if (result && typeof result.then === "function") {
|
|
72
|
+
result.catch((error) => reportListenerError(channel, error));
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
reportListenerError(channel, error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const bus = {
|
|
80
|
+
emit(channel, payload) {
|
|
81
|
+
deliver(channel, payload);
|
|
82
|
+
},
|
|
83
|
+
on(channel, listener) {
|
|
84
|
+
const set = registry.get(channel) ?? /* @__PURE__ */ new Set();
|
|
85
|
+
set.add(listener);
|
|
86
|
+
registry.set(channel, set);
|
|
87
|
+
return () => {
|
|
88
|
+
const current = registry.get(channel);
|
|
89
|
+
if (!current) return;
|
|
90
|
+
current.delete(listener);
|
|
91
|
+
if (current.size === 0) registry.delete(channel);
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
listeners(channel) {
|
|
95
|
+
return [...registry.get(channel) ?? []];
|
|
96
|
+
},
|
|
97
|
+
clear() {
|
|
98
|
+
registry.clear();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
return bus;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/core/shared-bus.ts
|
|
105
|
+
var sharedBus = null;
|
|
106
|
+
function getSharedBus() {
|
|
107
|
+
if (!sharedBus) sharedBus = createSafeEventBus();
|
|
108
|
+
return sharedBus;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
BusChannels,
|
|
113
|
+
isRunAbortedPayload,
|
|
114
|
+
getSharedBus
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=chunk-D5YD55AR.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/core/package-root.ts
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
// src/engine/pi-mono-names.ts
|
|
7
|
+
var PI_MONO_PACKAGES = {
|
|
8
|
+
agentCore: "@earendil-works/pi-agent-core",
|
|
9
|
+
ai: "@earendil-works/pi-ai",
|
|
10
|
+
tui: "@earendil-works/pi-tui"
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// src/core/package-root.ts
|
|
14
|
+
var cached = null;
|
|
15
|
+
var cachedClioVersion = null;
|
|
16
|
+
var cachedPiMonoVersion = null;
|
|
17
|
+
function resolvePackageRoot(metaUrl = import.meta.url) {
|
|
18
|
+
if (cached) return cached;
|
|
19
|
+
const override = process.env.CLIO_CODER_PACKAGE_ROOT?.trim();
|
|
20
|
+
if (override) {
|
|
21
|
+
cached = resolve(override);
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
let dir = resolve(dirname(fileURLToPath(metaUrl)));
|
|
25
|
+
while (true) {
|
|
26
|
+
if (existsSync(join(dir, "package.json"))) {
|
|
27
|
+
cached = dir;
|
|
28
|
+
return dir;
|
|
29
|
+
}
|
|
30
|
+
const parent = dirname(dir);
|
|
31
|
+
if (parent === dir) {
|
|
32
|
+
throw new Error(`Could not find package.json above ${dir}`);
|
|
33
|
+
}
|
|
34
|
+
dir = parent;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function readPackageJson() {
|
|
38
|
+
const root = resolvePackageRoot();
|
|
39
|
+
const raw = readFileSync(join(root, "package.json"), "utf8");
|
|
40
|
+
return JSON.parse(raw);
|
|
41
|
+
}
|
|
42
|
+
function readClioVersion() {
|
|
43
|
+
if (cachedClioVersion) return cachedClioVersion;
|
|
44
|
+
const pkg = readPackageJson();
|
|
45
|
+
cachedClioVersion = pkg.version ?? "0.0.0";
|
|
46
|
+
return cachedClioVersion;
|
|
47
|
+
}
|
|
48
|
+
function readPiMonoVersion() {
|
|
49
|
+
if (cachedPiMonoVersion) return cachedPiMonoVersion;
|
|
50
|
+
const pkg = readPackageJson();
|
|
51
|
+
cachedPiMonoVersion = pkg.dependencies?.[PI_MONO_PACKAGES.agentCore] ?? "unknown";
|
|
52
|
+
return cachedPiMonoVersion;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
PI_MONO_PACKAGES,
|
|
57
|
+
resolvePackageRoot,
|
|
58
|
+
readClioVersion,
|
|
59
|
+
readPiMonoVersion
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=chunk-DXQNI4PC.js.map
|