koneck 2.128.34 → 2.128.35
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/engine.d.ts +19 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +30 -3
- package/dist/engine.js.map +1 -1
- package/dist/ink-chat.d.ts +19 -0
- package/dist/ink-chat.d.ts.map +1 -1
- package/dist/ink-chat.js +185 -8
- package/dist/ink-chat.js.map +1 -1
- package/dist/plan-file.d.ts +67 -0
- package/dist/plan-file.d.ts.map +1 -0
- package/dist/plan-file.js +95 -0
- package/dist/plan-file.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/ink-chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ink-chat.d.ts","sourceRoot":"","sources":["../src/ink-chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AA6B3D,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAuCtE,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ink-chat.d.ts","sourceRoot":"","sources":["../src/ink-chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AA6B3D,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAuCtE,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAkB5D,OAAO,EAA6C,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3F,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAoD7D,KAAK,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAGhD,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI9D;AAyED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAM7C;AA0BD,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BpE;AAED,qFAAqF;AACrF;;;;;GAKG;AASH,eAAO,MAAM,YAAY,mBAAuB,CAAC;AAEjD,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAchG;AAED,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAiB,GAAG,MAAM,CAM9E;AA6CD;;;;;;;;;;;GAWG;AACH,2EAA2E;AAC3E,eAAO,MAAM,eAAe,IAAI,CAAC;AAejC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,UAAU,UAAO,EACjB,KAAK,SAAkB,GACtB,MAAM,CAqBR;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGnE;AAoBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAAS,CAAC;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,OAAQ,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,gGAAgG;AAChG,eAAO,MAAM,SAAS,IAAI,CAAC;AAE3B,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,SAAY,GAC5D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAoB7C;AAmBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAE7F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAGlG;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAGtG;AAyBD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EACzC,KAAK,QAAQ,EAAE,KAAK,UAAU,GAC/B,MAAM,iBAAiB,CAAC;AA+EzB,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASpD;AAYD,8CAA8C;AAC9C,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAClF,UAAU,UAAU;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;AAEtG,qGAAqG;AACrG,wBAAgB,mBAAmB,CACjC,QAAQ,GAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAa,GAC5D,UAAU,EAAE,CAId;AAUD,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAK7E;AAiCD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAuBR;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAWlF;AAyBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,WAAiC,GAAG,MAAM,GAAG,SAAS,CAgBhH;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAM/F;AAED,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,EAAE,CAInG;AAGD,iGAAiG;AACjG,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAiBpE;AAQD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAMjF;AAGD;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,UAAU,GAAG,MAAM,CAAC;AAE9E,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAC7E,GAAG,WAAW,CAmBd;AAGD,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAKvF;AAGD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACZ,MAAM,CAMR;AAiCD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,UAAQ,GAAG,MAAM,CAEvD;AAED,KAAK,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC;AAElG,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,eAAe,EAAE,GAAG,MAAM,CAa1G;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,UAAQ,GAAG,MAAM,CAOzE;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,iGAAiG;AACjG,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9D;AAID,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAa7C,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQxE;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,6EAA6E;AAC7E,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO9E;AAED,8FAA8F;AAC9F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,MAAM,CAGjF;AAED,oFAAoF;AACpF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAsBpE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CASrF;AAED,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrF,GAAG,OAAO,CAEV;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,OAAO,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,sBAAsB,UAAQ,GAC7B,OAAO,GAAG,MAAM,GAAG,KAAK,CAiB1B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,sGAAsG;AACtG,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,eAAe,CAAC,EAAE,MAAM,EACxB,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAClC,MAAM,CAcR;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,OAAO,CAMnE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzD;AA6ED;;;;;GAKG;AACH;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAU3D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAKpB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAmB,EAC7E,GAAG,GAAE,MAAM,CAAC,UAAwB;AACpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,iBAAiB,UAAQ,GACxB,OAAO,CAQT;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EACjD,iBAAiB,EAAE,OAAO,EAC1B,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAmB,EAC7E,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAsBT;AAqDD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAgB,EAAE,MAAU,EAAE,EAAE;IAChE,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAC1D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,KAAK,CAAC,GAAG,CAAC,OAAO,CAiJnB;AAED;;;;;;;GAOG;AACH;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAqB1F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAC5D,MAAM,GAAG,IAAI,CASf;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GACnD,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAMzB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAC1E;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAMjC;AAED,wBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,kBAA0B,EAAE,EACxE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7C,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAm7LhE;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCvE"}
|
package/dist/ink-chat.js
CHANGED
|
@@ -49,6 +49,7 @@ import { startBus, listSessions as listBusSessions, resolveTarget, deliver, } fr
|
|
|
49
49
|
import { MODES as MODE_SPECS, modeSpec, decide, loadRules, saveRules, addRule, commandPrefixSuggestion, describeRule, ruleMatches, toolRisk, isReadOnlyCommand, } from './permissions.js';
|
|
50
50
|
import { AskQueue } from './ask-queue.js';
|
|
51
51
|
import { planSummary } from './plan.js';
|
|
52
|
+
import { savePlan, plansDir, PLAN_CHOICES, PROCEED_PROMPT } from './plan-file.js';
|
|
52
53
|
import { logoFor } from './logo.js';
|
|
53
54
|
import { describeActivity } from './activity.js';
|
|
54
55
|
import { redactSecrets, containsSecret } from './redact.js';
|
|
@@ -503,6 +504,41 @@ export const WORD_HOLD_MS = 60_000;
|
|
|
503
504
|
* appears frozen for seven seconds is worse than either.
|
|
504
505
|
*/
|
|
505
506
|
export const HEARTBEAT_MS = 1_000;
|
|
507
|
+
/**
|
|
508
|
+
* One row of the fork tree: the task on the left, what it has cost on the right.
|
|
509
|
+
*
|
|
510
|
+
* Right-aligning the cost is the whole point of doing this by hand. Laid out as flex siblings the
|
|
511
|
+
* numbers sat wherever the task text left them, so a column of forks had its timings in a ragged
|
|
512
|
+
* diagonal and could not be read down. Composed into one string they line up at the right edge —
|
|
513
|
+
* and it is one node per row rather than five, which is what a live list of eight agents can
|
|
514
|
+
* afford to repaint.
|
|
515
|
+
*
|
|
516
|
+
* The task gives way first: it is the part a reader can still recognise from its opening words,
|
|
517
|
+
* while a truncated token count is worth nothing at all.
|
|
518
|
+
*/
|
|
519
|
+
/** The width of what precedes the task on a fork row: a status glyph, a space, and "fork ". */
|
|
520
|
+
export const FORK_LEAD = 8;
|
|
521
|
+
export function forkRow(task, meta, width, indent = FORK_LEAD) {
|
|
522
|
+
/*
|
|
523
|
+
* Nothing here may add up to more than the width it was given.
|
|
524
|
+
*
|
|
525
|
+
* The first version floored the task at eight columns and the gap at one, which on a narrow
|
|
526
|
+
* terminal produced a row a character longer than the space it had. An overflowing row is not a
|
|
527
|
+
* cosmetic problem in this interface — it is how the live region grows past the window, and a
|
|
528
|
+
* live region past the window is what makes Ink wipe the whole terminal on every render.
|
|
529
|
+
*
|
|
530
|
+
* So the budget is spent in order of what is worth keeping: the cost first, because a truncated
|
|
531
|
+
* token count says nothing, then whatever is left goes to the task, which stays recognisable
|
|
532
|
+
* from its opening words. Where there is not even room for the cost, it is cut too — a row that
|
|
533
|
+
* fits and says less beats a row that says more and breaks the screen.
|
|
534
|
+
*/
|
|
535
|
+
const avail = Math.max(0, width - indent);
|
|
536
|
+
const shownMeta = meta.length <= avail ? meta : meta.slice(0, avail);
|
|
537
|
+
const room = Math.max(0, avail - shownMeta.length - 1);
|
|
538
|
+
const shownTask = room > 0 ? fitCells(task, room, true) : '';
|
|
539
|
+
const gap = ' '.repeat(Math.max(0, avail - displayWidth(shownTask) - shownMeta.length));
|
|
540
|
+
return { task: shownTask, gap, meta: shownMeta };
|
|
541
|
+
}
|
|
506
542
|
/**
|
|
507
543
|
* The cursor, drawn as a painted cell rather than as a character.
|
|
508
544
|
*
|
|
@@ -636,6 +672,7 @@ const COMMANDS = [
|
|
|
636
672
|
{ cmd: '/thinking', desc: 'Show or hide the model\'s reasoning as it arrives' },
|
|
637
673
|
{ cmd: '/activity', desc: 'What the model has done this session, and what it is on now' },
|
|
638
674
|
{ cmd: '/trajectory', desc: 'Where the time went: per-request timings, tool durations, waits' },
|
|
675
|
+
{ cmd: '/compact', desc: 'Summarise the conversation so far to free up context' },
|
|
639
676
|
{ cmd: '/update', desc: 'Check for a new version and update' },
|
|
640
677
|
{ cmd: '/name', desc: 'Name this session, so /resume can find it by name' },
|
|
641
678
|
{ cmd: '/fork', desc: 'Copy this session and continue on the copy' },
|
|
@@ -1226,6 +1263,7 @@ Type / on an empty line to browse every command; keep typing to filter.
|
|
|
1226
1263
|
|
|
1227
1264
|
Slash commands:
|
|
1228
1265
|
/help Show this help
|
|
1266
|
+
/compact Summarise the conversation so far to free up context
|
|
1229
1267
|
/update Updates and a key guide, in a side panel
|
|
1230
1268
|
/models [filter] Browse models from the connected provider and switch
|
|
1231
1269
|
/connect [provider] Connect a provider (picker when no name given)
|
|
@@ -1962,6 +2000,22 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
1962
2000
|
// run is the record of what the agent thought it was doing.
|
|
1963
2001
|
addRow({ role: 'plan', plan: next });
|
|
1964
2002
|
},
|
|
2003
|
+
/*
|
|
2004
|
+
* Compaction is announced, because it is not a detail.
|
|
2005
|
+
*
|
|
2006
|
+
* It already ran on its own when the window filled — `onCompress` has been in the config all
|
|
2007
|
+
* along and this interface never wired it, so the conversation was summarised and replaced
|
|
2008
|
+
* underneath somebody mid-task with nothing on screen to say so. The next answer would then
|
|
2009
|
+
* be missing something said an hour earlier and look like the model forgetting.
|
|
2010
|
+
*/
|
|
2011
|
+
onCompress: (before, after, limit) => {
|
|
2012
|
+
addSystem(`Context compacted — ${before} messages summarised into ${after}, to stay inside `
|
|
2013
|
+
+ `${limit.toLocaleString()} tokens. Earlier detail is now a summary; `
|
|
2014
|
+
+ '`/compact` forces this, and a new session starts clean.');
|
|
2015
|
+
},
|
|
2016
|
+
onCompactNoop: (reason) => {
|
|
2017
|
+
addSystem(`Nothing was compacted — ${reason}.`);
|
|
2018
|
+
},
|
|
1965
2019
|
onChunk: (text) => pushSay(text),
|
|
1966
2020
|
onToolCall: (name, args) => pushTool(name, args),
|
|
1967
2021
|
/*
|
|
@@ -2556,6 +2610,14 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
2556
2610
|
})();
|
|
2557
2611
|
}, [effort]);
|
|
2558
2612
|
const [showAnalytics, setShowAnalytics] = useState(false);
|
|
2613
|
+
/**
|
|
2614
|
+
* A finished plan, waiting to be answered.
|
|
2615
|
+
*
|
|
2616
|
+
* Plan mode used to end with the plan in the transcript and nothing else — you changed mode
|
|
2617
|
+
* yourself and asked again, from memory, for the thing you had just read. This is the handover
|
|
2618
|
+
* that was missing: the plan, where it was saved, and the obvious question.
|
|
2619
|
+
*/
|
|
2620
|
+
const [planAsk, setPlanAsk] = useState(null);
|
|
2559
2621
|
const [updatePane, setUpdatePane] = useState(null);
|
|
2560
2622
|
/**
|
|
2561
2623
|
* The version installed in the background, if one was; see auto-update.ts.
|
|
@@ -4654,6 +4716,26 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
4654
4716
|
+ '`/altscreen on` moves them into a pinned panel instead.');
|
|
4655
4717
|
return;
|
|
4656
4718
|
}
|
|
4719
|
+
case '/compact': {
|
|
4720
|
+
/*
|
|
4721
|
+
* Compacting on purpose, rather than waiting for the window to force it.
|
|
4722
|
+
*
|
|
4723
|
+
* The automatic kind exists to stop a request being rejected. This is the other reason:
|
|
4724
|
+
* a session about to change subject carries the whole of the last one into every turn to
|
|
4725
|
+
* come, and that is paid for on each request. Deferred to the next send because the
|
|
4726
|
+
* summary is itself a model call.
|
|
4727
|
+
*/
|
|
4728
|
+
const active = await getSession().catch(() => null);
|
|
4729
|
+
if (!active) {
|
|
4730
|
+
addSystem('Nothing to compact yet — no turn has run in this session.');
|
|
4731
|
+
return;
|
|
4732
|
+
}
|
|
4733
|
+
active.compactNow();
|
|
4734
|
+
addSystem('The conversation will be compacted before the next message, if there is '
|
|
4735
|
+
+ 'anything to summarise — it will say either way. What was said stays as a '
|
|
4736
|
+
+ 'summary; nothing is lost from the transcript above.');
|
|
4737
|
+
return;
|
|
4738
|
+
}
|
|
4657
4739
|
case '/changes': {
|
|
4658
4740
|
try {
|
|
4659
4741
|
const [status, unstaged, staged] = await Promise.all([
|
|
@@ -5586,6 +5668,48 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
5586
5668
|
answer(typed);
|
|
5587
5669
|
return;
|
|
5588
5670
|
}
|
|
5671
|
+
/*
|
|
5672
|
+
* A plan waiting for an answer owns the keyboard.
|
|
5673
|
+
*
|
|
5674
|
+
* Placed before the composer for the same reason the permission question is: an answer to a
|
|
5675
|
+
* question on screen should not also be typed into a draft behind it. Escape puts it away
|
|
5676
|
+
* without choosing, which leaves the plan in the transcript and the mode alone.
|
|
5677
|
+
*/
|
|
5678
|
+
if (planAsk) {
|
|
5679
|
+
if (key.escape) {
|
|
5680
|
+
setPlanAsk(null);
|
|
5681
|
+
addSystem('Left in plan mode. The plan is above'
|
|
5682
|
+
+ (planAsk.file ? ` and saved to \`${planAsk.file}\`` : '')
|
|
5683
|
+
+ ' — say what to change, or shift+tab to a mode that can act on it.');
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
if (key.upArrow) {
|
|
5687
|
+
setPlanAsk(p => (p ? { ...p, choice: Math.max(0, p.choice - 1) } : p));
|
|
5688
|
+
return;
|
|
5689
|
+
}
|
|
5690
|
+
if (key.downArrow) {
|
|
5691
|
+
setPlanAsk(p => (p ? { ...p, choice: Math.min(PLAN_CHOICES.length - 1, p.choice + 1) } : p));
|
|
5692
|
+
return;
|
|
5693
|
+
}
|
|
5694
|
+
const typed = PLAN_CHOICES.findIndex(c => c.key === input);
|
|
5695
|
+
const index = typed >= 0 ? typed : key.return ? planAsk.choice : -1;
|
|
5696
|
+
if (index < 0)
|
|
5697
|
+
return;
|
|
5698
|
+
const chosen = PLAN_CHOICES[index];
|
|
5699
|
+
setPlanAsk(null);
|
|
5700
|
+
if (chosen.mode === null) {
|
|
5701
|
+
addSystem('Tell it what to change, and it will plan again.');
|
|
5702
|
+
return;
|
|
5703
|
+
}
|
|
5704
|
+
setMode(chosen.mode);
|
|
5705
|
+
modeRef.current = chosen.mode;
|
|
5706
|
+
addSystem(`Carrying out the plan in **${modeSpec(chosen.mode).label}** mode.`
|
|
5707
|
+
+ (planAsk.file ? `\nSaved to \`${planAsk.file}\`` : ''));
|
|
5708
|
+
// The mode has to be in force before the turn starts, which is why it is set on the ref as
|
|
5709
|
+
// well as in state — the turn reads the ref, and state has not settled by the time it does.
|
|
5710
|
+
setTimeout(() => submitDraft(PROCEED_PROMPT), 0);
|
|
5711
|
+
return;
|
|
5712
|
+
}
|
|
5589
5713
|
if (addProv) {
|
|
5590
5714
|
if (key.escape) {
|
|
5591
5715
|
setAddProv(null);
|
|
@@ -6220,7 +6344,16 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
6220
6344
|
const active = await getSession();
|
|
6221
6345
|
const persistentGoal = goalRef.current;
|
|
6222
6346
|
const prefix = (persistentGoal ? `[Persistent session goal: ${persistentGoal}]\n` : '') +
|
|
6223
|
-
|
|
6347
|
+
/*
|
|
6348
|
+
* The ref, not the state.
|
|
6349
|
+
*
|
|
6350
|
+
* This closure is made when the turn is submitted, and a mode chosen a moment earlier
|
|
6351
|
+
* is not in it — React has not re-rendered yet. Approving a plan set the mode to auto
|
|
6352
|
+
* and then sent the request with plan mode's prefix still attached: "you cannot write
|
|
6353
|
+
* files or run commands in this mode", to a model that had just been told to carry
|
|
6354
|
+
* the plan out. The permission checks already read the ref for exactly this reason.
|
|
6355
|
+
*/
|
|
6356
|
+
modeSpec(modeRef.current).prefix +
|
|
6224
6357
|
(effort !== 'medium' ? `[Effort: ${effort}]\n` : '');
|
|
6225
6358
|
const controller = new AbortController();
|
|
6226
6359
|
abortRef.current = controller;
|
|
@@ -6303,6 +6436,22 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
6303
6436
|
addSystem(incompleteRef.current);
|
|
6304
6437
|
incompleteRef.current = null;
|
|
6305
6438
|
}
|
|
6439
|
+
/*
|
|
6440
|
+
* A plan-mode turn ends with a question, not with silence.
|
|
6441
|
+
*
|
|
6442
|
+
* Only in plan mode, and only when something was actually written: the mode denies
|
|
6443
|
+
* writes and commands, so whatever came back is a proposal by construction. Saved
|
|
6444
|
+
* first, so the offer can name the file it is offering.
|
|
6445
|
+
*/
|
|
6446
|
+
if (modeRef.current === 'plan' && content.trim() !== '') {
|
|
6447
|
+
// Under the session's state home, not always the real one: a run pointed at a
|
|
6448
|
+
// different directory should not write into the home directory behind it.
|
|
6449
|
+
const saved = await savePlan(content, {
|
|
6450
|
+
goal: goalRef.current, at: Date.now(),
|
|
6451
|
+
...(cfg.stateHome ? { dir: plansDir(cfg.stateHome) } : {}),
|
|
6452
|
+
});
|
|
6453
|
+
setPlanAsk({ text: content, file: 'path' in saved ? saved.path : null, choice: 0 });
|
|
6454
|
+
}
|
|
6306
6455
|
setAgentState('completed');
|
|
6307
6456
|
setTimeout(() => setAgentState('ready'), 700);
|
|
6308
6457
|
}
|
|
@@ -6650,17 +6799,28 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
6650
6799
|
const failed = agents.filter(a => a.status === 'failed').length;
|
|
6651
6800
|
const tokens = agents.reduce((n, a) => n + a.tokens, 0);
|
|
6652
6801
|
const started = Math.min(...agents.map(a => a.startedAt));
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6802
|
+
/*
|
|
6803
|
+
* A tree, because that is what it is.
|
|
6804
|
+
*
|
|
6805
|
+
* This was a flat list with its columns laid out as flex siblings, so the timings
|
|
6806
|
+
* and token counts landed wherever each task's text happened to end — a ragged
|
|
6807
|
+
* diagonal down the right-hand side that could not be read as a column. Naming the
|
|
6808
|
+
* session as the root and the sub-agents as forks of it also says the thing the
|
|
6809
|
+
* list left implicit: these are branches of the work you asked for, not separate
|
|
6810
|
+
* conversations.
|
|
6811
|
+
*/
|
|
6812
|
+
const width = Math.max(30, barWidth - 2);
|
|
6813
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: CYAN, children: "\u25C6" }), _jsxs(Text, { color: INK, bold: true, children: [agents.length, " ", agents.length === 1 ? 'fork' : 'forks'] }), _jsx(Text, { color: DIM, children: "\u00B7" }), _jsxs(Text, { color: done === agents.length ? GREEN : AMBER, children: [done, "/", agents.length, " done"] }), _jsx(Text, { color: DIM, children: "\u00B7" }), _jsxs(Text, { color: MUTED, children: [humanTokens(tokens), " tok"] }), _jsx(Text, { color: DIM, children: "\u00B7" }), _jsx(Text, { color: MUTED, children: fmtElapsed(Date.now() - started) }), failed > 0 && _jsxs(Text, { color: CRIMSON, children: ["\u00B7 ", failed, " failed"] })] }), _jsxs(Text, { children: [_jsxs(Text, { color: CYAN, children: [G.ok === '✓' ? '●' : '*', " "] }), _jsx(Text, { color: INK, children: "main" })] }), agents.map(a => {
|
|
6657
6814
|
const glyph = a.status === 'running' ? SPINNER[spinFrame]
|
|
6658
6815
|
: a.status === 'failed' ? G.fail : G.ok;
|
|
6659
6816
|
const color = a.status === 'running' ? AMBER
|
|
6660
6817
|
: a.status === 'failed' ? CRIMSON : GREEN;
|
|
6661
6818
|
const took = (a.endedAt ?? Date.now()) - a.startedAt;
|
|
6662
|
-
const
|
|
6663
|
-
|
|
6819
|
+
const meta = `${fmtElapsed(took)} · ${G.ok === '✓' ? '↓' : 'v'} ${humanTokens(a.tokens)} tokens`;
|
|
6820
|
+
const row = forkRow(a.task, meta, width, FORK_LEAD);
|
|
6821
|
+
// One Text, not a Box of them: five layout nodes per agent times eight agents
|
|
6822
|
+
// is a repaint cost for a list that changes every second anyway.
|
|
6823
|
+
return (_jsxs(Text, { children: [_jsxs(Text, { color: color, children: [glyph, " "] }), _jsx(Text, { color: DIM, children: "fork " }), _jsx(Text, { color: a.status === 'running' ? INK : MUTED, children: row.task }), _jsx(Text, { children: row.gap }), _jsx(Text, { color: DIM, children: row.meta })] }, a.index));
|
|
6664
6824
|
})] }));
|
|
6665
6825
|
})(), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [_jsxs(Text, { color: GREEN, children: [animate ? SPINNER[spinFrame] : '●', " "] }), _jsx(Shimmer, { text: workWord({
|
|
6666
6826
|
elapsedMs, tools: turnToolsRef.current,
|
|
@@ -6994,7 +7154,24 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
|
|
|
6994
7154
|
: { label: 'repoint ' + addProv.name + '? (y/n)',
|
|
6995
7155
|
hint: `it ships with KONECK, pointing at ${shadowed?.baseURL}` };
|
|
6996
7156
|
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: CYAN, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsx(Text, { color: CYAN, bold: true, children: "Declare a provider" }), _jsxs(Text, { color: MUTED, children: [ask.hint, " \u00B7 esc to cancel"] }), addProv.name !== '' && (_jsxs(Text, { color: DIM, children: [addProv.name, addProv.url ? ' ' + addProv.url : ''] })), addProv.error && _jsx(Text, { color: CRIMSON, children: addProv.error }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [ask.label, ": "] }), _jsx(Text, { color: INK, children: addProv.value }), _jsx(Cursor, {})] })] }));
|
|
6997
|
-
})(), keyPrompt && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AMBER, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsxs(Text, { color: AMBER, bold: true, children: ["API key for ", keyPrompt.provider] }), _jsx(Text, { color: MUTED, children: "Paste it and press enter, or ctrl+v to read the clipboard. Held in memory for this session only; esc to cancel." }), keyPrompt.note && _jsx(Text, { color: CYAN, children: keyPrompt.note }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [keyPrompt.env, ": "] }), _jsx(Text, { color: INK, children: '*'.repeat(Math.min(keyPrompt.value.length, 48)) }), _jsx(Cursor, {}), keyPrompt.value.length > 0 && (_jsxs(Text, { color: DIM, children: [" ", keyPrompt.value.length, " characters"] }))] })] })),
|
|
7157
|
+
})(), keyPrompt && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AMBER, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsxs(Text, { color: AMBER, bold: true, children: ["API key for ", keyPrompt.provider] }), _jsx(Text, { color: MUTED, children: "Paste it and press enter, or ctrl+v to read the clipboard. Held in memory for this session only; esc to cancel." }), keyPrompt.note && _jsx(Text, { color: CYAN, children: keyPrompt.note }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [keyPrompt.env, ": "] }), _jsx(Text, { color: INK, children: '*'.repeat(Math.min(keyPrompt.value.length, 48)) }), _jsx(Cursor, {}), keyPrompt.value.length > 0 && (_jsxs(Text, { color: DIM, children: [" ", keyPrompt.value.length, " characters"] }))] })] })), planAsk && (() => {
|
|
7158
|
+
/*
|
|
7159
|
+
* The question, straight after the plan rather than instead of it.
|
|
7160
|
+
*
|
|
7161
|
+
* The plan itself is already in the transcript above — repeating it here would push the
|
|
7162
|
+
* choices off a short screen, which is the one thing this panel must not do. So it says
|
|
7163
|
+
* where the plan was saved and asks.
|
|
7164
|
+
*/
|
|
7165
|
+
const lines = [
|
|
7166
|
+
'A plan is ready. Carry it out?',
|
|
7167
|
+
'',
|
|
7168
|
+
...PLAN_CHOICES.map((c, i) => i === planAsk.choice ? `**${G.caret} ${c.key}. ${c.label}**` : ` ${c.key}. ${c.label}`),
|
|
7169
|
+
'',
|
|
7170
|
+
'Up/down and enter, or press the number. Esc leaves it in plan mode.',
|
|
7171
|
+
...(planAsk.file ? [`Saved to \`${planAsk.file}\``] : ['This plan could not be written to disk.']),
|
|
7172
|
+
];
|
|
7173
|
+
return (_jsx(Box, { marginTop: 1, children: _jsx(Panel, { width: Math.min(barWidth, 84), color: CYAN, title: "Plan ready", children: lines }) }));
|
|
7174
|
+
})(), ask && (() => {
|
|
6998
7175
|
let detail = '';
|
|
6999
7176
|
let isCommand = false;
|
|
7000
7177
|
try {
|