@agents-ensemble/cli 0.10.1 → 0.12.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.
Files changed (62) hide show
  1. package/README.md +3 -1
  2. package/config.example.yaml +6 -2
  3. package/dist/async-operator-input.js +1 -1
  4. package/dist/async-operator-input.js.map +1 -1
  5. package/dist/display/session-display-reducer.d.ts.map +1 -1
  6. package/dist/display/session-display-reducer.js +13 -6
  7. package/dist/display/session-display-reducer.js.map +1 -1
  8. package/dist/index.js +58 -6
  9. package/dist/index.js.map +1 -1
  10. package/dist/issue-command.d.ts +2 -0
  11. package/dist/issue-command.d.ts.map +1 -1
  12. package/dist/issue-command.js +6 -2
  13. package/dist/issue-command.js.map +1 -1
  14. package/dist/pi-model-catalog-command.d.ts +24 -0
  15. package/dist/pi-model-catalog-command.d.ts.map +1 -0
  16. package/dist/pi-model-catalog-command.js +293 -0
  17. package/dist/pi-model-catalog-command.js.map +1 -0
  18. package/dist/prompt-human-inquiry.d.ts.map +1 -1
  19. package/dist/prompt-human-inquiry.js +11 -3
  20. package/dist/prompt-human-inquiry.js.map +1 -1
  21. package/dist/session-log-lines.d.ts.map +1 -1
  22. package/dist/session-log-lines.js +23 -5
  23. package/dist/session-log-lines.js.map +1 -1
  24. package/dist/tui/create-issue-session-tui-host.d.ts.map +1 -1
  25. package/dist/tui/create-issue-session-tui-host.js +19 -1
  26. package/dist/tui/create-issue-session-tui-host.js.map +1 -1
  27. package/dist/tui/create-issue-session-tui-host.test.js +71 -0
  28. package/dist/tui/create-issue-session-tui-host.test.js.map +1 -1
  29. package/dist/tui/create-tui-telemetry-sink.d.ts.map +1 -1
  30. package/dist/tui/create-tui-telemetry-sink.js +2 -1
  31. package/dist/tui/create-tui-telemetry-sink.js.map +1 -1
  32. package/dist/tui/issue-session-tui-stream.d.ts.map +1 -1
  33. package/dist/tui/issue-session-tui-stream.js +5 -3
  34. package/dist/tui/issue-session-tui-stream.js.map +1 -1
  35. package/dist/tui/issue-session-tui-stream.test.js +42 -13
  36. package/dist/tui/issue-session-tui-stream.test.js.map +1 -1
  37. package/dist/tui/issue-session-tui.d.ts.map +1 -1
  38. package/dist/tui/issue-session-tui.js +4 -2
  39. package/dist/tui/issue-session-tui.js.map +1 -1
  40. package/dist/tui/issue-session-tui.test.js +47 -20
  41. package/dist/tui/issue-session-tui.test.js.map +1 -1
  42. package/dist/tui/open-questions-pane.d.ts.map +1 -1
  43. package/dist/tui/open-questions-pane.js +40 -15
  44. package/dist/tui/open-questions-pane.js.map +1 -1
  45. package/dist/tui/operator-command-suggestions.d.ts +15 -0
  46. package/dist/tui/operator-command-suggestions.d.ts.map +1 -0
  47. package/dist/tui/operator-command-suggestions.js +19 -0
  48. package/dist/tui/operator-command-suggestions.js.map +1 -0
  49. package/dist/tui/tui-layout-constants.d.ts +2 -2
  50. package/dist/tui/tui-layout-constants.d.ts.map +1 -1
  51. package/dist/tui/tui-layout-constants.js +2 -2
  52. package/dist/tui/tui-layout-constants.js.map +1 -1
  53. package/dist/tui/wrap-text-to-width.d.ts +2 -0
  54. package/dist/tui/wrap-text-to-width.d.ts.map +1 -1
  55. package/dist/tui/wrap-text-to-width.js +45 -0
  56. package/dist/tui/wrap-text-to-width.js.map +1 -1
  57. package/docs/config.md +8 -3
  58. package/docs/pi-conductor-setup.md +285 -0
  59. package/docs/settings.md +6 -2
  60. package/package.json +3 -2
  61. package/scripts/pi/cached-auth.mjs +873 -0
  62. package/scripts/pi/cached-auth.sh +11 -0
@@ -39,9 +39,9 @@ export declare const OPEN_QUESTIONS_PANE_MAX_DISPLAY_LINES = 14;
39
39
  /** Open questions ペインタイトルに付与する選択操作ヒント。 */
40
40
  export declare const OPEN_QUESTIONS_SELECTION_HINT = " \u2014 Shift+\u2191\u2193\u3067\u9078\u629E";
41
41
  /** Open questions がないときに Operator input へ表示する任意入力 prompt。 */
42
- export declare const OPERATOR_INPUT_DISCRETIONARY_HINT = "\u4EFB\u610F\u306E\u30BF\u30A4\u30DF\u30F3\u30B0\u3067\u5165\u529B \u00B7 /reconnect \u3067\u518D\u63A5\u7D9A \u00B7 /exit \u3067\u7D42\u4E86";
42
+ export declare const OPERATOR_INPUT_DISCRETIONARY_HINT = "\u4EFB\u610F\u5165\u529B \u00B7 /reconnect \u00B7 /close \u4FDD\u5B58\u3057\u3066\u9589\u3058\u308B \u00B7 /exit \u6383\u9664\u3057\u3066\u7D42\u4E86";
43
43
  /** post-loop 待機中に Operator input へ表示する追加入力 prompt。 */
44
- export declare const OPERATOR_INPUT_POST_LOOP_HINT = "\u8FFD\u52A0\u6307\u793A\u3092\u5165\u529B\u3059\u308B\u304B /reconnect \u3067\u518D\u63A5\u7D9A \u00B7 /exit \u3067\u7D42\u4E86";
44
+ export declare const OPERATOR_INPUT_POST_LOOP_HINT = "\u8FFD\u52A0\u6307\u793A \u00B7 /reconnect \u00B7 /close \u4FDD\u5B58\u3057\u3066\u9589\u3058\u308B \u00B7 /exit \u6383\u9664\u3057\u3066\u7D42\u4E86";
45
45
  /** 終了処理中に Operator input へ表示する prompt。 */
46
46
  export declare const OPERATOR_INPUT_SHUTTING_DOWN_HINT = "\u7D42\u4E86\u3057\u3066\u3044\u307E\u3059\u2026";
47
47
  /** 入力ペインの枠線(上下)行数。`PANE_BORDER_ROWS` と同値。 */
