@manishbht/helpcode 0.2.3 → 0.3.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/bin/helpcode.js +0 -0
- package/dist/src/commands/ask.js +15 -1
- package/dist/src/commands/ask.js.map +1 -1
- package/dist/src/commands/cockpit.d.ts +13 -0
- package/dist/src/commands/cockpit.js +33 -0
- package/dist/src/commands/cockpit.js.map +1 -0
- package/dist/src/commands/plan.d.ts +14 -0
- package/dist/src/commands/plan.js +117 -0
- package/dist/src/commands/plan.js.map +1 -0
- package/dist/src/commands/run.js +55 -4
- package/dist/src/commands/run.js.map +1 -1
- package/dist/src/core/cockpit.d.ts +27 -0
- package/dist/src/core/cockpit.js +109 -0
- package/dist/src/core/cockpit.js.map +1 -0
- package/dist/src/core/cockpitHtml.d.ts +52 -0
- package/dist/src/core/cockpitHtml.js +395 -0
- package/dist/src/core/cockpitHtml.js.map +1 -0
- package/dist/src/core/consent.d.ts +20 -0
- package/dist/src/core/consent.js +34 -0
- package/dist/src/core/consent.js.map +1 -0
- package/dist/src/core/decompose.d.ts +45 -0
- package/dist/src/core/decompose.js +86 -0
- package/dist/src/core/decompose.js.map +1 -0
- package/dist/src/core/gemini.d.ts +41 -0
- package/dist/src/core/gemini.js +91 -0
- package/dist/src/core/gemini.js.map +1 -0
- package/dist/src/core/keys.d.ts +23 -0
- package/dist/src/core/keys.js +68 -0
- package/dist/src/core/keys.js.map +1 -0
- package/dist/src/core/llmSelector.d.ts +6 -0
- package/dist/src/core/llmSelector.js +22 -7
- package/dist/src/core/llmSelector.js.map +1 -1
- package/dist/src/core/selector.d.ts +9 -4
- package/dist/src/core/selector.js +88 -29
- package/dist/src/core/selector.js.map +1 -1
- package/dist/src/core/souschef.d.ts +63 -0
- package/dist/src/core/souschef.js +55 -0
- package/dist/src/core/souschef.js.map +1 -0
- package/dist/src/core/state.d.ts +13 -1
- package/dist/src/core/state.js +47 -5
- package/dist/src/core/state.js.map +1 -1
- package/dist/src/core/triage.d.ts +14 -1
- package/dist/src/core/triage.js +23 -5
- package/dist/src/core/triage.js.map +1 -1
- package/dist/src/index.d.ts +8 -7
- package/dist/src/index.js +21 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +64 -1
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sous-chef layer (v0.3.2) — makes local and remote workers interchangeable
|
|
3
|
+
* behind one interface, with a privacy gate and cheapest-capable-first routing.
|
|
4
|
+
*
|
|
5
|
+
* Design doc: docs/v0.3.2-remote-souschef-design.md
|
|
6
|
+
*
|
|
7
|
+
* The privacy gate is the load-bearing rule: a REMOTE free-tier worker may only
|
|
8
|
+
* receive data the user has accepted leaving the machine. By default that means
|
|
9
|
+
* decomposition only (input is the task description, not code). A per-project
|
|
10
|
+
* `allowRemoteCode` opt-in lets consenting users route code-bearing tasks too.
|
|
11
|
+
*
|
|
12
|
+
* Routing is cheapest-capable-first: local before remote. A remote worker is
|
|
13
|
+
* only chosen when (a) the privacy gate permits the task, (b) no local worker
|
|
14
|
+
* can handle it, and (c) the worker's own canHandle() says yes (e.g. has quota).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The privacy gate. Which tasks may a REMOTE worker receive?
|
|
18
|
+
* - decomposition: always (input is the user's task description, no code)
|
|
19
|
+
* - everything else: only if the project opted into allowRemoteCode
|
|
20
|
+
*
|
|
21
|
+
* Local workers are never gated by this — code never leaves the machine.
|
|
22
|
+
*/
|
|
23
|
+
export function isRemoteAllowedForTask(task, allowRemoteCode) {
|
|
24
|
+
if (task === 'decomposition')
|
|
25
|
+
return true;
|
|
26
|
+
return allowRemoteCode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Can this specific worker handle this task, accounting for privacy AND the
|
|
30
|
+
* worker's own availability veto?
|
|
31
|
+
*/
|
|
32
|
+
export function canWorkerHandle(worker, task, ctx) {
|
|
33
|
+
if (worker.kind === 'remote' && !isRemoteAllowedForTask(task, ctx.allowRemoteCode)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return worker.canHandle(task, ctx);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Pick the cheapest capable worker. Local workers are cheaper than remote, so
|
|
40
|
+
* they're preferred; within a kind, the first in the list wins (stable order).
|
|
41
|
+
* Returns null if nothing can handle the task.
|
|
42
|
+
*/
|
|
43
|
+
export function pickWorker(workers, task, ctx) {
|
|
44
|
+
const capable = workers.filter(w => canWorkerHandle(w, task, ctx));
|
|
45
|
+
if (capable.length === 0)
|
|
46
|
+
return null;
|
|
47
|
+
// local (cheaper) before remote; preserve input order within a kind.
|
|
48
|
+
const localFirst = [...capable].sort((a, b) => {
|
|
49
|
+
if (a.kind === b.kind)
|
|
50
|
+
return 0;
|
|
51
|
+
return a.kind === 'local' ? -1 : 1;
|
|
52
|
+
});
|
|
53
|
+
return localFirst[0];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=souschef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"souschef.js","sourceRoot":"","sources":["../../../src/core/souschef.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiCH;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAkB,EAClB,eAAwB;IAExB,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAgB,EAChB,IAAkB,EAClB,GAAkB;IAElB,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QACnF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,OAAmB,EACnB,IAAkB,EAClB,GAAkB;IAElB,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,qEAAqE;IACrE,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC5C,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC"}
|
package/dist/src/core/state.d.ts
CHANGED
|
@@ -4,8 +4,20 @@
|
|
|
4
4
|
* State is intentionally readable JSON. Users can `cat` it to see exactly
|
|
5
5
|
* what helpcode is thinking. No black-box memory.
|
|
6
6
|
*/
|
|
7
|
-
import { AgentState, CurrentTask } from '../types.js';
|
|
7
|
+
import { AgentState, CurrentTask, SousChefEvent } from '../types.js';
|
|
8
8
|
export declare function loadState(cwd?: string): AgentState;
|
|
9
9
|
export declare function saveState(state: AgentState, cwd?: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* Append a sous-chef event to an in-memory state object (capped). Use this
|
|
12
|
+
* when the caller already holds a loaded state and will saveState() itself —
|
|
13
|
+
* avoids the read-modify-write clobber of two independent load/save cycles.
|
|
14
|
+
*/
|
|
15
|
+
export declare function appendSousChefEvent(state: AgentState, event: SousChefEvent): void;
|
|
16
|
+
/**
|
|
17
|
+
* Append a sous-chef event and persist immediately. Use this only when the
|
|
18
|
+
* caller does NOT already hold a state it will save (standalone recording).
|
|
19
|
+
* If you have a loaded state, prefer appendSousChefEvent + your own saveState.
|
|
20
|
+
*/
|
|
21
|
+
export declare function recordSousChefEvent(event: SousChefEvent, cwd?: string): void;
|
|
10
22
|
export declare function createTask(description: string): CurrentTask;
|
|
11
23
|
export declare function resetState(cwd?: string): void;
|
package/dist/src/core/state.js
CHANGED
|
@@ -9,11 +9,14 @@ import * as path from 'path';
|
|
|
9
9
|
import { HelpcodeError, ErrorCode } from '../lib/errors.js';
|
|
10
10
|
const STATE_DIR = '.helpcode';
|
|
11
11
|
const STATE_FILE = path.join(STATE_DIR, 'state.json');
|
|
12
|
+
/** Keep the sous-chef log bounded so state.json stays small. */
|
|
13
|
+
const MAX_SOUSCHEF_EVENTS = 50;
|
|
12
14
|
function emptyState() {
|
|
13
15
|
return {
|
|
14
|
-
version:
|
|
16
|
+
version: 2,
|
|
15
17
|
currentTask: null,
|
|
16
18
|
history: [],
|
|
19
|
+
sousChefLog: [],
|
|
17
20
|
};
|
|
18
21
|
}
|
|
19
22
|
export function loadState(cwd = process.cwd()) {
|
|
@@ -23,10 +26,7 @@ export function loadState(cwd = process.cwd()) {
|
|
|
23
26
|
}
|
|
24
27
|
try {
|
|
25
28
|
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
26
|
-
|
|
27
|
-
throw new HelpcodeError(ErrorCode.STATE_ERROR, `Unknown state version: ${parsed.version}`, 'This state was written by a different helpcode version. Run `helpcode reset` to start fresh.');
|
|
28
|
-
}
|
|
29
|
-
return parsed;
|
|
29
|
+
return migrate(parsed);
|
|
30
30
|
}
|
|
31
31
|
catch (e) {
|
|
32
32
|
if (e instanceof HelpcodeError)
|
|
@@ -34,6 +34,27 @@ export function loadState(cwd = process.cwd()) {
|
|
|
34
34
|
throw new HelpcodeError(ErrorCode.STATE_ERROR, `Could not parse state file: ${e.message}`, 'Run `helpcode reset` to start fresh (this won\'t touch your code).');
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Migrate older state forward. v1 had no sousChefLog; we add an empty one and
|
|
39
|
+
* bump the version rather than erroring, so existing installs keep working.
|
|
40
|
+
*/
|
|
41
|
+
function migrate(parsed) {
|
|
42
|
+
if (parsed.version === 2) {
|
|
43
|
+
// Defensive: ensure the log array exists even if hand-edited away.
|
|
44
|
+
if (!Array.isArray(parsed.sousChefLog))
|
|
45
|
+
parsed.sousChefLog = [];
|
|
46
|
+
return parsed;
|
|
47
|
+
}
|
|
48
|
+
if (parsed.version === 1) {
|
|
49
|
+
return {
|
|
50
|
+
version: 2,
|
|
51
|
+
currentTask: parsed.currentTask ?? null,
|
|
52
|
+
history: Array.isArray(parsed.history) ? parsed.history : [],
|
|
53
|
+
sousChefLog: [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
throw new HelpcodeError(ErrorCode.STATE_ERROR, `Unknown state version: ${parsed.version}`, 'This state was written by a newer helpcode. Upgrade, or run `helpcode reset`.');
|
|
57
|
+
}
|
|
37
58
|
export function saveState(state, cwd = process.cwd()) {
|
|
38
59
|
const dir = path.join(cwd, STATE_DIR);
|
|
39
60
|
if (!fs.existsSync(dir))
|
|
@@ -43,6 +64,27 @@ export function saveState(state, cwd = process.cwd()) {
|
|
|
43
64
|
fs.writeFileSync(tmp, JSON.stringify(state, null, 2), 'utf-8');
|
|
44
65
|
fs.renameSync(tmp, file);
|
|
45
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Append a sous-chef event to an in-memory state object (capped). Use this
|
|
69
|
+
* when the caller already holds a loaded state and will saveState() itself —
|
|
70
|
+
* avoids the read-modify-write clobber of two independent load/save cycles.
|
|
71
|
+
*/
|
|
72
|
+
export function appendSousChefEvent(state, event) {
|
|
73
|
+
state.sousChefLog.push(event);
|
|
74
|
+
if (state.sousChefLog.length > MAX_SOUSCHEF_EVENTS) {
|
|
75
|
+
state.sousChefLog = state.sousChefLog.slice(-MAX_SOUSCHEF_EVENTS);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Append a sous-chef event and persist immediately. Use this only when the
|
|
80
|
+
* caller does NOT already hold a state it will save (standalone recording).
|
|
81
|
+
* If you have a loaded state, prefer appendSousChefEvent + your own saveState.
|
|
82
|
+
*/
|
|
83
|
+
export function recordSousChefEvent(event, cwd = process.cwd()) {
|
|
84
|
+
const state = loadState(cwd);
|
|
85
|
+
appendSousChefEvent(state, event);
|
|
86
|
+
saveState(state, cwd);
|
|
87
|
+
}
|
|
46
88
|
export function createTask(description) {
|
|
47
89
|
const now = new Date().toISOString();
|
|
48
90
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/core/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE5D,MAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAEtD,SAAS,UAAU;IACjB,OAAO;QACL,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/core/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,8 +16,10 @@ import { OllamaSettings } from '../types.js';
|
|
|
16
16
|
export interface TriageResult {
|
|
17
17
|
/** The compacted output to put in the brief. */
|
|
18
18
|
text: string;
|
|
19
|
-
/** True if
|
|
19
|
+
/** True if a model (local or remote) produced the summary; false if fallback. */
|
|
20
20
|
triaged: boolean;
|
|
21
|
+
/** True if the remote model produced it (for the cockpit). */
|
|
22
|
+
remote?: boolean;
|
|
21
23
|
}
|
|
22
24
|
type GenerateImpl = (host: string, model: string, prompt: string, opts?: {
|
|
23
25
|
timeoutMs?: number;
|
|
@@ -25,6 +27,12 @@ type GenerateImpl = (host: string, model: string, prompt: string, opts?: {
|
|
|
25
27
|
export interface TriageDeps {
|
|
26
28
|
/** Injectable model call for testing. Defaults to the real Ollama client. */
|
|
27
29
|
generateImpl?: GenerateImpl;
|
|
30
|
+
/**
|
|
31
|
+
* Optional remote-model fallback (prompt → text). Supplied by the caller ONLY
|
|
32
|
+
* when allowRemoteCode is on and a key is present (triage output is
|
|
33
|
+
* code-bearing). Tried after local fails, before deterministic truncation.
|
|
34
|
+
*/
|
|
35
|
+
remoteGenerate?: (prompt: string) => Promise<string>;
|
|
28
36
|
}
|
|
29
37
|
/** Is this output worth sending to the model? Long, and Ollama enabled. */
|
|
30
38
|
export declare function shouldTriage(output: string, ollama: Pick<OllamaSettings, 'enabled'>): boolean;
|
|
@@ -32,6 +40,11 @@ export declare function buildTriagePrompt(output: string): string;
|
|
|
32
40
|
/**
|
|
33
41
|
* Triage command output. Returns a compacted version plus whether the model
|
|
34
42
|
* was used. Never throws — any failure falls back to deterministic truncation.
|
|
43
|
+
*
|
|
44
|
+
* Order: local model → remote model (if provided; privacy-gated by the caller)
|
|
45
|
+
* → deterministic truncation. `deps.remoteGenerate` is supplied by the caller
|
|
46
|
+
* only when allowRemoteCode is on and a key is present — triage output can
|
|
47
|
+
* contain code, so it's code-bearing.
|
|
35
48
|
*/
|
|
36
49
|
export declare function triageOutput(output: string, ollama: OllamaSettings, deps?: TriageDeps): Promise<TriageResult>;
|
|
37
50
|
export {};
|
package/dist/src/core/triage.js
CHANGED
|
@@ -41,6 +41,11 @@ export function buildTriagePrompt(output) {
|
|
|
41
41
|
/**
|
|
42
42
|
* Triage command output. Returns a compacted version plus whether the model
|
|
43
43
|
* was used. Never throws — any failure falls back to deterministic truncation.
|
|
44
|
+
*
|
|
45
|
+
* Order: local model → remote model (if provided; privacy-gated by the caller)
|
|
46
|
+
* → deterministic truncation. `deps.remoteGenerate` is supplied by the caller
|
|
47
|
+
* only when allowRemoteCode is on and a key is present — triage output can
|
|
48
|
+
* contain code, so it's code-bearing.
|
|
44
49
|
*/
|
|
45
50
|
export async function triageOutput(output, ollama, deps = {}) {
|
|
46
51
|
// Short output, or triage disabled: return as-is or truncate, no model.
|
|
@@ -51,19 +56,32 @@ export async function triageOutput(output, ollama, deps = {}) {
|
|
|
51
56
|
: output;
|
|
52
57
|
return { text, triaged: false };
|
|
53
58
|
}
|
|
59
|
+
const prompt = buildTriagePrompt(output);
|
|
60
|
+
// 1. Local model (cheapest).
|
|
54
61
|
const generateImpl = deps.generateImpl ?? generate;
|
|
55
62
|
try {
|
|
56
|
-
const summary = await generateImpl(ollama.host, ollama.model,
|
|
63
|
+
const summary = await generateImpl(ollama.host, ollama.model, prompt, { timeoutMs: ollama.timeoutMs });
|
|
57
64
|
if (summary && summary.trim().length > 0) {
|
|
58
65
|
return { text: summary.trim(), triaged: true };
|
|
59
66
|
}
|
|
60
|
-
// Empty model result: fall back.
|
|
61
|
-
return { text: truncateLines(output, FALLBACK_MAX_LINES, 'lines'), triaged: false };
|
|
62
67
|
}
|
|
63
68
|
catch (e) {
|
|
64
|
-
// Transport/timeout/etc.: fall back to deterministic truncation.
|
|
65
69
|
void (e instanceof OllamaError);
|
|
66
|
-
|
|
70
|
+
// fall through to remote / deterministic
|
|
71
|
+
}
|
|
72
|
+
// 2. Remote model, if the caller provided one (privacy-gated upstream).
|
|
73
|
+
if (deps.remoteGenerate) {
|
|
74
|
+
try {
|
|
75
|
+
const summary = await deps.remoteGenerate(prompt);
|
|
76
|
+
if (summary && summary.trim().length > 0) {
|
|
77
|
+
return { text: summary.trim(), triaged: true, remote: true };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// fall through to deterministic
|
|
82
|
+
}
|
|
67
83
|
}
|
|
84
|
+
// 3. Deterministic truncation — always works.
|
|
85
|
+
return { text: truncateLines(output, FALLBACK_MAX_LINES, 'lines'), triaged: false };
|
|
68
86
|
}
|
|
69
87
|
//# sourceMappingURL=triage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triage.js","sourceRoot":"","sources":["../../../src/core/triage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,iEAAiE;AACjE,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,6CAA6C;AAC7C,MAAM,kBAAkB,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"triage.js","sourceRoot":"","sources":["../../../src/core/triage.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* helpcode — CLI router.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* init
|
|
6
|
-
* ask
|
|
7
|
-
* apply
|
|
8
|
-
* run
|
|
9
|
-
* status
|
|
10
|
-
*
|
|
4
|
+
* Commands, kept deliberately small:
|
|
5
|
+
* init detect project and set up .helpcode/
|
|
6
|
+
* ask compose a prompt for Claude.ai
|
|
7
|
+
* apply apply Claude's reply
|
|
8
|
+
* run run a shell command, get compact output
|
|
9
|
+
* status show current state
|
|
10
|
+
* cockpit show the sous-chef kitchen this session (v0.3)
|
|
11
|
+
* reset clear state
|
|
11
12
|
*/
|
|
12
13
|
export declare function run(argv: string[]): Promise<number>;
|
package/dist/src/index.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* helpcode — CLI router.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* init
|
|
6
|
-
* ask
|
|
7
|
-
* apply
|
|
8
|
-
* run
|
|
9
|
-
* status
|
|
10
|
-
*
|
|
4
|
+
* Commands, kept deliberately small:
|
|
5
|
+
* init detect project and set up .helpcode/
|
|
6
|
+
* ask compose a prompt for Claude.ai
|
|
7
|
+
* apply apply Claude's reply
|
|
8
|
+
* run run a shell command, get compact output
|
|
9
|
+
* status show current state
|
|
10
|
+
* cockpit show the sous-chef kitchen this session (v0.3)
|
|
11
|
+
* reset clear state
|
|
11
12
|
*/
|
|
12
13
|
import { handleInit } from './commands/init.js';
|
|
13
14
|
import { handleAsk } from './commands/ask.js';
|
|
14
15
|
import { handleApply } from './commands/apply.js';
|
|
15
16
|
import { handleRun } from './commands/run.js';
|
|
16
17
|
import { handleStatus } from './commands/status.js';
|
|
18
|
+
import { handlePlan } from './commands/plan.js';
|
|
19
|
+
import { handleCockpit } from './commands/cockpit.js';
|
|
17
20
|
import { handleReset } from './commands/reset.js';
|
|
18
21
|
import { HelpcodeError } from './lib/errors.js';
|
|
19
22
|
import { c, log } from './lib/ui.js';
|
|
20
|
-
const VERSION = '0.
|
|
23
|
+
const VERSION = '0.3.4';
|
|
21
24
|
const HELP = `helpcode v${VERSION}
|
|
22
25
|
|
|
23
26
|
A local agent that makes Claude.ai conversations efficient enough to ship
|
|
@@ -32,9 +35,11 @@ COMMANDS:
|
|
|
32
35
|
--files <paths...> include specific files (skips auto-selection)
|
|
33
36
|
--no-llm force keyword selection even if Ollama is on
|
|
34
37
|
--explain-selection show why each file was chosen
|
|
38
|
+
plan "<task>" Propose an ordered breakdown of a big task (local model)
|
|
35
39
|
apply [--yes] [--dry-run] Apply Claude's pasted reply (from stdin)
|
|
36
40
|
run "<command>" Run a shell command, get compact output
|
|
37
41
|
status Show current task and state
|
|
42
|
+
cockpit [--html] [--out F] Show the kitchen; --html writes a visual cockpit
|
|
38
43
|
reset [--yes] Clear state (project config is untouched)
|
|
39
44
|
|
|
40
45
|
GLOBAL FLAGS:
|
|
@@ -66,6 +71,10 @@ export async function run(argv) {
|
|
|
66
71
|
explainSelection: rest.includes('--explain-selection'),
|
|
67
72
|
});
|
|
68
73
|
}
|
|
74
|
+
case 'plan': {
|
|
75
|
+
const task = rest.filter(a => !a.startsWith('--')).join(' ');
|
|
76
|
+
return await handlePlan(task);
|
|
77
|
+
}
|
|
69
78
|
case 'apply':
|
|
70
79
|
return await handleApply({
|
|
71
80
|
yes: rest.includes('--yes'),
|
|
@@ -78,6 +87,10 @@ export async function run(argv) {
|
|
|
78
87
|
}
|
|
79
88
|
case 'status':
|
|
80
89
|
return await handleStatus();
|
|
90
|
+
case 'cockpit': {
|
|
91
|
+
const out = extractFlagValues(rest, '--out')[0];
|
|
92
|
+
return await handleCockpit({ html: rest.includes('--html'), out });
|
|
93
|
+
}
|
|
81
94
|
case 'reset':
|
|
82
95
|
return await handleReset({ yes: rest.includes('--yes') });
|
|
83
96
|
default:
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -19,6 +19,24 @@ export interface ProjectConfig {
|
|
|
19
19
|
createdAt: string;
|
|
20
20
|
/** Optional local-LLM (Ollama) settings for smarter file selection (v0.2). */
|
|
21
21
|
ollama?: OllamaSettings;
|
|
22
|
+
/** Optional remote free-tier sous-chef settings (v0.3.2). */
|
|
23
|
+
remote?: RemoteSettings;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Remote free-tier sous-chef configuration (v0.3.2). Opt-in by presence of an
|
|
27
|
+
* API key (env var or .helpcode/keys.json) — this block only carries the
|
|
28
|
+
* privacy preference, never the key itself (keys must never touch project.json).
|
|
29
|
+
*/
|
|
30
|
+
export interface RemoteSettings {
|
|
31
|
+
/**
|
|
32
|
+
* Allow code-bearing tasks (file selection, output triage) to be sent to a
|
|
33
|
+
* remote FREE-TIER provider, whose terms may use inputs to train their models.
|
|
34
|
+
* Default false: by default only decomposition (task description, no code)
|
|
35
|
+
* goes remote. Flip to true ONLY if you accept your source code leaving the
|
|
36
|
+
* machine to a free tier. A one-time notice is shown the first time it takes
|
|
37
|
+
* effect.
|
|
38
|
+
*/
|
|
39
|
+
allowRemoteCode: boolean;
|
|
22
40
|
}
|
|
23
41
|
/** Local-LLM configuration. Opt-in; absent or disabled = heuristic only. */
|
|
24
42
|
export interface OllamaSettings {
|
|
@@ -36,10 +54,23 @@ export type TaskStatus = 'idle' | 'awaiting_paste' | 'applying' | 'testing' | 'r
|
|
|
36
54
|
/** The agent's memory across CLI invocations. Stored at .helpcode/state.json. */
|
|
37
55
|
export interface AgentState {
|
|
38
56
|
/** Schema version so we can migrate later without breaking installs. */
|
|
39
|
-
version:
|
|
57
|
+
version: 2;
|
|
40
58
|
currentTask: CurrentTask | null;
|
|
41
59
|
/** History of resolved tasks (summary only, not full content). */
|
|
42
60
|
history: TaskHistoryEntry[];
|
|
61
|
+
/**
|
|
62
|
+
* Rolling log of sous-chef work this session (v0.3). The cockpit reads this;
|
|
63
|
+
* the tasks (and future engine) append to it. Capped to a recent window so
|
|
64
|
+
* the state file stays small.
|
|
65
|
+
*/
|
|
66
|
+
sousChefLog: SousChefEvent[];
|
|
67
|
+
/** One-time UI flags (e.g. consent notices already shown). Optional. */
|
|
68
|
+
flags?: StateFlags;
|
|
69
|
+
}
|
|
70
|
+
/** One-time flags persisted so we don't repeat notices. All optional. */
|
|
71
|
+
export interface StateFlags {
|
|
72
|
+
/** True once the "sending code to a free tier" notice has been shown. */
|
|
73
|
+
remoteCodeNoticeShown?: boolean;
|
|
43
74
|
}
|
|
44
75
|
export interface CurrentTask {
|
|
45
76
|
id: string;
|
|
@@ -68,3 +99,35 @@ export interface TaskHistoryEntry {
|
|
|
68
99
|
resolvedAt: string;
|
|
69
100
|
iterations: number;
|
|
70
101
|
}
|
|
102
|
+
/** Who did a unit of prep work. */
|
|
103
|
+
export type WorkerKind = 'local' | 'remote' | 'deterministic' | 'principal';
|
|
104
|
+
/** A prep task helpcode knows how to route to a worker. */
|
|
105
|
+
export type SousChefTask = 'file_selection' | 'output_triage' | 'decomposition' | 'other';
|
|
106
|
+
/** One recorded unit of work, written by whoever performed it. */
|
|
107
|
+
export interface SousChefEvent {
|
|
108
|
+
/** ISO timestamp. */
|
|
109
|
+
at: string;
|
|
110
|
+
/** Which prep task. */
|
|
111
|
+
task: SousChefTask;
|
|
112
|
+
/** Who did it. */
|
|
113
|
+
worker: WorkerKind;
|
|
114
|
+
/** Model tag if a model did it (e.g. "qwen2.5-coder:7b"), else null. */
|
|
115
|
+
model: string | null;
|
|
116
|
+
/** One-line human-readable summary of what happened. */
|
|
117
|
+
summary: string;
|
|
118
|
+
/** Did this work succeed, or fall back to a cheaper worker? */
|
|
119
|
+
outcome: 'ok' | 'fallback' | 'escalated';
|
|
120
|
+
/** Rough estimate of principal tokens this prep saved, if known. */
|
|
121
|
+
estTokensSaved: number | null;
|
|
122
|
+
}
|
|
123
|
+
/** Per-worker rolling status for the cockpit panels. */
|
|
124
|
+
export interface WorkerStatus {
|
|
125
|
+
kind: WorkerKind;
|
|
126
|
+
model: string | null;
|
|
127
|
+
/** Free-tier quota used 0..1, if the worker has a quota (remote). null = N/A. */
|
|
128
|
+
quotaUsed: number | null;
|
|
129
|
+
/** Count of events this session. */
|
|
130
|
+
eventsThisSession: number;
|
|
131
|
+
/** Last summary line, for the panel log. */
|
|
132
|
+
lastSummary: string | null;
|
|
133
|
+
}
|
package/package.json
CHANGED