@cleocode/cleo-os 2026.4.16 → 2026.4.17
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/bin/postinstall.js +187 -73
- package/bin/postinstall.js.map +1 -0
- package/extensions/cleo-cant-bridge.d.ts +85 -0
- package/extensions/cleo-cant-bridge.d.ts.map +1 -0
- package/extensions/cleo-cant-bridge.js +451 -0
- package/extensions/cleo-cant-bridge.js.map +1 -0
- package/extensions/cleo-chatroom.d.ts +83 -0
- package/extensions/cleo-chatroom.d.ts.map +1 -0
- package/extensions/cleo-chatroom.js +344 -0
- package/extensions/cleo-chatroom.js.map +1 -0
- package/package.json +5 -5
package/bin/postinstall.js
CHANGED
|
@@ -1,94 +1,208 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
/**
|
|
3
|
-
* CleoOS postinstall — scaffolds global XDG hub and deploys extensions.
|
|
2
|
+
* CleoOS postinstall — scaffolds the global XDG hub and deploys extensions.
|
|
4
3
|
*
|
|
5
4
|
* Runs automatically after `npm install -g @cleocode/cleo-os`.
|
|
6
|
-
* Creates XDG-compliant directory structure
|
|
7
|
-
* extension
|
|
5
|
+
* Creates an XDG-compliant directory structure, copies the compiled CANT
|
|
6
|
+
* bridge extension to the extensions directory, and optionally invokes
|
|
7
|
+
* `cleo skills install` for any bundled CleoOS skills.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Behaviour:
|
|
10
|
+
* - Skips silently during workspace/dev installs (non-global).
|
|
11
|
+
* - All directory creation is idempotent (no-op if directory exists).
|
|
12
|
+
* - All file copies are idempotent (only copies if target is missing).
|
|
13
|
+
* - Skill install is best-effort; failures are logged but not fatal.
|
|
14
|
+
* - Missing `@mariozechner/pi-coding-agent` is handled gracefully.
|
|
10
15
|
*
|
|
11
|
-
* This
|
|
12
|
-
*
|
|
16
|
+
* This source compiles to `bin/postinstall.js` via a dedicated tsconfig
|
|
17
|
+
* (see `tsconfig.postinstall.json`). The `postinstall` script in
|
|
18
|
+
* `package.json` references the compiled output at `bin/postinstall.js`.
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
13
21
|
*/
|
|
14
|
-
|
|
15
|
-
import { existsSync, mkdirSync,
|
|
22
|
+
import { execFileSync } from 'node:child_process';
|
|
23
|
+
import { cpSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
16
25
|
import { dirname, join, resolve } from 'node:path';
|
|
17
26
|
import { fileURLToPath } from 'node:url';
|
|
18
|
-
import { homedir } from 'node:os';
|
|
19
|
-
|
|
20
27
|
const __filename = fileURLToPath(import.meta.url);
|
|
21
28
|
const __dirname = dirname(__filename);
|
|
22
|
-
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// XDG path resolution (inline copy — avoids importing from dist/ which may
|
|
31
|
+
// not exist when this script runs for the first time)
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
/**
|
|
34
|
+
* Inline XDG path resolution that mirrors `src/xdg.ts`.
|
|
35
|
+
*
|
|
36
|
+
* Uses an inline copy here so the postinstall script can run before
|
|
37
|
+
* the compiled `dist/` tree is available on a fresh install.
|
|
38
|
+
*
|
|
39
|
+
* @returns Resolved CleoOS XDG directory paths.
|
|
40
|
+
*/
|
|
41
|
+
function resolveCleoOsPaths() {
|
|
42
|
+
const home = homedir();
|
|
43
|
+
const xdgData = process.env['XDG_DATA_HOME'] ?? join(home, '.local', 'share');
|
|
44
|
+
const xdgConfig = process.env['XDG_CONFIG_HOME'] ?? join(home, '.config');
|
|
45
|
+
const data = join(xdgData, 'cleo');
|
|
46
|
+
const config = join(xdgConfig, 'cleo');
|
|
47
|
+
return {
|
|
48
|
+
data,
|
|
49
|
+
config,
|
|
50
|
+
agentDir: data,
|
|
51
|
+
extensions: join(data, 'extensions'),
|
|
52
|
+
cant: join(data, 'cant'),
|
|
53
|
+
auth: join(config, 'auth'),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Global install detection
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
23
59
|
/**
|
|
24
|
-
* Detect
|
|
60
|
+
* Detect whether this is a global npm / pnpm install.
|
|
61
|
+
*
|
|
62
|
+
* Uses four heuristics in priority order:
|
|
63
|
+
* 1. `npm_config_global=true` env var (set by npm/pnpm for global installs)
|
|
64
|
+
* 2. Package path contains `lib/node_modules/` (npm global pattern)
|
|
65
|
+
* 3. Package path starts with `npm_config_prefix` (npm prefix-based check)
|
|
66
|
+
* 4. Presence of `pnpm-workspace.yaml` two levels up (workspace = dev)
|
|
67
|
+
*
|
|
68
|
+
* @returns `true` if the install appears to be a global install.
|
|
25
69
|
*/
|
|
26
70
|
function isGlobalInstall() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return false;
|
|
71
|
+
const pkgRoot = resolve(__dirname, '..');
|
|
72
|
+
// Signal 1: npm_config_global env var (set by npm during global installs)
|
|
73
|
+
if (process.env['npm_config_global'] === 'true')
|
|
74
|
+
return true;
|
|
75
|
+
// Signal 2: path contains a global node_modules (npm, pnpm, yarn)
|
|
76
|
+
if (/[/\\]lib[/\\]node_modules[/\\]/.test(pkgRoot))
|
|
77
|
+
return true;
|
|
78
|
+
// Signal 3: npm_config_prefix matches the package path
|
|
79
|
+
const prefix = process.env['npm_config_prefix'];
|
|
80
|
+
if (prefix !== undefined && pkgRoot.startsWith(prefix))
|
|
81
|
+
return true;
|
|
82
|
+
// Signal 4: inside a pnpm workspace — definitely not global
|
|
83
|
+
const workspaceMarker = join(pkgRoot, '..', '..', 'pnpm-workspace.yaml');
|
|
84
|
+
if (existsSync(workspaceMarker))
|
|
85
|
+
return false;
|
|
86
|
+
return false;
|
|
44
87
|
}
|
|
45
|
-
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Directory scaffolding
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
46
91
|
/**
|
|
47
|
-
*
|
|
92
|
+
* Idempotently create a directory if it does not already exist.
|
|
93
|
+
*
|
|
94
|
+
* @param dir - Absolute path to the directory to create.
|
|
48
95
|
*/
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const data = join(xdgData, 'cleo');
|
|
55
|
-
const config = join(xdgConfig, 'cleo');
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
data,
|
|
59
|
-
config,
|
|
60
|
-
agentDir: data,
|
|
61
|
-
extensions: join(data, 'extensions'),
|
|
62
|
-
cant: join(data, 'cant'),
|
|
63
|
-
auth: join(config, 'auth'),
|
|
64
|
-
};
|
|
96
|
+
function ensureDir(dir) {
|
|
97
|
+
if (!existsSync(dir)) {
|
|
98
|
+
mkdirSync(dir, { recursive: true });
|
|
99
|
+
process.stdout.write(`CleoOS: created ${dir}\n`);
|
|
100
|
+
}
|
|
65
101
|
}
|
|
66
|
-
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Extension deployment
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
/**
|
|
106
|
+
* Copy a compiled extension to the XDG extensions directory.
|
|
107
|
+
*
|
|
108
|
+
* Only copies if the target does not already exist (idempotent). The
|
|
109
|
+
* source is the compiled `.js` file in the package's `extensions/` folder.
|
|
110
|
+
*
|
|
111
|
+
* @param extensionName - Filename without the `.js` extension.
|
|
112
|
+
* @param pkgRoot - Absolute path to the installed package root.
|
|
113
|
+
* @param extensionsDir - Absolute path to the XDG extensions directory.
|
|
114
|
+
*/
|
|
115
|
+
function deployExtension(extensionName, pkgRoot, extensionsDir) {
|
|
116
|
+
const src = join(pkgRoot, 'extensions', `${extensionName}.js`);
|
|
117
|
+
const dest = join(extensionsDir, `${extensionName}.js`);
|
|
118
|
+
if (!existsSync(src)) {
|
|
119
|
+
process.stdout.write(`CleoOS: skipping ${extensionName}.js (source not found at ${src})\n`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (existsSync(dest)) {
|
|
123
|
+
// Already deployed — idempotent, skip.
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
cpSync(src, dest, { force: false });
|
|
127
|
+
process.stdout.write(`CleoOS: deployed ${extensionName}.js to ${dest}\n`);
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Default CANT file scaffolding
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Write a default `model-routing.cant` stub to the XDG CANT directory if
|
|
134
|
+
* no `.cant` files are present. This gives the user a starting point for
|
|
135
|
+
* CANT declarations without overwriting any existing work.
|
|
136
|
+
*
|
|
137
|
+
* @param cantDir - Absolute path to the XDG CANT directory.
|
|
138
|
+
*/
|
|
139
|
+
function scaffoldDefaultCant(cantDir) {
|
|
140
|
+
const modelRoutingPath = join(cantDir, 'model-routing.cant');
|
|
141
|
+
if (existsSync(modelRoutingPath))
|
|
142
|
+
return;
|
|
143
|
+
const stub = [
|
|
144
|
+
'# CleoOS default model-routing.cant',
|
|
145
|
+
'# Declare agents, teams, and routing rules here.',
|
|
146
|
+
'# See: https://github.com/kryptobaseddev/cleo/blob/main/docs/cant-dsl.md',
|
|
147
|
+
'',
|
|
148
|
+
].join('\n');
|
|
149
|
+
try {
|
|
150
|
+
writeFileSync(modelRoutingPath, stub, 'utf-8');
|
|
151
|
+
process.stdout.write(`CleoOS: created default ${modelRoutingPath}\n`);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Best-effort: non-fatal.
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Skill installation
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
/**
|
|
161
|
+
* Invoke `cleo skills install` via `execFileSync` to register the CleoOS
|
|
162
|
+
* bundled skills with the project. This is best-effort — if `cleo` is not
|
|
163
|
+
* on PATH or the command fails, we log and continue.
|
|
164
|
+
*
|
|
165
|
+
* Uses `execFileSync` (not `exec`) to prevent shell injection: the command
|
|
166
|
+
* and arguments are passed as separate parameters so no shell is spawned.
|
|
167
|
+
*/
|
|
168
|
+
function installSkills() {
|
|
169
|
+
try {
|
|
170
|
+
execFileSync('cleo', ['skills', 'install'], { stdio: 'inherit' });
|
|
171
|
+
process.stdout.write('CleoOS: skills install complete\n');
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// cleo may not be installed or skills may already be up to date.
|
|
175
|
+
process.stdout.write('CleoOS: skipping skills install (cleo not found or already installed)\n');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
// Main
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
/**
|
|
182
|
+
* Entry point for the CleoOS postinstall script.
|
|
183
|
+
*
|
|
184
|
+
* Orchestrates directory scaffolding, extension deployment, CANT stub
|
|
185
|
+
* creation, and optional skill installation. All operations are idempotent.
|
|
186
|
+
*/
|
|
67
187
|
function main() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!existsSync(dir)) {
|
|
78
|
-
mkdirSync(dir, { recursive: true });
|
|
79
|
-
console.log(`CleoOS: created ${dir}`);
|
|
188
|
+
if (!isGlobalInstall()) {
|
|
189
|
+
process.stdout.write('CleoOS: skipping postinstall (not global install)\n');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const paths = resolveCleoOsPaths();
|
|
193
|
+
const pkgRoot = resolve(__dirname, '..');
|
|
194
|
+
// 1. Scaffold XDG directories
|
|
195
|
+
for (const dir of [paths.data, paths.config, paths.extensions, paths.cant, paths.auth]) {
|
|
196
|
+
ensureDir(dir);
|
|
80
197
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
console.log('CleoOS: postinstall complete');
|
|
198
|
+
// 2. Deploy compiled extensions
|
|
199
|
+
deployExtension('cleo-cant-bridge', pkgRoot, paths.extensions);
|
|
200
|
+
deployExtension('cleo-chatroom', pkgRoot, paths.extensions);
|
|
201
|
+
// 3. Write default CANT stub (only if file does not exist)
|
|
202
|
+
scaffoldDefaultCant(paths.cant);
|
|
203
|
+
// 4. Install CleoOS skills (best-effort)
|
|
204
|
+
installSkills();
|
|
205
|
+
process.stdout.write('CleoOS: postinstall complete\n');
|
|
92
206
|
}
|
|
93
|
-
|
|
94
207
|
main();
|
|
208
|
+
//# sourceMappingURL=postinstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CleoOS CANT bridge — Wave 2 Pi extension.
|
|
3
|
+
*
|
|
4
|
+
* CANONICAL LOCATION: `packages/cleo-os/extensions/cleo-cant-bridge.ts`
|
|
5
|
+
*
|
|
6
|
+
* This file was copied from
|
|
7
|
+
* `packages/cleo/templates/cleoos-hub/pi-extensions/cleo-cant-bridge.ts`
|
|
8
|
+
* (T393). The template path is kept for reference but this file is the
|
|
9
|
+
* authoritative source. A future cleanup wave (post-T381) should remove
|
|
10
|
+
* the template copy once all consumers have migrated.
|
|
11
|
+
*
|
|
12
|
+
* Installed to: $XDG_DATA_HOME/cleo/extensions/cleo-cant-bridge.js
|
|
13
|
+
* Loaded by: Pi via `--extension <path>` injected by CleoOS cli.ts
|
|
14
|
+
*
|
|
15
|
+
* This bridge discovers `.cant` files in the project's `.cleo/cant/`
|
|
16
|
+
* directory at session start, compiles them via `@cleocode/cant`'s
|
|
17
|
+
* `compileBundle()`, and appends the compiled declarations to Pi's
|
|
18
|
+
* system prompt on `before_agent_start`. This gives the LLM awareness
|
|
19
|
+
* of all declared agents, teams, and tools without hand-authored
|
|
20
|
+
* protocol text.
|
|
21
|
+
*
|
|
22
|
+
* Wave 2 scope:
|
|
23
|
+
* - Scans project tier only: `<cwd>/.cleo/cant/` (recursive)
|
|
24
|
+
* - Three-tier resolution (global, user, project) is Wave 5
|
|
25
|
+
* - Prompt strategy: APPEND (per ULTRAPLAN L6, never replace)
|
|
26
|
+
*
|
|
27
|
+
* Wave 8 additions (T420):
|
|
28
|
+
* - validate-on-load mental-model injection
|
|
29
|
+
* - When the spawned agent's CANT definition has a `mentalModel` block,
|
|
30
|
+
* fetches prior mental-model observations via memoryFind and injects
|
|
31
|
+
* them into the Pi system prompt with VALIDATE_ON_LOAD_PREAMBLE.
|
|
32
|
+
* - Exports `VALIDATE_ON_LOAD_PREAMBLE` and `buildMentalModelInjection`
|
|
33
|
+
* for testability (T421).
|
|
34
|
+
*
|
|
35
|
+
* Requirements:
|
|
36
|
+
* - `@cleocode/cant` must be installed (provides `compileBundle`)
|
|
37
|
+
* - Pi coding agent runtime (`@mariozechner/pi-coding-agent`)
|
|
38
|
+
*
|
|
39
|
+
* Guardrails:
|
|
40
|
+
* - Best-effort: if `@cleocode/cant` is not installed or `.cleo/cant`
|
|
41
|
+
* does not exist, the bridge is a no-op. NEVER crash Pi.
|
|
42
|
+
* - NO top-level await; all work happens inside event handlers.
|
|
43
|
+
* - APPEND to system prompt, never replace.
|
|
44
|
+
*
|
|
45
|
+
* @packageDocumentation
|
|
46
|
+
*/
|
|
47
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
48
|
+
/**
|
|
49
|
+
* Preamble text injected into the Pi system prompt when an agent has a
|
|
50
|
+
* `mental_model:` CANT block. The agent MUST re-evaluate each observation
|
|
51
|
+
* against the current project state before acting.
|
|
52
|
+
*
|
|
53
|
+
* Exported so empirical tests (T421) can assert on its presence.
|
|
54
|
+
*/
|
|
55
|
+
export declare const VALIDATE_ON_LOAD_PREAMBLE: string;
|
|
56
|
+
/** Minimal observation shape returned by memoryFind / searchBrainCompact. */
|
|
57
|
+
export interface MentalModelObservation {
|
|
58
|
+
id: string;
|
|
59
|
+
type: string;
|
|
60
|
+
title: string;
|
|
61
|
+
date?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build the validate-on-load mental-model injection string.
|
|
65
|
+
*
|
|
66
|
+
* Pure function — no I/O, safe to call in tests without a real DB.
|
|
67
|
+
*
|
|
68
|
+
* @param agentName - Name of the spawned agent (used in the header line).
|
|
69
|
+
* @param observations - Prior mental-model observations to list.
|
|
70
|
+
* @returns System-prompt block containing the preamble and numbered observations,
|
|
71
|
+
* or an empty string when `observations` is empty.
|
|
72
|
+
*/
|
|
73
|
+
export declare function buildMentalModelInjection(agentName: string, observations: MentalModelObservation[]): string;
|
|
74
|
+
/**
|
|
75
|
+
* Pi extension factory for the CleoOS CANT bridge.
|
|
76
|
+
*
|
|
77
|
+
* Registers event handlers for `session_start` (compile `.cant` files)
|
|
78
|
+
* and `before_agent_start` (append compiled bundle + mental-model injection
|
|
79
|
+
* to system prompt). Also registers a `/cant:bundle-info` command for
|
|
80
|
+
* introspection.
|
|
81
|
+
*
|
|
82
|
+
* @param pi - The Pi extension API instance.
|
|
83
|
+
*/
|
|
84
|
+
export default function (pi: ExtensionAPI): void;
|
|
85
|
+
//# sourceMappingURL=cleo-cant-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleo-cant-bridge.d.ts","sourceRoot":"","sources":["cleo-cant-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,+BAA+B,CAAC;AAMvC;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,QAIiC,CAAC;AAExE,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,sBAAsB,EAAE,GACrC,MAAM,CAmBR;AA+OD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CA6O/C"}
|