@miller-tech/uap 1.104.1 → 1.105.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/.tsbuildinfo +1 -1
- package/dist/bin/cli.js +11 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +12 -0
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/handsfree.d.ts +33 -0
- package/dist/cli/handsfree.d.ts.map +1 -0
- package/dist/cli/handsfree.js +228 -0
- package/dist/cli/handsfree.js.map +1 -0
- package/dist/coordination/persistence-inject.d.ts +16 -0
- package/dist/coordination/persistence-inject.d.ts.map +1 -0
- package/dist/coordination/persistence-inject.js +45 -0
- package/dist/coordination/persistence-inject.js.map +1 -0
- package/dist/coordination/reactor.d.ts.map +1 -1
- package/dist/coordination/reactor.js +13 -0
- package/dist/coordination/reactor.js.map +1 -1
- package/dist/delivery/completion-ledger.d.ts +71 -0
- package/dist/delivery/completion-ledger.d.ts.map +1 -0
- package/dist/delivery/completion-ledger.js +130 -0
- package/dist/delivery/completion-ledger.js.map +1 -0
- package/dist/delivery/handsfree-config.d.ts +12 -0
- package/dist/delivery/handsfree-config.d.ts.map +1 -0
- package/dist/delivery/handsfree-config.js +44 -0
- package/dist/delivery/handsfree-config.js.map +1 -0
- package/dist/delivery/persistence-profile.d.ts +47 -0
- package/dist/delivery/persistence-profile.d.ts.map +1 -0
- package/dist/delivery/persistence-profile.js +78 -0
- package/dist/delivery/persistence-profile.js.map +1 -0
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence reactor injection (Option D) — inject the "keep going, here is
|
|
3
|
+
* what remains" directive into interactive sessions each prompt, so any model
|
|
4
|
+
* (not just Fable, and not only inside `uap deliver`) is continuously told to
|
|
5
|
+
* persist toward the whole multi-epic build's completion.
|
|
6
|
+
*
|
|
7
|
+
* Fires ONLY when hands-free is enabled AND an active completion ledger has
|
|
8
|
+
* remaining items — casual sessions with no build in progress see nothing.
|
|
9
|
+
* Deduped per session by the reactor via a surfaced key; fail-soft.
|
|
10
|
+
*/
|
|
11
|
+
import { loadLedger, remainingItems, formatRemaining } from '../delivery/completion-ledger.js';
|
|
12
|
+
import { loadPersistenceConfig, resolveActiveModel } from '../delivery/handsfree-config.js';
|
|
13
|
+
import { resolvePersistenceProfile } from '../delivery/persistence-profile.js';
|
|
14
|
+
/**
|
|
15
|
+
* Return the persistence directive for injection, or null when hands-free is
|
|
16
|
+
* off, there is no ledger, or the build is already complete.
|
|
17
|
+
*/
|
|
18
|
+
export function maybePersistenceInjection(cwd) {
|
|
19
|
+
try {
|
|
20
|
+
const cfg = loadPersistenceConfig(cwd);
|
|
21
|
+
if (cfg.enabled === false)
|
|
22
|
+
return null;
|
|
23
|
+
const ledger = loadLedger(cwd);
|
|
24
|
+
if (!ledger)
|
|
25
|
+
return null;
|
|
26
|
+
const remaining = remainingItems(ledger);
|
|
27
|
+
if (remaining.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
const profile = resolvePersistenceProfile(resolveActiveModel(cwd), cfg);
|
|
30
|
+
if (!profile.injectAutonomy)
|
|
31
|
+
return null;
|
|
32
|
+
return [
|
|
33
|
+
'A multi-epic build is IN PROGRESS and is NOT complete. Work hands-free to',
|
|
34
|
+
'100% completion: do not stop to ask, do not hand back partial work, and do',
|
|
35
|
+
'not declare done while items remain. Finish the current item, then continue',
|
|
36
|
+
'to the next until the whole build is complete and its gates pass.',
|
|
37
|
+
'',
|
|
38
|
+
formatRemaining(ledger),
|
|
39
|
+
].join('\n');
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=persistence-inject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence-inject.js","sourceRoot":"","sources":["../../src/coordination/persistence-inject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAE/E;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAExC,MAAM,OAAO,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO,CAAC,cAAc;YAAE,OAAO,IAAI,CAAC;QAEzC,OAAO;YACL,2EAA2E;YAC3E,4EAA4E;YAC5E,6EAA6E;YAC7E,mEAAmE;YACnE,EAAE;YACF,eAAe,CAAC,MAAM,CAAC;SACxB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactor.d.ts","sourceRoot":"","sources":["../../src/coordination/reactor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAuB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAoB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"reactor.d.ts","sourceRoot":"","sources":["../../src/coordination/reactor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAuB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAoB,MAAM,qBAAqB,CAAC;AAOtE,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC;AAE/G,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,SAAS,GAAG,WAAW,CAAC;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAuBD,wBAAgB,OAAO,CACrB,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,cAAc,EACrB,IAAI,CAAC,EAAE,WAAW,GACjB,aAAa,CA0Qf"}
|
|
@@ -4,6 +4,7 @@ import { maybeDesignInjection } from '../design/reactor-inject.js';
|
|
|
4
4
|
import { maybeBoardInjection } from './board-inject.js';
|
|
5
5
|
import { maybeCollaborationInjection } from './collaboration-inject.js';
|
|
6
6
|
import { maybeStateInjection } from '../state/reactor-inject.js';
|
|
7
|
+
import { maybePersistenceInjection } from './persistence-inject.js';
|
|
7
8
|
const DEFAULT_INJECT_THRESHOLD = 0.30;
|
|
8
9
|
const DEFAULT_AUTO_SPAWN_THRESHOLD = 0.80;
|
|
9
10
|
const DEFAULT_MAX_INJECT_CHARS = 1200;
|
|
@@ -76,6 +77,14 @@ export function resolve(ctx, opts, deps) {
|
|
|
76
77
|
const collabInject = ctx.cwd && !(ctx.surfaced ?? []).includes(collabKey)
|
|
77
78
|
? maybeCollaborationInjection(ctx.cwd, ctx.promptText)
|
|
78
79
|
: null;
|
|
80
|
+
// Hands-free persistence (Options A-D): when a multi-epic build is in
|
|
81
|
+
// progress (active completion ledger with remaining items), inject a
|
|
82
|
+
// "keep going until the whole build is complete — REMAINING: ..." directive
|
|
83
|
+
// so any model persists like Fable. Deduped per session via `handsfree:persist`.
|
|
84
|
+
const persistKey = 'handsfree:persist';
|
|
85
|
+
const persistInject = ctx.cwd && !(ctx.surfaced ?? []).includes(persistKey)
|
|
86
|
+
? maybePersistenceInjection(ctx.cwd)
|
|
87
|
+
: null;
|
|
79
88
|
// #3-B: delivery routing. Surface up-front (deduped per session via
|
|
80
89
|
// `deliver:routing`) whenever the task routes to a code capability, so the
|
|
81
90
|
// agent calls deliver instead of editing source directly and tripping the gate.
|
|
@@ -111,6 +120,10 @@ export function resolve(ctx, opts, deps) {
|
|
|
111
120
|
blocks.push(`## Agent collaboration\n${collabInject}`);
|
|
112
121
|
keys.push(collabKey);
|
|
113
122
|
}
|
|
123
|
+
if (persistInject) {
|
|
124
|
+
blocks.push(`## Hands-free build — keep going until 100% complete\n${persistInject}`);
|
|
125
|
+
keys.push(persistKey);
|
|
126
|
+
}
|
|
114
127
|
if (boardInject) {
|
|
115
128
|
blocks.push(`## Collaboration board\n${boardInject}`);
|
|
116
129
|
keys.push(boardKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactor.js","sourceRoot":"","sources":["../../src/coordination/reactor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAiB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"reactor.js","sourceRoot":"","sources":["../../src/coordination/reactor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion Ledger (Option B) — the persistent, objective "definition of done"
|
|
3
|
+
* for a huge multi-epic build.
|
|
4
|
+
*
|
|
5
|
+
* A single deliver run judges one task; a huge build is many epics/tasks that
|
|
6
|
+
* can span many turns and many sessions. The ledger externalizes the whole
|
|
7
|
+
* build's DAG + per-item status to `.uap/completion-ledger.json`, so the
|
|
8
|
+
* hands-free machinery (Stop-hook block, reactor injection) can answer one
|
|
9
|
+
* question at any moment: "is the WHOLE build 100% done, and if not, what
|
|
10
|
+
* remains?" — independent of any model's self-assessment.
|
|
11
|
+
*
|
|
12
|
+
* Pure + fail-soft: every reader tolerates a missing/corrupt file by returning
|
|
13
|
+
* null, so the ledger can never wedge a session on its own.
|
|
14
|
+
*/
|
|
15
|
+
export type LedgerStatus = 'pending' | 'in_progress' | 'done' | 'failed';
|
|
16
|
+
export type LedgerKind = 'epic' | 'task' | 'criterion';
|
|
17
|
+
export interface LedgerItem {
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
kind: LedgerKind;
|
|
21
|
+
status: LedgerStatus;
|
|
22
|
+
/** ids this item depends on (informational; the build order lives upstream). */
|
|
23
|
+
deps?: string[];
|
|
24
|
+
/** acceptance criteria for this item (used by the judge / reporting). */
|
|
25
|
+
criteria?: string[];
|
|
26
|
+
/** last status note (e.g. a failure summary). */
|
|
27
|
+
note?: string;
|
|
28
|
+
updatedAt?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface CompletionLedger {
|
|
31
|
+
mission: string;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
updatedAt: string;
|
|
34
|
+
items: LedgerItem[];
|
|
35
|
+
}
|
|
36
|
+
/** Where the ledger lives for a project. */
|
|
37
|
+
export declare function ledgerPath(cwd?: string): string;
|
|
38
|
+
export declare function ledgerExists(cwd?: string): boolean;
|
|
39
|
+
/** Load the ledger, or null when absent/unreadable/corrupt (fail-soft). */
|
|
40
|
+
export declare function loadLedger(cwd?: string): CompletionLedger | null;
|
|
41
|
+
export declare function saveLedger(cwd: string, ledger: CompletionLedger): void;
|
|
42
|
+
export declare function clearLedger(cwd?: string): void;
|
|
43
|
+
export interface NewItem {
|
|
44
|
+
id: string;
|
|
45
|
+
title: string;
|
|
46
|
+
kind?: LedgerKind;
|
|
47
|
+
deps?: string[];
|
|
48
|
+
criteria?: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create (or replace) the ledger for a mission from a set of items. Existing
|
|
52
|
+
* items with the same id preserve their status so re-planning is non-destructive.
|
|
53
|
+
*/
|
|
54
|
+
export declare function initLedger(cwd: string, mission: string, items: NewItem[]): CompletionLedger;
|
|
55
|
+
/** Update one item's status. No-op (returns false) if the ledger/item is absent. */
|
|
56
|
+
export declare function markItem(cwd: string, id: string, status: LedgerStatus, note?: string): boolean;
|
|
57
|
+
/** Items that are not yet done (pending / in_progress / failed). */
|
|
58
|
+
export declare function remainingItems(ledger: CompletionLedger): LedgerItem[];
|
|
59
|
+
/** The whole build is complete only when EVERY item is done. */
|
|
60
|
+
export declare function isComplete(ledger: CompletionLedger): boolean;
|
|
61
|
+
export interface LedgerProgress {
|
|
62
|
+
total: number;
|
|
63
|
+
done: number;
|
|
64
|
+
failed: number;
|
|
65
|
+
pending: number;
|
|
66
|
+
pct: number;
|
|
67
|
+
}
|
|
68
|
+
export declare function progress(ledger: CompletionLedger): LedgerProgress;
|
|
69
|
+
/** A compact, model-facing summary of what still needs doing. */
|
|
70
|
+
export declare function formatRemaining(ledger: CompletionLedger, max?: number): string;
|
|
71
|
+
//# sourceMappingURL=completion-ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion-ledger.d.ts","sourceRoot":"","sources":["../../src/delivery/completion-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AACzE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAE9D;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAEjE;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,gBAAgB,GAAG,IAAI,CAU/E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAKtE;AAED,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,IAAI,CAO7D;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAuB3F;AAED,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAU9F;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,EAAE,CAErE;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAE5D;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,cAAc,CAMjE;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,SAAK,GAAG,MAAM,CAU1E"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion Ledger (Option B) — the persistent, objective "definition of done"
|
|
3
|
+
* for a huge multi-epic build.
|
|
4
|
+
*
|
|
5
|
+
* A single deliver run judges one task; a huge build is many epics/tasks that
|
|
6
|
+
* can span many turns and many sessions. The ledger externalizes the whole
|
|
7
|
+
* build's DAG + per-item status to `.uap/completion-ledger.json`, so the
|
|
8
|
+
* hands-free machinery (Stop-hook block, reactor injection) can answer one
|
|
9
|
+
* question at any moment: "is the WHOLE build 100% done, and if not, what
|
|
10
|
+
* remains?" — independent of any model's self-assessment.
|
|
11
|
+
*
|
|
12
|
+
* Pure + fail-soft: every reader tolerates a missing/corrupt file by returning
|
|
13
|
+
* null, so the ledger can never wedge a session on its own.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
|
|
16
|
+
import { dirname, join } from 'path';
|
|
17
|
+
/** Where the ledger lives for a project. */
|
|
18
|
+
export function ledgerPath(cwd = process.cwd()) {
|
|
19
|
+
return join(cwd, '.uap', 'completion-ledger.json');
|
|
20
|
+
}
|
|
21
|
+
export function ledgerExists(cwd = process.cwd()) {
|
|
22
|
+
return existsSync(ledgerPath(cwd));
|
|
23
|
+
}
|
|
24
|
+
/** Load the ledger, or null when absent/unreadable/corrupt (fail-soft). */
|
|
25
|
+
export function loadLedger(cwd = process.cwd()) {
|
|
26
|
+
try {
|
|
27
|
+
const p = ledgerPath(cwd);
|
|
28
|
+
if (!existsSync(p))
|
|
29
|
+
return null;
|
|
30
|
+
const raw = JSON.parse(readFileSync(p, 'utf-8'));
|
|
31
|
+
if (!raw || !Array.isArray(raw.items))
|
|
32
|
+
return null;
|
|
33
|
+
return raw;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function saveLedger(cwd, ledger) {
|
|
40
|
+
const p = ledgerPath(cwd);
|
|
41
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
42
|
+
ledger.updatedAt = nowISO();
|
|
43
|
+
writeFileSync(p, JSON.stringify(ledger, null, 2) + '\n');
|
|
44
|
+
}
|
|
45
|
+
export function clearLedger(cwd = process.cwd()) {
|
|
46
|
+
try {
|
|
47
|
+
const p = ledgerPath(cwd);
|
|
48
|
+
if (existsSync(p))
|
|
49
|
+
rmSync(p);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* best-effort */
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create (or replace) the ledger for a mission from a set of items. Existing
|
|
57
|
+
* items with the same id preserve their status so re-planning is non-destructive.
|
|
58
|
+
*/
|
|
59
|
+
export function initLedger(cwd, mission, items) {
|
|
60
|
+
const prior = loadLedger(cwd);
|
|
61
|
+
const priorById = new Map((prior?.items ?? []).map((i) => [i.id, i]));
|
|
62
|
+
const ledger = {
|
|
63
|
+
mission: mission.slice(0, 500),
|
|
64
|
+
createdAt: prior?.createdAt ?? nowISO(),
|
|
65
|
+
updatedAt: nowISO(),
|
|
66
|
+
items: items.map((it) => {
|
|
67
|
+
const existing = priorById.get(it.id);
|
|
68
|
+
return {
|
|
69
|
+
id: it.id,
|
|
70
|
+
title: it.title.slice(0, 200),
|
|
71
|
+
kind: it.kind ?? 'epic',
|
|
72
|
+
status: existing?.status ?? 'pending',
|
|
73
|
+
...(it.deps && it.deps.length ? { deps: it.deps } : {}),
|
|
74
|
+
...(it.criteria && it.criteria.length ? { criteria: it.criteria } : {}),
|
|
75
|
+
...(existing?.note ? { note: existing.note } : {}),
|
|
76
|
+
updatedAt: existing?.updatedAt ?? nowISO(),
|
|
77
|
+
};
|
|
78
|
+
}),
|
|
79
|
+
};
|
|
80
|
+
saveLedger(cwd, ledger);
|
|
81
|
+
return ledger;
|
|
82
|
+
}
|
|
83
|
+
/** Update one item's status. No-op (returns false) if the ledger/item is absent. */
|
|
84
|
+
export function markItem(cwd, id, status, note) {
|
|
85
|
+
const ledger = loadLedger(cwd);
|
|
86
|
+
if (!ledger)
|
|
87
|
+
return false;
|
|
88
|
+
const item = ledger.items.find((i) => i.id === id);
|
|
89
|
+
if (!item)
|
|
90
|
+
return false;
|
|
91
|
+
item.status = status;
|
|
92
|
+
item.updatedAt = nowISO();
|
|
93
|
+
if (note !== undefined)
|
|
94
|
+
item.note = note.slice(0, 300);
|
|
95
|
+
saveLedger(cwd, ledger);
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
/** Items that are not yet done (pending / in_progress / failed). */
|
|
99
|
+
export function remainingItems(ledger) {
|
|
100
|
+
return ledger.items.filter((i) => i.status !== 'done');
|
|
101
|
+
}
|
|
102
|
+
/** The whole build is complete only when EVERY item is done. */
|
|
103
|
+
export function isComplete(ledger) {
|
|
104
|
+
return ledger.items.length > 0 && ledger.items.every((i) => i.status === 'done');
|
|
105
|
+
}
|
|
106
|
+
export function progress(ledger) {
|
|
107
|
+
const total = ledger.items.length;
|
|
108
|
+
const done = ledger.items.filter((i) => i.status === 'done').length;
|
|
109
|
+
const failed = ledger.items.filter((i) => i.status === 'failed').length;
|
|
110
|
+
const pending = total - done - failed;
|
|
111
|
+
return { total, done, failed, pending, pct: total ? Math.round((done / total) * 100) : 0 };
|
|
112
|
+
}
|
|
113
|
+
/** A compact, model-facing summary of what still needs doing. */
|
|
114
|
+
export function formatRemaining(ledger, max = 12) {
|
|
115
|
+
const rem = remainingItems(ledger);
|
|
116
|
+
if (rem.length === 0)
|
|
117
|
+
return 'All ledger items complete.';
|
|
118
|
+
const p = progress(ledger);
|
|
119
|
+
const lines = rem.slice(0, max).map((i) => {
|
|
120
|
+
const mark = i.status === 'failed' ? 'x' : i.status === 'in_progress' ? '~' : ' ';
|
|
121
|
+
return ` [${mark}] ${i.id}: ${i.title}${i.note ? ` (${i.note})` : ''}`;
|
|
122
|
+
});
|
|
123
|
+
const more = rem.length > max ? `\n ...and ${rem.length - max} more` : '';
|
|
124
|
+
return `Build progress ${p.done}/${p.total} (${p.pct}%). REMAINING:\n${lines.join('\n')}${more}`;
|
|
125
|
+
}
|
|
126
|
+
function nowISO() {
|
|
127
|
+
// Date.now/new Date are fine at runtime (not inside a workflow script).
|
|
128
|
+
return new Date().toISOString();
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=completion-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion-ledger.js","sourceRoot":"","sources":["../../src/delivery/completion-ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hands-free config resolution — the master switch and active-model lookup for
|
|
3
|
+
* the persistence machinery (Options A-D). Auto-ON by default: hands-free
|
|
4
|
+
* persistence applies to any project with an active completion ledger unless
|
|
5
|
+
* explicitly disabled via `UAP_HANDSFREE=0` or `.uap.json` handsfree.enabled=false.
|
|
6
|
+
*/
|
|
7
|
+
import type { PersistenceConfig } from './persistence-profile.js';
|
|
8
|
+
/** Resolve the persistence config from env + .uap.json (fail-soft, default ON). */
|
|
9
|
+
export declare function loadPersistenceConfig(cwd?: string): PersistenceConfig;
|
|
10
|
+
/** The model doing the work — env override, else the executor role, else unknown. */
|
|
11
|
+
export declare function resolveActiveModel(cwd?: string): string;
|
|
12
|
+
//# sourceMappingURL=handsfree-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handsfree-config.d.ts","sourceRoot":"","sources":["../../src/delivery/handsfree-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAsB,GAAG,iBAAiB,CAepF;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAWtE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hands-free config resolution — the master switch and active-model lookup for
|
|
3
|
+
* the persistence machinery (Options A-D). Auto-ON by default: hands-free
|
|
4
|
+
* persistence applies to any project with an active completion ledger unless
|
|
5
|
+
* explicitly disabled via `UAP_HANDSFREE=0` or `.uap.json` handsfree.enabled=false.
|
|
6
|
+
*/
|
|
7
|
+
import { loadUapConfigRaw } from '../utils/config-loader.js';
|
|
8
|
+
/** Resolve the persistence config from env + .uap.json (fail-soft, default ON). */
|
|
9
|
+
export function loadPersistenceConfig(cwd = process.cwd()) {
|
|
10
|
+
if (process.env.UAP_HANDSFREE === '0')
|
|
11
|
+
return { enabled: false };
|
|
12
|
+
let raw = {};
|
|
13
|
+
try {
|
|
14
|
+
raw = loadUapConfigRaw(cwd) ?? {};
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
raw = {};
|
|
18
|
+
}
|
|
19
|
+
const hf = raw.handsfree ?? {};
|
|
20
|
+
const envIntensity = process.env.UAP_HANDSFREE_INTENSITY;
|
|
21
|
+
return {
|
|
22
|
+
enabled: hf.enabled !== false && process.env.UAP_HANDSFREE !== '0',
|
|
23
|
+
...(envIntensity ? { intensity: envIntensity } : hf.intensity ? { intensity: hf.intensity } : {}),
|
|
24
|
+
...(hf.overrides ? { overrides: hf.overrides } : {}),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** The model doing the work — env override, else the executor role, else unknown. */
|
|
28
|
+
export function resolveActiveModel(cwd = process.cwd()) {
|
|
29
|
+
if (process.env.UAP_ACTIVE_MODEL)
|
|
30
|
+
return process.env.UAP_ACTIVE_MODEL;
|
|
31
|
+
if (process.env.ANTHROPIC_MODEL)
|
|
32
|
+
return process.env.ANTHROPIC_MODEL;
|
|
33
|
+
try {
|
|
34
|
+
const raw = loadUapConfigRaw(cwd) ?? {};
|
|
35
|
+
const mm = raw.multiModel;
|
|
36
|
+
if (mm?.roles?.executor)
|
|
37
|
+
return mm.roles.executor;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* fall through */
|
|
41
|
+
}
|
|
42
|
+
return 'unknown';
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=handsfree-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handsfree-config.js","sourceRoot":"","sources":["../../src/delivery/handsfree-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG7D,mFAAmF;AACnF,MAAM,UAAU,qBAAqB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC/D,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACjE,IAAI,GAAG,GAA4B,EAAE,CAAC;IACtC,IAAI,CAAC;QACH,GAAG,GAAI,gBAAgB,CAAC,GAAG,CAA6B,IAAI,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,EAAE,GAAI,GAAG,CAAC,SAA2C,IAAI,EAAE,CAAC;IAClE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAqE,CAAC;IACvG,OAAO;QACL,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG;QAClE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC5D,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACtE,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACpE,IAAI,CAAC;QACH,MAAM,GAAG,GAAI,gBAAgB,CAAC,GAAG,CAA6B,IAAI,EAAE,CAAC;QACrE,MAAM,EAAE,GAAG,GAAG,CAAC,UAA2D,CAAC;QAC3E,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ;YAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence Profile (Option C) — model-aware hands-free forcing intensity.
|
|
3
|
+
*
|
|
4
|
+
* Fable persists on long tasks intrinsically (trained). Frontier chat models
|
|
5
|
+
* (Opus/Sonnet/GPT) are capable but stop at turn boundaries and declare
|
|
6
|
+
* premature "done". Small local models (qwen35-a3b) additionally loop and
|
|
7
|
+
* mis-declare completion. So the EXTERNAL forcing the harness applies should
|
|
8
|
+
* scale inversely with the model's intrinsic persistence: trust Fable, nudge
|
|
9
|
+
* the frontier, firmly drive the local model — while every profile keeps the
|
|
10
|
+
* anti-spin safeguards (bounded blocks + stagnation give-up) so "never stop
|
|
11
|
+
* early" never becomes "spin forever".
|
|
12
|
+
*
|
|
13
|
+
* Pure + fail-soft: resolution never throws; unknown models get the safe
|
|
14
|
+
* `moderate` default.
|
|
15
|
+
*/
|
|
16
|
+
export type PersistenceIntensity = 'off' | 'light' | 'moderate' | 'aggressive';
|
|
17
|
+
export type ModelFamily = 'fable' | 'frontier' | 'local' | 'unknown';
|
|
18
|
+
export interface PersistenceProfile {
|
|
19
|
+
model: string;
|
|
20
|
+
family: ModelFamily;
|
|
21
|
+
intensity: PersistenceIntensity;
|
|
22
|
+
/** Whether the Stop hook may block session-end while the build is incomplete. */
|
|
23
|
+
stopHookBlocks: boolean;
|
|
24
|
+
/** Hard cap on consecutive Stop-hook blocks before giving up (anti-wedge). */
|
|
25
|
+
maxBlocks: number;
|
|
26
|
+
/** Consecutive no-progress blocks that trigger give-up + escalation. */
|
|
27
|
+
stagnationLimit: number;
|
|
28
|
+
/** Whether to inject the strong autonomy directive into interactive prompts. */
|
|
29
|
+
injectAutonomy: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Classify a model id into a persistence family by name heuristics. */
|
|
32
|
+
export declare function classifyModelFamily(modelId: string): ModelFamily;
|
|
33
|
+
export interface PersistenceConfig {
|
|
34
|
+
/** hands-free master switch; default ON (auto-applied). */
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
/** force a specific intensity regardless of model. */
|
|
37
|
+
intensity?: PersistenceIntensity;
|
|
38
|
+
/** per-model overrides keyed by model id substring. */
|
|
39
|
+
overrides?: Record<string, Partial<PersistenceProfile>>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the effective persistence profile for a model. `off` when hands-free
|
|
43
|
+
* is disabled. An explicit `intensity` (env/config) overrides the family
|
|
44
|
+
* default; per-model overrides refine individual fields.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolvePersistenceProfile(modelId: string | undefined, cfg?: PersistenceConfig): PersistenceProfile;
|
|
47
|
+
//# sourceMappingURL=persistence-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence-profile.d.ts","sourceRoot":"","sources":["../../src/delivery/persistence-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,OAAO,GAAG,UAAU,GAAG,YAAY,CAAC;AAC/E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,oBAAoB,CAAC;IAChC,iFAAiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,cAAc,EAAE,OAAO,CAAC;CACzB;AAmBD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAMhE;AAeD,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,GAAG,GAAE,iBAAsB,GAC1B,kBAAkB,CAqBpB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence Profile (Option C) — model-aware hands-free forcing intensity.
|
|
3
|
+
*
|
|
4
|
+
* Fable persists on long tasks intrinsically (trained). Frontier chat models
|
|
5
|
+
* (Opus/Sonnet/GPT) are capable but stop at turn boundaries and declare
|
|
6
|
+
* premature "done". Small local models (qwen35-a3b) additionally loop and
|
|
7
|
+
* mis-declare completion. So the EXTERNAL forcing the harness applies should
|
|
8
|
+
* scale inversely with the model's intrinsic persistence: trust Fable, nudge
|
|
9
|
+
* the frontier, firmly drive the local model — while every profile keeps the
|
|
10
|
+
* anti-spin safeguards (bounded blocks + stagnation give-up) so "never stop
|
|
11
|
+
* early" never becomes "spin forever".
|
|
12
|
+
*
|
|
13
|
+
* Pure + fail-soft: resolution never throws; unknown models get the safe
|
|
14
|
+
* `moderate` default.
|
|
15
|
+
*/
|
|
16
|
+
const PROFILES = {
|
|
17
|
+
// Fable — trust intrinsic persistence; keep only a light safety net.
|
|
18
|
+
light: { intensity: 'light', stopHookBlocks: true, maxBlocks: 3, stagnationLimit: 2, injectAutonomy: false },
|
|
19
|
+
// Opus/Sonnet/GPT — nudge past premature-done; moderate blocking.
|
|
20
|
+
moderate: { intensity: 'moderate', stopHookBlocks: true, maxBlocks: 6, stagnationLimit: 3, injectAutonomy: true },
|
|
21
|
+
// qwen / small local — firmly drive; more blocks tolerated, tighter stagnation.
|
|
22
|
+
aggressive: { intensity: 'aggressive', stopHookBlocks: true, maxBlocks: 9, stagnationLimit: 3, injectAutonomy: true },
|
|
23
|
+
};
|
|
24
|
+
const OFF_PROFILE = {
|
|
25
|
+
intensity: 'off',
|
|
26
|
+
stopHookBlocks: false,
|
|
27
|
+
maxBlocks: 0,
|
|
28
|
+
stagnationLimit: 0,
|
|
29
|
+
injectAutonomy: false,
|
|
30
|
+
};
|
|
31
|
+
/** Classify a model id into a persistence family by name heuristics. */
|
|
32
|
+
export function classifyModelFamily(modelId) {
|
|
33
|
+
const m = (modelId || '').toLowerCase();
|
|
34
|
+
if (m.includes('fable'))
|
|
35
|
+
return 'fable';
|
|
36
|
+
if (/qwen|a3b|llama|gemma|mistral|deepseek|local|small|3b|7b|8b|14b|32b|35b/.test(m))
|
|
37
|
+
return 'local';
|
|
38
|
+
if (/opus|sonnet|claude|gpt|o1|o3|gemini|grok|haiku/.test(m))
|
|
39
|
+
return 'frontier';
|
|
40
|
+
return 'unknown';
|
|
41
|
+
}
|
|
42
|
+
function familyIntensity(family) {
|
|
43
|
+
switch (family) {
|
|
44
|
+
case 'fable':
|
|
45
|
+
return 'light';
|
|
46
|
+
case 'local':
|
|
47
|
+
return 'aggressive';
|
|
48
|
+
case 'frontier':
|
|
49
|
+
return 'moderate';
|
|
50
|
+
default:
|
|
51
|
+
return 'moderate';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the effective persistence profile for a model. `off` when hands-free
|
|
56
|
+
* is disabled. An explicit `intensity` (env/config) overrides the family
|
|
57
|
+
* default; per-model overrides refine individual fields.
|
|
58
|
+
*/
|
|
59
|
+
export function resolvePersistenceProfile(modelId, cfg = {}) {
|
|
60
|
+
const model = modelId || 'unknown';
|
|
61
|
+
const family = classifyModelFamily(model);
|
|
62
|
+
if (cfg.enabled === false) {
|
|
63
|
+
return { model, family, ...OFF_PROFILE };
|
|
64
|
+
}
|
|
65
|
+
const intensity = cfg.intensity ?? familyIntensity(family);
|
|
66
|
+
const base = intensity === 'off' ? OFF_PROFILE : PROFILES[intensity];
|
|
67
|
+
let profile = { model, family, ...base, intensity };
|
|
68
|
+
// Apply any per-model override whose key is a substring of the model id.
|
|
69
|
+
if (cfg.overrides) {
|
|
70
|
+
for (const [key, ov] of Object.entries(cfg.overrides)) {
|
|
71
|
+
if (model.toLowerCase().includes(key.toLowerCase())) {
|
|
72
|
+
profile = { ...profile, ...ov, model, family };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return profile;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=persistence-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence-profile.js","sourceRoot":"","sources":["../../src/delivery/persistence-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAmBH,MAAM,QAAQ,GAA+F;IAC3G,qEAAqE;IACrE,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE;IAC5G,kEAAkE;IAClE,QAAQ,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE;IACjH,gFAAgF;IAChF,UAAU,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE;CACtH,CAAC;AAEF,MAAM,WAAW,GAAiD;IAChE,SAAS,EAAE,KAAK;IAChB,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,CAAC;IACZ,eAAe,EAAE,CAAC;IAClB,cAAc,EAAE,KAAK;CACtB,CAAC;AAEF,wEAAwE;AACxE,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACxC,IAAI,wEAAwE,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACrG,IAAI,gDAAgD,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC;IAChF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,MAAmB;IAC1C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,YAAY,CAAC;QACtB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC;AAWD;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAA2B,EAC3B,MAAyB,EAAE;IAE3B,MAAM,KAAK,GAAG,OAAO,IAAI,SAAS,CAAC;IACnC,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAE1C,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,SAAS,GAAyB,GAAG,CAAC,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IACjF,MAAM,IAAI,GAAG,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACrE,IAAI,OAAO,GAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC;IAExE,yEAAyE;IACzE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBACpD,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YACjD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
Binary file
|