ai-runtime-kit 0.5.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/LICENSE +21 -0
- package/README.md +307 -0
- package/bin/cli.js +52 -0
- package/package.json +40 -0
- package/runtime/BOOTSTRAP.md +230 -0
- package/runtime/CAPABILITIES.md +166 -0
- package/runtime/INDEX.md +397 -0
- package/runtime/PRIORITIES.md +84 -0
- package/runtime/RUNTIME_HEALTH.md +87 -0
- package/runtime/RUNTIME_MODE.md +109 -0
- package/runtime/RUNTIME_TRANSITIONS.md +141 -0
- package/runtime/RUNTIME_VERSION.md +17 -0
- package/runtime/SAFETY.md +156 -0
- package/runtime/adr/0000-template.md +55 -0
- package/runtime/agents/executor.md +19 -0
- package/runtime/agents/verifier.md +83 -0
- package/runtime/hooks/README.md +163 -0
- package/runtime/hooks/_template/HOOK.md +87 -0
- package/runtime/hooks/pre-executor/runtime-scoped-preflight/HOOK.md +189 -0
- package/runtime/memory/architecture/principles.md +107 -0
- package/runtime/memory/engineering/principles.md +102 -0
- package/runtime/memory/runtime/context-loading.md +107 -0
- package/runtime/plans/_template.md +81 -0
- package/runtime/prds/_template.md +73 -0
- package/runtime/reviews/_template.md +37 -0
- package/runtime/rules/README.md +101 -0
- package/runtime/rules/_template/RULE.md +75 -0
- package/runtime/skills/README.md +96 -0
- package/runtime/skills/_template/SKILL.md +61 -0
- package/runtime/specs/_template/spec.md +50 -0
- package/runtime/specs/_template-bug-fix/spec.md +120 -0
- package/runtime/tasks/TASK_STATUS.md +58 -0
- package/runtime/tasks/_template.md +73 -0
- package/runtime/workflows/branching.md +128 -0
- package/runtime/workflows/bug-fix.md +169 -0
- package/runtime/workflows/feature-development.md +238 -0
- package/src/diff.js +81 -0
- package/src/git.js +38 -0
- package/src/init.js +166 -0
- package/src/prompt.js +17 -0
- package/src/snapshot.js +84 -0
- package/src/templates.js +96 -0
- package/src/upgrade.js +179 -0
- package/src/version.js +42 -0
package/src/templates.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Project-side templates instantiated by `init` into .ai/project/.
|
|
4
|
+
|
|
5
|
+
function projectStateMd() {
|
|
6
|
+
return `# Project Runtime State
|
|
7
|
+
|
|
8
|
+
This file holds the current instance values for runtime metadata
|
|
9
|
+
whose definitions live in \`.ai/runtime/\`. Reading this file plus
|
|
10
|
+
the corresponding runtime file is equivalent to reading the
|
|
11
|
+
single-file version.
|
|
12
|
+
|
|
13
|
+
## Mode
|
|
14
|
+
|
|
15
|
+
FEATURE_DEVELOPMENT
|
|
16
|
+
|
|
17
|
+
### Runtime Intent
|
|
18
|
+
|
|
19
|
+
Current focus:
|
|
20
|
+
|
|
21
|
+
- (fill me in: what this project is currently optimizing for)
|
|
22
|
+
|
|
23
|
+
## Health
|
|
24
|
+
|
|
25
|
+
GREEN
|
|
26
|
+
|
|
27
|
+
### Health Drivers
|
|
28
|
+
|
|
29
|
+
Reasons:
|
|
30
|
+
|
|
31
|
+
- (fill me in: what is currently true that justifies GREEN)
|
|
32
|
+
|
|
33
|
+
### Recovery Goals
|
|
34
|
+
|
|
35
|
+
(fill me in: what would degrade health, and how to recover)
|
|
36
|
+
|
|
37
|
+
## Priorities
|
|
38
|
+
|
|
39
|
+
Current runtime health:
|
|
40
|
+
|
|
41
|
+
- GREEN
|
|
42
|
+
|
|
43
|
+
Current priority focus:
|
|
44
|
+
|
|
45
|
+
- (fill me in)
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function projectTaskStatusMd() {
|
|
50
|
+
return `# Task Status — Active Sets
|
|
51
|
+
|
|
52
|
+
Active task lifecycle state for this project. Lifecycle schema is
|
|
53
|
+
defined in \`.ai/runtime/tasks/TASK_STATUS.md\`.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Active Task Sets
|
|
58
|
+
|
|
59
|
+
(empty — populate as task sets are opened)
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function agentEntryClaudeMd() {
|
|
64
|
+
return `# CLAUDE.md
|
|
65
|
+
|
|
66
|
+
This repository uses an \`.ai/\` runtime managed by
|
|
67
|
+
[ai-runtime-kit](https://github.com/kaelen2026/ai-runtime-kit).
|
|
68
|
+
|
|
69
|
+
## Agent entry point
|
|
70
|
+
|
|
71
|
+
Before doing engineering work in this repo, read the runtime bootstrap:
|
|
72
|
+
|
|
73
|
+
\`\`\`
|
|
74
|
+
.ai/runtime/BOOTSTRAP.md
|
|
75
|
+
\`\`\`
|
|
76
|
+
|
|
77
|
+
That file defines the read sequence (INDEX → CAPABILITIES → RUNTIME_MODE
|
|
78
|
+
→ SAFETY → PRIORITIES → workflows). Project-instance state — current
|
|
79
|
+
mode, health, priorities — lives at \`.ai/project/STATE.md\`.
|
|
80
|
+
|
|
81
|
+
## Loading order
|
|
82
|
+
|
|
83
|
+
1. This file (\`CLAUDE.md\`), auto-loaded by Claude Code from cwd.
|
|
84
|
+
2. \`.ai/runtime/BOOTSTRAP.md\` — explicitly read on task start.
|
|
85
|
+
3. \`.ai/project/STATE.md\` — current instance state.
|
|
86
|
+
4. Task-relevant runtime and project files per BOOTSTRAP's read sequence.
|
|
87
|
+
|
|
88
|
+
## Editing this file
|
|
89
|
+
|
|
90
|
+
This file is **project-owned**. \`ai-runtime-kit upgrade\` never
|
|
91
|
+
touches it. Add repo-specific notes (stack, conventions, gotchas)
|
|
92
|
+
below — they will be preserved across kit upgrades.
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = { projectStateMd, projectTaskStatusMd, agentEntryClaudeMd };
|
package/src/upgrade.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { parseArgs } = require('node:util');
|
|
6
|
+
|
|
7
|
+
const { copyKitRuntimeTo, removeDir } = require('./snapshot');
|
|
8
|
+
const {
|
|
9
|
+
KIT_VERSION,
|
|
10
|
+
readProjectKitVersion,
|
|
11
|
+
writeProjectKitVersion,
|
|
12
|
+
compareSemver,
|
|
13
|
+
} = require('./version');
|
|
14
|
+
const { computeRuntimeDiff, printDiffSummary, printPerFileDiff } = require('./diff');
|
|
15
|
+
const { gitStatusPorcelain, isGitRepo } = require('./git');
|
|
16
|
+
const { confirm } = require('./prompt');
|
|
17
|
+
|
|
18
|
+
async function run(argv) {
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = parseArgs({
|
|
22
|
+
args: argv,
|
|
23
|
+
options: {
|
|
24
|
+
cwd: { type: 'string' },
|
|
25
|
+
yes: { type: 'boolean', short: 'y', default: false },
|
|
26
|
+
'no-diff': { type: 'boolean', default: false },
|
|
27
|
+
pager: { type: 'string' },
|
|
28
|
+
'allow-dirty': { type: 'boolean', default: false },
|
|
29
|
+
'allow-downgrade': { type: 'boolean', default: false },
|
|
30
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
31
|
+
},
|
|
32
|
+
strict: true,
|
|
33
|
+
allowPositionals: false,
|
|
34
|
+
});
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.error(`upgrade: ${e.message}`);
|
|
37
|
+
console.error('Try: ai-runtime-kit upgrade --help');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (parsed.values.help) {
|
|
42
|
+
printHelp();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const cwd = path.resolve(parsed.values.cwd ?? process.cwd());
|
|
47
|
+
const runtimeDir = path.join(cwd, '.ai', 'runtime');
|
|
48
|
+
|
|
49
|
+
if (!fs.existsSync(runtimeDir)) {
|
|
50
|
+
console.error(`upgrade: ${runtimeDir} does not exist.`);
|
|
51
|
+
console.error('Run `ai-runtime-kit init` first.');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const installedVersion = readProjectKitVersion(cwd);
|
|
56
|
+
if (!installedVersion) {
|
|
57
|
+
console.error('upgrade: .ai/runtime/KIT_VERSION not found.');
|
|
58
|
+
console.error('Either re-run init in --migrate mode or write KIT_VERSION manually.');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const cmp = compareSemver(KIT_VERSION, installedVersion);
|
|
63
|
+
if (cmp === 0) {
|
|
64
|
+
console.log(`Already on kit ${KIT_VERSION}. No upgrade needed.`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (cmp < 0) {
|
|
68
|
+
if (!parsed.values['allow-downgrade']) {
|
|
69
|
+
console.error(`upgrade: refusing downgrade — installed ${installedVersion} > kit ${KIT_VERSION}.`);
|
|
70
|
+
console.error('Pass --allow-downgrade to override.');
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
console.warn(`Warning: downgrading from ${installedVersion} to ${KIT_VERSION}.`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Git dirty check
|
|
77
|
+
if (!parsed.values['allow-dirty']) {
|
|
78
|
+
if (isGitRepo(cwd)) {
|
|
79
|
+
const status = gitStatusPorcelain('.ai/runtime', cwd);
|
|
80
|
+
if (!status.ok) {
|
|
81
|
+
console.error(`upgrade: git status check failed: ${status.error}`);
|
|
82
|
+
console.error('Pass --allow-dirty to skip the git check.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
if (status.lines.length) {
|
|
86
|
+
console.error('upgrade: .ai/runtime/ has uncommitted changes:');
|
|
87
|
+
for (const line of status.lines) console.error(` ${line}`);
|
|
88
|
+
console.error('Commit or stash them, or pass --allow-dirty.');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
console.warn(`upgrade: ${cwd} is not a git repository — skipping dirty check.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Compute and print diff
|
|
97
|
+
const diff = computeRuntimeDiff(runtimeDir);
|
|
98
|
+
console.log(`Upgrading kit ${installedVersion} → ${KIT_VERSION}`);
|
|
99
|
+
console.log('');
|
|
100
|
+
printDiffSummary(diff);
|
|
101
|
+
|
|
102
|
+
if (
|
|
103
|
+
diff.added.length === 0 &&
|
|
104
|
+
diff.removed.length === 0 &&
|
|
105
|
+
diff.replaced.length === 0
|
|
106
|
+
) {
|
|
107
|
+
console.log('No file-level changes. Updating KIT_VERSION only.');
|
|
108
|
+
writeProjectKitVersion(cwd, KIT_VERSION);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!parsed.values['no-diff']) {
|
|
113
|
+
const pagerCmd = parsed.values.pager ?? process.env.AI_RUNTIME_KIT_PAGER;
|
|
114
|
+
if (pagerCmd && process.stdout.isTTY) {
|
|
115
|
+
const { spawn } = require('node:child_process');
|
|
116
|
+
const [bin, ...pagerArgs] = pagerCmd.split(/\s+/);
|
|
117
|
+
const child = spawn(bin, pagerArgs, {
|
|
118
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
119
|
+
});
|
|
120
|
+
printPerFileDiff(diff, runtimeDir, child.stdin);
|
|
121
|
+
child.stdin.end();
|
|
122
|
+
await new Promise((resolve, reject) => {
|
|
123
|
+
child.on('close', resolve);
|
|
124
|
+
child.on('error', reject);
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
printPerFileDiff(diff, runtimeDir);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Confirm
|
|
132
|
+
let ok;
|
|
133
|
+
if (parsed.values.yes) {
|
|
134
|
+
ok = true;
|
|
135
|
+
console.log('--yes passed; proceeding without prompt.');
|
|
136
|
+
} else {
|
|
137
|
+
ok = await confirm('Apply this upgrade?', { defaultYes: false });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!ok) {
|
|
141
|
+
console.log('Aborted. No changes made.');
|
|
142
|
+
process.exit(2);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
removeDir(runtimeDir);
|
|
146
|
+
copyKitRuntimeTo(runtimeDir);
|
|
147
|
+
writeProjectKitVersion(cwd, KIT_VERSION);
|
|
148
|
+
console.log(`Done. Kit upgraded to ${KIT_VERSION}.`);
|
|
149
|
+
console.log('Changes are unstaged; review with `git diff .ai/runtime/` and commit when ready.');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function printHelp() {
|
|
153
|
+
console.log(`ai-runtime-kit upgrade [options]
|
|
154
|
+
|
|
155
|
+
Replace .ai/runtime/ with the kit's current canonical snapshot.
|
|
156
|
+
|
|
157
|
+
Process:
|
|
158
|
+
1. Verify .ai/runtime/KIT_VERSION exists.
|
|
159
|
+
2. Verify .ai/runtime/ has no uncommitted git changes.
|
|
160
|
+
3. Show file-level ADD / REPLACE / DELETE summary + per-file diff.
|
|
161
|
+
4. Prompt: Apply this upgrade? (y/N).
|
|
162
|
+
5. On y: rm -rf .ai/runtime/, lay down new snapshot, update KIT_VERSION.
|
|
163
|
+
|
|
164
|
+
Never touches .ai/project/.
|
|
165
|
+
|
|
166
|
+
Options:
|
|
167
|
+
--cwd <dir> Target directory (default: process.cwd())
|
|
168
|
+
--yes, -y Skip the y/N prompt (apply immediately)
|
|
169
|
+
--no-diff Skip the per-file diff preview (still shows summary)
|
|
170
|
+
--pager <cmd> Pipe per-file diff through this pager (e.g.
|
|
171
|
+
\`--pager 'less -R'\`). Also honored via env
|
|
172
|
+
AI_RUNTIME_KIT_PAGER. Only applied when stdout
|
|
173
|
+
is a TTY.
|
|
174
|
+
--allow-dirty Skip the git dirty check
|
|
175
|
+
--allow-downgrade Permit installing an older kit version
|
|
176
|
+
-h, --help Show this help.`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports = { run, printHelp };
|
package/src/version.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
const KIT_PKG = require('../package.json');
|
|
7
|
+
|
|
8
|
+
const KIT_VERSION = KIT_PKG.version;
|
|
9
|
+
|
|
10
|
+
function kitVersionFilePath(projectRoot) {
|
|
11
|
+
return path.join(projectRoot, '.ai', 'runtime', 'KIT_VERSION');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function readProjectKitVersion(projectRoot) {
|
|
15
|
+
const f = kitVersionFilePath(projectRoot);
|
|
16
|
+
if (!fs.existsSync(f)) return null;
|
|
17
|
+
return fs.readFileSync(f, 'utf8').trim();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function writeProjectKitVersion(projectRoot, version) {
|
|
21
|
+
fs.writeFileSync(kitVersionFilePath(projectRoot), `${version}\n`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Returns 1 / 0 / -1 if a is newer / equal / older than b. Pre-release tags
|
|
25
|
+
// ignored (we don't need full semver here — v0.x and v1.x suffice).
|
|
26
|
+
function compareSemver(a, b) {
|
|
27
|
+
const norm = (s) => s.replace(/^v/, '').split('-')[0].split('.').map(Number);
|
|
28
|
+
const [aMaj, aMin, aPat] = norm(a);
|
|
29
|
+
const [bMaj, bMin, bPat] = norm(b);
|
|
30
|
+
if (aMaj !== bMaj) return aMaj > bMaj ? 1 : -1;
|
|
31
|
+
if (aMin !== bMin) return aMin > bMin ? 1 : -1;
|
|
32
|
+
if (aPat !== bPat) return aPat > bPat ? 1 : -1;
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
KIT_VERSION,
|
|
38
|
+
kitVersionFilePath,
|
|
39
|
+
readProjectKitVersion,
|
|
40
|
+
writeProjectKitVersion,
|
|
41
|
+
compareSemver,
|
|
42
|
+
};
|