@kal-elsam/kairo-runtime 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -12,6 +12,10 @@ The npm package (`@kal-elsam/kairo-runtime`) is how Kairo Runtime is distributed
12
12
  product identity is the local control plane: setup, status, sync, doctor (with `update`
13
13
  as a technical alias).
14
14
 
15
+ `@kal-elsam/harness` remains available as a **compatibility bridge** that delegates to
16
+ Kairo Runtime and prints a migration warning. Prefer `@kal-elsam/kairo-runtime` and the
17
+ `kairo` CLI for new installs. See [`packages/harness-bridge/README.md`](packages/harness-bridge/README.md).
18
+
15
19
  Terminal UX aims for Pi-like clarity (clear modes, non-interactive flags, extensible
16
20
  commands) without depending on Pi as a runtime or adding a Pi adapter.
17
21
 
@@ -649,7 +653,23 @@ Install the harness in enterprise mode because this project will have AI, API, D
649
653
 
650
654
  ## Publishing
651
655
 
652
- Published on npm as `@kal-elsam/kairo-runtime`. Releases use **npm Trusted Publishing/OIDC** from GitHub Actions — no `NPM_TOKEN`.
656
+ Published on npm as `@kal-elsam/kairo-runtime`. Releases use **npm Trusted Publishing/OIDC**
657
+ from GitHub Actions — no `NPM_TOKEN`.
658
+
659
+ `@kal-elsam/harness` is published separately as a compatibility bridge from
660
+ `packages/harness-bridge/` (see bridge README).
661
+
662
+ ### Git tags (package-aware)
663
+
664
+ | Tag pattern | Package | Publish root |
665
+ |---|---|---|
666
+ | `kairo-runtime-v*` | `@kal-elsam/kairo-runtime` | repo root |
667
+ | `harness-bridge-v*` | `@kal-elsam/harness` | `packages/harness-bridge/` |
668
+ | `v*` | legacy / historical root releases | repo root |
669
+
670
+ Kairo Runtime releases should use `kairo-runtime-vX.Y.Z` going forward. The first
671
+ bootstrap used `v0.1.0`; later releases use package-aware tags such as
672
+ `kairo-runtime-v0.1.1`.
653
673
 
654
674
  Before tagging a new version:
655
675
 
@@ -684,37 +704,68 @@ to end:
684
704
  rollback apply (with safety backup), `uninstall`.
685
705
  - **workspace:** `install --scope=workspace`, `doctor`, `update --dry-run`.
686
706
 
687
- Release flow:
707
+ Release flow (Kairo Runtime):
688
708
 
689
709
  ```bash
690
710
  # bump version in package.json and package-lock.json
691
711
  git add .
692
- git commit -m "chore: release 0.5.0"
712
+ git commit -m "chore: release kairo-runtime 0.1.1"
693
713
  npm run release:check
694
- git tag v0.5.0
714
+ git tag kairo-runtime-v0.1.1
695
715
  git push origin main
696
- git push origin v0.5.0
716
+ git push origin kairo-runtime-v0.1.1
697
717
  ```
698
718
 
719
+ Bridge release flow:
720
+
721
+ ```bash
722
+ # bump packages/harness-bridge/package.json (+ lockfile)
723
+ git add .
724
+ git commit -m "chore: release harness bridge 0.30.0"
725
+ npm run release:check
726
+ git tag harness-bridge-v0.30.0
727
+ git push origin main
728
+ git push origin harness-bridge-v0.30.0
729
+ ```
730
+
731
+ Legacy `v*` tags still publish from the repo root for historical continuity.
732
+
699
733
  After npm publishes the tag, verify published provenance against git and the registry:
700
734
 
