@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.
@@ -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 and copies the CANT bridge
7
- * extension template into the extensions directory.
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
- * Skips during workspace/dev installs (non-global).
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 file is plain JS (not compiled from src/) so it can run before
12
- * the package is built, matching the @cleocode/cleo postinstall pattern.
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, cpSync } from 'node:fs';
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 if this is a global npm install (not a workspace/dev install).
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
- const pkgRoot = resolve(__dirname, '..');
28
-
29
- // Signal 1: npm_config_global env var (set by npm during global installs)
30
- if (process.env.npm_config_global === 'true') return true;
31
-
32
- // Signal 2: path contains a global node_modules (npm, pnpm, yarn)
33
- if (/[/\\]lib[/\\]node_modules[/\\]/.test(pkgRoot)) return true;
34
-
35
- // Signal 3: npm_config_prefix matches the package path
36
- const prefix = process.env.npm_config_prefix;
37
- if (prefix && pkgRoot.startsWith(prefix)) return true;
38
-
39
- // Signal 4: inside a pnpm workspace — definitely not global
40
- const workspaceMarker = join(pkgRoot, '..', '..', 'pnpm-workspace.yaml');
41
- if (existsSync(workspaceMarker)) return false;
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
- * Inline XDG path resolution (avoids importing from dist/ which may not exist).
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 resolveCleoOsPaths() {
50
- const home = homedir();
51
- const xdgData = process.env.XDG_DATA_HOME ?? join(home, '.local', 'share');
52
- const xdgConfig = process.env.XDG_CONFIG_HOME ?? join(home, '.config');
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
- if (!isGlobalInstall()) {
69
- console.log('CleoOS: skipping postinstall (not global install)');
70
- return;
71
- }
72
-
73
- const paths = resolveCleoOsPaths();
74
-
75
- // Scaffold directories
76
- for (const dir of [paths.data, paths.config, paths.extensions, paths.cant, paths.auth]) {
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
- // Deploy bridge extension from package template
84
- const bridgeTemplate = join(__dirname, '..', 'extensions', 'cleo-cant-bridge.js');
85
- const bridgeTarget = join(paths.extensions, 'cleo-cant-bridge.js');
86
- if (existsSync(bridgeTemplate)) {
87
- cpSync(bridgeTemplate, bridgeTarget, { force: true });
88
- console.log(`CleoOS: deployed bridge extension to ${bridgeTarget}`);
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"}