@@ -1 +1 @@
1
- {"version":3,"file":"tui-layout-constants.d.ts","sourceRoot":"","sources":["../../src/tui/tui-layout-constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,6BAA6B;AAC7B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,oEAAoE;AACpE,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAE/C,2BAA2B;AAC3B,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C,qDAAqD;AACrD,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAE9C,mCAAmC;AACnC,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAE5C,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAE9C,sDAAsD;AACtD,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAExD,sDAAsD;AACtD,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAExD,0CAA0C;AAC1C,eAAO,MAAM,6BAA6B,iDAAmB,CAAC;AAE9D,6DAA6D;AAC7D,eAAO,MAAM,iCAAiC,kJACD,CAAC;AAE9C,sDAAsD;AACtD,eAAO,MAAM,6BAA6B,qIACA,CAAC;AAE3C,0CAA0C;AAC1C,eAAO,MAAM,iCAAiC,qDAAa,CAAC;AAE5D,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,IAAmB,CAAC;AAEvD,kCAAkC;AAClC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,kDAAkD;AAClD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,QAAkD,CAAC;AAEvF;;;GAGG;AACH,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD,gCAAgC;AAChC,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,uBAAuB;AACvB,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,0BAA0B;AAC1B,eAAO,MAAM,4BAA4B,IAAI,CAAC"}
1
+ {"version":3,"file":"tui-layout-constants.d.ts","sourceRoot":"","sources":["../../src/tui/tui-layout-constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,6BAA6B;AAC7B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,oEAAoE;AACpE,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAE/C,2BAA2B;AAC3B,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C,qDAAqD;AACrD,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAE9C,mCAAmC;AACnC,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAE5C,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAE9C,sDAAsD;AACtD,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAExD,sDAAsD;AACtD,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAExD,0CAA0C;AAC1C,eAAO,MAAM,6BAA6B,iDAAmB,CAAC;AAE9D,6DAA6D;AAC7D,eAAO,MAAM,iCAAiC,0JACO,CAAC;AAEtD,sDAAsD;AACtD,eAAO,MAAM,6BAA6B,0JACW,CAAC;AAEtD,0CAA0C;AAC1C,eAAO,MAAM,iCAAiC,qDAAa,CAAC;AAE5D,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,IAAmB,CAAC;AAEvD,kCAAkC;AAClC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,kDAAkD;AAClD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,QAAkD,CAAC;AAEvF;;;GAGG;AACH,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD,gCAAgC;AAChC,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,uBAAuB;AACvB,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,0BAA0B;AAC1B,eAAO,MAAM,4BAA4B,IAAI,CAAC"}
@@ -39,9 +39,9 @@ export const OPEN_QUESTIONS_PANE_MAX_DISPLAY_LINES = 14;
39
39
  /** Open questions ペインタイトルに付与する選択操作ヒント。 */
40
40
  export const OPEN_QUESTIONS_SELECTION_HINT = ' — Shift+↑↓で選択';
41
41
  /** Open questions がないときに Operator input へ表示する任意入力 prompt。 */
42
- export const OPERATOR_INPUT_DISCRETIONARY_HINT = '任意のタイミングで入力 · /reconnect で再接続 · /exit で終了';
42
+ export const OPERATOR_INPUT_DISCRETIONARY_HINT = '任意入力 · /reconnect · /close 保存して閉じる · /exit 掃除して終了';
43
43
  /** post-loop 待機中に Operator input へ表示する追加入力 prompt。 */
44
- export const OPERATOR_INPUT_POST_LOOP_HINT = '追加指示を入力するか /reconnect で再接続 · /exit で終了';
44
+ export const OPERATOR_INPUT_POST_LOOP_HINT = '追加指示 · /reconnect · /close 保存して閉じる · /exit 掃除して終了';
45
45
  /** 終了処理中に Operator input へ表示する prompt。 */
46
46
  export const OPERATOR_INPUT_SHUTTING_DOWN_HINT = '終了しています…';
47
47
  /** 入力ペインの枠線(上下)行数。`PANE_BORDER_ROWS` と同値。 */
@@ -1 +1 @@
1
- {"version":3,"file":"tui-layout-constants.js","sourceRoot":"","sources":["../../src/tui/tui-layout-constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yCAAyC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;AAE/C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,qDAAqD;AACrD,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAE1D,kCAAkC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD,kDAAkD;AAClD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,mCAAmC;AACnC,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,4CAA4C;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,sDAAsD;AACtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,GAAG,CAAC;AAExD,sDAAsD;AACtD,MAAM,CAAC,MAAM,qCAAqC,GAAG,EAAE,CAAC;AAExD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,6BAA6B,GAAG,gBAAgB,CAAC;AAE9D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,iCAAiC,GAC5C,2CAA2C,CAAC;AAE9C,sDAAsD;AACtD,MAAM,CAAC,MAAM,6BAA6B,GACxC,wCAAwC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,iCAAiC,GAAG,UAAU,CAAC;AAE5D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEvD,kCAAkC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,kDAAkD;AAClD,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,8BAA8B,GAAG,cAAc,CAAC;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEhD,gCAAgC;AAChC,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAEhD,uBAAuB;AACvB,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAE/C,0BAA0B;AAC1B,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"tui-layout-constants.js","sourceRoot":"","sources":["../../src/tui/tui-layout-constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yCAAyC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;AAE/C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,qDAAqD;AACrD,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAE1D,kCAAkC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD,kDAAkD;AAClD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,mCAAmC;AACnC,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,4CAA4C;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,sDAAsD;AACtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,GAAG,CAAC;AAExD,sDAAsD;AACtD,MAAM,CAAC,MAAM,qCAAqC,GAAG,EAAE,CAAC;AAExD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,6BAA6B,GAAG,gBAAgB,CAAC;AAE9D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,iCAAiC,GAC5C,mDAAmD,CAAC;AAEtD,sDAAsD;AACtD,MAAM,CAAC,MAAM,6BAA6B,GACxC,mDAAmD,CAAC;AAEtD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,iCAAiC,GAAG,UAAU,CAAC;AAE5D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEvD,kCAAkC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,kDAAkD;AAClD,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,8BAA8B,GAAG,cAAc,CAAC;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEhD,gCAAgC;AAChC,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAEhD,uBAAuB;AACvB,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAE/C,0BAA0B;AAC1B,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC"}
@@ -17,4 +17,6 @@ export declare function findWrapBreakIndex(text: string, width: number): number;
17
17
  * セグメント境界を跨いで単語境界を探し、分割後も各行の style を維持する。
18
18
  */
19
19
  export declare function wrapInlineMarkdownToWidth(segments: InlineMarkdownSegment[], width: number): InlineMarkdownLine[];
20
+ /** 表示幅に合わせて 1 行を切り詰め、省略記号を付ける。 */
21
+ export declare function truncateInlineMarkdownLineToWidth(segments: InlineMarkdownLine, width: number): InlineMarkdownLine;
20
22
  //# sourceMappingURL=wrap-text-to-width.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-text-to-width.d.ts","sourceRoot":"","sources":["../../src/tui/wrap-text-to-width.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAE/B,uCAAuC;AACvC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAIT;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBrE;AAED,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAwBtE;AAwID;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,qBAAqB,EAAE,EACjC,KAAK,EAAE,MAAM,GACZ,kBAAkB,EAAE,CAQtB"}
1
+ {"version":3,"file":"wrap-text-to-width.d.ts","sourceRoot":"","sources":["../../src/tui/wrap-text-to-width.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAE/B,uCAAuC;AACvC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAIT;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBrE;AAED,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAwBtE;AAwID;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,qBAAqB,EAAE,EACjC,KAAK,EAAE,MAAM,GACZ,kBAAkB,EAAE,CAQtB;AAED,kCAAkC;AAClC,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,MAAM,GACZ,kBAAkB,CA+CpB"}
@@ -155,4 +155,49 @@ export function wrapInlineMarkdownToWidth(segments, width) {
155
155
  }
156
156
  return toStyledCharacterLines(segments).flatMap((line) => wrapStyledCharacterLine(line, width));
157
157
  }
158
+ /** 表示幅に合わせて 1 行を切り詰め、省略記号を付ける。 */
159
+ export function truncateInlineMarkdownLineToWidth(segments, width) {
160
+ const safeWidth = Math.max(1, width);
161
+ const ellipsis = '…';
162
+ const textWidth = Math.max(0, safeWidth - stringWidth(ellipsis));
163
+ const truncated = [];
164
+ let currentWidth = 0;
165
+ let isFull = false;
166
+ for (const segment of segments) {
167
+ for (const character of Array.from(segment.text)) {
168
+ const characterWidth = stringWidth(character);
169
+ if (currentWidth + characterWidth > textWidth) {
170
+ isFull = true;
171
+ break;
172
+ }
173
+ appendStyledSegment(truncated, character, {
174
+ text: character,
175
+ width: characterWidth,
176
+ ...(segment.bold ? { bold: true } : {}),
177
+ ...(segment.code ? { code: true } : {}),
178
+ ...(segment.href !== undefined ? { href: segment.href } : {}),
179
+ });
180
+ currentWidth += characterWidth;
181
+ }
182
+ if (isFull) {
183
+ break;
184
+ }
185
+ }
186
+ while (truncated.length > 0) {
187
+ const lastSegment = truncated.at(-1);
188
+ const lastCharacter = lastSegment && Array.from(lastSegment.text).at(-1);
189
+ if (!lastSegment || !lastCharacter || lastCharacter.trim() !== '') {
190
+ break;
191
+ }
192
+ lastSegment.text = Array.from(lastSegment.text).slice(0, -1).join('');
193
+ if (lastSegment.text === '') {
194
+ truncated.pop();
195
+ }
196
+ }
197
+ appendStyledSegment(truncated, ellipsis, {
198
+ text: ellipsis,
199
+ width: stringWidth(ellipsis),
200
+ });
201
+ return truncated;
202
+ }
158
203
  //# sourceMappingURL=wrap-text-to-width.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-text-to-width.js","sourceRoot":"","sources":["../../src/tui/wrap-text-to-width.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrap-text-to-width.js","sourceRoot":"","sources":["../../src/tui/wrap-text-to-width.ts"],"names":[],"mappings":"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"}
package/docs/config.md CHANGED
@@ -47,7 +47,7 @@ cp config.example.yaml ~/.ensemble/config.yaml
47
47
 
48
48
  ```yaml
49
49
  profile:
50
- default: implementer-and-reviewer # ENSEMBLE_DEFAULT_PROFILE 相当
50
+ default: implementer-and-reviewer-v2 # ENSEMBLE_DEFAULT_PROFILE 相当
51
51
 
52
52
  conductor:
53
53
  backend: pi # cursor(既定) | pi
@@ -66,6 +66,7 @@ acp:
66
66
 
67
67
  session:
68
68
  worktree: isolated # --worktree 既定(isolated | in-repo)
69
+ lazyWorkers: false # true: 初回 prompt_worker まで worker ACP attach を遅延
69
70
  maxTurns:
70
71
  tty: 0 # 0 = 無制限
71
72
  nonTty: 5
@@ -83,7 +84,7 @@ github:
83
84
  stopPollWaitMs: 5000
84
85
 
85
86
  tui:
86
- layout: pane # ENSEMBLE_TUI_LAYOUT 相当
87
+ layout: stream # TTY での既定(pane に戻す場合は明示)
87
88
  forceHyperlink: auto # FORCE_HYPERLINK 相当(auto | on | off)
88
89
  ```
89
90
 
@@ -100,6 +101,7 @@ tui:
100
101
  | `acp.defaultPreset` | worker ACP built-in preset | `--default-acp-cli` 等 | `ENSEMBLE_DEFAULT_ACP_CLI` |
101
102
  | `acp.env` | codex-acp 等 spawn 時の env(string map) | — | — |
102
103
  | `session.worktree` | worker workspace モード | `--worktree` | — |
104
+ | `session.lazyWorkers` | 初回 `prompt_worker` まで worker ACP attach を遅延 | — | — |
103
105
  | `session.maxTurns.tty` / `nonTty` | 自律ターン上限 | `--max-turns` / `--no-max-turns` | — |
104
106
  | `session.postLoop.wait` | post-loop 待機(TTY) | `--no-wait` | — |
105
107
  | `tui.layout` | TTY レイアウト(`pane` / `stream`) | — | `ENSEMBLE_TUI_LAYOUT` |
@@ -180,7 +182,7 @@ worker ACP spawn のフィンガープリント([ADR 0011](adr/0011-session-si
180
182
  - `prompts/`: Markdown template を読み込み、`/name args` の user prompt を Pi 標準の引数置換で展開します。
181
183
  - `themes/`: Pi 標準 JSON として読み込み、project 同名を優先します。conductor は headless `AgentSession` のため TUI renderer がなく、theme の色・表示設定はモデル入出力には適用しません。
182
184
 
183
- Pi の初回セットアップ、provider 認証、認証優先順、TTY / stderr の login、project OAuth の制約、`ensemble models list`、missing key / 401 の復旧は [Pi conductor セットアップと認証](pi-conductor-setup.md)を正本とします。この config reference では、headless conductor が `settings.json` の `apiKey` / `apiKeys` を認証 fallback として使い、`models.json` の provider `apiKey` と `!command` も Pi resource として解決することだけを定義します。`!command` は conductor process の shell と OS 権限で実行されるため、信頼できる設定でのみ使用してください。Pi の MCP HTTP OAuth は provider OAuth とは別に、公式 MCP extension が管理します。
185
+ Pi の初回セットアップ、provider 認証、認証優先順、TTY / stderr の login、project OAuth の制約、`ensemble models list`、missing key / 401 の復旧は [Pi conductor セットアップと認証](pi-conductor-setup.md)を正本とします。この config reference では、headless conductor が `settings.json` の `apiKey` / `apiKeys` を認証 fallback として使い、`models.json` の provider `apiKey` と `!command` も Pi resource として解決することだけを定義します。`!command` は conductor process の shell と OS 権限で実行されるため、信頼できる設定でのみ使用してください。`gcloud auth print-identity-token` 等を連続実行しないためのキャッシュ付きヘルパーは harness では提供せず、[pi-conductor-setup.md の `!command` とトークン取得](pi-conductor-setup.md#command-とトークン取得の連続実行litellm--gcloud-等) と Node 実装の [scripts/pi/cached-auth.mjs](../scripts/pi/cached-auth.mjs) を参照してください。`@agents-ensemble/cli` の配布物には `scripts/pi/cached-auth.mjs` と、これへ委譲する非推奨の `.sh` wrapper が含まれます。既存 `~/.ensemble/pi/cached-auth.sh` コピーからの移行と p50 測定手順も Pi セットアップガイドに記載しています。Pi の MCP HTTP OAuth は provider OAuth とは別に、公式 MCP extension が管理します。
184
186
 
185
187
  #### `settings.json` の headless 対応範囲
186
188
 
@@ -250,6 +252,7 @@ conductor の system prompt の基底は modular-prompt のコンパイル結果
250
252
  | `CONDUCTOR_MODEL_ID` | `conductor.model` | 同上 |
251
253
  | `ENSEMBLE_DEFAULT_ACP_CLI` | `acp.defaultPreset` | 同上 |
252
254
  | CLI `--worktree` 既定 `isolated` | `session.worktree` | |
255
+ | eager worker attach | `session.lazyWorkers: false` | 未指定も eager(後方互換) |
253
256
  | TTY 無制限 / 非 TTY 5 | `session.maxTurns.tty` / `nonTty` | |
254
257
  | TTY post-loop 待機 ON | `session.postLoop.wait` | |
255
258
  | monitor 各種定数 | `github.monitor.*` | |
@@ -258,6 +261,8 @@ conductor の system prompt の基底は modular-prompt のコンパイル結果
258
261
 
259
262
  **config 未作成時**は従来どおり env とコード default のみが効く(後方互換)。
260
263
 
264
+ `session.lazyWorkers` は既定 `false` です。`true` にすると profile の全 worker を session に登録して TUI / `list_workers` に `sleeping` と表示し、初回の通常 `prompt_worker` で対象 worker だけを attach / init します。init prompt 完了後に最初の instruction を別ラウンドで送り、その後はセッション終了まで常駐します。resume は sidecar に保存した設定を使い、ACP session のある worker は再 attach、まだ使っていない worker は sleeping のままにします。lazy 設定のない旧 sidecar は eager として扱います。
265
+
261
266
  ### team profile `acp` の削除
262
267
 
263
268
  team profile の `acp` / `workers[].acp` は **削除済み**。YAML に残すと profile load 時にエラーになる。
@@ -0,0 +1,285 @@
1
+ # Pi conductor セットアップと認証
2
+
3
+ > **正本:** `ensemble issue` の Pi conductor を初回設定し、provider 認証を取得・確認・復旧する利用者向け手順。
4
+
5
+ このガイドは `conductor.backend: pi` を選んだときの conductor の設定を説明します。worker の ACP preset `pi` や、Pi CLI の通常の `<cwd>/.pi/` 設定とは別の経路です。
6
+
7
+ ## 最短セットアップ
8
+
9
+ ### 1. Pi backend を選ぶ
10
+
11
+ リポジトリの `.ensemble/config.yaml`(またはユーザの `~/.ensemble/config.yaml`)に設定します。
12
+
13
+ ```yaml
14
+ conductor:
15
+ backend: pi
16
+ ```
17
+
18
+ profile に `conductor.backend` がある場合は profile の値が config より優先されます。`backend` を指定しない場合の既定は Cursor です。
19
+
20
+ Pi の設定を置く場所は次の 2 層です。
21
+
22
+ | 層 | 既定の resource root | 用途 |
23
+ |----|----------------------|------|
24
+ | user | `~/.ensemble/pi/` | 個人の設定・user credential |
25
+ | project | `<repoRoot>/.ensemble/pi/` | リポジトリ固有の model/resource と project credential |
26
+
27
+ resource root は `conductor.pi.agentDir`(user)と `conductor.pi.projectDir`(project)で上書きできます。相対パスはリポジトリの root 基準、`~` はユーザ home 基準です。
28
+
29
+ ```yaml
30
+ conductor:
31
+ backend: pi
32
+ pi:
33
+ agentDir: ~/.ensemble/pi
34
+ projectDir: .ensemble/pi
35
+ ```
36
+
37
+ Pi conductor は各 root の `settings.json`、`auth.json`、`models.json`、`extensions/`、`skills/`、`prompts/`、`themes/` を user → project の順で読みます。project の設定が同じ provider/resource を上書きします。headless conductor の対応範囲は [config.md の Pi resource root](config.md#pi-resource-root) を参照してください。
38
+
39
+ ### Skills(Pi 標準)
40
+
41
+ profile の `conductor.piSkills`(省略時は有効)が `true` のとき、conductor は Pi の `DefaultResourceLoader` で skill を索引します。system prompt には skill 名・説明・ファイルパスのカタログが載り、本文は built-in の `read` または `/skill:<name>` で読みます。`conductor.builtinTools: false` のときは `read` が無く、カタログが載らない場合があるため、skill を使う Pi conductor では built-in tools を有効にするか、別途 skill 索引手段を用意してください。
42
+
43
+ `.ensemble/pi/skills/` に置いた skill は Pi discovery に渡されます。リポジトリ直下の `.agents/skills/` や、Claude / Cursor / Codex の skill ディレクトリは Pi 標準どおり `settings.json` の `skills` 配列で追加します(例: `"skills": [".claude/skills", ".cursor/skills"]`)。詳細は [Pi skills ドキュメント](https://github.com/earendil-works/pi/blob/v1.0.2/packages/coding-agent/docs/skills.md) を参照してください。
44
+
45
+ ### 2. provider と model を選ぶ
46
+
47
+ 通常は Pi の resource root のどちらかに `settings.json` を置き、provider と model を指定します。`conductor.model` または `ensemble issue --model` で provider/model を明示する場合は、model 選択だけのために `settings.json` を置く必要はありません。
48
+
49
+ ```json
50
+ {
51
+ "defaultProvider": "<provider-id>",
52
+ "defaultModel": "<model-id>"
53
+ }
54
+ ```
55
+
56
+ `defaultModel` に `<provider-id>/<model-id>` を指定することもできます。選択中の model を `conductor.model` または `ensemble issue --model <provider>/<model>` で明示した場合は、それが Pi の設定より優先されます。provider を省略しても、model id から一意に決まる場合は推測されます。
57
+
58
+ provider を確実に指定して認証する場合は、次のようにします。
59
+
60
+ ```bash
61
+ ensemble auth login --provider <provider-id>
62
+ ```
63
+
64
+ `--provider` を省略した場合は、Pi の `defaultProvider`、選択された model、または `--model-id` から provider を解決します。`auth login` / `logout` / `status` の provider 解決は同じです。
65
+
66
+ ### 3. 認証を取得する
67
+
68
+ Pi のログインは Cursor のような全体ログインではなく **provider 単位**です。
69
+
70
+ #### API key provider
71
+
72
+ ```bash
73
+ ensemble auth login --provider <provider-id>
74
+ ```
75
+
76
+ TTY の secret prompt に API key を入力します。prompt と入力待ちは stderr に出力され、入力値は表示されません。成功した credential は user resource root の `auth.json`(既定では `~/.ensemble/pi/auth.json`)へ保存されます。`conductor.pi.agentDir` を指定している場合はその配下です。project の `auth.json` はこのコマンドでは書き換えません。
77
+
78
+ API-key login は対話的な TTY が必要です。CI や非 TTY では login prompt を使わず、下記の provider 環境変数または Pi resource の fallback を設定してください。
79
+
80
+ #### OAuth provider
81
+
82
+ ```bash
83
+ ensemble auth login --provider <oauth-provider-id>
84
+ ```
85
+
86
+ OAuth login も TTY が必要です。Pi 1.x の `ModelRuntime.login` が認証を行い、URL、device code、進捗、追加 prompt は stderr に出します。SSH では表示された URL / device code を別のブラウザで使えます。OAuth credential は user runtime に保存され、conductor の各 request で runtime が必要に応じて refresh します。
87
+
88
+ project 層の `auth.json` にある OAuth entry は refresh 対象になりません。project の明示的な OAuth credential は実行時に拒否されるため、project 側の stale entry を除去または置き換えたうえで、`ensemble auth login --provider <oauth-provider-id>` を user 層に実行してください。login は project `auth.json` を上書きしません。
89
+
90
+ ### 4. 状態と model を確認する
91
+
92
+ ```bash
93
+ ensemble auth status
94
+ ensemble models list
95
+ ensemble models list --provider <provider-id>
96
+ ```
97
+
98
+ `auth status` は Pi の auth file の場所、provider ごとの configured 状態、credential の source を秘密値なしで表示します。`models list` は Pi の `ModelRegistry` と解決済み resource を使い、認証済み provider の model だけを表示します。対象 provider を `--provider` で絞れます。認証済み model が無い場合は Pi 向けの login / auth file / 環境変数の案内を含むエラーになります。
99
+
100
+ ### OpenAI 互換 provider の catalog を比較・追加する
101
+
102
+ LiteLLM など、`models.json` に OpenAI 互換 endpoint として設定した provider は、明示的に `models sync` を実行して `/v1/models` catalog を確認できます。provider には `api: "openai-completions"` など Pi の OpenAI 互換 `api` と `baseUrl` が必要です。`baseUrl` は Pi の API base URL(通常は末尾が `/v1`)を指定してください。末尾が `/v1` なら `/models`、それ以外なら `/v1/models` を追加して取得します。
103
+
104
+ ```bash
105
+ # API only / JSON only / 両方にある ID を表示(models.json は変更しない)
106
+ ensemble models sync --provider litellm
107
+
108
+ # API にある ID を選んで user models.json に追加
109
+ ensemble models sync --provider litellm --target user --add gpt-6-luna
110
+
111
+ # project models.json に追加
112
+ ensemble models sync --provider litellm --target project --add gpt-6-luna
113
+
114
+ # 同じ比較結果を機械処理する
115
+ ensemble models sync --provider litellm --json
116
+ ```
117
+
118
+ 追加時は `--add <id>` を繰り返して複数 ID を指定できます。書込先は `--target project|user` で明示してください。project は `conductor.pi.projectDir`(既定 `<repoRoot>/.ensemble/pi`)、user は `conductor.pi.agentDir`(既定 `~/.ensemble/pi`)にある `models.json` です。既存の provider 設定と model 定義は残し、同じ ID がすでに有効なら更新せずスキップします。API にない ID の削除や既存定義の force update は行いません。
119
+
120
+ user の `models.json` に追加しても、project の同じ provider に `models` 配列がある場合は Pi の project 優先により user 配列が隠れます。その場合はコマンドが書込前に停止するので、`--target project` を選んでください。
121
+
122
+ このコマンドは Pi provider の `baseUrl`、`apiKey`(環境変数参照や `!command` を含む)、`authHeader` と既存の Pi credential 解決を使って catalog を取得します。認証情報、header、provider の応答本文は出力しません。ネットワーク接続は `models sync` の明示実行時だけで、conductor の通常の `ModelRuntime` は引き続き `allowModelNetwork: false` です。
123
+
124
+ API が `max_input_tokens` を返す場合は、追加する Pi model の `contextWindow` にその整数値を設定します。Pi の `contextWindow` はモデルの入力コンテキスト上限として使われます。この値は provider が返した上限の取り込みであり、Pi の出力上限 `maxTokens` は設定しません。endpoint 側の値が不正または欠落していれば `contextWindow` は省略され、Pi の既定値が使われます。
125
+
126
+ 追加内容は、次回の `ensemble models list --provider <id>` で読み直されます。新しい conductor session でも create / resume 時に `models.json` が読み込まれます。実行中 session は hot reload しません。
127
+
128
+ ### 5. Issue を実行する
129
+
130
+ ```bash
131
+ ensemble issue https://github.com/OWNER/REPOSITORY/issues/123
132
+ ```
133
+
134
+ Pi backend の選択後も、Issue、worker、worktree、PR の主経路は Cursor backend と同じです。
135
+
136
+ ## 認証の解決順
137
+
138
+ 選択された provider の request credential は、明示的な内部 API key override を除き、次の順で解決されます。
139
+
140
+ | 優先 | source | 説明 |
141
+ |------|--------|------|
142
+ | 1 | project `auth.json` | project resource root の provider entry。user runtime より先に読みます。 |
143
+ | 2 | user Pi runtime | user root の `auth.json` を Pi 1.x `ModelRuntime` が管理します。`ensemble auth login` の書込先で、OAuth refresh もここで行います。 |
144
+ | 3 | `settings.json` fallback / `models.json` provider key | `apiKey`、`apiKeys[provider]`、または `models.json` の provider `apiKey`。auth file に credential が無い場合に使います。 |
145
+ | 4 | provider 環境変数 | Pi が provider ごとに認識する環境変数。provider により名前が異なります。 |
146
+
147
+ project → user の優先関係は provider 単位です。project に API-key credential があれば user credential や環境変数より優先されます。project の OAuth entry は user credential へフォールバックせず、refresh 不可として拒否されます。
148
+
149
+ 古い Pi API の説明で `AuthStorage` と呼ばれている user credential 層は、現在の Pi 1.0.x 経路では `ModelRuntime` が担います。利用者が意識する保存先と login の挙動は user `auth.json` です。
150
+
151
+ `settings.json` / `models.json` の `apiKey` は環境変数参照(`$NAME` / `${NAME}`)や `!command` を含められます。`!command` は conductor process の shell と OS 権限で実行されるため、信頼できる設定だけで使ってください。login の保存先や OAuth refresh の user runtime とは別の resource fallback です。詳細は [config.md](config.md#pi-resource-root) を参照してください。
152
+
153
+ user `auth.json` の credential は CLI が生成・更新するものを使うのが基本です。project resource、`settings.json`、`models.json` に秘密値を置く場合もリポジトリへ commit せず、`.ensemble/` の ignore 方針とアクセス権を確認してください。
154
+
155
+ ### `!command` とトークン取得の連続実行(LiteLLM / gcloud 等)
156
+
157
+ Pi conductor は **LLM リクエストの直前**で `apiKey` の `!command` を解決します。1 回の `conductor.send` の中でもツール往復により **同じコマンドが短時間に複数回**走ることがあります。`gcloud auth print-identity-token` のように **トークン発行 API に触れるコマンド**を直に `!` すると、OAuth 側のレート制限や一時的な失敗の原因になり得ます([Issue #432](https://github.com/otolab/agents-ensemble/issues/432))。
158
+
159
+ **ensemble harness は `!command` の自動ラップや TTL 設定を持ちません**([ADR 0028](adr/0028-authentication-delegation-and-ensemble-auth.md) の移譲モデルのまま)。代わりに、**キャッシュ付きの認証ヘルパースクリプト**を `models.json` から呼び出してください。Codex worker の `[model_providers.*.auth]` + `refresh_interval_ms` と同型で、**毎 `getAuth` でスクリプトは起動するが、キャッシュ hit 時は内側の gcloud を実行しない**運用です。
160
+
161
+ Pi の `!command` は Node.js 実装の [scripts/pi/cached-auth.mjs](../scripts/pi/cached-auth.mjs) を使います。repository clone ではその絶対パスを指定してください。npm 配布版を使う場合、`@agents-ensemble/cli/scripts/pi/cached-auth.mjs` は package 内の相対パスなので、そのまま `!command` には渡せません。npm の install root から実ファイルの絶対パスを取得します。
162
+
163
+ ```bash
164
+ # npm でグローバル install した場合(/ から実行し、repo の packageManager 設定を避ける)
165
+ realpath "$(cd / && npm root -g)/@agents-ensemble/cli/scripts/pi/cached-auth.mjs"
166
+
167
+ # 現在のプロジェクトに install した場合(consumer project root から実行)
168
+ realpath "./node_modules/@agents-ensemble/cli/scripts/pi/cached-auth.mjs"
169
+ ```
170
+
171
+ 出力された絶対パスを `models.json` の `apiKey` に使います。package subpath や `realpath` コマンド自体を `apiKey` に書くのではなく、出力された helper のパスを `!` の直後に指定してください。下の例の `/absolute/path/to/cached-auth.mjs` は、clone のパスまたは上記コマンドの出力に置き換えます。キャッシュファイルは既定で **`~/.ensemble/pi/cache/auth/`**(`600`。CWD や作業リポジトリに依存しない)に置きます。リポジトリ配下に置きたい場合は `--cache-dir` または `ENSEMBLE_PI_AUTH_CACHE_DIR` で上書きしてください。
172
+
173
+ ```json
174
+ {
175
+ "providers": {
176
+ "litellm": {
177
+ "baseUrl": "https://your-litellm.example/v1",
178
+ "apiKey": "!/absolute/path/to/cached-auth.mjs --ttl-ms 300000 -- gcloud auth print-identity-token --account=you@example.com",
179
+ "api": "openai-responses",
180
+ "authHeader": true,
181
+ "models": [{ "id": "your-model", "name": "your-model" }]
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ | 項目 | 説明 |
188
+ |------|------|
189
+ | `--ttl-ms` | この間隔より短い再実行では内側コマンドをスキップ(既定 `300000` = 5 分)。`ENSEMBLE_PI_AUTH_CACHE_TTL_MS` でも指定可。TTL を過ぎても JWT の `exp` が約 5 分より先なら再利用します。 |
190
+ | `--cache-dir` | キャッシュの置き場(**スコープの本体**)。既定は `~/.ensemble/pi/cache/auth` または `ENSEMBLE_PI_AUTH_CACHE_DIR`。 |
191
+ | `--cache-key` | 同一 `--cache-dir` 内で複数 credential を分けたいときだけ指定。未指定は `default`(内側コマンド行はキーに含めない)。 |
192
+ | `--` | 以降の argv を内側コマンドへ渡します。helper は shell を介さず、そのコマンドを直接起動します。 |
193
+ | JWT | stdout が JWT のとき、TTL に加え `exp` を Node.js で判定します。`python3` は不要です。 |
194
+ | クリア | 同じ `--cache-dir`(と `--cache-key`)で `--clear -- gcloud …`。`--clear` でも `--` と内側コマンドは必要です。`gcloud auth login` 後に実行するとよいです。 |
195
+
196
+ Worker(Codex)側は `~/.codex/config.toml` の `refresh_interval_ms` で同様の抑制ができます。Pi conductor だけ直 `!gcloud` のままにしないでください。
197
+
198
+ Node helper は既存の `default.token` / `default.meta` 形式を読み書きするため、#437 以降の bash 版が作ったキャッシュをそのまま使えます。`.meta` は引き続き取得時刻のミリ秒だけを保存します。miss / refresh / clear は cache-dir 内の `.lock.d` symlink で排他し、所有者の host・PID・process start identity を同じ cache-dir 内の専用 directory に記録します。Linux ではさらに owner と recovery process の PID namespace identity を `/proc/self/ns/pid` から記録し、確認側も一致する場合だけ PID を検査します。namespace identity が読めない、記録がない、または一致しない場合は owner を stale とみなさず、その lock を奪いません。Linux で現在の namespace identity を読めない場合、新しい lock の作成もエラーで止めます。同じ host・同じ PID namespace 上で owner の終了を確認できた lock は回収します。Linux の `/proc` が別 PID namespace から mount されている場合は `/proc/1/ns/pid` も照合し、現在の namespace と一致するときだけ `/proc/<pid>/stat` の field 22 `starttime`(clock ticks)を PID の開始 identity として使います。新形式で同じ PID が再利用され starttime が異なれば古い owner と区別して回収できます。namespace を照合できない、または starttime を読めない場合は、生きている PID を stale と判定せず lock を奪いません。生きた PID の identity が読めず保護された場合は timeout 後に失敗することがあります。終了済み PID は同じ namespace 上の `kill(pid, 0)` が `ESRCH` を返す場合に回収できます。更新前 helper が作成した秒粒度の Linux owner identity は、移行中に生きた lock を誤って奪わないよう従来の `ps` identity で照合します。旧形式は同秒の PID 再利用を区別できず live 扱いとなることがあり、その場合も lock を奪わず timeout まで待つ可能性があります。旧形式の照合ができない場合も stale とせず、生きた PID を保護します。
199
+
200
+ owner metadata を読んでいる間に別の helper が recovery directory と `.lock.d` symlink を片付けた場合は、symlink target を再確認して現在の lock state を読み直します。同じ target に owner metadata がない状態が続けば、短い bounded retry の後に fail-closed で停止します。固定された ownerless lock は自動削除しません。
201
+
202
+ macOS の process start identity は `ps -o lstart=` から得るため秒単位です。同じ秒のうちに PID が再利用され、start identity が一致して見える場合は owner を生存中として扱います。lock は奪われませんが、古い lock でも最大 60 秒の lock timeout まで待ってから失敗することがあります。より細かな時刻を返す Darwin native API はありますが、この単体 Node helper は native bridge / helper を含まず、そこからは取得しません。start identity を取得できない場合も PID の生存状態で保守的に判定し、終了済み PID が再利用されていれば同様に timeout まで待つ可能性があります。別 host や所有者を確認できない lock は奪わず、PID namespace が欠落・不一致の場合など判定不能な lock は待たずにエラーで停止します。
203
+
204
+ 旧実装が作った owner metadata のない `.lock.d/` directory は、生きた旧 helper と異常終了後の残留物を安全に区別できないため自動回収しません。また、新しい owner metadata に Linux PID namespace identity がない旧形式 lock も Linux では回収しません。いずれもエラーが出た場合は、その cache-dir を使う helper がどの PID namespace からも動いていないことを確認してから、`.lock.d` を手動で削除してください。`.lock.d` が owner symlink の場合、参照先の `.lock-owner-*` directory は lock ではなく残骸になります。旧 bash 版の `.lock` file / directory には触れません。キャッシュディレクトリは `700`、token / meta は `600` で保存します。
205
+
206
+ #### bash 版からの移行
207
+
208
+ `scripts/pi/cached-auth.sh` は非推奨の互換 wrapper です。同じディレクトリに `cached-auth.mjs` がある場合だけ Node helper へ委譲します。Pi は Node.js が前提のため、bash 版単独の Node-less fallback は提供しません。
209
+
210
+ `~/.ensemble/pi/cached-auth.sh` を以前コピーして使っている場合、そのコピーは自動更新されません。`models.json` の `apiKey` を新しい `cached-auth.mjs` の絶対パスへ変更してください。ホーム配下のコピーを続ける場合は、`cached-auth.mjs` を同じ場所へコピーし、`apiKey` のパスも `.mjs` に変えます。既定 cache-dir と key が同じなら、既存の `~/.ensemble/pi/cache/auth/default.token` / `default.meta` は再利用されます。新しい entrypoint で読めることを確認してから旧 shell コピーを削除できます。
211
+
212
+ #### macOS で hit 時間を測る
213
+
214
+ リポジトリ clone から次を実行します。ベンチは一時 cache-dir に `benchmark-token` を作り、`/bin/sh` から Node の shebang script を新しい process として起動します。10 組の no-op / hit を交互の順序で測り、各組の `hit - no-op` と p50 を出します。hit 側では、キャッシュが外れて内側コマンドが実行された場合に一時 marker を作るため、実際の credential command を使わず hit を確認できます。終了時に一時ディレクトリを削除します。
215
+
216
+ ```bash
217
+ node scripts/pi/bench-cached-auth.mjs
218
+ ```
219
+
220
+ 出力には platform / architecture、Node.js の版、10 組それぞれの no-op / hit 時間と差分、各 p50 が表示されます。これらの性能値は helper の起動コストと追加遅延を把握するための参考情報で、今回の Issue / PR の完了判定には使いません。hit / no-op の絶対 p50 と全サンプルを環境情報とともに記録してください。
221
+
222
+ ベンチスクリプトには以前の比較値を表示する `macOS acceptance (<= 25 ms)` 診断と、macOS でその値を超えたときに終了コード 1 を返す挙動が残っています。これは未変更のスクリプト動作です。オペレータの判断により、25 ms は現在の Issue / PR の受け入れ gate ではなく、測定値とともに参考情報として扱います。
223
+
224
+ 2026-10-16 の初回測定は macOS 15.7.9(build 24G830、Apple Silicon / arm64)で、Node.js 24.16.0 の hit p50 が **148.72 ms**、no-op 起動 p50 が **128.72 ms**でした。Node.js 22.22.3 の hit p50 は **346.56 ms**でした。これらは当時の測定記録です。
225
+
226
+ 2026-10-17 に同じ Mac で新しい paired ベンチを実行しました。別プロセスを止めずに計測したため、no-op の絶対時間にも大きなばらつきがあります。paired `hit - no-op` p50 は Node.js 24.16.0 で **30.65 ms**、Node.js 22.22.3 で **11.12 ms**でした。これらも pass/fail 判定ではなく参考値です。
227
+
228
+ | Node.js | no-op p50 | hit p50 | paired `hit - no-op` p50 |
229
+ |---------|-----------|---------|--------------------------|
230
+ | 24.16.0 | 516.14 ms | 577.82 ms | **30.65 ms** |
231
+ | 22.22.3 | 597.53 ms | 606.35 ms | **11.12 ms** |
232
+
233
+ 10 組のサンプルは次のとおりです(各列は同じ組の no-op / hit / 差分)。
234
+
235
+ | Node.js | no-op ms | hit ms | hit − no-op ms |
236
+ |---------|----------|--------|----------------|
237
+ | 24.16.0 | 758.75, 449.12, 514.32, 464.70, 511.93, 517.96, 669.41, 495.54, 601.80, 563.23 | 514.07, 609.14, 659.47, 610.92, 543.98, 546.50, 623.96, 524.79, 528.54, 646.49 | -244.69, 160.02, 145.15, 146.22, 32.05, 28.54, -45.45, 29.25, -73.26, 83.26 |
238
+ | 22.22.3 | 807.09, 547.69, 598.60, 547.81, 581.10, 596.45, 782.49, 618.37, 629.50, 585.55 | 531.15, 610.22, 717.29, 602.47, 549.25, 597.37, 700.96, 595.58, 650.81, 637.55 | -275.94, 62.53, 118.69, 54.67, -31.85, 0.92, -81.53, -22.79, 21.31, 52.00 |
239
+
240
+ 測定したのはこの Mac のみです。no-op p50 が 500 ms を超え、差分にも負値を含むため、同時稼働プロセスの影響が見える測定として扱います。安定した負荷条件の測定は未実施です。
241
+
242
+ ## `ensemble auth` と Cursor の違い
243
+
244
+ | | Cursor backend(既定) | Pi backend |
245
+ |---|---|---|
246
+ | backend の選択 | `conductor.backend` を省略 | `conductor.backend: pi` |
247
+ | login | `ensemble auth login` → Cursor SDK | `ensemble auth login --provider <id>` → provider 単位の Pi runtime |
248
+ | API key | `CURSOR_API_KEY` または Cursor SDK の stored login | TTY secret prompt、user `auth.json`、Pi の provider env/fallback |
249
+ | OAuth / 出力 | Cursor SDK の login | TTY の Pi OAuth flow。URL / device code は stderr |
250
+ | model list | Cursor SDK の catalog | 認証済み Pi model のみ。`--provider` で絞り込み |
251
+ | worker の認証 | `agent login` は worker ACP 用 | 同じく `agent login` は worker ACP 用。conductor の Pi login とは別 |
252
+
253
+ Cursor backend の既存 `ensemble auth login`、`CURSOR_API_KEY`、model catalog の挙動は Pi の設定では変更されません。
254
+
255
+ ## 認証エラーからの復旧
256
+
257
+ ### login 前の missing key
258
+
259
+ 次を順に確認します。
260
+
261
+ 1. `settings.json` の `defaultProvider` / `defaultModel` または `ensemble issue --model` が意図した provider/model を選んでいるか確認する。
262
+ 2. `ensemble auth status --provider <provider-id>` で user credential の状態と保存先を確認する。
263
+ 3. `ensemble auth login --provider <provider-id>` を TTY で実行する。
264
+ 4. login を使わない場合は、表示された provider 固有の環境変数、project `auth.json`、`settings.json` / `models.json` fallback を確認する。
265
+ 5. `ensemble models list --provider <provider-id>` で認証済み model が見えることを確認する。
266
+
267
+ ### 実行中の 401 / auth error
268
+
269
+ Pi の send が missing key、401、unauthorized などを返すと、harness は provider 固有の復旧 hint を表示します。hint には次の情報が含まれます。
270
+
271
+ - `ensemble auth login --provider <provider-id>`
272
+ - `agentDir/auth.json`(既定 `~/.ensemble/pi/auth.json`)
273
+ - Pi が認識する provider 固有の環境変数名(例: Anthropic は `ANTHROPIC_OAUTH_TOKEN` / `ANTHROPIC_API_KEY`、OpenAI は `OPENAI_API_KEY`、GitHub Copilot は `COPILOT_GITHUB_TOKEN`)
274
+ - 現在の conductor を再試行する `--resume <agentId>`(または `--continue`)
275
+
276
+ 認証を直した後、終了 JSON や hint に示された agent id を使って再開します。
277
+
278
+ 再接続の in-process retry、auth error の判定、backend 固有 hint の設計は [conductor-auth-reconnect.md](conductor-auth-reconnect.md) が正本です。
279
+
280
+ ## 参照
281
+
282
+ - [設定値リファレンス](settings.md) — backend、設定層、全体の解決順
283
+ - [ensemble 共通設定](config.md) — `config.yaml`、Pi resource root、headless 対応範囲
284
+ - [conductor 認証再接続](conductor-auth-reconnect.md) — send の再接続と auth hint の設計
285
+ - [ADR 0025](adr/0025-conductor-agent-backend-sdk-and-pi.md) — Cursor SDK / Pi backend の設計判断
package/docs/settings.md CHANGED
@@ -10,6 +10,7 @@
10
10
  | **環境変数** | シェル / CI | 一時上書き・秘密情報・自動化注入 |
11
11
  | **project config** | `<repoRoot>/.ensemble/config.yaml` | リポジトリ単位の既定 |
12
12
  | **user config** | `~/.ensemble/config.yaml` | マシン全体の既定 |
13
+ | **user conductor instructions** | `~/.ensemble/AGENTS.md` | profile に依存しない conductor 向けの運用前提 |
13
14
  | **team profile** | `profile.yaml`([elements.md](elements.md)) | worker 構成・workspace(**ACP は含まない → [config.md](config.md)**) |
14
15
  | **Codex profile** | `~/.codex/config.toml` + `codex --profile` | Codex CLI の profile(ensemble team profile とは無関係) |
15
16
  | **MCP** | `.agents/mcp.json` / `~/.ensemble/mcp.json` | conductor 向け MCP([config.md § MCP](config.md#conductor-mcp-設定mcpjson)) |
@@ -78,7 +79,7 @@ config キーなし。CI・スクリプト・端末検出、または 1 回限
78
79
 
79
80
  | 設定 | config キー | 環境変数 | CLI | コード default | 解決 |
80
81
  |------|-------------|----------|-----|----------------|------|
81
- | 既定 team profile | `profile.default` | `ENSEMBLE_DEFAULT_PROFILE` | `--profile` | 同梱 `implementer-and-reviewer` | A |
82
+ | 既定 team profile | `profile.default` | `ENSEMBLE_DEFAULT_PROFILE` | `--profile` | 同梱 `implementer-and-reviewer-v2` | A |
82
83
  | conductor モデル | `conductor.model` | `CONDUCTOR_MODEL_ID` | `--model` | `default` | A |
83
84
  | conductor 詳細 telemetry | `conductor.verbose` | `CONDUCTOR_VERBOSE` | `--verbose` | `false` | A |
84
85
  | conductor backend | `conductor.backend` | — | — | `cursor` | profile > config > default |
@@ -87,6 +88,7 @@ config キーなし。CI・スクリプト・端末検出、または 1 回限
87
88
  | worker ACP preset(profile 未指定 worker) | `acp.defaultPreset` | `ENSEMBLE_DEFAULT_ACP_CLI` | `--default-acp-cli` 等 | `cursor` | C |
88
89
  | worker ACP spawn env | `acp.env` | — | — | — | config deep merge |
89
90
  | Issue worktree | `session.worktree` | — | `--worktree` | `isolated` | B |
91
+ | worker ACP lazy attach | `session.lazyWorkers` | — | — | `false` | B |
90
92
  | 自律ターン上限(TTY) | `session.maxTurns.tty` | — | `--max-turns` / `--no-max-turns` | `0`(無制限) | B |
91
93
  | 自律ターン上限(非 TTY) | `session.maxTurns.nonTty` | — | `--max-turns` / `--no-max-turns` | `5` | B |
92
94
  | post-loop 待機(TTY) | `session.postLoop.wait` | — | `--no-wait` | `true` | B |
@@ -101,7 +103,7 @@ config キーなし。CI・スクリプト・端末検出、または 1 回限
101
103
 
102
104
  | 設定 | 環境変数 | config | CLI | コード default | 解決 |
103
105
  |------|----------|--------|-----|----------------|------|
104
- | TTY レイアウト | `ENSEMBLE_TUI_LAYOUT` | `tui.layout` | — | `pane` | A |
106
+ | TTY レイアウト | `ENSEMBLE_TUI_LAYOUT` | `tui.layout` | — | `stream` | A |
105
107
  | OSC 8 ハイパーリンク | `FORCE_HYPERLINK`(`1`/`0`) | `tui.forceHyperlink`(`auto`/`on`/`off`) | — | `auto` | A |
106
108
  | オペレータ 1 回注入 | `ENSEMBLE_OPERATOR_MESSAGE` | — | `ensemble issue <ref> [message...]` | — | D |
107
109
 
@@ -132,6 +134,7 @@ TUI 設定は `loadEnsembleConfig` 結果を `createIssueSessionTuiHost` へ渡
132
134
  | 設定 | ファイル | 解決順 |
133
135
  |------|----------|--------|
134
136
  | conductor MCP | `.agents/mcp.json` / `~/.ensemble/mcp.json` | project > user(サーバー名単位 merge) |
137
+ | conductor 向け user 文書 | `~/.ensemble/AGENTS.md` | user 固定。project 層なし |
135
138
  | team profile | `.ensemble/profiles/…` / `--profile` パス | [ADR 0018](https://github.com/otolab/agents-ensemble/blob/main/docs/adr/0018-team-profile-four-layer-resolution.md) |
136
139
 
137
140
  ## 一覧 — ランタイム(利用者が「設定」しない)
@@ -146,6 +149,7 @@ TUI 設定は `loadEnsembleConfig` 結果を `createIssueSessionTuiHost` へ渡
146
149
 
147
150
  | やりたいこと | 推奨 |
148
151
  |--------------|------|
152
+ | 複数 repo で conductor に共有する短い運用前提 | `~/.ensemble/AGENTS.md`([modular-prompt の文書の役割](modular-prompt.md)を参照) |
149
153
  | チーム / 個人の恒久既定(モデル、worktree、monitor) | `~/.ensemble/config.yaml` または project `.ensemble/config.yaml` |
150
154
  | CI で 1 ジョブだけ上書き | 環境変数(`CONDUCTOR_MODEL_ID` 等) |
151
155
  | 1 回限りの実行 | CLI フラグ(初回メッセージは `ensemble issue <ref> [message...]`) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-ensemble/cli",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "ensemble CLI — Issue-based agent orchestration",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "react": "19.2.0",
18
18
  "react-ink-textarea": "npm:@otolab/react-ink-textarea@0.4.1-otolab.3",
19
19
  "string-width": "8.1.0",
20
- "@agents-ensemble/core": "0.10.1"
20
+ "@agents-ensemble/core": "0.12.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/js-yaml": "4.0.9",
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "files": [
38
38
  "dist",
39
+ "scripts/pi/**",
39
40
  "README.md",
40
41
  "docs/**",
41
42
  "config.example.yaml"