701
735
  ```bash
702
736
  git fetch --tags origin
703
737
  git fetch origin main
704
- npm run release:published -- --version 0.1.0
705
- npm run smoke:registry -- --version 0.1.0
706
- npm run smoke:installer -- --version 0.1.0
738
+ npm run release:published -- --version 0.1.1 --tag kairo-runtime-v0.1.1
739
+ npm run smoke:registry -- --version 0.1.1
740
+ npm run smoke:installer -- --version 0.1.1
741
+ npm run smoke:bridge
742
+ ```
743
+
744
+ `release:published` checks npm `version`, npm `gitHead`, the release git tag on
745
+ `origin`, and `origin/main`. Override the package and tag when needed:
746
+
747
+ ```bash
748
+ npm run release:published -- \
749
+ --package @kal-elsam/kairo-runtime \
750
+ --tag kairo-runtime-v0.1.1 \
751
+ --version 0.1.1
752
+
753
+ npm run release:published -- \
754
+ --package @kal-elsam/harness \
755
+ --tag harness-bridge-v0.30.0 \
756
+ --version 0.30.0
707
757
  ```
708
758
 
709
- `release:published` checks npm `version`, npm `gitHead`, local tag `v*`, remote tag on `origin`, and `origin/main`. Override the package with `--package @kal-elsam/kairo-runtime` when needed.
759
+ Without `--tag`, provenance checks fall back to `v${version}` (legacy tags).
710
760
 
711
761
  `smoke:registry` installs `@kal-elsam/kairo-runtime` from the npm registry (not the local tarball) into a throwaway workspace with a fake `HARNESS_HOME` and npm cache, then runs the recommended flow via `kairo`: `setup --dry-run`, `setup --yes`, `status`, drift simulation, `sync`, `status --json` (expects `overall=ok`), and `uninstall`. Use `latest` by default, pin with `--version x.y.z`, or override with `--package`.
712
762
 
713
763
  `smoke:installer` validates the public one-liner path: `curl .../install.sh | sh` against GitHub `raw` and the npm registry with isolated `HARNESS_HOME`. Preview must not write `~/.harness`; `--yes --agents all` must reach `kairo status --json` with `overall=ok`, then `kairo uninstall` must remove managed sections. Pin with `--version x.y.z` after publish.
714
764
 
715
- Suggested first publish tag: `kairo-runtime-v0.1.0` (or `v0.30.0` if you prefer repo version continuity).
765
+ Suggested first Kairo Runtime tag after bootstrap: `kairo-runtime-v0.1.1`.
716
766
 
717
- The `publish.yml` workflow runs on `v*` tags and publishes to npm using the `npm-publish` environment.
767
+ The `publish.yml` workflow runs on `v*`, `kairo-runtime-v*`, and `harness-bridge-v*`
768
+ tags and publishes to npm using the `npm-publish` environment.
718
769
  It runs `npm run release:check` on `HEAD` immediately before `npm publish`.
719
770
 
720
771
  See the full policy in `SECURITY.md`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kal-elsam/kairo-runtime",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Kairo Runtime — local agent operating system for Codex, Cursor, Claude, Gemini, Copilot, Engram, and Graphify.",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/Kal-elSam/harness#readme",
@@ -35,6 +35,7 @@
35
35
  "ux:smoke": "bash scripts/ux-smoke-test.sh",
36
36
  "smoke:registry": "bash scripts/registry-smoke-test.sh",
37
37
  "smoke:installer": "bash scripts/installer-smoke-test.sh",
38
+ "smoke:bridge": "bash scripts/bridge-smoke-test.sh",
38
39
  "release:check": "node scripts/check-release-commit.mjs",
39
40
  "release:published": "node scripts/check-published-release.mjs"
