@aligndottech/cli 0.35.0 → 0.37.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/dist/commands/import/github.d.ts.map +1 -1
- package/dist/commands/import/github.js +13 -3
- package/dist/commands/import/github.js.map +1 -1
- package/dist/commands/import/sessions.d.ts +16 -4
- package/dist/commands/import/sessions.d.ts.map +1 -1
- package/dist/commands/import/sessions.js +110 -17
- package/dist/commands/import/sessions.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +7 -2
- package/dist/commands/setup.js.map +1 -1
- package/dist/lib/decision-render.d.ts +35 -0
- package/dist/lib/decision-render.d.ts.map +1 -0
- package/dist/lib/decision-render.js +149 -0
- package/dist/lib/decision-render.js.map +1 -0
- package/dist/lib/fetchers/github.d.ts +23 -1
- package/dist/lib/fetchers/github.d.ts.map +1 -1
- package/dist/lib/fetchers/github.js +28 -1
- package/dist/lib/fetchers/github.js.map +1 -1
- package/dist/lib/local-gateway-client.d.ts.map +1 -1
- package/dist/lib/local-gateway-client.js +4 -1
- package/dist/lib/local-gateway-client.js.map +1 -1
- package/dist/lib/local-llm.d.ts +66 -1
- package/dist/lib/local-llm.d.ts.map +1 -1
- package/dist/lib/local-llm.js +165 -11
- package/dist/lib/local-llm.js.map +1 -1
- package/dist/lib/local-relationship-classifier.d.ts +18 -0
- package/dist/lib/local-relationship-classifier.d.ts.map +1 -1
- package/dist/lib/local-relationship-classifier.js +32 -6
- package/dist/lib/local-relationship-classifier.js.map +1 -1
- package/dist/lib/sessions/confirm-freetext.d.ts +43 -0
- package/dist/lib/sessions/confirm-freetext.d.ts.map +1 -0
- package/dist/lib/sessions/confirm-freetext.js +82 -0
- package/dist/lib/sessions/confirm-freetext.js.map +1 -0
- package/dist/lib/sessions/extract-freetext.d.ts +26 -0
- package/dist/lib/sessions/extract-freetext.d.ts.map +1 -0
- package/dist/lib/sessions/extract-freetext.js +53 -0
- package/dist/lib/sessions/extract-freetext.js.map +1 -0
- package/dist/lib/token-estimate.d.ts +17 -0
- package/dist/lib/token-estimate.d.ts.map +1 -0
- package/dist/lib/token-estimate.js +24 -0
- package/dist/lib/token-estimate.js.map +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AgentName, CanonicalSession } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* ALI-809 Pass B, heuristic half: a HUMAN turn whose own words redirect or settle on an
|
|
4
|
+
* approach mid-session. Everything downstream (confirm-freetext.ts) treats this as a proposal
|
|
5
|
+
* only - "heuristic proposes, LLM adjudicates, only adjudicated results assert" is the same
|
|
6
|
+
* shape as decision_links' writer split (align decision ALI-409), applied here to candidates
|
|
7
|
+
* instead of edges.
|
|
8
|
+
*/
|
|
9
|
+
export interface RawFreeTextCandidate {
|
|
10
|
+
agent: AgentName;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
/** `turn-<index>` into the parsed session's turns array - stable for one session file, and
|
|
13
|
+
* used only as an object-reference-free identity in the source_url; nothing here needs it
|
|
14
|
+
* to survive a re-parse of a DIFFERENT file. */
|
|
15
|
+
messageId: string;
|
|
16
|
+
/** The human's own words, verbatim - the only decider-authored content in this candidate. */
|
|
17
|
+
humanText: string;
|
|
18
|
+
/** The assistant turn immediately after, when there is one - CONTEXT for the LLM confirmation
|
|
19
|
+
* pass to read, never itself scanned for the trigger phrase and never the source of the
|
|
20
|
+
* claim (the same "don't let bot content pass as the human's own statement" principle as
|
|
21
|
+
* align decision ALI-538, applied to a different pipeline). */
|
|
22
|
+
contextText: string | null;
|
|
23
|
+
timestamp: string | null;
|
|
24
|
+
}
|
|
25
|
+
export declare function findFreeTextCandidates(session: CanonicalSession): RawFreeTextCandidate[];
|
|
26
|
+
//# sourceMappingURL=extract-freetext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-freetext.d.ts","sourceRoot":"","sources":["../../../src/lib/sessions/extract-freetext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;;qDAEiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB;;;oEAGgE;IAChE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAsCD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,oBAAoB,EAAE,CAgBxF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phrases a human types when redirecting or settling on an approach mid-session. Calibrated
|
|
3
|
+
* against four REAL captured sessions (fixtures/sessions/), not invented - see
|
|
4
|
+
* extract-freetext.test.ts's end-to-end block for which fixture drove which pattern. A miss
|
|
5
|
+
* here is a missed candidate, not a wrong one (the LLM pass only ever narrows further), so
|
|
6
|
+
* staying narrow and growing this as more real sessions are captured beats guessing at
|
|
7
|
+
* phrasings nobody has actually said.
|
|
8
|
+
*/
|
|
9
|
+
const DECISION_PHRASES = [
|
|
10
|
+
/\binstead of\b/i,
|
|
11
|
+
/\blet'?s (go with|use|do|switch to|just use|just go with)\b/i,
|
|
12
|
+
/\bdecid(e|ed|ing|ision)\b/i,
|
|
13
|
+
/\bgo with\b/i,
|
|
14
|
+
/\bswitch(ed|ing)? to\b/i,
|
|
15
|
+
];
|
|
16
|
+
function isDecisionShaped(text) {
|
|
17
|
+
return DECISION_PHRASES.some(p => p.test(text));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The assistant's reply to a human's redirect is rarely one turn: a commentary aside, a tool
|
|
21
|
+
* call, and the actual resolution routinely land as separate turns in the canonical shape
|
|
22
|
+
* (confirmed against the real codex and opencode fixtures - a tool-call turn carries text: ''
|
|
23
|
+
* and sits between the commentary and the resolution in both). Walks every CONSECUTIVE
|
|
24
|
+
* assistant turn starting at `from`, joining the non-empty ones, and stops at the next human
|
|
25
|
+
* turn or the end of the session - never crossing into a later human turn's own reply.
|
|
26
|
+
*/
|
|
27
|
+
function collectAssistantContext(turns, from) {
|
|
28
|
+
const parts = [];
|
|
29
|
+
for (let i = from; i < turns.length && turns[i].role === 'assistant'; i++) {
|
|
30
|
+
if (turns[i].text)
|
|
31
|
+
parts.push(turns[i].text);
|
|
32
|
+
}
|
|
33
|
+
return parts.length ? parts.join('\n') : null;
|
|
34
|
+
}
|
|
35
|
+
export function findFreeTextCandidates(session) {
|
|
36
|
+
const candidates = [];
|
|
37
|
+
session.turns.forEach((turn, i) => {
|
|
38
|
+
// toolCalls-only turns carry text: '' (types.ts), which no phrase can match - no special
|
|
39
|
+
// case needed beyond the phrase test itself.
|
|
40
|
+
if (turn.role !== 'user' || !isDecisionShaped(turn.text))
|
|
41
|
+
return;
|
|
42
|
+
candidates.push({
|
|
43
|
+
agent: session.agent,
|
|
44
|
+
sessionId: session.sessionId,
|
|
45
|
+
messageId: `turn-${i}`,
|
|
46
|
+
humanText: turn.text,
|
|
47
|
+
contextText: collectAssistantContext(session.turns, i + 1),
|
|
48
|
+
timestamp: turn.timestamp,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
return candidates;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=extract-freetext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-freetext.js","sourceRoot":"","sources":["../../../src/lib/sessions/extract-freetext.ts"],"names":[],"mappings":"AA0BA;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAsB;IAC1C,iBAAiB;IACjB,8DAA8D;IAC9D,4BAA4B;IAC5B,cAAc;IACd,yBAAyB;CAC1B,CAAC;AAEF,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAAC,KAAgC,EAAE,IAAY;IAC7E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1E,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAyB;IAC9D,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAChC,yFAAyF;QACzF,6CAA6C;QAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO;QACjE,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,QAAQ,CAAC,EAAE;YACtB,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,WAAW,EAAE,uBAAuB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;YAC1D,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chars per token, measured (2026-09-03 research doc) with Anthropic's count_tokens against a
|
|
3
|
+
* rendered decision corpus: 2.56 on 4.7+ models, 3.43 on older ones. The SMALLER ratio is the
|
|
4
|
+
* conservative one - it estimates MORE tokens per char - so Phase 0 uses it for every family.
|
|
5
|
+
* Never chars/4: that under-counts our corpus by ~36% and the under-count is silent.
|
|
6
|
+
* The per-family table is ALI-852.
|
|
7
|
+
*/
|
|
8
|
+
export declare const CHARS_PER_TOKEN = 2.56;
|
|
9
|
+
export declare const ESTIMATE_MARGIN = 1.1;
|
|
10
|
+
/** Conservative token estimate for a string: rounds UP, and adds a 10% margin on top. */
|
|
11
|
+
export declare function estimateTokens(text: string): number;
|
|
12
|
+
/**
|
|
13
|
+
* The char budget that fits `tokens`, inverse of estimateTokens. Rounds DOWN, so a caller
|
|
14
|
+
* that slices text to `charsForTokens(n)` characters never re-estimates above `n`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function charsForTokens(tokens: number): number;
|
|
17
|
+
//# sourceMappingURL=token-estimate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimate.d.ts","sourceRoot":"","sources":["../../src/lib/token-estimate.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ALI-845 Phase 0: no token-estimation helper existed anywhere in the CLI, so every
|
|
2
|
+
// prompt was assembled by concatenating decision text with no cap. This is the
|
|
3
|
+
// conservative estimator for that phase - a real per-family table is ALI-852's job.
|
|
4
|
+
/**
|
|
5
|
+
* Chars per token, measured (2026-09-03 research doc) with Anthropic's count_tokens against a
|
|
6
|
+
* rendered decision corpus: 2.56 on 4.7+ models, 3.43 on older ones. The SMALLER ratio is the
|
|
7
|
+
* conservative one - it estimates MORE tokens per char - so Phase 0 uses it for every family.
|
|
8
|
+
* Never chars/4: that under-counts our corpus by ~36% and the under-count is silent.
|
|
9
|
+
* The per-family table is ALI-852.
|
|
10
|
+
*/
|
|
11
|
+
export const CHARS_PER_TOKEN = 2.56;
|
|
12
|
+
export const ESTIMATE_MARGIN = 1.1;
|
|
13
|
+
/** Conservative token estimate for a string: rounds UP, and adds a 10% margin on top. */
|
|
14
|
+
export function estimateTokens(text) {
|
|
15
|
+
return Math.ceil((text.length / CHARS_PER_TOKEN) * ESTIMATE_MARGIN);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The char budget that fits `tokens`, inverse of estimateTokens. Rounds DOWN, so a caller
|
|
19
|
+
* that slices text to `charsForTokens(n)` characters never re-estimates above `n`.
|
|
20
|
+
*/
|
|
21
|
+
export function charsForTokens(tokens) {
|
|
22
|
+
return Math.floor((tokens * CHARS_PER_TOKEN) / ESTIMATE_MARGIN);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=token-estimate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimate.js","sourceRoot":"","sources":["../../src/lib/token-estimate.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,+EAA+E;AAC/E,oFAAoF;AAEpF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AAEnC,yFAAyF;AACzF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,GAAG,eAAe,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,eAAe,CAAC,GAAG,eAAe,CAAC,CAAC;AAClE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aligndottech/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.0",
|
|
4
4
|
"mcpName": "io.github.aligndottech/cli",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Align CLI - capture decisions, check alignment, and manage connectors",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"test:coverage": "vitest run --coverage"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@aligndottech/connector-core": "^0.
|
|
37
|
+
"@aligndottech/connector-core": "^0.7.0",
|
|
38
38
|
"@clack/prompts": "^1.7.0",
|
|
39
39
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
40
40
|
"chalk": "^5.3.0",
|
|
@@ -65,6 +65,15 @@
|
|
|
65
65
|
"optionalDependencies": {
|
|
66
66
|
"@huggingface/transformers": "^4.2.0"
|
|
67
67
|
},
|
|
68
|
+
"overrides": {
|
|
69
|
+
"hono": "4.13.7",
|
|
70
|
+
"@hono/node-server": "1.19.17",
|
|
71
|
+
"undici": "6.28.1",
|
|
72
|
+
"fast-uri": "3.1.7",
|
|
73
|
+
"ip-address": "10.7.0",
|
|
74
|
+
"qs": "6.16.0",
|
|
75
|
+
"body-parser": "2.3.0"
|
|
76
|
+
},
|
|
68
77
|
"engines": {
|
|
69
78
|
"node": ">=22.16"
|
|
70
79
|
},
|