ark-runtime-kernel 1.1.0 → 1.3.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/README.md +59 -2
- package/bin/ark-check.mjs +411 -24
- package/bin/ark-mcp.mjs +42 -1
- package/bin/ark-postinstall.mjs +12 -0
- package/bin/ark-shared.mjs +2 -1
- package/bin/ark.mjs +129 -0
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.cjs +1 -1
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +1 -1
- package/dist/nestjs/index.js.map +1 -1
- package/docs/agent-guide.md +353 -0
- package/docs/ai-gates.md +177 -0
- package/docs/ark-check-example.json +87 -0
- package/docs/assets/ark-write-gate.svg +28 -0
- package/docs/production-hardening.md +59 -0
- package/package.json +4 -1
- package/server.json +2 -2
package/bin/ark-shared.mjs
CHANGED
|
@@ -72,12 +72,13 @@ export const DEFAULT_RULES = createStrictDenyRules(
|
|
|
72
72
|
export function createElevenLayerConfig(options = {}) {
|
|
73
73
|
const rootDir = options.rootDir ?? 'src';
|
|
74
74
|
const optional = options.optionalLayers ?? true;
|
|
75
|
+
const prefix = rootDir === '.' ? '' : `${rootDir}/`;
|
|
75
76
|
return {
|
|
76
77
|
include: options.include ?? [rootDir],
|
|
77
78
|
layers: DEFAULT_INTENT_PREFIXES.map((entry) => ({
|
|
78
79
|
name: entry.layer,
|
|
79
80
|
patterns: (DEFAULT_LAYER_DIRECTORIES[entry.layer] ?? [entry.layer]).map(
|
|
80
|
-
(directory) => `${
|
|
81
|
+
(directory) => `${prefix}${directory}/**`
|
|
81
82
|
),
|
|
82
83
|
intentPrefixes: entry.prefixes,
|
|
83
84
|
optional,
|
package/bin/ark.mjs
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import readline from 'node:readline/promises';
|
|
7
|
+
|
|
8
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const arkCheck = path.join(here, 'ark-check.mjs');
|
|
10
|
+
|
|
11
|
+
function parseArgs(argv) {
|
|
12
|
+
const args = {
|
|
13
|
+
command: argv[2],
|
|
14
|
+
root: process.cwd(),
|
|
15
|
+
yes: false,
|
|
16
|
+
force: false,
|
|
17
|
+
strict: true,
|
|
18
|
+
help: false,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
for (let i = 3; i < argv.length; i += 1) {
|
|
22
|
+
const arg = argv[i];
|
|
23
|
+
if (arg === '--root') args.root = path.resolve(argv[++i]);
|
|
24
|
+
else if (arg === '--yes' || arg === '-y') args.yes = true;
|
|
25
|
+
else if (arg === '--force') args.force = true;
|
|
26
|
+
else if (arg === '--no-strict') args.strict = false;
|
|
27
|
+
else if (arg === '--help' || arg === '-h') args.help = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return args;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function usage() {
|
|
34
|
+
return `Usage:
|
|
35
|
+
ark init [--root <project>] [--yes] [--force] [--no-strict]
|
|
36
|
+
|
|
37
|
+
Commands:
|
|
38
|
+
init Configure Ark project enforcement with explicit prompts.
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
--yes Non-interactive defaults: create config if needed, install gate templates, run strict check.
|
|
42
|
+
--force Allow generated files to overwrite existing files.
|
|
43
|
+
--no-strict Skip the final strict ark-check run.
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function runArkCheck(args, options = {}) {
|
|
48
|
+
const result = spawnSync(process.execPath, [arkCheck, ...args], {
|
|
49
|
+
cwd: options.cwd,
|
|
50
|
+
stdio: options.stdio ?? 'inherit',
|
|
51
|
+
encoding: 'utf8',
|
|
52
|
+
});
|
|
53
|
+
return result.status ?? 1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function askYesNo(rl, question, defaultYes = true) {
|
|
57
|
+
const suffix = defaultYes ? ' [Y/n] ' : ' [y/N] ';
|
|
58
|
+
const answer = (await rl.question(`${question}${suffix}`)).trim().toLowerCase();
|
|
59
|
+
if (!answer) return defaultYes;
|
|
60
|
+
return answer === 'y' || answer === 'yes';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function init(args) {
|
|
64
|
+
const root = args.root;
|
|
65
|
+
const configPath = path.join(root, 'ark.config.json');
|
|
66
|
+
const rl = args.yes
|
|
67
|
+
? null
|
|
68
|
+
: readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
let shouldInit = !fs.existsSync(configPath);
|
|
72
|
+
if (fs.existsSync(configPath)) {
|
|
73
|
+
shouldInit = args.force
|
|
74
|
+
? true
|
|
75
|
+
: args.yes
|
|
76
|
+
? false
|
|
77
|
+
: await askYesNo(rl, 'ark.config.json already exists. Regenerate it?', false);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (shouldInit) {
|
|
81
|
+
const initArgs = ['--root', root, '--init'];
|
|
82
|
+
if (args.force) initArgs.push('--force');
|
|
83
|
+
const status = runArkCheck(initArgs, { cwd: root });
|
|
84
|
+
if (status !== 0) return status;
|
|
85
|
+
} else {
|
|
86
|
+
console.log('Skipped ark.config.json generation.');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const installGates = args.yes || await askYesNo(rl, 'Configure agent and CI gate templates?', true);
|
|
90
|
+
if (installGates) {
|
|
91
|
+
const gateArgs = ['--root', root, '--install-agent-gates'];
|
|
92
|
+
if (args.force) gateArgs.push('--force');
|
|
93
|
+
const status = runArkCheck(gateArgs, { cwd: root });
|
|
94
|
+
if (status !== 0) return status;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const runStrict =
|
|
98
|
+
args.strict && (args.yes || await askYesNo(rl, 'Run strict architecture check now?', true));
|
|
99
|
+
if (runStrict) {
|
|
100
|
+
return runArkCheck(
|
|
101
|
+
['--root', root, '--config', 'ark.config.json', '--strict-config'],
|
|
102
|
+
{ cwd: root }
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log('Ark init complete. Run `npx ark-check --root . --config ark.config.json --strict-config` before merging.');
|
|
107
|
+
return 0;
|
|
108
|
+
} finally {
|
|
109
|
+
rl?.close();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function main() {
|
|
114
|
+
const args = parseArgs(process.argv);
|
|
115
|
+
if (args.help || !args.command) {
|
|
116
|
+
console.log(usage());
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (args.command === 'init') {
|
|
121
|
+
return init(args);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.error(`Unknown command: ${args.command}`);
|
|
125
|
+
console.error(usage());
|
|
126
|
+
return 2;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
process.exitCode = await main();
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/version.ts
|
|
4
|
-
var version = "1.
|
|
4
|
+
var version = "1.3.0";
|
|
5
5
|
|
|
6
6
|
// src/kernel/intent/IntentRegistry.ts
|
|
7
7
|
var IntentRegistry = class {
|
|
@@ -1833,12 +1833,13 @@ var defaultElevenLayerDirectories = {
|
|
|
1833
1833
|
function createElevenLayerArkConfig(options = {}) {
|
|
1834
1834
|
const rootDir = options.rootDir ?? "src";
|
|
1835
1835
|
const optional = options.optionalLayers ?? true;
|
|
1836
|
+
const prefix = rootDir === "." ? "" : `${rootDir}/`;
|
|
1836
1837
|
return {
|
|
1837
1838
|
include: options.include ?? [rootDir],
|
|
1838
1839
|
layers: elevenLayerProfile.layers.map((layer) => ({
|
|
1839
1840
|
name: layer.name,
|
|
1840
1841
|
patterns: (defaultElevenLayerDirectories[layer.name] ?? [layer.name]).map(
|
|
1841
|
-
(directory) => `${
|
|
1842
|
+
(directory) => `${prefix}${directory}/**`
|
|
1842
1843
|
),
|
|
1843
1844
|
intentPrefixes: layer.prefixes,
|
|
1844
1845
|
optional
|