40
41
  },
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
5
+ BRIDGE_DIR="$ROOT/packages/harness-bridge"
6
+ WORKDIR="$(mktemp -d)"
7
+ FAKE_HOME="$(mktemp -d)"
8
+ NPM_CACHE="$(mktemp -d)"
9
+
10
+ cleanup() {
11
+ rm -rf "$WORKDIR" "$FAKE_HOME" "$NPM_CACHE"
12
+ }
13
+ trap cleanup EXIT
14
+
15
+ export HARNESS_HOME="$FAKE_HOME"
16
+ export npm_config_cache="$NPM_CACHE"
17
+
18
+ mkdir -p \
19
+ "$FAKE_HOME/.cursor" \
20
+ "$FAKE_HOME/.codex" \
21
+ "$FAKE_HOME/.config/opencode" \
22
+ "$FAKE_HOME/.claude"
23
+
24
+ echo "Packing @kal-elsam/kairo-runtime from $ROOT"
25
+ RUNTIME_TGZ="$(cd "$ROOT" && npm pack --silent --pack-destination "$WORKDIR")"
26
+ RUNTIME_TGZ_PATH="$WORKDIR/$RUNTIME_TGZ"
27
+
28
+ echo "Packing @kal-elsam/harness bridge"
29
+ BRIDGE_TGZ="$(cd "$BRIDGE_DIR" && npm pack --silent --pack-destination "$WORKDIR")"
30
+ BRIDGE_TGZ_PATH="$WORKDIR/$BRIDGE_TGZ"
31
+
32
+ INSTALL_DIR="$WORKDIR/project"
33
+ mkdir -p "$INSTALL_DIR"
34
+ (
35
+ cd "$INSTALL_DIR"
36
+ npm init -y >/dev/null
37
+ npm install "$RUNTIME_TGZ_PATH" "$BRIDGE_TGZ_PATH" --ignore-scripts
38
+ )
39
+
40
+ HARNESS_BIN="$INSTALL_DIR/node_modules/@kal-elsam/harness/bin/harness.js"
41
+
42
+ echo
43
+ echo "== harness --version (warning on stderr, version on stdout) =="
44
+ VERSION_OUTPUT="$(node "$HARNESS_BIN" --version 2>"$WORKDIR/version.stderr" || true)"
45
+ VERSION_STDERR="$(cat "$WORKDIR/version.stderr")"
46
+
47
+ if ! grep -q "@kal-elsam/harness has moved to @kal-elsam/kairo-runtime" <<<"$VERSION_STDERR"; then
48
+ echo "Expected migration warning on stderr" >&2
49
+ echo "stderr: $VERSION_STDERR" >&2
50
+ exit 1
51
+ fi
52
+
53
+ if ! grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' <<<"$VERSION_OUTPUT"; then
54
+ echo "Expected semver on stdout, got: $VERSION_OUTPUT" >&2
55
+ exit 1
56
+ fi
57
+
58
+ if grep -q "@kal-elsam/harness has moved" <<<"$VERSION_OUTPUT"; then
59
+ echo "Migration warning must not appear on stdout" >&2
60
+ exit 1
61
+ fi
62
+
63
+ echo "stdout version: $VERSION_OUTPUT"
64
+
65
+ echo
66
+ echo "== harness status --json (JSON on stdout only) =="
67
+ set +e
68
+ STATUS_OUTPUT="$(node "$HARNESS_BIN" status --json 2>"$WORKDIR/status.stderr")"
69
+ STATUS_EXIT=$?
70
+ set -e
71
+ STATUS_STDERR="$(cat "$WORKDIR/status.stderr")"
72
+
73
+ if [ "$STATUS_EXIT" -ne 0 ] && [ "$STATUS_EXIT" -ne 1 ]; then
74
+ echo "Unexpected exit code from harness status --json: $STATUS_EXIT" >&2
75
+ exit 1
76
+ fi
77
+
78
+ if ! grep -q "@kal-elsam/harness has moved to @kal-elsam/kairo-runtime" <<<"$STATUS_STDERR"; then
79
+ echo "Expected migration warning on stderr for status --json" >&2
80
+ exit 1
81
+ fi
82
+
83
+ node -e "JSON.parse(process.argv[1])" "$STATUS_OUTPUT"
84
+
85
+ if grep -q "@kal-elsam/harness has moved" <<<"$STATUS_OUTPUT"; then
86
+ echo "Migration warning must not appear in JSON stdout" >&2
87
+ exit 1
88
+ fi
89
+
90
+ echo
91
+ echo "Bridge smoke test passed."
@@ -15,10 +15,19 @@ async function defaultFetchJson(url) {
15
15
  return response.json();
16
16
  }
17
17
 
