@yourtechtribe-labs/koncept-cli 0.2.0-alpha.2 → 0.2.0-alpha.4
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/dist/commands/acks.d.ts +38 -0
- package/dist/commands/acks.d.ts.map +1 -0
- package/dist/commands/acks.js +70 -0
- package/dist/commands/acks.js.map +1 -0
- package/dist/commands/affected.d.ts +2 -0
- package/dist/commands/affected.d.ts.map +1 -1
- package/dist/commands/affected.js +0 -0
- package/dist/commands/affected.js.map +1 -1
- package/dist/commands/anthropic-client.d.ts +9 -0
- package/dist/commands/anthropic-client.d.ts.map +1 -0
- package/dist/commands/anthropic-client.js +65 -0
- package/dist/commands/anthropic-client.js.map +1 -0
- package/dist/commands/git.d.ts +14 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +41 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +29 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/review.d.ts +3 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +78 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +26 -1
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acknowledgment resolution for `koncepto affected --require-ack`.
|
|
3
|
+
*
|
|
4
|
+
* Two sources, unioned: (1) commit trailers `Koncepto-Reviewed: <c>:<i>` in the
|
|
5
|
+
* `<from>..HEAD` range (CI-friendly audit trail), (2) the `--ack` csv flag
|
|
6
|
+
* (local override). Pure parsers are exported for unit tests; `gatherAcks`
|
|
7
|
+
* wires the git invocation (the one side effect).
|
|
8
|
+
*
|
|
9
|
+
* Range note: default `--from HEAD` ⇒ empty range ⇒ no trailer acks (only
|
|
10
|
+
* `--ack` applies). `--files` override ⇒ no git range ⇒ `--ack` only.
|
|
11
|
+
*/
|
|
12
|
+
export type AckCsvResult = {
|
|
13
|
+
ok: true;
|
|
14
|
+
keys: string[];
|
|
15
|
+
} | {
|
|
16
|
+
ok: false;
|
|
17
|
+
bad: string;
|
|
18
|
+
};
|
|
19
|
+
/** Parses the `--ack` csv into ack keys; fails on an entry missing a colon. */
|
|
20
|
+
export declare function parseAckCsv(csv: string): AckCsvResult;
|
|
21
|
+
/** Extracts ack keys from `git log` trailer output (one value per line). */
|
|
22
|
+
export declare function parseReviewedTrailers(gitOutput: string): string[];
|
|
23
|
+
export interface GatherAcksOptions {
|
|
24
|
+
rootDir: string;
|
|
25
|
+
from: string;
|
|
26
|
+
/** When false (e.g. --files override), skip the git range entirely. */
|
|
27
|
+
useGit: boolean;
|
|
28
|
+
ackCsv: string | null;
|
|
29
|
+
}
|
|
30
|
+
export type GatherAcksResult = {
|
|
31
|
+
ok: true;
|
|
32
|
+
acks: ReadonlySet<string>;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
error: string;
|
|
36
|
+
};
|
|
37
|
+
export declare function gatherAcks(opts: GatherAcksOptions): GatherAcksResult;
|
|
38
|
+
//# sourceMappingURL=acks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acks.d.ts","sourceRoot":"","sources":["../../src/commands/acks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9B,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CASrD;AAED,4EAA4E;AAC5E,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjE;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhC,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAqBpE"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acknowledgment resolution for `koncepto affected --require-ack`.
|
|
3
|
+
*
|
|
4
|
+
* Two sources, unioned: (1) commit trailers `Koncepto-Reviewed: <c>:<i>` in the
|
|
5
|
+
* `<from>..HEAD` range (CI-friendly audit trail), (2) the `--ack` csv flag
|
|
6
|
+
* (local override). Pure parsers are exported for unit tests; `gatherAcks`
|
|
7
|
+
* wires the git invocation (the one side effect).
|
|
8
|
+
*
|
|
9
|
+
* Range note: default `--from HEAD` ⇒ empty range ⇒ no trailer acks (only
|
|
10
|
+
* `--ack` applies). `--files` override ⇒ no git range ⇒ `--ack` only.
|
|
11
|
+
*/
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
13
|
+
const TRAILER_KEY = 'Koncepto-Reviewed';
|
|
14
|
+
/** Parses the `--ack` csv into ack keys; fails on an entry missing a colon. */
|
|
15
|
+
export function parseAckCsv(csv) {
|
|
16
|
+
const keys = [];
|
|
17
|
+
for (const raw of csv.split(',')) {
|
|
18
|
+
const entry = raw.trim();
|
|
19
|
+
if (entry.length === 0)
|
|
20
|
+
continue;
|
|
21
|
+
if (!entry.includes(':'))
|
|
22
|
+
return { ok: false, bad: entry };
|
|
23
|
+
keys.push(entry);
|
|
24
|
+
}
|
|
25
|
+
return { ok: true, keys };
|
|
26
|
+
}
|
|
27
|
+
/** Extracts ack keys from `git log` trailer output (one value per line). */
|
|
28
|
+
export function parseReviewedTrailers(gitOutput) {
|
|
29
|
+
return gitOutput
|
|
30
|
+
.split('\n')
|
|
31
|
+
.map((l) => l.trim())
|
|
32
|
+
.filter((l) => l.length > 0 && l.includes(':'));
|
|
33
|
+
}
|
|
34
|
+
export function gatherAcks(opts) {
|
|
35
|
+
const acks = new Set();
|
|
36
|
+
if (opts.ackCsv !== null) {
|
|
37
|
+
const parsed = parseAckCsv(opts.ackCsv);
|
|
38
|
+
if (!parsed.ok) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
error: `invalid --ack entry: '${parsed.bad}' (want concept-id:invariant-id)`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
for (const k of parsed.keys)
|
|
45
|
+
acks.add(k);
|
|
46
|
+
}
|
|
47
|
+
if (opts.useGit) {
|
|
48
|
+
const fromTrailers = trailersFromGit(opts.rootDir, opts.from);
|
|
49
|
+
if (!fromTrailers.ok)
|
|
50
|
+
return fromTrailers;
|
|
51
|
+
for (const k of fromTrailers.keys)
|
|
52
|
+
acks.add(k);
|
|
53
|
+
}
|
|
54
|
+
return { ok: true, acks };
|
|
55
|
+
}
|
|
56
|
+
function trailersFromGit(rootDir, from) {
|
|
57
|
+
const result = spawnSync('git', ['log', `${from}..HEAD`, `--format=%(trailers:key=${TRAILER_KEY},valueonly)`], { cwd: rootDir, encoding: 'utf-8' });
|
|
58
|
+
if (result.error) {
|
|
59
|
+
return { ok: false, error: `git invocation failed: ${result.error.message}` };
|
|
60
|
+
}
|
|
61
|
+
if (result.status !== 0) {
|
|
62
|
+
const stderr = (result.stderr ?? '').trim();
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
error: `git log exited with status ${result.status}${stderr ? `: ${stderr}` : ''}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { ok: true, keys: parseReviewedTrailers(result.stdout ?? '') };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=acks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acks.js","sourceRoot":"","sources":["../../src/commands/acks.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,8 @@ export interface AffectedOptions {
|
|
|
4
4
|
from: string;
|
|
5
5
|
filesOverride: string[] | null;
|
|
6
6
|
json: boolean;
|
|
7
|
+
requireAck: boolean;
|
|
8
|
+
ackCsv: string | null;
|
|
7
9
|
}
|
|
8
10
|
export declare function runAffected(ctx: CommandContext): Promise<number>;
|
|
9
11
|
//# sourceMappingURL=affected.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affected.d.ts","sourceRoot":"","sources":["../../src/commands/affected.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"affected.d.ts","sourceRoot":"","sources":["../../src/commands/affected.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC9B,IAAI,EAAE,OAAO,CAAA;IACb,UAAU,EAAE,OAAO,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAyCtE"}
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affected.js","sourceRoot":"","sources":["../../src/commands/affected.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"affected.js","sourceRoot":"","sources":["../../src/commands/affected.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Messages API provider for `koncepto review` — global `fetch`, no
|
|
3
|
+
* SDK (D-004). Returns an `llm: (prompt) => Promise<string>` matching the seam
|
|
4
|
+
* koncept-core's reviewAffected injects. One retry on network/5xx; a final
|
|
5
|
+
* failure throws (reviewAffected re-tags it with concept:invariant → exit 2).
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
8
|
+
export declare function makeAnthropicLlm(apiKey: string, model: string): (prompt: string) => Promise<string>;
|
|
9
|
+
//# sourceMappingURL=anthropic-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-client.d.ts","sourceRoot":"","sources":["../../src/commands/anthropic-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,eAAO,MAAM,aAAa,sBAAsB,CAAA;AAMhD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAUrC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Messages API provider for `koncepto review` — global `fetch`, no
|
|
3
|
+
* SDK (D-004). Returns an `llm: (prompt) => Promise<string>` matching the seam
|
|
4
|
+
* koncept-core's reviewAffected injects. One retry on network/5xx; a final
|
|
5
|
+
* failure throws (reviewAffected re-tags it with concept:invariant → exit 2).
|
|
6
|
+
*/
|
|
7
|
+
const ENDPOINT = 'https://api.anthropic.com/v1/messages';
|
|
8
|
+
const ANTHROPIC_VERSION = '2023-06-01';
|
|
9
|
+
const MAX_TOKENS = 1024;
|
|
10
|
+
export const DEFAULT_MODEL = 'claude-sonnet-4-6';
|
|
11
|
+
export function makeAnthropicLlm(apiKey, model) {
|
|
12
|
+
return async (prompt) => {
|
|
13
|
+
const res = await postWithRetry(apiKey, model, prompt);
|
|
14
|
+
const json = (await res.json());
|
|
15
|
+
const text = json.content?.find((b) => b.type === 'text')?.text;
|
|
16
|
+
if (typeof text !== 'string') {
|
|
17
|
+
throw new Error('Anthropic response had no text content block');
|
|
18
|
+
}
|
|
19
|
+
return text;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async function postWithRetry(apiKey, model, prompt) {
|
|
23
|
+
let lastError = '';
|
|
24
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
25
|
+
let res;
|
|
26
|
+
try {
|
|
27
|
+
res = await post(apiKey, model, prompt);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
lastError = err instanceof Error ? err.message : String(err); // network → retry
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (res.ok)
|
|
34
|
+
return res;
|
|
35
|
+
if (res.status < 500) {
|
|
36
|
+
throw new Error(`Anthropic API ${res.status}: ${await safeBody(res)}`); // client error → no retry
|
|
37
|
+
}
|
|
38
|
+
lastError = `Anthropic API ${res.status}`; // 5xx → retry
|
|
39
|
+
}
|
|
40
|
+
throw new Error(lastError || 'Anthropic API request failed');
|
|
41
|
+
}
|
|
42
|
+
function post(apiKey, model, prompt) {
|
|
43
|
+
return fetch(ENDPOINT, {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: {
|
|
46
|
+
'content-type': 'application/json',
|
|
47
|
+
'x-api-key': apiKey,
|
|
48
|
+
'anthropic-version': ANTHROPIC_VERSION,
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
model,
|
|
52
|
+
max_tokens: MAX_TOKENS,
|
|
53
|
+
messages: [{ role: 'user', content: prompt }],
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function safeBody(res) {
|
|
58
|
+
try {
|
|
59
|
+
return (await res.text()).slice(0, 300);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return '(no body)';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=anthropic-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-client.js","sourceRoot":"","sources":["../../src/commands/anthropic-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,QAAQ,GAAG,uCAAuC,CAAA;AACxD,MAAM,iBAAiB,GAAG,YAAY,CAAA;AACtC,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAA;AAMhD,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,KAAa;IAEb,OAAO,KAAK,EAAE,MAAc,EAAmB,EAAE;QAC/C,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAA;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,IAAI,CAAA;QAC/D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QACjE,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,MAAc,EACd,KAAa,EACb,MAAc;IAEd,IAAI,SAAS,GAAG,EAAE,CAAA;IAClB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,IAAI,GAAa,CAAA;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA,CAAC,kBAAkB;YAC/E,SAAQ;QACV,CAAC;QACD,IAAI,GAAG,CAAC,EAAE;YAAE,OAAO,GAAG,CAAA;QACtB,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA,CAAC,0BAA0B;QACnG,CAAC;QACD,SAAS,GAAG,iBAAiB,GAAG,CAAC,MAAM,EAAE,CAAA,CAAC,cAAc;IAC1D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,8BAA8B,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,IAAI,CAAC,MAAc,EAAE,KAAa,EAAE,MAAc;IACzD,OAAO,KAAK,CAAC,QAAQ,EAAE;QACrB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,WAAW,EAAE,MAAM;YACnB,mBAAmB,EAAE,iBAAiB;SACvC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK;YACL,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;SAC9C,CAAC;KACH,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,GAAa;IACnC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAA;IACpB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git helpers shared by `affected` and `review` — the diff resolution both
|
|
3
|
+
* commands need. `git diff --name-only -z` is NUL-terminated (so paths with
|
|
4
|
+
* spaces survive); splitting on space silently matched nothing.
|
|
5
|
+
*/
|
|
6
|
+
export interface ChangedFilesResult {
|
|
7
|
+
ok: boolean;
|
|
8
|
+
files: string[];
|
|
9
|
+
error: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function resolveChangedFiles(rootDir: string, from: string, filesOverride: string[] | null): ChangedFilesResult;
|
|
12
|
+
/** Unified diff for one file against `from` (sync — the injected `diff` seam). */
|
|
13
|
+
export declare function fileDiff(rootDir: string, from: string, file: string): string;
|
|
14
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/commands/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,GAC7B,kBAAkB,CAsBpB;AAED,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5E"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git helpers shared by `affected` and `review` — the diff resolution both
|
|
3
|
+
* commands need. `git diff --name-only -z` is NUL-terminated (so paths with
|
|
4
|
+
* spaces survive); splitting on space silently matched nothing.
|
|
5
|
+
*/
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
export function resolveChangedFiles(rootDir, from, filesOverride) {
|
|
8
|
+
if (filesOverride !== null) {
|
|
9
|
+
return { ok: true, files: filesOverride, error: '' };
|
|
10
|
+
}
|
|
11
|
+
const result = spawnSync('git', ['diff', '--name-only', '-z', from], {
|
|
12
|
+
cwd: rootDir,
|
|
13
|
+
encoding: 'buffer',
|
|
14
|
+
});
|
|
15
|
+
if (result.error) {
|
|
16
|
+
return { ok: false, files: [], error: `git invocation failed: ${result.error.message}` };
|
|
17
|
+
}
|
|
18
|
+
if (result.status !== 0) {
|
|
19
|
+
const stderr = result.stderr ? result.stderr.toString('utf-8').trim() : '';
|
|
20
|
+
return {
|
|
21
|
+
ok: false,
|
|
22
|
+
files: [],
|
|
23
|
+
error: `git diff exited with status ${result.status}${stderr ? `: ${stderr}` : ''}`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const stdout = result.stdout ? result.stdout.toString('utf-8') : '';
|
|
27
|
+
const files = stdout.split('\0').filter((s) => s.length > 0);
|
|
28
|
+
return { ok: true, files, error: '' };
|
|
29
|
+
}
|
|
30
|
+
/** Unified diff for one file against `from` (sync — the injected `diff` seam). */
|
|
31
|
+
export function fileDiff(rootDir, from, file) {
|
|
32
|
+
const result = spawnSync('git', ['diff', from, '--', file], {
|
|
33
|
+
cwd: rootDir,
|
|
34
|
+
encoding: 'utf-8',
|
|
35
|
+
});
|
|
36
|
+
if (result.error) {
|
|
37
|
+
throw new Error(`git diff failed for ${file}: ${result.error.message}`);
|
|
38
|
+
}
|
|
39
|
+
return result.stdout ?? '';
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/commands/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAQ9C,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,IAAY,EACZ,aAA8B;IAE9B,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;IACtD,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QACnE,GAAG,EAAE,OAAO;QACZ,QAAQ,EAAE,QAAQ;KACnB,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,0BAA0B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAA;IAC1F,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,+BAA+B,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;SACpF,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACnE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC5D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;AACvC,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAY,EAAE,IAAY;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QAC1D,GAAG,EAAE,OAAO;QACZ,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAmIjD,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlE"}
|
package/dist/commands/init.js
CHANGED
|
@@ -30,7 +30,7 @@ Each \`concepts/<id>.yaml\` MUST validate against this shape:
|
|
|
30
30
|
| \`description\` | string | yes | Why this concept exists; what changing it would break. |
|
|
31
31
|
| \`source_of_truth\` | { file, symbol? } | yes | The single file (and optionally symbol) that defines the concept. |
|
|
32
32
|
| \`participants\` | [{ file, role, purpose }] | no | Files that participate. \`role\` ∈ \`writer\` \\| \`reader\` \\| \`tester\` \\| \`docs\`. |
|
|
33
|
-
| \`invariants\` | [{ id, description, severity,
|
|
33
|
+
| \`invariants\` | [{ id, description, severity, check? }] | no | Properties that MUST hold. \`severity\` ∈ \`high\` \\| \`medium\` \\| \`low\`. \`check\` makes it enforced (see below). |
|
|
34
34
|
| \`risks_if_broken\` | [string] | no | What goes wrong when an invariant is violated. |
|
|
35
35
|
| \`related_concepts\` | [kebab-id] | no | Cross-references to other concept ids in this registry. |
|
|
36
36
|
| \`tags\` | [string] | no | Free-form tags for search/filter. |
|
|
@@ -42,6 +42,26 @@ Each \`concepts/<id>.yaml\` MUST validate against this shape:
|
|
|
42
42
|
See \`EXAMPLE.yaml\` (sibling of this README) for a fully-populated reference.
|
|
43
43
|
Full Zod schema: \`@yourtechtribe-labs/koncept-core\` → \`ConceptSchema\`.
|
|
44
44
|
|
|
45
|
+
## Invariant \`check\` — advisory vs enforced
|
|
46
|
+
|
|
47
|
+
An invariant with no \`check\` (or \`kind: none\`) is **advisory**: surfaced to agents via
|
|
48
|
+
\`koncept_for_file\`, but never evaluated. Add a \`check\` to make it an **enforced gate**.
|
|
49
|
+
|
|
50
|
+
\`koncepto verify\` runs the **static** kinds by default (\`--no-checks\` to skip);
|
|
51
|
+
\`kind: command\` is run only by \`koncepto check\` (never by \`verify\`).
|
|
52
|
+
|
|
53
|
+
| \`kind\` | Runs over | Passes when | Run by |
|
|
54
|
+
|-------------------|-----------|-------------|--------|
|
|
55
|
+
| \`none\` | — | always (advisory) | — |
|
|
56
|
+
| \`implication\` | participants (per file) | every file matching \`if\` also matches \`then\` | verify + check |
|
|
57
|
+
| \`symbol_present\` | participants (per file) | every selected file matches \`pattern\` | verify + check |
|
|
58
|
+
| \`forbidden\` | participants (per file) | no selected file matches \`pattern\` | verify + check |
|
|
59
|
+
| \`grep\` | explicit \`in: [files]\` | pattern (not) found per \`should_match\` | verify + check |
|
|
60
|
+
| \`command\` | shell | command exits 0 | **check only** |
|
|
61
|
+
|
|
62
|
+
\`over: { role: writer }\` narrows the static kinds to participants of that role
|
|
63
|
+
(default: all participants). \`if\`/\`then\`/\`pattern\` are JavaScript \`RegExp\` sources.
|
|
64
|
+
|
|
45
65
|
## Workflow
|
|
46
66
|
|
|
47
67
|
1. Copy \`EXAMPLE.yaml\` into \`concepts/<your-id>.yaml\` and edit.
|
|
@@ -81,7 +101,14 @@ invariants:
|
|
|
81
101
|
- id: example-invariant
|
|
82
102
|
description: A property that MUST hold across the participants above.
|
|
83
103
|
severity: high # high | medium | low
|
|
84
|
-
|
|
104
|
+
# No 'check' (or kind: none) → advisory: surfaced to agents, never evaluated.
|
|
105
|
+
# Add a 'check' to make it an enforced gate that 'koncepto verify' runs.
|
|
106
|
+
# Example — the "no loose ends" implication (per file: if it matches 'if', it must match 'then'):
|
|
107
|
+
# check:
|
|
108
|
+
# kind: implication # implication | symbol_present | forbidden | grep | command | none
|
|
109
|
+
# over: { role: writer } # optional: narrow to a participant role (default: all)
|
|
110
|
+
# if: "BankingCacheService"
|
|
111
|
+
# then: "CacheInvalidationService"
|
|
85
112
|
|
|
86
113
|
risks_if_broken:
|
|
87
114
|
- What goes wrong if a future change silently violates the invariant.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,MAAM,eAAe,GAAG
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEvB,CAAA;AAED,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDxB,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAmB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;IAE1C,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;IACnD,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACjC,MAAM,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAA;IACrD,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,IAAI,IAAI,CAAC,CAAA;IACvD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;QAChB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAcjD,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4CpE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { loadConcepts, reviewAffected, } from '@yourtechtribe-labs/koncept-core';
|
|
2
|
+
import { DEFAULT_MODEL, makeAnthropicLlm } from './anthropic-client.js';
|
|
3
|
+
import { fileDiff, resolveChangedFiles } from './git.js';
|
|
4
|
+
export async function runReview(ctx) {
|
|
5
|
+
const opts = parseOptions(ctx);
|
|
6
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
7
|
+
if (apiKey === undefined || apiKey.length === 0) {
|
|
8
|
+
process.stderr.write('koncepto review: ANTHROPIC_API_KEY is required\n');
|
|
9
|
+
return 2;
|
|
10
|
+
}
|
|
11
|
+
const filesResult = resolveChangedFiles(opts.rootDir, opts.from, opts.filesOverride);
|
|
12
|
+
if (!filesResult.ok) {
|
|
13
|
+
process.stderr.write(`koncepto review: ${filesResult.error}\n`);
|
|
14
|
+
return 2;
|
|
15
|
+
}
|
|
16
|
+
const loaded = await loadConcepts(opts.rootDir);
|
|
17
|
+
if (loaded.parseErrors.length > 0 && !opts.json) {
|
|
18
|
+
for (const e of loaded.parseErrors) {
|
|
19
|
+
process.stderr.write(`koncepto review: warning: parse error in ${e.filePath}: ${e.message}\n`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
let result;
|
|
23
|
+
try {
|
|
24
|
+
result = await reviewAffected(loaded.concepts, {
|
|
25
|
+
rootDir: opts.rootDir,
|
|
26
|
+
changedFiles: filesResult.files,
|
|
27
|
+
diff: (file) => fileDiff(opts.rootDir, opts.from, file),
|
|
28
|
+
minSeverity: opts.minSeverity,
|
|
29
|
+
llm: makeAnthropicLlm(apiKey, opts.model),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
34
|
+
process.stderr.write(`koncepto review: ${detail}\n`);
|
|
35
|
+
return 2;
|
|
36
|
+
}
|
|
37
|
+
if (opts.json) {
|
|
38
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
renderReview(result);
|
|
42
|
+
}
|
|
43
|
+
return exitCodeFor(result, opts.strict);
|
|
44
|
+
}
|
|
45
|
+
const SEVERITIES = ['high', 'medium', 'low'];
|
|
46
|
+
function parseOptions(ctx) {
|
|
47
|
+
const filesFlag = ctx.flags.files;
|
|
48
|
+
const filesOverride = typeof filesFlag === 'string'
|
|
49
|
+
? filesFlag.split(',').map((s) => s.trim()).filter((s) => s.length > 0)
|
|
50
|
+
: null;
|
|
51
|
+
const sevFlag = ctx.flags.severity;
|
|
52
|
+
const minSeverity = typeof sevFlag === 'string' && SEVERITIES.includes(sevFlag)
|
|
53
|
+
? sevFlag
|
|
54
|
+
: 'medium';
|
|
55
|
+
return {
|
|
56
|
+
rootDir: ctx.rootDir,
|
|
57
|
+
from: typeof ctx.flags.from === 'string' ? ctx.flags.from : 'HEAD',
|
|
58
|
+
filesOverride,
|
|
59
|
+
minSeverity,
|
|
60
|
+
strict: ctx.flags.strict === true,
|
|
61
|
+
model: typeof ctx.flags.model === 'string' ? ctx.flags.model : DEFAULT_MODEL,
|
|
62
|
+
json: ctx.flags.json === true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const VERDICT_SYMBOL = { holds: '✓', violated: '✗', uncertain: '?' };
|
|
66
|
+
function renderReview(result) {
|
|
67
|
+
process.stdout.write(`koncepto review — ${result.reviews.length} advisory invariant(s), ${result.skipped} skipped\n`);
|
|
68
|
+
for (const r of result.reviews) {
|
|
69
|
+
process.stdout.write(`\n ${r.conceptId} / ${r.invariantId} [${r.severity}]\n`);
|
|
70
|
+
process.stdout.write(` ${VERDICT_SYMBOL[r.verdict] ?? '?'} ${r.verdict} — ${r.rationale}\n`);
|
|
71
|
+
}
|
|
72
|
+
process.stdout.write(`\n Results: ${result.holds} holds · ${result.violated} violated · ${result.uncertain} uncertain · ${result.skipped} skipped\n`);
|
|
73
|
+
}
|
|
74
|
+
/** Advisory by default (exit 0). --strict gates on `violated`; uncertain never fails. */
|
|
75
|
+
function exitCodeFor(result, strict) {
|
|
76
|
+
return strict && result.violated > 0 ? 1 : 0;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDpE"}
|
package/dist/commands/verify.js
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
import { indexConcepts, isIndexClean, loadConcepts, suggestLinks, writeIndex, } from '@yourtechtribe-labs/koncept-core';
|
|
1
|
+
import { indexConcepts, isIndexClean, loadConcepts, runChecks, suggestLinks, writeIndex, } from '@yourtechtribe-labs/koncept-core';
|
|
2
2
|
export async function runVerify(ctx) {
|
|
3
3
|
const result = await indexConcepts(ctx.rootDir);
|
|
4
4
|
await writeIndex(ctx.rootDir, result.entries);
|
|
5
5
|
const quiet = ctx.flags.quiet === true;
|
|
6
6
|
const wantSuggestions = ctx.flags['no-suggestions'] !== true;
|
|
7
|
+
const wantChecks = ctx.flags['no-checks'] !== true;
|
|
7
8
|
if (!quiet) {
|
|
8
9
|
process.stdout.write(`koncepto verify: ${result.entries.length} concept(s) indexed\n`);
|
|
9
10
|
}
|
|
10
11
|
if (isIndexClean(result)) {
|
|
12
|
+
// Structural validation passed. Now run the STATIC invariant checks (#36) by
|
|
13
|
+
// default — fast, read-only, deterministic. `kind: command` is never run here
|
|
14
|
+
// (staticOnly), it stays exclusive to `koncepto check`. `--no-checks` opts out.
|
|
15
|
+
if (wantChecks) {
|
|
16
|
+
const checks = await runChecks({ cwd: ctx.rootDir, staticOnly: true });
|
|
17
|
+
if (checks.failed + checks.errors > 0) {
|
|
18
|
+
printCheckFailures(checks.results);
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
11
22
|
if (!quiet)
|
|
12
23
|
process.stdout.write('koncepto verify: ✓ all checks passed\n');
|
|
13
24
|
if (wantSuggestions && !quiet) {
|
|
@@ -16,6 +27,7 @@ export async function runVerify(ctx) {
|
|
|
16
27
|
}
|
|
17
28
|
return 0;
|
|
18
29
|
}
|
|
30
|
+
// Structural errors present → don't run checks (we can't trust the graph).
|
|
19
31
|
for (const e of result.errors) {
|
|
20
32
|
process.stderr.write(`✗ parse: ${e.filePath}\n`);
|
|
21
33
|
for (const err of e.errors) {
|
|
@@ -35,6 +47,19 @@ export async function runVerify(ctx) {
|
|
|
35
47
|
}
|
|
36
48
|
return 1;
|
|
37
49
|
}
|
|
50
|
+
function printCheckFailures(results) {
|
|
51
|
+
process.stderr.write('koncepto verify: ✗ invariant check failed\n\n');
|
|
52
|
+
for (const r of results) {
|
|
53
|
+
if (r.status !== 'fail' && r.status !== 'error')
|
|
54
|
+
continue;
|
|
55
|
+
const mark = r.status === 'error' ? '⚠' : '✗';
|
|
56
|
+
process.stderr.write(` ${mark} ${r.conceptId} / ${r.invariantId} (${r.kind})\n`);
|
|
57
|
+
if (r.detail)
|
|
58
|
+
process.stderr.write(` ${r.detail}\n`);
|
|
59
|
+
if (r.description)
|
|
60
|
+
process.stderr.write(` → ${r.description.trim()}\n`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
38
63
|
function printSuggestions(suggestions) {
|
|
39
64
|
if (suggestions.length === 0)
|
|
40
65
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA0CA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAA;CACxC;AAcD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBtF"}
|
package/dist/index.js
CHANGED
|
@@ -9,22 +9,31 @@ import { runList } from './commands/list.js';
|
|
|
9
9
|
import { runLink } from './commands/link.js';
|
|
10
10
|
import { runAffected } from './commands/affected.js';
|
|
11
11
|
import { runCheck } from './commands/check.js';
|
|
12
|
+
import { runReview } from './commands/review.js';
|
|
12
13
|
import { VERSION } from './version.js';
|
|
13
14
|
const HELP = `koncepto ${VERSION}
|
|
14
15
|
|
|
15
16
|
Usage:
|
|
16
17
|
koncepto init Bootstrap .koncept/ in cwd
|
|
17
|
-
koncepto verify Validate concepts
|
|
18
|
+
koncepto verify Validate concepts, run static invariant checks,
|
|
19
|
+
and write index.json
|
|
18
20
|
[--no-suggestions] (suppress auto-link suggestions)
|
|
21
|
+
[--no-checks] (skip static invariant checks; structural only)
|
|
19
22
|
koncepto list [--type] [--tag] List concepts (with optional filters)
|
|
20
23
|
[--status]
|
|
21
24
|
koncepto link <id> <file> Add a participant to an existing concept
|
|
22
25
|
--role=<r> --purpose=<p>
|
|
23
26
|
koncepto affected [--from <ref>] Report concepts/invariants touched by a diff
|
|
24
27
|
[--files=a,b,c] [--json]
|
|
28
|
+
[--require-ack] (exit 3 if an advisory high invariant is unacked)
|
|
29
|
+
[--ack=c:i,c2:i2] (acknowledge invariants; supplements commit trailers)
|
|
25
30
|
koncepto check Execute invariant.check payloads (grep + command)
|
|
26
31
|
[--id <concept-id>] (filter to one concept)
|
|
27
32
|
[--json] (machine-readable output)
|
|
33
|
+
koncepto review [--from <ref>] LLM review of touched advisory invariants
|
|
34
|
+
[--files=a,b,c] [--json] (requires ANTHROPIC_API_KEY)
|
|
35
|
+
[--severity high|medium|low] (min severity to review; default medium)
|
|
36
|
+
[--strict] [--model <id>] (--strict: exit 1 on any 'violated')
|
|
28
37
|
|
|
29
38
|
Flags:
|
|
30
39
|
--help, --version
|
|
@@ -36,6 +45,7 @@ const COMMANDS = {
|
|
|
36
45
|
link: runLink,
|
|
37
46
|
affected: runAffected,
|
|
38
47
|
check: runCheck,
|
|
48
|
+
review: runReview,
|
|
39
49
|
};
|
|
40
50
|
export async function run(argv, cwd = process.cwd()) {
|
|
41
51
|
const { command, positional, flags } = parseArgs(argv);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,IAAI,GAAG,YAAY,OAAO
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yourtechtribe-labs/koncept-cli",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.4",
|
|
4
4
|
"description": "CLI for koncepto — init, verify, list, link operations on .koncept/ concept graphs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@yourtechtribe-labs/koncept-core": "^0.2.0-alpha.0",
|
|
34
34
|
"glob": "13.0.6",
|
|
35
|
-
"yaml": "2.
|
|
35
|
+
"yaml": "2.9.0"
|
|
36
36
|
},
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public",
|