@dmsdc-ai/aigentry-telepty 0.3.5 → 0.4.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 (39) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/cli.js +36 -15
  3. package/daemon.js +355 -5
  4. package/package.json +25 -1
  5. package/session-state.js +23 -0
  6. package/src/prompt-symbol-registry.js +43 -1
  7. package/.claude/commands/telepty-allow.md +0 -58
  8. package/.claude/commands/telepty-attach.md +0 -22
  9. package/.claude/commands/telepty-inject.md +0 -72
  10. package/.claude/commands/telepty-list.md +0 -22
  11. package/.claude/commands/telepty-manual-test.md +0 -73
  12. package/.claude/commands/telepty-start.md +0 -25
  13. package/.claude/commands/telepty-test.md +0 -25
  14. package/.claude/commands/telepty.md +0 -82
  15. package/AGENTS.md +0 -97
  16. package/BOUNDARY.md +0 -31
  17. package/BUS_EVENT_SCHEMA.md +0 -206
  18. package/CLAUDE.md +0 -100
  19. package/GEMINI.md +0 -10
  20. package/URGENT_ISSUES.resolved.md +0 -1
  21. package/docs/reports/2026-05-05-issue-8-claude-review.md +0 -194
  22. package/docs/specs/2026-05-05-issue-8-telepty-init.md +0 -477
  23. package/docs/superpowers/specs/2026-04-26-inject-submit-enter-reliability.md +0 -447
  24. package/docs/superpowers/specs/2026-04-26-prompt-symbol-render-gate.md +0 -571
  25. package/docs/superpowers/specs/2026-04-26-submit-gate-fixes-v2.md +0 -608
  26. package/docs/superpowers/specs/2026-05-02-submit-force-and-retry.md +0 -139
  27. package/protocol/mailbox.md +0 -244
  28. package/scripts/regen-snippet-fixtures.js +0 -42
  29. package/specs/codex-inject-spec.md +0 -201
  30. package/specs/enforce-report-spec.md +0 -237
  31. package/templates/AGENTS.md +0 -71
  32. package/tests/snippet-protocol/v1/golden-agents.json +0 -1
  33. package/tests/snippet-protocol/v1/golden-agents.md +0 -17
  34. package/tests/snippet-protocol/v1/golden-all.json +0 -3
  35. package/tests/snippet-protocol/v1/golden-all.md +0 -53
  36. package/tests/snippet-protocol/v1/golden-claude.json +0 -1
  37. package/tests/snippet-protocol/v1/golden-claude.md +0 -17
  38. package/tests/snippet-protocol/v1/golden-gemini.json +0 -1
  39. package/tests/snippet-protocol/v1/golden-gemini.md +0 -17
