@minhpnq1807/contextos 0.5.13 → 0.5.15

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.15
4
+
5
+ - Replaces the misleading `ctx install --agent codex|claude|agy` usage text with separate commands.
6
+ - Adds a clear CLI error when an install agent value contains shell-choice separators such as `|` or `/`.
7
+
8
+ ## 0.5.14
9
+
10
+ - Adds an actual rendered terminal demo GIF generated from `ctx debug` plus a real `codex exec` hook run.
11
+ - Points the README demo section at `docs/demo/contextos-demo.gif`.
12
+
3
13
  ## 0.5.13
4
14
 
5
15
  - Reworks the README for launch: demo-first positioning, fear hook, one-line install, before/after, and quick command table.
package/DEMO.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  Use this to record the README GIF or a short terminal clip.
4
4
 
5
+ The current rendered demo is checked in at:
6
+
7
+ ```text
8
+ docs/demo/contextos-demo.gif
9
+ ```
10
+
11
+ It was generated from an actual terminal transcript using:
12
+
13
+ ```text
14
+ node docs/demo/render-terminal-gif.mjs <terminal-log> docs/demo/contextos-demo.gif
15
+ ```
16
+
5
17
  ## Goal
6
18
 
7
19
  Show one thing clearly:
package/README.md CHANGED
@@ -21,7 +21,7 @@ Published package: [`@minhpnq1807/contextos`](https://www.npmjs.com/package/@min
21
21
 
22
22
  ## Demo
23
23
 
24
- ![ContextOS demo GIF placeholder](docs/contextos-demo-placeholder.svg)
24
+ ![ContextOS actual terminal demo](docs/demo/contextos-demo.gif)
25
25
 
26
26
  Example hook context injected before the agent works:
27
27
 
@@ -440,6 +440,8 @@ This warning comes from a transitive dependency in the local embedding/WASM stac
440
440
  | `ctx skillshare -- <args>` | Forwards args to the installed `skillshare` CLI. | You need native skillshare commands such as `status`, `target list`, `doctor`, `push`, or `pull`. | Preserves skillshare stdout/stderr and exit status. |
441
441
  | `ctx --version` | Prints the installed ContextOS CLI version. | You want to confirm which npm version is being executed. | Prints the version from package metadata. |
442
442
 
443
+ Do not run `ctx install --agent codex|claude|agy` in a shell. The `|` character is a pipe, so the shell will run `ctx install --agent codex`, pipe its output into `claude`, then pipe that into `agy`. Pick one command per agent instead.
444
+
443
445
  ## Runtime Files
444
446
 
445
447
  ContextOS writes shared caches to:
package/bin/ctx.js CHANGED
@@ -42,7 +42,9 @@ Usage:
42
42
  ctx install codex
43
43
  ctx install claude
44
44
  ctx install agy
45
- ctx install --agent codex|claude|agy
45
+ ctx install --agent codex
46
+ ctx install --agent claude
47
+ ctx install --agent agy
46
48
  ctx install --quiet
47
49
  ctx install --inject
48
50
  ctx install --copy
@@ -77,6 +79,17 @@ Usage:
77
79
 
78
80
  function normalizeInstallAgent(agent) {
79
81
  const normalized = String(agent || "").trim().toLowerCase();
82
+ if (/[|/]/.test(normalized)) {
83
+ throw new Error([
84
+ `Invalid agent '${agent}'.`,
85
+ "Install one agent per command:",
86
+ " ctx install --agent codex",
87
+ " ctx install --agent claude",
88
+ " ctx install --agent agy",
89
+ "",
90
+ "Do not run `ctx install --agent codex|claude|agy`: `|` is a shell pipe."
91
+ ].join("\n"));
92
+ }
80
93
  if (normalized === "antigravity") return "agy";
81
94
  return normalized;
82
95
  }
Binary file
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { execFileSync } from "node:child_process";
6
+
7
+ const [, , inputPath, outputPath = "docs/demo/contextos-demo.gif"] = process.argv;
8
+ if (!inputPath) {
9
+ console.error("Usage: node docs/demo/render-terminal-gif.mjs <terminal-log> [output.gif]");
10
+ process.exit(1);
11
+ }
12
+
13
+ const width = 960;
14
+ const height = 540;
15
+ const marginX = 52;
16
+ const marginY = 54;
17
+ const lineHeight = 18;
18
+ const maxLines = 22;
19
+ const maxColumns = 100;
20
+ const frameStep = 5;
21
+
22
+ const raw = fs.readFileSync(inputPath, "utf8");
23
+ const lines = clean(raw)
24
+ .split(/\r?\n/)
25
+ .map((line) => line.trimEnd())
26
+ .filter((line) => line && !line.includes("Script started") && !line.includes("Script done"));
27
+
28
+ const displayLines = wrapLines(lines, maxColumns).slice(0, 110);
29
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "contextos-demo-frames-"));
30
+ const frames = [];
31
+
32
+ for (let count = 1; count <= displayLines.length; count += frameStep) {
33
+ frames.push(writeFrame({ tmpDir, index: frames.length, lines: displayLines.slice(0, count) }));
34
+ }
35
+ frames.push(writeFrame({ tmpDir, index: frames.length, lines: displayLines }));
36
+
37
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
38
+ execFileSync("convert", ["-delay", "12", "-loop", "0", ...frames, outputPath], { stdio: "inherit" });
39
+ console.log(`Wrote ${outputPath}`);
40
+
41
+ function writeFrame({ tmpDir, index, lines }) {
42
+ const visible = lines.slice(-maxLines);
43
+ const svg = [
44
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`,
45
+ `<rect width="${width}" height="${height}" fill="#0f1419"/>`,
46
+ `<rect x="24" y="24" width="${width - 48}" height="${height - 48}" rx="16" fill="#151b22" stroke="#34404d"/>`,
47
+ `<circle cx="56" cy="50" r="6" fill="#ff6b6b"/><circle cx="78" cy="50" r="6" fill="#ffd166"/><circle cx="100" cy="50" r="6" fill="#70d88b"/>`,
48
+ `<text x="124" y="57" fill="#9aa6b2" font-family="DejaVu Sans Mono, Consolas, monospace" font-size="15">ContextOS actual terminal demo</text>`,
49
+ `<text x="${marginX}" y="${marginY + 30}" fill="#d8dee9" font-family="DejaVu Sans Mono, Consolas, monospace" font-size="15">`
50
+ ];
51
+ visible.forEach((line, offset) => {
52
+ const y = offset === 0 ? 0 : lineHeight;
53
+ svg.push(`<tspan x="${marginX}" dy="${y}" fill="${colorForLine(line)}">${escapeXml(line)}</tspan>`);
54
+ });
55
+ svg.push("</text></svg>");
56
+ const filePath = path.join(tmpDir, `frame-${String(index).padStart(4, "0")}.svg`);
57
+ fs.writeFileSync(filePath, svg.join(""));
58
+ return filePath;
59
+ }
60
+
61
+ function clean(value) {
62
+ return String(value)
63
+ .replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "")
64
+ .replace(/\r/g, "\n")
65
+ .replace(/\n+/g, "\n");
66
+ }
67
+
68
+ function wrapLines(sourceLines, widthLimit) {
69
+ const wrapped = [];
70
+ for (const line of sourceLines) {
71
+ if (line.length <= widthLimit) {
72
+ wrapped.push(line);
73
+ continue;
74
+ }
75
+ for (let index = 0; index < line.length; index += widthLimit) {
76
+ wrapped.push(`${index === 0 ? "" : " "}${line.slice(index, index + widthLimit)}`);
77
+ }
78
+ }
79
+ return wrapped;
80
+ }
81
+
82
+ function colorForLine(line) {
83
+ if (line.startsWith("$ ")) return "#8bd5ff";
84
+ if (/^(ContextOS debug|ContextOS report|Final additionalContext|Suggested files|Suggested workflows)/.test(line)) return "#ffd166";
85
+ if (/^(hook:|mcp:)/.test(line)) return "#9ad97f";
86
+ if (/^(codex|user|OpenAI Codex)/.test(line)) return "#c792ea";
87
+ if (/^#|^[-—]+$/.test(line)) return "#8a96a3";
88
+ return "#d8dee9";
89
+ }
90
+
91
+ function escapeXml(value) {
92
+ return String(value)
93
+ .replace(/&/g, "&amp;")
94
+ .replace(/</g, "&lt;")
95
+ .replace(/>/g, "&gt;")
96
+ .replace(/"/g, "&quot;");
97
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhpnq1807/contextos",
3
- "version": "0.5.13",
3
+ "version": "0.5.15",
4
4
  "description": "Task-aware AGENTS.md context injection and compliance reporting for Codex, Claude Code, and Antigravity.",
5
5
  "type": "module",
6
6
  "bin": {