18
+ export function resolveReleaseTag({ version, tag = null }) {
19
+ if (tag) {
20
+ return tag;
21
+ }
22
+
23
+ return `v${version}`;
24
+ }
25
+
18
26
  export function parsePublishedReleaseArgs(argv) {
19
27
  const args = [...argv];
20
28
  let version = null;
21
29
  let packageName = "@kal-elsam/kairo-runtime";
30
+ let tag = null;
22
31
 
23
32
  for (let index = 2; index < args.length; index += 1) {
24
33
  const arg = args[index];
@@ -43,6 +52,16 @@ export function parsePublishedReleaseArgs(argv) {
43
52
  continue;
44
53
  }
45
54
 
55
+ if (arg === "--tag") {
56
+ tag = args[++index];
57
+ continue;
58
+ }
59
+
60
+ if (arg.startsWith("--tag=")) {
61
+ tag = arg.slice("--tag=".length);
62
+ continue;
63
+ }
64
+
46
65
  throw new Error(`Unknown option "${arg}".`);
47
66
  }
48
67
 
@@ -50,16 +69,17 @@ export function parsePublishedReleaseArgs(argv) {
50
69
  throw new Error("Missing required --version <x.y.z>.");
51
70
  }
52
71
 
53
- return { version, packageName };
72
+ return { version, packageName, tag };
54
73
  }
55
74
 
56
75
  export async function verifyPublishedRelease({
57
76
  version,
58
77
  packageName = "@kal-elsam/kairo-runtime",
78
+ tag = null,
59
79
  runGit = defaultRunGit,
60
80
  fetchJson = defaultFetchJson
61
81
  }) {
62
- const tag = `v${version}`;
82
+ const releaseTag = resolveReleaseTag({ version, tag });
63
83
  const encodedPackage = encodeURIComponent(packageName);
64
84
  const meta = await fetchJson(`https://registry.npmjs.org/${encodedPackage}/${version}`);
65
85
 
@@ -72,10 +92,12 @@ export async function verifyPublishedRelease({
72
92
  }
73
93
 
74
94
  const gitHead = meta.gitHead.trim();
75
- const tagSha = runGit(`git rev-parse ${tag}^{commit}`).trim();
95
+ const tagSha = runGit(`git rev-parse ${releaseTag}^{commit}`).trim();
76
96
 
77
97
  if (tagSha !== gitHead) {
78
- throw new Error(`Local tag ${tag} (${tagSha}) does not match npm gitHead (${gitHead})`);
98
+ throw new Error(
99
+ `Local tag ${releaseTag} (${tagSha}) does not match npm gitHead (${gitHead})`
100
+ );
79
101
  }
80
102
 
81
103
  const mainSha = runGit("git rev-parse origin/main").trim();
@@ -90,17 +112,19 @@ export async function verifyPublishedRelease({
90
112
  }
91
113
  }
92
114
 
93
- const remoteTagLine = runGit(`git ls-remote --tags origin refs/tags/${tag}`).trim();
115
+ const remoteTagLine = runGit(`git ls-remote --tags origin refs/tags/${releaseTag}`).trim();
94
116
 
95
117
  if (!remoteTagLine.startsWith(gitHead)) {
96
- throw new Error(`Remote tag ${tag} on origin does not point to npm gitHead (${gitHead})`);
118
+ throw new Error(
119
+ `Remote tag ${releaseTag} on origin does not point to npm gitHead (${gitHead})`
120
+ );
97
121
  }
98
122
 
99
123
  return {
100
124
  version,
101
125
  packageName,
102
126
  gitHead,
103
- tag,
127
+ tag: releaseTag,
104
128
  mainSha,
105
129
  tagSha,
106
130
  mainAhead: mainSha !== gitHead
@@ -114,8 +138,8 @@ function isMainModule() {
114
138
  }
115
139
 
116
140
  if (isMainModule()) {
117
- const { version, packageName } = parsePublishedReleaseArgs(process.argv);
118
- const result = await verifyPublishedRelease({ version, packageName });
141
+ const { version, packageName, tag } = parsePublishedReleaseArgs(process.argv);
142
+ const result = await verifyPublishedRelease({ version, packageName, tag });
119
143
 
120
144
  console.log("Published release provenance OK");
121
145
  console.log(`Package: ${result.packageName}@${result.version}`);