@slowcook-ai/cli 0.7.21 → 0.8.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.
|
@@ -1,87 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
complete(args: LlmRequest): Promise<LlmResponse>;
|
|
8
|
-
}
|
|
9
|
-
export interface LlmMessage {
|
|
10
|
-
role: "user" | "assistant";
|
|
11
|
-
content: string;
|
|
12
|
-
}
|
|
13
|
-
export interface LlmRequest {
|
|
14
|
-
system: string;
|
|
15
|
-
/** System content will be cached if `cacheSystem` is true. */
|
|
16
|
-
cacheSystem?: boolean;
|
|
17
|
-
messages: LlmMessage[];
|
|
18
|
-
/** Model id to use (e.g., "claude-opus-4-7"). */
|
|
19
|
-
model: string;
|
|
20
|
-
maxTokens?: number;
|
|
21
|
-
temperature?: number;
|
|
22
|
-
}
|
|
23
|
-
export interface LlmUsage {
|
|
24
|
-
inputTokens: number;
|
|
25
|
-
outputTokens: number;
|
|
26
|
-
cacheReadTokens: number;
|
|
27
|
-
cacheCreateTokens: number;
|
|
28
|
-
}
|
|
29
|
-
export interface LlmResponse {
|
|
30
|
-
text: string;
|
|
31
|
-
usage: LlmUsage;
|
|
32
|
-
/** Adapter-computed cost for this call. CLI never does price arithmetic
|
|
33
|
-
* itself — 0.8's `LlmAdapter` contract preserves this boundary. */
|
|
34
|
-
costUsd: number;
|
|
35
|
-
model: string;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Compute USD cost from normalized usage counters + a model id.
|
|
39
|
-
* Anthropic's API reports `input_tokens` as new-input-only (cache tokens
|
|
40
|
-
* are separate counters, not subsets). Cache reads bill at ~10% of input;
|
|
41
|
-
* cache writes at ~125%.
|
|
42
|
-
*/
|
|
43
|
-
export declare function costUsdForUsage(model: string, usage: LlmUsage): number;
|
|
44
|
-
export declare class AnthropicClient implements LlmClient {
|
|
45
|
-
private readonly client;
|
|
46
|
-
constructor(apiKey: string);
|
|
47
|
-
complete(args: LlmRequest): Promise<LlmResponse>;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Build an HTML-comment cost marker for embedding in audit-trail comments
|
|
51
|
-
* (source-issue comments from refine / testgen / brew). Hidden from
|
|
52
|
-
* human-rendered markdown but machine-parseable by `on-brew-merged`'s
|
|
53
|
-
* pipeline-total aggregator.
|
|
2
|
+
* LLM adapter surface — thin shim in the CLI since 0.8. The interface
|
|
3
|
+
* lives in `@slowcook-ai/core`; the Anthropic implementation + pricing
|
|
4
|
+
* helpers live in `@slowcook-ai/llm-anthropic`. Existing import paths
|
|
5
|
+
* (`from "../refine/llm.js"`) keep working through this re-export, so the
|
|
6
|
+
* refactor is invisible at every consumer call site.
|
|
54
7
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* Chosen over a persisted .brewing/costs/*.jsonl file because (a) no extra
|
|
58
|
-
* git commits, (b) the comment trail is already the audit log, (c) the
|
|
59
|
-
* aggregator just walks issue comments via the GitHub API.
|
|
60
|
-
*/
|
|
61
|
-
export declare function costMarker(fields: {
|
|
62
|
-
agent: "refine" | "testgen" | "brew";
|
|
63
|
-
usd: number;
|
|
64
|
-
tokensIn?: number;
|
|
65
|
-
tokensOut?: number;
|
|
66
|
-
cacheRead?: number;
|
|
67
|
-
cacheCreate?: number;
|
|
68
|
-
model?: string;
|
|
69
|
-
round?: number | string;
|
|
70
|
-
}): string;
|
|
71
|
-
/**
|
|
72
|
-
* Parse one or more cost markers out of a text blob (typically a GitHub
|
|
73
|
-
* issue comment body). Returns a flat list — a single comment can contain
|
|
74
|
-
* at most one marker by convention, but the parser is robust to multiple.
|
|
8
|
+
* See `docs/plans/0.8-llm-adapter-refactor.md`.
|
|
75
9
|
*/
|
|
76
|
-
export
|
|
77
|
-
|
|
78
|
-
usd: number;
|
|
79
|
-
tokensIn?: number;
|
|
80
|
-
tokensOut?: number;
|
|
81
|
-
cacheRead?: number;
|
|
82
|
-
cacheCreate?: number;
|
|
83
|
-
model?: string;
|
|
84
|
-
round?: string;
|
|
85
|
-
}
|
|
86
|
-
export declare function parseCostMarkers(body: string): ParsedCostMarker[];
|
|
10
|
+
export type { LlmClient, LlmMessage, LlmRequest, LlmResponse, LlmUsage, } from "@slowcook-ai/core";
|
|
11
|
+
export { AnthropicClient, costUsdForUsage, costMarker, parseCostMarkers, PRICING_PER_M_TOKENS, type ParsedCostMarker, } from "@slowcook-ai/llm-anthropic";
|
|
87
12
|
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../../src/commands/refine/llm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../../src/commands/refine/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,YAAY,EACV,SAAS,EACT,UAAU,EACV,UAAU,EACV,WAAW,EACX,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,eAAe,EACf,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,gBAAgB,GACtB,MAAM,4BAA4B,CAAC"}
|
|
@@ -1,151 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Per-million-token prices for Claude models. Source of truth for Anthropic
|
|
4
|
-
* cost accounting; 0.8 will move this into the `@slowcook-ai/llm-anthropic`
|
|
5
|
-
* package alongside the adapter. Today it lives here because that's where
|
|
6
|
-
* the Anthropic SDK import lives.
|
|
7
|
-
*/
|
|
8
|
-
const PRICING_PER_M_TOKENS = {
|
|
9
|
-
"claude-opus-4-7": { input: 15, output: 75 },
|
|
10
|
-
"claude-sonnet-4-6": { input: 3, output: 15 },
|
|
11
|
-
"claude-sonnet-4-5": { input: 3, output: 15 },
|
|
12
|
-
"claude-haiku-4-5": { input: 0.8, output: 4 },
|
|
13
|
-
};
|
|
14
|
-
function matchPricing(model) {
|
|
15
|
-
if (PRICING_PER_M_TOKENS[model])
|
|
16
|
-
return PRICING_PER_M_TOKENS[model];
|
|
17
|
-
for (const key of Object.keys(PRICING_PER_M_TOKENS)) {
|
|
18
|
-
if (model.startsWith(key))
|
|
19
|
-
return PRICING_PER_M_TOKENS[key];
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Compute USD cost from normalized usage counters + a model id.
|
|
25
|
-
* Anthropic's API reports `input_tokens` as new-input-only (cache tokens
|
|
26
|
-
* are separate counters, not subsets). Cache reads bill at ~10% of input;
|
|
27
|
-
* cache writes at ~125%.
|
|
28
|
-
*/
|
|
29
|
-
export function costUsdForUsage(model, usage) {
|
|
30
|
-
const pricing = matchPricing(model);
|
|
31
|
-
if (!pricing)
|
|
32
|
-
return 0;
|
|
33
|
-
const effectiveInput = usage.inputTokens +
|
|
34
|
-
usage.cacheReadTokens * 0.1 +
|
|
35
|
-
usage.cacheCreateTokens * 1.25;
|
|
36
|
-
return ((effectiveInput / 1_000_000) * pricing.input +
|
|
37
|
-
(usage.outputTokens / 1_000_000) * pricing.output);
|
|
38
|
-
}
|
|
39
|
-
export class AnthropicClient {
|
|
40
|
-
client;
|
|
41
|
-
constructor(apiKey) {
|
|
42
|
-
this.client = new Anthropic({ apiKey });
|
|
43
|
-
}
|
|
44
|
-
async complete(args) {
|
|
45
|
-
const systemContent = args.cacheSystem
|
|
46
|
-
? [
|
|
47
|
-
{
|
|
48
|
-
type: "text",
|
|
49
|
-
text: args.system,
|
|
50
|
-
cache_control: { type: "ephemeral" },
|
|
51
|
-
},
|
|
52
|
-
]
|
|
53
|
-
: args.system;
|
|
54
|
-
// Newer Claude reasoning-enabled models (Opus 4.7, Sonnet 4.5+) reject
|
|
55
|
-
// `temperature` with a 400. Only include it if the caller explicitly
|
|
56
|
-
// passed one; otherwise let the model use its own default.
|
|
57
|
-
const base = {
|
|
58
|
-
model: args.model,
|
|
59
|
-
max_tokens: args.maxTokens ?? 4096,
|
|
60
|
-
system: systemContent,
|
|
61
|
-
messages: args.messages.map((m) => ({
|
|
62
|
-
role: m.role,
|
|
63
|
-
content: m.content,
|
|
64
|
-
})),
|
|
65
|
-
};
|
|
66
|
-
const response = await this.client.messages.create(args.temperature !== undefined
|
|
67
|
-
? { ...base, temperature: args.temperature }
|
|
68
|
-
: base);
|
|
69
|
-
const first = response.content[0];
|
|
70
|
-
if (!first || first.type !== "text") {
|
|
71
|
-
throw new Error(`Expected a text response from Claude, got: ${JSON.stringify(response.content).slice(0, 200)}`);
|
|
72
|
-
}
|
|
73
|
-
// Normalize usage. Anthropic's SDK may add new fields over time; read via
|
|
74
|
-
// loose cast so newer cache shapes don't break older SDKs.
|
|
75
|
-
const raw = response.usage;
|
|
76
|
-
const usage = {
|
|
77
|
-
inputTokens: raw?.input_tokens ?? 0,
|
|
78
|
-
outputTokens: raw?.output_tokens ?? 0,
|
|
79
|
-
cacheReadTokens: raw?.cache_read_input_tokens ?? 0,
|
|
80
|
-
cacheCreateTokens: raw?.cache_creation_input_tokens ?? 0,
|
|
81
|
-
};
|
|
82
|
-
return {
|
|
83
|
-
text: first.text,
|
|
84
|
-
usage,
|
|
85
|
-
costUsd: costUsdForUsage(args.model, usage),
|
|
86
|
-
model: args.model,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Build an HTML-comment cost marker for embedding in audit-trail comments
|
|
92
|
-
* (source-issue comments from refine / testgen / brew). Hidden from
|
|
93
|
-
* human-rendered markdown but machine-parseable by `on-brew-merged`'s
|
|
94
|
-
* pipeline-total aggregator.
|
|
95
|
-
*
|
|
96
|
-
* Format: `<!-- slowcook:cost k1=v1 k2=v2 ... -->`
|
|
97
|
-
*
|
|
98
|
-
* Chosen over a persisted .brewing/costs/*.jsonl file because (a) no extra
|
|
99
|
-
* git commits, (b) the comment trail is already the audit log, (c) the
|
|
100
|
-
* aggregator just walks issue comments via the GitHub API.
|
|
101
|
-
*/
|
|
102
|
-
export function costMarker(fields) {
|
|
103
|
-
const parts = [`agent=${fields.agent}`, `usd=${fields.usd.toFixed(4)}`];
|
|
104
|
-
if (fields.tokensIn !== undefined)
|
|
105
|
-
parts.push(`tokens_in=${fields.tokensIn}`);
|
|
106
|
-
if (fields.tokensOut !== undefined)
|
|
107
|
-
parts.push(`tokens_out=${fields.tokensOut}`);
|
|
108
|
-
if (fields.cacheRead !== undefined)
|
|
109
|
-
parts.push(`cache_read=${fields.cacheRead}`);
|
|
110
|
-
if (fields.cacheCreate !== undefined)
|
|
111
|
-
parts.push(`cache_create=${fields.cacheCreate}`);
|
|
112
|
-
if (fields.model)
|
|
113
|
-
parts.push(`model=${fields.model}`);
|
|
114
|
-
if (fields.round !== undefined)
|
|
115
|
-
parts.push(`round=${fields.round}`);
|
|
116
|
-
return `<!-- slowcook:cost ${parts.join(" ")} -->`;
|
|
117
|
-
}
|
|
118
|
-
export function parseCostMarkers(body) {
|
|
119
|
-
const out = [];
|
|
120
|
-
const re = /<!--\s*slowcook:cost\s+([^>]+?)\s*-->/g;
|
|
121
|
-
let m;
|
|
122
|
-
while ((m = re.exec(body)) !== null) {
|
|
123
|
-
const kv = {};
|
|
124
|
-
for (const pair of (m[1] ?? "").split(/\s+/)) {
|
|
125
|
-
const eq = pair.indexOf("=");
|
|
126
|
-
if (eq > 0)
|
|
127
|
-
kv[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
128
|
-
}
|
|
129
|
-
if (kv.agent && kv.usd !== undefined) {
|
|
130
|
-
const parsed = {
|
|
131
|
-
agent: kv.agent,
|
|
132
|
-
usd: parseFloat(kv.usd),
|
|
133
|
-
};
|
|
134
|
-
if (kv.tokens_in !== undefined)
|
|
135
|
-
parsed.tokensIn = parseInt(kv.tokens_in, 10);
|
|
136
|
-
if (kv.tokens_out !== undefined)
|
|
137
|
-
parsed.tokensOut = parseInt(kv.tokens_out, 10);
|
|
138
|
-
if (kv.cache_read !== undefined)
|
|
139
|
-
parsed.cacheRead = parseInt(kv.cache_read, 10);
|
|
140
|
-
if (kv.cache_create !== undefined)
|
|
141
|
-
parsed.cacheCreate = parseInt(kv.cache_create, 10);
|
|
142
|
-
if (kv.model !== undefined)
|
|
143
|
-
parsed.model = kv.model;
|
|
144
|
-
if (kv.round !== undefined)
|
|
145
|
-
parsed.round = kv.round;
|
|
146
|
-
out.push(parsed);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return out;
|
|
150
|
-
}
|
|
1
|
+
export { AnthropicClient, costUsdForUsage, costMarker, parseCostMarkers, PRICING_PER_M_TOKENS, } from "@slowcook-ai/llm-anthropic";
|
|
151
2
|
//# sourceMappingURL=llm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/commands/refine/llm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/commands/refine/llm.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,eAAe,EACf,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,4BAA4B,CAAC"}
|
|
@@ -34,44 +34,44 @@ export declare const schemas: {
|
|
|
34
34
|
supersedes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
35
35
|
superseded_by: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNull]>>;
|
|
36
36
|
}, "strip", z.ZodTypeAny, {
|
|
37
|
-
status: "draft" | "active" | "superseded";
|
|
38
37
|
title: string;
|
|
39
|
-
|
|
40
|
-
superseded_by?: string | null | undefined;
|
|
38
|
+
status: "draft" | "active" | "superseded";
|
|
41
39
|
source_issue?: string | undefined;
|
|
42
40
|
tags?: string[] | undefined;
|
|
43
41
|
summary?: string | undefined;
|
|
44
|
-
}, {
|
|
45
|
-
status: "draft" | "active" | "superseded";
|
|
46
|
-
title: string;
|
|
47
42
|
supersedes?: string[] | undefined;
|
|
48
43
|
superseded_by?: string | null | undefined;
|
|
44
|
+
}, {
|
|
45
|
+
title: string;
|
|
46
|
+
status: "draft" | "active" | "superseded";
|
|
49
47
|
source_issue?: string | undefined;
|
|
50
48
|
tags?: string[] | undefined;
|
|
51
49
|
summary?: string | undefined;
|
|
50
|
+
supersedes?: string[] | undefined;
|
|
51
|
+
superseded_by?: string | null | undefined;
|
|
52
52
|
}>>;
|
|
53
53
|
}, "strip", z.ZodTypeAny, {
|
|
54
54
|
schema_version: 1;
|
|
55
55
|
stories: Record<string, {
|
|
56
|
-
status: "draft" | "active" | "superseded";
|
|
57
56
|
title: string;
|
|
58
|
-
|
|
59
|
-
superseded_by?: string | null | undefined;
|
|
57
|
+
status: "draft" | "active" | "superseded";
|
|
60
58
|
source_issue?: string | undefined;
|
|
61
59
|
tags?: string[] | undefined;
|
|
62
60
|
summary?: string | undefined;
|
|
61
|
+
supersedes?: string[] | undefined;
|
|
62
|
+
superseded_by?: string | null | undefined;
|
|
63
63
|
}>;
|
|
64
64
|
$schema?: string | undefined;
|
|
65
65
|
}, {
|
|
66
66
|
schema_version: 1;
|
|
67
67
|
stories: Record<string, {
|
|
68
|
-
status: "draft" | "active" | "superseded";
|
|
69
68
|
title: string;
|
|
70
|
-
|
|
71
|
-
superseded_by?: string | null | undefined;
|
|
69
|
+
status: "draft" | "active" | "superseded";
|
|
72
70
|
source_issue?: string | undefined;
|
|
73
71
|
tags?: string[] | undefined;
|
|
74
72
|
summary?: string | undefined;
|
|
73
|
+
supersedes?: string[] | undefined;
|
|
74
|
+
superseded_by?: string | null | undefined;
|
|
75
75
|
}>;
|
|
76
76
|
$schema?: string | undefined;
|
|
77
77
|
}>;
|
|
@@ -109,20 +109,20 @@ export declare const schemas: {
|
|
|
109
109
|
note: z.ZodOptional<z.ZodString>;
|
|
110
110
|
}, "strip", z.ZodTypeAny, {
|
|
111
111
|
id: string;
|
|
112
|
-
relationship: "
|
|
112
|
+
relationship: "superseded" | "overlap" | "related";
|
|
113
113
|
note?: string | undefined;
|
|
114
114
|
}, {
|
|
115
115
|
id: string;
|
|
116
|
-
relationship: "
|
|
116
|
+
relationship: "superseded" | "overlap" | "related";
|
|
117
117
|
note?: string | undefined;
|
|
118
118
|
}>, "many">>;
|
|
119
119
|
}, "strip", z.ZodTypeAny, {
|
|
120
|
-
status: "draft" | "active" | "superseded";
|
|
121
|
-
story_id: string;
|
|
122
120
|
title: string;
|
|
123
|
-
|
|
121
|
+
status: "draft" | "active" | "superseded";
|
|
124
122
|
supersedes: string[];
|
|
125
123
|
superseded_by: string | null;
|
|
124
|
+
story_id: string;
|
|
125
|
+
created_at: string;
|
|
126
126
|
actors: {
|
|
127
127
|
name: string;
|
|
128
128
|
notes?: string | undefined;
|
|
@@ -131,25 +131,25 @@ export declare const schemas: {
|
|
|
131
131
|
invariants: string[];
|
|
132
132
|
acceptance_scenarios: string[];
|
|
133
133
|
non_goals: string[];
|
|
134
|
+
source_issue?: string | undefined;
|
|
135
|
+
$schema?: string | undefined;
|
|
134
136
|
token_budget_usd?: number | undefined;
|
|
135
137
|
estimate?: "small" | "medium" | "large" | undefined;
|
|
136
|
-
source_issue?: string | undefined;
|
|
137
138
|
refined_by?: string | undefined;
|
|
138
139
|
api_contract?: unknown[] | undefined;
|
|
139
140
|
ui_behavior?: Record<string, string> | undefined;
|
|
140
141
|
related_specs?: {
|
|
141
142
|
id: string;
|
|
142
|
-
relationship: "
|
|
143
|
+
relationship: "superseded" | "overlap" | "related";
|
|
143
144
|
note?: string | undefined;
|
|
144
145
|
}[] | undefined;
|
|
145
|
-
$schema?: string | undefined;
|
|
146
146
|
}, {
|
|
147
|
-
status: "draft" | "active" | "superseded";
|
|
148
|
-
story_id: string;
|
|
149
147
|
title: string;
|
|
150
|
-
|
|
148
|
+
status: "draft" | "active" | "superseded";
|
|
151
149
|
supersedes: string[];
|
|
152
150
|
superseded_by: string | null;
|
|
151
|
+
story_id: string;
|
|
152
|
+
created_at: string;
|
|
153
153
|
actors: {
|
|
154
154
|
name: string;
|
|
155
155
|
notes?: string | undefined;
|
|
@@ -158,18 +158,18 @@ export declare const schemas: {
|
|
|
158
158
|
invariants: string[];
|
|
159
159
|
acceptance_scenarios: string[];
|
|
160
160
|
non_goals: string[];
|
|
161
|
+
source_issue?: string | undefined;
|
|
162
|
+
$schema?: string | undefined;
|
|
161
163
|
token_budget_usd?: number | undefined;
|
|
162
164
|
estimate?: "small" | "medium" | "large" | undefined;
|
|
163
|
-
source_issue?: string | undefined;
|
|
164
165
|
refined_by?: string | undefined;
|
|
165
166
|
api_contract?: unknown[] | undefined;
|
|
166
167
|
ui_behavior?: Record<string, string> | undefined;
|
|
167
168
|
related_specs?: {
|
|
168
169
|
id: string;
|
|
169
|
-
relationship: "
|
|
170
|
+
relationship: "superseded" | "overlap" | "related";
|
|
170
171
|
note?: string | undefined;
|
|
171
172
|
}[] | undefined;
|
|
172
|
-
$schema?: string | undefined;
|
|
173
173
|
}>;
|
|
174
174
|
SpecIndexEntry: z.ZodObject<{
|
|
175
175
|
title: z.ZodString;
|
|
@@ -180,21 +180,21 @@ export declare const schemas: {
|
|
|
180
180
|
supersedes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
181
181
|
superseded_by: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNull]>>;
|
|
182
182
|
}, "strip", z.ZodTypeAny, {
|
|
183
|
-
status: "draft" | "active" | "superseded";
|
|
184
183
|
title: string;
|
|
185
|
-
|
|
186
|
-
superseded_by?: string | null | undefined;
|
|
184
|
+
status: "draft" | "active" | "superseded";
|
|
187
185
|
source_issue?: string | undefined;
|
|
188
186
|
tags?: string[] | undefined;
|
|
189
187
|
summary?: string | undefined;
|
|
190
|
-
}, {
|
|
191
|
-
status: "draft" | "active" | "superseded";
|
|
192
|
-
title: string;
|
|
193
188
|
supersedes?: string[] | undefined;
|
|
194
189
|
superseded_by?: string | null | undefined;
|
|
190
|
+
}, {
|
|
191
|
+
title: string;
|
|
192
|
+
status: "draft" | "active" | "superseded";
|
|
195
193
|
source_issue?: string | undefined;
|
|
196
194
|
tags?: string[] | undefined;
|
|
197
195
|
summary?: string | undefined;
|
|
196
|
+
supersedes?: string[] | undefined;
|
|
197
|
+
superseded_by?: string | null | undefined;
|
|
198
198
|
}>;
|
|
199
199
|
};
|
|
200
200
|
/** Minimal helper for the agent to build a SpecIndexEntry from a Spec. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slowcook-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "CLI for the slowcook brewing harness",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "aminazar",
|
|
@@ -38,8 +38,9 @@
|
|
|
38
38
|
"ts-morph": "^24.0.0",
|
|
39
39
|
"yaml": "^2.6.0",
|
|
40
40
|
"zod": "^3.23.8",
|
|
41
|
-
"@slowcook-ai/core": "^0.
|
|
41
|
+
"@slowcook-ai/core": "^0.8.0",
|
|
42
42
|
"@slowcook-ai/stack-ts": "^0.7.16",
|
|
43
|
+
"@slowcook-ai/llm-anthropic": "^0.8.0",
|
|
43
44
|
"@slowcook-ai/forge-github": "^0.7.12"
|
|
44
45
|
},
|
|
45
46
|
"publishConfig": {
|