package/session-state.js CHANGED
@@ -203,6 +203,9 @@ class SessionStateMachine {
203
203
 
204
204
  // Strip ANSI and split into lines for pattern analysis
205
205
  const cleaned = stripAnsi(data);
206
+ if (cleaned.trim().length === 0) {
207
+ return;
208
+ }
206
209
  const lines = cleaned.split(/\r?\n/).filter(l => l.trim().length > 0);
207
210
 
208
211
  for (const line of lines) {
@@ -269,6 +272,16 @@ class SessionStateMachine {
269
272
  this._transition(STATES.RESTARTING, 1.0, { trigger: 'lifecycle' });
270
273
  }
271
274
 
275
+ markIdle(confidence = 1.0, detail = {}) {
276
+ if (this._state === STATES.DEAD || this._state === STATES.RESTARTING) {
277
+ return;
278
+ }
279
+ this._transition(STATES.IDLE, confidence, {
280
+ trigger: 'manual_idle',
281
+ ...detail,
282
+ });
283
+ }
284
+
272
285
  // --- Internal ---
273
286
 
274
287
  _transition(newState, confidence, detail) {
@@ -538,6 +551,16 @@ class SessionStateManager {
538
551
  if (sm) sm.markRestarting();
539
552
  }
540
553
 
554
+ /**
555
+ * Mark a session as idle from a semantic daemon event.
556
+ */
557
+ markIdle(sessionId, confidence = 1.0, detail = {}) {
558
+ const sm = this._machines.get(sessionId);
559
+ if (!sm) return false;
560
+ sm.markIdle(confidence, detail);
561
+ return true;
562
+ }
563
+
541
564
  /**
542
565
  * Unregister and cleanup a session's state machine.
543
566
  */
@@ -94,4 +94,46 @@ function lookup(command) {
94
94
  return null;
95
95
  }
96
96
 
97
- module.exports = { lookup, ENTRIES };
97
+ function commandKey(command) {
98
+ const entry = lookup(command);
99
+ if (!entry) return null;
100
+ for (const [key, value] of Object.entries(ENTRIES)) {
101
+ if (value === entry) return key;
102
+ }
103
+ return null;
104
+ }
105
+
106
+ function isKnownAiCli(command) {
107
+ return !!lookup(command);
108
+ }
109
+
110
+ const ANSI_RE = /\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07]*(?:\x07|\x1b\\)|\x1b[()][AB012]|\x1b[>=<78DMEHcNOZ~}|]/g;
111
+
112
+ function stripAnsi(value) {
113
+ return String(value == null ? '' : value).replace(ANSI_RE, '');
114
+ }
115
+
116
+ function normalizeOutputForDetection(output) {
117
+ return stripAnsi(output)
118
+ .replace(/\r\n/g, '\n')
119
+ .replace(/\r/g, '\n')
120
+ .replace(/\n{2,}/g, '\n');
121
+ }
122
+
123
+ function detectOutput(command, output) {
124
+ const entry = lookup(command);
125
+ if (!entry) {
126
+ return { found: false, reason: 'unknown_cli' };
127
+ }
128
+ const screenLike = normalizeOutputForDetection(output);
129
+ return entry.detect(screenLike);
130
+ }
131
+
132
+ module.exports = {
133
+ lookup,
134
+ commandKey,
135
+ isKnownAiCli,
136
+ detectOutput,
137
+ normalizeOutputForDetection,
138
+ ENTRIES,
139
+ };
@@ -1,58 +0,0 @@
1
- # telepty-allow
2
-
3
- Allow inject on an LLM CLI (or any command) via telepty.
4
-
5
- ## Instructions
6
-
7
- ### Usage
8
- ```bash
9
- telepty allow [--id <session_id>] -- <command> [args...]
10
- ```
11
-
12
- ### Examples
13
- ```bash
14
- # Claude Code with custom session ID
15
- telepty allow --id my-claude -- claude
16
-
17
- # Codex with auto-generated ID
18
- telepty allow -- codex
19
-
20
- # Gemini with custom ID
21
- telepty allow --id gemini-main -- gemini
22
-
23
- # Any shell command
24
- telepty allow --id dev-shell -- bash
25
- ```
26
-
27
- ### What it does
28
- 1. Registers the session with the telepty daemon
29
- 2. Spawns the command locally via `node-pty` (preserves isTTY, raw mode, colors)
30
- 3. Connects to daemon as WebSocket owner for inject reception
31
- 4. Sets `TELEPTY_SESSION_ID` env var inside the process
32
-
33
- ### Key behaviors
34
- - **isTTY preserved**: TUI apps (claude, codex, gemini) work normally
35
- - **Daemon fault-tolerant**: if daemon dies, the CLI keeps running (inject unavailable until reconnect)
36
- - **Session auto-cleanup**: when the command exits, session is deregistered
37
-
38
- ### After allowing, from another terminal:
39
- ```bash
40
- # List sessions
41
- telepty list
42
-
43
- # Inject into the session
44
- telepty inject <session_id> "your prompt here"
45
-
46
- # Attach to watch output
47
- telepty attach <session_id>
48
- ```
49
-
50
- ## Execute
51
- If the user provides arguments, run the allow command for them:
52
-
53
- ```bash
54
- cd /Users/duckyoungkim/projects/aigentry-telepty
55
- node cli.js allow $ARGUMENTS
56
- ```
57
-
58
- If no arguments, show the usage guide above and ask what they want to run.
@@ -1,22 +0,0 @@
1
- # telepty-attach
2
-
3
- Attach to an active telepty session to observe its output in real-time.
4
-
5
- ## Instructions
6
-
7
- ### Execute
8
- ```bash
9
- cd /Users/duckyoungkim/projects/aigentry-telepty && node cli.js attach $ARGUMENTS
10
- ```
11
-
12
- ### If no arguments
13
- 1. List available sessions: `node cli.js list`
14
- 2. Ask the user which session to attach to
15
-
16
- ### Notes
17
- - For **spawned** sessions: you can both view output and send input
18
- - For **wrapped** sessions: input from attached clients is forwarded to the owner as inject
19
- - Press `Ctrl+C` to detach without killing the session
20
-
21
- ## Arguments
22
- - `$ARGUMENTS`: session ID to attach to
@@ -1,72 +0,0 @@
1
- # telepty-inject
2
-
3
- Inject a prompt into a telepty session (spawned or wrapped).
4
-
5
- ## Instructions
6
-
7
- Parse `$ARGUMENTS` to extract target session ID and prompt text.
8
-
9
- ### Format
10
- ```
11
- <session_id> <prompt text>
12
- ```
13
-
14
- ### Step 1: Parse Arguments
15
-
16
- If no arguments provided:
17
- 1. List available sessions: `telepty list`
18
- 2. Ask the user which session to target and what to inject
19
-
20
- Extract `session_id` (first word) and `prompt` (rest of the arguments).
21
-
22
- ### Step 2: English-Only Enforcement
23
-
24
- Check if the prompt body contains non-English text (Korean, Japanese, Chinese, etc.).
25
-
26
- - If non-English text detected: Warn the user and auto-translate the prompt to English before proceeding.
27
- - Exception: Technical terms (e.g., 'hangul', 'jamo', session IDs like 'aigentry-*') used alongside English are OK.
28
- - The `--from` header and `[reply-to:]` metadata are exempt from this check.
29
-
30
- ### Step 3: Auto --ref for Long Content
31
-
32
- Detect if the prompt is long (>500 characters OR >3 lines):
33
-
34
- - **Long content**: Use `--ref` flag automatically. This writes the prompt to a shared file and sends a SHA reference instead of inline text. Tell the user: "Using --ref (content is X chars / Y lines)."
35
- - **Short content**: Send inline as-is.
36
-
37
- ### Step 4: Pre-Send Confirmation
38
-
39
- Before executing, show the user:
40
- ```
41
- Target: <session_id>
42
- Prompt: <first 100 chars of prompt>... (X chars total)
43
- Flags: --ref (if applicable), --from (if set)
44
- ```
45
-
46
- Then ask: "Send? (y/n)"
47
-
48
- **Skip confirmation when:**
49
- - User explicitly said "send it", "just send", "바로 보내", or similar
50
- - The command was invoked with `--yes` or `-y` flag
51
- - Context clearly implies immediate send (e.g., replying to an orchestrator request)
52
-
53
- ### Step 5: Execute
54
-
55
- ```bash
56
- telepty inject [--ref] [--from <from_id>] <session_id> "<prompt>"
57
- ```
58
-
59
- If `TELEPTY_SESSION_ID` env var is set, automatically add `--from $TELEPTY_SESSION_ID`.
60
-
61
- ### Multicast (multiple targets)
62
- ```bash
63
- telepty multicast <id1>,<id2> "<prompt>"
64
- ```
65
-
66
- ### Broadcast (all sessions)
67
- ```bash
68
- telepty broadcast "<prompt>"
69
- ```
70
-
71
- ## Arguments
72
- - `$ARGUMENTS`: `<session_id> "<prompt>"` or empty for interactive mode
@@ -1,22 +0,0 @@
1
- # telepty-list
2
-
3
- List all active telepty sessions with their types and status.
4
-
5
- ## Instructions
6
-
7
- 1. Run:
8
- ```bash
9
- cd /Users/duckyoungkim/projects/aigentry-telepty && node cli.js list
10
- ```
11
-
12
- 2. If the daemon is not running, tell the user and suggest `/project:telepty-start`.
13
-
14
- 3. Format the output as a clear table showing:
15
- - Session ID
16
- - Type (spawned / wrapped)
17
- - Command
18
- - Active clients
19
- - Created time
20
-
21
- ## Arguments
22
- - `$ARGUMENTS`: ignored
@@ -1,73 +0,0 @@
1
- # telepty-manual-test
2
-
3
- Guided manual test of the telepty enable (inject) feature. Runs step-by-step verification.
4
-
5
- ## Instructions
6
-
7
- Execute each step sequentially, verifying results before proceeding.
8
-
9
- ### Step 1: Ensure daemon is running
10
- ```bash
11
- cd /Users/duckyoungkim/projects/aigentry-telepty
12
- curl -s http://127.0.0.1:3848/api/sessions 2>/dev/null || node daemon.js &
13
- sleep 1
14
- ```
15
-
16
- ### Step 2: Register a wrapped session via API
17
- ```bash
18
- TOKEN=$(cat ~/.telepty/config.json 2>/dev/null | grep authToken | cut -d '"' -f 4)
19
- curl -s -X POST http://127.0.0.1:3848/api/sessions/register \
20
- -H "Content-Type: application/json" \
21
- -H "x-telepty-token: $TOKEN" \
22
- -d '{"session_id": "manual-test-1", "command": "test", "cwd": "'"$(pwd)"'"}'
23
- ```
24
- **Verify**: response has `type: "wrapped"` and status 201.
25
-
26
- ### Step 3: Check session listing
27
- ```bash
28
- curl -s http://127.0.0.1:3848/api/sessions -H "x-telepty-token: $TOKEN" | python3 -m json.tool
29
- ```
30
- **Verify**: `manual-test-1` appears with `type: "wrapped"`.
31
-
32
- ### Step 4: Test inject without owner (should fail)
33
- ```bash
34
- curl -s -X POST http://127.0.0.1:3848/api/sessions/manual-test-1/inject \
35
- -H "Content-Type: application/json" \
36
- -H "x-telepty-token: $TOKEN" \
37
- -d '{"prompt": "hello"}'
38
- ```
39
- **Verify**: returns 503 with "not connected" error.
40
-
41
- ### Step 5: Clean up test session
42
- ```bash
43
- curl -s -X DELETE http://127.0.0.1:3848/api/sessions/manual-test-1 \
44
- -H "x-telepty-token: $TOKEN"
45
- ```
46
- **Verify**: returns status "closing".
47
-
48
- ### Step 6: Verify session removed
49
- ```bash
50
- curl -s http://127.0.0.1:3848/api/sessions -H "x-telepty-token: $TOKEN"
51
- ```
52
- **Verify**: `manual-test-1` no longer in the list.
53
-
54
- ### Step 7: Run automated tests
55
- ```bash
56
- npm test
57
- ```
58
- **Verify**: all 25 tests pass.
59
-
60
- ### Report
61
- Summarize all verification results in a table:
62
-
63
- | Step | Check | Result |
64
- |------|-------|--------|
65
- | 2 | Register returns 201 + wrapped | ? |
66
- | 3 | Session in list with type | ? |
67
- | 4 | Inject without owner = 503 | ? |
68
- | 5 | DELETE returns closing | ? |
69
- | 6 | Session removed | ? |
70
- | 7 | All tests pass | ? |
71
-
72
- ## Arguments
73
- - `$ARGUMENTS`: ignored
@@ -1,25 +0,0 @@
1
- # telepty-start
2
-
3
- Start the telepty daemon process.
4
-
5
- ## Instructions
6
-
7
- 1. Check if daemon is already running:
8
- ```bash
9
- curl -s http://127.0.0.1:3848/api/sessions 2>/dev/null && echo "RUNNING" || echo "NOT RUNNING"
10
- ```
11
-
12
- 2. If not running, start it:
13
- ```bash
14
- cd /Users/duckyoungkim/projects/aigentry-telepty && node daemon.js &
15
- ```
16
-
17
- 3. Verify it started:
18
- ```bash
19
- sleep 1 && curl -s http://127.0.0.1:3848/api/sessions
20
- ```
21
-
22
- 4. Report status.
23
-
24
- ## Arguments
25
- - `$ARGUMENTS`: optional port override (e.g., "3849")
@@ -1,25 +0,0 @@
1
- # telepty-test
2
-
3
- Run the telepty automated test suite and report results.
4
-
5
- ## Instructions
6
-
7
- 1. Run the full test suite:
8
- ```bash
9
- cd /Users/duckyoungkim/projects/aigentry-telepty && npm test
10
- ```
11
-
12
- 2. Parse the output and report:
13
- - Total tests, passed, failed
14
- - If any failures: show the failing test name and error message
15
- - If all pass: confirm with count
16
-
17
- 3. If tests fail, investigate:
18
- - Read the failing test in `test/daemon.test.js`
19
- - Check if daemon.js has related issues
20
- - Suggest or apply fixes
21
- - Re-run tests to confirm
22
-
23
- ## Arguments
24
- - No arguments: run all tests
25
- - `$ARGUMENTS`: if provided, use as a grep filter to run specific tests (e.g., "wrap", "register", "inject")
@@ -1,82 +0,0 @@
1
- # telepty
2
-
3
- Help the user interact with the `telepty` daemon — check session IDs, list active sessions, inject commands, send bus events, and manage terminal windows.
4
-
5
- ## Trigger
6
-
7
- When the user asks about their current session ID, wants to check/list active sessions, inject a prompt into a session, send a JSON event via the bus, subscribe to the bus, rename a session, or update telepty.
8
-
9
- ## Instructions
10
-
11
- ### 1. Check Current Session ID
12
- - Run: `echo $TELEPTY_SESSION_ID`
13
- - If empty: this shell is NOT inside a telepty session.
14
- - If set: display it. This is the ID other agents use to target this session.
15
-
16
- ### 2. List All Sessions
17
- - Run: `telepty list`
18
-
19
- ### 3. Send a Message to Another Agent
20
- Choose ONE of three methods based on intent:
21
-
22
- **Method A: Prompt Injection (Active Interruption)**
23
- The receiving AI will IMMEDIATELY read and execute the message as a prompt.
24
- ```bash
25
- telepty inject <target_session_id> "<prompt text>"
26
- ```
27
- For multiple targets: `telepty multicast <id1>,<id2> "<prompt>"`
28
-
29
- **Method B: Log Injection (Visual Notification)**
30
- The message appears on the receiving terminal screen for the user to see, but the AI does NOT execute it as a prompt.
31
- ```bash
32
- telepty inject <target_session_id> "echo '\x1b[33m[Message from $TELEPTY_SESSION_ID]\x1b[0m <message text>'"
33
- ```
34
-
35
- **Method C: Background JSON Bus (Passive/Silent)**
36
- Structured data transfer that won't disturb the receiving terminal screen.
37
- ```bash
38
- TOKEN=$(cat ~/.telepty/config.json | grep authToken | cut -d '"' -f 4)
39
- curl -s -X POST http://127.0.0.1:3848/api/bus/publish \
40
- -H "Content-Type: application/json" \
41
- -H "x-telepty-token: $TOKEN" \
42
- -d '{"type": "bg_message", "payload": "..."}'
43
- ```
44
-
45
- ### 4. Subscribe to the Event Bus
46
- ```bash
47
- nohup telepty listen > .telepty_bus_events.log 2>&1 &
48
- ```
49
-
50
- ### 5. Open a New Ghostty Terminal Window
51
- Physically spawn a new terminal window already attached to a telepty session:
52
- ```bash
53
- cat << 'EOF' > /tmp/telepty-auto.command
54
- #!/bin/bash
55
- telepty spawn --id <ID> <CMD>
56
- EOF
57
- chmod +x /tmp/telepty-auto.command
58
- open -a Ghostty /tmp/telepty-auto.command || open /tmp/telepty-auto.command
59
- ```
60
-
61
- ### 6. Terminal Title Convention
62
- Each telepty session displays its ID in the Ghostty tab title:
63
- - Local: `⚡ telepty :: {session_id}`
64
- - Remote: `⚡ telepty :: {session_id} @ {host}`
65
-
66
- ### 7. Allow Inject on a CLI
67
- Run any command with inject allowed:
68
- ```bash
69
- # With custom session ID
70
- telepty allow --id my-claude -- claude
71
- telepty allow --id codex-main -- codex
72
- telepty allow --id gemini-1 -- gemini
73
-
74
- # Auto-generated session ID
75
- telepty allow -- bash
76
- ```
77
- The process runs locally (isTTY preserved), but registers with the daemon so inject works.
78
-
79
- ### 8. Update
80
- ```bash
81
- telepty update
82
- ```
package/AGENTS.md DELETED
@@ -1,97 +0,0 @@
1
- # AGENTS.md — aigentry-telepty
2
-
3
- ## Overview
4
-
5
- PTY Multiplexer & Session Orchestrator — aigentry 에코시스템의 **통신 인프라**.
6
- npm: `@dmsdc-ai/aigentry-telepty` | 멀티 AI 세션을 생성·연결·제어하는 PTY 멀티플렉서.
7
-
8
- ## Architecture
9
-
10
- ```
11
- CLI (cli.js) ──→ HTTP/WS ──→ Daemon (daemon.js:3848)
12
- ├── Session WS (/api/sessions/:id)
13
- ├── Event Bus WS (/api/bus)
14
- └── REST API (/api/sessions/*)
15
- ```
16
-
17
- | 파일 | 역할 |
18
- |------|------|
19
- | `cli.js` | CLI 명령 + allow-bridge (PTY 래핑) |
20
- | `daemon.js` | HTTP/WS 서버, 세션 상태, inject 전달 |
21
- | `tui.js` | blessed 기반 TUI 대시보드 |
22
- | `session-routing.js` | 세션 ID 해석, alias 매칭, 호스트 그룹핑 |
23
- | `daemon-control.js` | 싱글톤 daemon PID 관리 |
24
- | `auth.js` | UUID 토큰 기반 인증 |
25
- | `interactive-terminal.js` | raw mode stdin/stdout 관리 |
26
- | `skill-installer.js` | CLI별 스킬 설치 (Claude/Codex/Gemini) |
27
-
28
- ## Inject 전달 경로 (wrapped session)
29
-
30
- 1. **Primary**: `kitty @ send-text` (터미널 직접 전달, allow-bridge 우회)
31
- 2. **Fallback**: WS → allow-bridge → `child.write()` (PTY)
32
- 3. **Submit**: `osascript` Return 키 → kitty fallback → WS `\r`
33
-
34
- busy 세션: CR은 큐에 대기 중인 텍스트와 함께 큐잉 후 올바른 순서로 flush.
35
-
36
- ## Commands
37
-
38
- ```bash
39
- npm test # 43 tests (node:test)
40
- telepty daemon # daemon 시작 (포트 3848)
41
- telepty allow --id <name> claude # 세션 래핑
42
- telepty tui # TUI 대시보드
43
- telepty list # 세션 목록
44
- telepty inject <id> "msg" # 메시지 주입
45
- telepty broadcast "msg" # 전체 브로드캐스트
46
- telepty session start --launch # kitty 탭으로 다중 세션 시작
47
- ```
48
-
49
- ## Key Rules
50
-
51
- - inject 후 submit은 항상 `osascript`로 통일 (`--no-enter` + osascript keystroke)
52
- - inject 시 발신자 session ID (`--from`)를 항상 포함
53
- - PTY `\r` 직접 의존 금지
54
-
55
- ## Session Communication
56
-
57
- ```bash
58
- # List active sessions
59
- telepty list
60
-
61
- # Send message to another session
62
- telepty inject --from aigentry-telepty-{cli} <target-session> "message"
63
-
64
- # Report to orchestrator
65
- telepty inject --ref --from aigentry-telepty-{cli} aigentry-orchestrator-claude "report"
66
- ```
67
-
68
- ## Work Principles
69
-
70
- - **Best-First**: 항상 최선의 해결책 선택. 차선책/우회 금지.
71
- - **Configurable**: 설정으로 제어 가능한 구조. 하드코딩 금지.
72
- - **Evidence-Based**: 추측 금지. 데이터/로그/테스트 결과 기반 판단.
73
- - **Fail Fast**: 에러 즉시 보고. 숨기지 않음.
74
- - **Constitution**: ~/projects/aigentry/docs/CONSTITUTION.md 준수.
75
-
76
- ## Legacy exception — `skill-installer.js`
77
-
78
- `skill-installer.js` is a **named legacy exception** grandfathered by
79
- **ADR 2026-05-05-telepty-devkit-boundary §6.2.1**. It is the single
80
- exception to the telepty/devkit boundary rule and is NOT precedent for
81
- new placements.
82
-
83
- - **Scope**: bugfixes, security patches, dependency upgrades only.
84
- - **No new feature expansion**: net-new functionality (new CLI detection,
85
- new skill types, new install paths, new flags) MUST land in
86
- `@dmsdc-ai/aigentry-devkit`. At migration time devkit will introduce
87
- `aigentry scaffold install-skills`.
88
- - **Reviewer enforcement**: PR reviewers cite ADR 2026-05-05 §6.2.1 when
89
- rejecting feature-expansion PRs against `skill-installer.js`.
90
- - **Migration triggers** (per ADR §6.2.1): ≥2 PRs in 60 days attempting
91
- net-new features; devkit feature requires functionality only in
92
- `skill-installer.js`; breaking change to its interface.
93
-
94
- Per-CLI hook installation, `CLAUDE.md`/`AGENTS.md`/`GEMINI.md` scaffolding,
95
- project-file generation, and cross-cutting installable skills are
96
- **devkit-owned** per ADR 2026-05-05 §3.3 — not telepty's responsibility.
97
- See `@dmsdc-ai/aigentry-devkit` (`aigentry scaffold …`).
package/BOUNDARY.md DELETED
@@ -1,31 +0,0 @@
1
- # telepty Responsibility Boundary
2
-
3
- ## What telepty owns
4
-
5
- - **PTY lifecycle**: spawn, resize, kill PTY processes; emit session_spawn / session_register / session_rename events
6
- - **Raw stdin write**: accept inject requests and write bytes to the PTY fd (best-effort, fire-and-forget)
7
- - **stdout streaming**: pipe PTY output to connected WebSocket clients in real time
8
- - **Bus event broadcast**: publish structured events to all `/api/bus` subscribers
9
- - **Session lifecycle**: track active sessions, clean up on exit or owner disconnect
10
- - **Liveness heartbeat**: emit `session_health` every 10 seconds per active session
11
-
12
- ## What telepty does NOT own
13
-
14
- - **CLI state management**: the caller owns its own state machine; telepty does not know what state an agent is in
15
- - **Inject processing confirmation**: telepty emits `inject_written` when bytes are handed to the OS; it cannot confirm the process consumed or acted on them
16
- - **Output parsing / interpretation**: telepty streams raw bytes; callers parse meaning
17
- - **Message guarantee / retry / ordering**: no retry logic, no queue, no ordering guarantees across multiple injects
18
- - **Session recovery / persistence**: sessions are in-memory; a daemon restart loses all sessions
19
- - **Cross-session routing**: routing logic (which session gets which message) belongs to the caller or an orchestration layer above telepty
20
-
21
- ## PTY limitations
22
-
23
- - `inject_written` is **best-effort**: it confirms the write syscall to the OS PTY fd succeeded, not that the running process read or processed the input
24
- - The OS buffers stdin asynchronously; a process blocked, sleeping, or not reading stdin will silently queue the bytes
25
- - There is no read-back or echo confirmation; callers must observe stdout via the WebSocket stream to infer processing
26
-
27
- ## Design principle
28
-
29
- > **telepty = stateless dumb pipe**
30
-
31
- telepty moves bytes. It does not interpret, retry, sequence, or guarantee delivery beyond the OS write call. All higher-level semantics (acknowledgement, ordering, state machines, recovery) are the responsibility of the layer above.