tissues 0.3.0 → 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.
package/README.md CHANGED
@@ -1,18 +1,19 @@
1
- # ghissue
1
+ # tissues
2
2
 
3
3
  AI-enhanced GitHub issue creation with built-in safety guardrails.
4
4
 
5
5
  Create structured, deduplicated GitHub issues from the command line — with circuit breakers and rate limiting to prevent runaway issue creation when used inside AI agent workflows.
6
6
 
7
- [![npm version](https://img.shields.io/npm/v/ghissue)](https://www.npmjs.com/package/ghissue)
7
+ [![npm version](https://img.shields.io/npm/v/tissues)](https://www.npmjs.com/package/tissues)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![Website](https://img.shields.io/badge/website-tissues.cc-blue)](https://tissues.cc)
9
10
 
10
11
  ---
11
12
 
12
13
  ## Install
13
14
 
14
15
  ```bash
15
- npm install -g ghissue
16
+ npm install -g tissues
16
17
  ```
17
18
 
18
19
  Requires Node.js >= 18.
@@ -23,45 +24,45 @@ Requires Node.js >= 18.
23
24
 
24
25
  ```bash
25
26
  # Authenticate (auto-detects gh CLI token)
26
- ghissue auth
27
+ tissues auth
27
28
 
28
29
  # Set your active repo
29
- ghissue open
30
+ tissues open
30
31
 
31
32
  # Create an issue interactively
32
- ghissue create
33
+ tissues create
33
34
 
34
35
  # Check safety status before running in CI
35
- ghissue status
36
+ tissues status
36
37
  ```
37
38
 
38
39
  ---
39
40
 
40
41
  ## Commands
41
42
 
42
- ### `ghissue auth`
43
+ ### `tissues auth`
43
44
 
44
45
  Authenticate with GitHub. Auto-detects your `gh` CLI token if you're already logged in via `gh`. Falls back to GitHub OAuth Device Flow if not.
45
46
 
46
47
  ```bash
47
- ghissue auth
48
+ tissues auth
48
49
  ```
49
50
 
50
- ### `ghissue open`
51
+ ### `tissues open`
51
52
 
52
53
  Set the active repository context. All subsequent commands use this repo unless overridden with `--repo`.
53
54
 
54
55
  ```bash
55
- ghissue open
56
+ tissues open
56
57
  # prompts: pick a repo from your GitHub account
57
58
  ```
58
59
 
59
- ### `ghissue create`
60
+ ### `tissues create`
60
61
 
61
62
  Create a new GitHub issue. Runs dedup checks and safety gates before creating anything.
62
63
 
63
64
  ```bash
64
- ghissue create [options]
65
+ tissues create [options]
65
66
  ```
66
67
 
67
68
  **Options:**
@@ -82,10 +83,10 @@ ghissue create [options]
82
83
 
83
84
  ```bash
84
85
  # Interactive
85
- ghissue create
86
+ tissues create
86
87
 
87
88
  # Fully scripted (no prompts)
88
- ghissue create \
89
+ tissues create \
89
90
  --repo owner/my-repo \
90
91
  --template bug \
91
92
  --title "Login fails on Safari 17" \
@@ -93,7 +94,7 @@ ghissue create \
93
94
  --labels "bug,P1"
94
95
 
95
96
  # From an AI agent
96
- ghissue create \
97
+ tissues create \
97
98
  --agent claude-opus-4-6 \
98
99
  --session abc123 \
99
100
  --template feature \
@@ -101,23 +102,23 @@ ghissue create \
101
102
  --dry-run
102
103
  ```
103
104
 
104
- ### `ghissue list`
105
+ ### `tissues list`
105
106
 
106
107
  Browse open issues for the active repo.
107
108
 
108
109
  ```bash
109
- ghissue list
110
- ghissue list --repo owner/other-repo
110
+ tissues list
111
+ tissues list --repo owner/other-repo
111
112
  ```
112
113
 
113
- ### `ghissue status`
114
+ ### `tissues status`
114
115
 
115
116
  Show circuit breaker state and rate limit usage for the active repo.
116
117
 
117
118
  ```bash
118
- ghissue status
119
- ghissue status --agent claude-opus-4-6
120
- ghissue status --reset # force-reset circuit breaker to closed
119
+ tissues status
120
+ tissues status --agent claude-opus-4-6
121
+ tissues status --reset # force-reset circuit breaker to closed
121
122
  ```
122
123
 
123
124
  Output:
@@ -136,7 +137,7 @@ Fingerprints stored: 47
136
137
 
137
138
  ## Safety Features
138
139
 
139
- ghissue is designed to be called from AI agent loops. The safety infrastructure prevents one misconfigured agent from flooding a repo with issues.
140
+ tissues is designed to be called from AI agent loops. The safety infrastructure prevents one misconfigured agent from flooding a repo with issues.
140
141
 
141
142
  ### Circuit Breaker
142
143
 
@@ -151,8 +152,8 @@ The circuit trips after 3 blocked attempts (dedup blocks count as failures). If
151
152
  To inspect or reset:
152
153
 
153
154
  ```bash
154
- ghissue status
155
- ghissue status --reset
155
+ tissues status
156
+ tissues status --reset
156
157
  ```
157
158
 
158
159
  ### Rate Limiting
@@ -165,7 +166,7 @@ Three independent rate limits, all checked before creating:
165
166
  | Per-agent burst | 5 issues / 5 minutes | per repo + agent |
166
167
  | Global hourly | 30 issues/hour | per repo, all agents combined |
167
168
 
168
- All limits are configurable in `.gitissues/config.json`.
169
+ All limits are configurable in `.tissues/config.json`.
169
170
 
170
171
  ### Deduplication (3 layers)
171
172
 
@@ -179,7 +180,7 @@ A `block` always prevents creation. A `warn` prompts interactively (or is skippe
179
180
 
180
181
  ### Attribution Tracking
181
182
 
182
- Every issue created by ghissue includes a machine-readable `<!-- gitissues-meta -->` block. See [Attribution](#attribution) below.
183
+ Every issue created by tissues includes a machine-readable `<!-- tissues-meta -->` block. See [Attribution](#attribution) below.
183
184
 
184
185
  ---
185
186
 
@@ -188,11 +189,11 @@ Every issue created by ghissue includes a machine-readable `<!-- gitissues-meta
188
189
  Configuration is loaded and merged from four sources in ascending priority order:
189
190
 
190
191
  1. Built-in defaults
191
- 2. User-level config: `~/.config/gitissues/config.json`
192
- 3. Repo-level config: `.gitissues/config.json`
193
- 4. Environment variables: `GITISSUES_*`
192
+ 2. User-level config: `~/.config/tissues/config.json`
193
+ 3. Repo-level config: `.tissues/config.json`
194
+ 4. Environment variables: `TISSUES_*`
194
195
 
195
- ### Example `.gitissues/config.json`
196
+ ### Example `.tissues/config.json`
196
197
 
197
198
  ```json
198
199
  {
@@ -214,7 +215,7 @@ Configuration is loaded and merged from four sources in ascending priority order
214
215
  "defaultAgent": "human"
215
216
  },
216
217
  "templates": {
217
- "dir": ".gitissues/templates",
218
+ "dir": ".tissues/templates",
218
219
  "default": "bug"
219
220
  },
220
221
  "hooks": {
@@ -225,13 +226,13 @@ Configuration is loaded and merged from four sources in ascending priority order
225
226
 
226
227
  ### Environment Variables
227
228
 
228
- Environment variables follow the pattern `GITISSUES_<SECTION>_<KEY>`:
229
+ Environment variables follow the pattern `TISSUES_<SECTION>_<KEY>`:
229
230
 
230
231
  ```bash
231
- GITISSUES_SAFETY_MAX_PER_HOUR=5
232
- GITISSUES_SAFETY_BURST_LIMIT=3
233
- GITISSUES_SAFETY_GLOBAL_MAX_PER_HOUR=20
234
- GITISSUES_ATTRIBUTION_DEFAULT_AGENT=my-agent
232
+ TISSUES_SAFETY_MAX_PER_HOUR=5
233
+ TISSUES_SAFETY_BURST_LIMIT=3
234
+ TISSUES_SAFETY_GLOBAL_MAX_PER_HOUR=20
235
+ TISSUES_ATTRIBUTION_DEFAULT_AGENT=my-agent
235
236
  ```
236
237
 
237
238
  ### Hooks
@@ -239,9 +240,9 @@ GITISSUES_ATTRIBUTION_DEFAULT_AGENT=my-agent
239
240
  `postCreate` runs a shell command after every successful issue creation. Three environment variables are injected:
240
241
 
241
242
  ```bash
242
- GITISSUES_REPO # owner/repo
243
- GITISSUES_ISSUE_NUMBER # 142
244
- GITISSUES_ISSUE_URL # https://github.com/owner/repo/issues/142
243
+ TISSUES_REPO # owner/repo
244
+ TISSUES_ISSUE_NUMBER # 142
245
+ TISSUES_ISSUE_URL # https://github.com/owner/repo/issues/142
245
246
  ```
246
247
 
247
248
  ---
@@ -261,7 +262,7 @@ GITISSUES_ISSUE_URL # https://github.com/owner/repo/issues/142
261
262
 
262
263
  ### Custom Templates
263
264
 
264
- Place `.md` files in `.gitissues/templates/` (repo-level) or `~/.config/gitissues/templates/` (user-level). Repo templates take priority over user templates, which take priority over built-ins.
265
+ Place `.md` files in `.tissues/templates/` (repo-level) or `~/.config/tissues/templates/` (user-level). Repo templates take priority over user templates, which take priority over built-ins.
265
266
 
266
267
  Template files support `{{variable}}` substitution:
267
268
 
@@ -274,7 +275,7 @@ Template files support `{{variable}}` substitution:
274
275
  | `{{date}}` | ISO date (YYYY-MM-DD) |
275
276
  | `{{repo}}` | Repository (owner/name) |
276
277
 
277
- **Example** `.gitissues/templates/incident.md`:
278
+ **Example** `.tissues/templates/incident.md`:
278
279
 
279
280
  ```markdown
280
281
  name: Incident Report
@@ -303,21 +304,21 @@ Use it with `--template incident`.
303
304
 
304
305
  ## Attribution
305
306
 
306
- Every issue created by ghissue includes a machine-readable HTML comment at the bottom of the body. GitHub renders it as invisible text; it does not appear in the rendered issue.
307
+ Every issue created by tissues includes a machine-readable HTML comment at the bottom of the body. GitHub renders it as invisible text; it does not appear in the rendered issue.
307
308
 
308
309
  ```html
309
- <!-- gitissues-meta
310
+ <!-- tissues-meta
310
311
  agent: claude-opus-4-6
311
312
  session: abc123
312
313
  pid: 84921
313
314
  trigger: cli-create
314
315
  fingerprint: sha256:3f2a1b...
315
316
  created_at: 2026-02-19T15:30:00.000Z
316
- created_via: ghissue-cli/0.3.0
317
+ created_via: tissues-cli/0.3.0
317
318
  -->
318
319
  ```
319
320
 
320
- The block is used by ghissue to:
321
+ The block is used by tissues to:
321
322
 
322
323
  - Power content fingerprint dedup (prevents re-creating identical issues)
323
324
  - Track which agent created which issue
@@ -329,10 +330,10 @@ You can pass additional fields via `--agent`, `--session`, and the programmatic
329
330
 
330
331
  ## State Database
331
332
 
332
- ghissue stores local state in a SQLite database at:
333
+ tissues stores local state in a SQLite database at:
333
334
 
334
335
  ```
335
- .gitissues/data/gitissues.db
336
+ .tissues/data/tissues.db
336
337
  ```
337
338
 
338
339
  **No separate SQLite install.** The CLI uses [better-sqlite3](https://github.com/WiseLibs/better-sqlite3), which compiles SQLite into the Node addon at `npm install` time. Users do not need to install SQLite on their system. SQLite is a common choice for CLI tool state when you need queryable, structured data (rate limits, dedup history, circuit breaker); simpler config lives in JSON (e.g. `conf` store).
package/package.json CHANGED
@@ -1,18 +1,17 @@
1
1
  {
2
2
  "name": "tissues",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "AI-enhanced GitHub issue creation with built-in safety guardrails. Wraps gh CLI with circuit breakers, rate limiting, dedup, and templates.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "tissues": "./bin/gitissues.js"
7
+ "tissues": "./bin/tissues.js"
8
8
  },
9
9
  "scripts": {
10
- "dev": "node bin/gitissues.js",
11
- "watch": "node --watch bin/gitissues.js --help",
10
+ "dev": "node bin/tissues.js",
11
+ "watch": "node --watch bin/tissues.js --help",
12
12
  "test": "node --test src/**/*.test.js",
13
13
  "audit": "node scripts/audit.js",
14
14
  "build": "node scripts/build.js",
15
- "prepublishOnly": "node scripts/audit.js",
16
15
  "dev:install": "node scripts/dev-install.js",
17
16
  "dev:uninstall": "node scripts/dev-install.js --uninstall"
18
17
  },
@@ -28,13 +27,13 @@
28
27
  ],
29
28
  "author": "Caleb Ogden",
30
29
  "license": "MIT",
31
- "homepage": "https://ghissue.dev",
30
+ "homepage": "https://tissues.cc",
32
31
  "repository": {
33
32
  "type": "git",
34
- "url": "https://github.com/calebogden/ghissue.git"
33
+ "url": "https://github.com/calebogden/tissues.git"
35
34
  },
36
35
  "bugs": {
37
- "url": "https://github.com/calebogden/ghissue/issues"
36
+ "url": "https://github.com/calebogden/tissues/issues"
38
37
  },
39
38
  "files": [
40
39
  "bin",
package/src/cli.js CHANGED
@@ -49,7 +49,8 @@ program.addHelpText(
49
49
  'after',
50
50
  `
51
51
 
52
- Repo: https://github.com/calebogden/ghissue
52
+ Web: https://tissues.cc
53
+ Pkg: https://www.npmjs.com/package/tissues
53
54
  `,
54
55
  )
55
56
 
@@ -29,7 +29,7 @@ function warnIfCircuitNotClosed(circuitState) {
29
29
  chalk.yellow('[safety]') +
30
30
  ' Circuit breaker is ' +
31
31
  stateColor(circuitState.toUpperCase()) +
32
- '. Use `ghissue status` to view details.',
32
+ '. Use `tissues status` to view details.',
33
33
  )
34
34
  }
35
35
 
@@ -62,9 +62,9 @@ function runPostCreateHook(hookCmd, ctx) {
62
62
  execSync(hookCmd, {
63
63
  env: {
64
64
  ...process.env,
65
- GITISSUES_REPO: ctx.repo,
66
- GITISSUES_ISSUE_NUMBER: String(ctx.issueNumber),
67
- GITISSUES_ISSUE_URL: ctx.issueUrl,
65
+ TISSUES_REPO: ctx.repo,
66
+ TISSUES_ISSUE_NUMBER: String(ctx.issueNumber),
67
+ TISSUES_ISSUE_URL: ctx.issueUrl,
68
68
  },
69
69
  stdio: 'inherit',
70
70
  })
@@ -83,7 +83,7 @@ export const statusCommand = new Command('status')
83
83
  }
84
84
 
85
85
  if (!repo) {
86
- console.error(chalk.red('No active repo. Set one with: ghissue open'))
86
+ console.error(chalk.red('No active repo. Set one with: tissues open'))
87
87
  process.exit(1)
88
88
  }
89
89
 
@@ -23,7 +23,7 @@ function resolvePackageVersion() {
23
23
  const pkgPath = path.join(dir, 'package.json')
24
24
  if (fs.existsSync(pkgPath)) {
25
25
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
26
- if ((pkg.name === 'ghissue' || pkg.name === 'gitissues') && pkg.version) return pkg.version
26
+ if (pkg.name === 'tissues' && pkg.version) return pkg.version
27
27
  }
28
28
  dir = path.dirname(dir)
29
29
  }
@@ -120,7 +120,7 @@ export function buildAttribution(opts = {}) {
120
120
 
121
121
  // Timestamps / versioning
122
122
  meta.created_at = createdAt ?? nowISO()
123
- meta.created_via = `ghissue-cli/${PKG_VERSION}`
123
+ meta.created_via = `tissues-cli/${PKG_VERSION}`
124
124
 
125
125
  return meta
126
126
  }
@@ -130,18 +130,18 @@ export function buildAttribution(opts = {}) {
130
130
  * bottom of a GitHub issue body.
131
131
  *
132
132
  * The format is a YAML-like key: value listing inside an HTML comment, which
133
- * GitHub renders as invisible text. Other tools (including gitissues itself)
133
+ * GitHub renders as invisible text. Other tools (including tissues itself)
134
134
  * can parse it back via `parseAttribution`.
135
135
  *
136
136
  * @example
137
- * <!-- gitissues-meta
137
+ * <!-- tissues-meta
138
138
  * agent: claude-opus-4-6
139
139
  * session: abc123
140
140
  * pid: 12345
141
141
  * trigger: cli-create
142
142
  * fingerprint: sha256:deadbeef
143
143
  * created_at: 2026-02-19T15:30:00Z
144
- * created_via: gitissues-cli/0.1.0
144
+ * created_via: tissues-cli/0.1.0
145
145
  * -->
146
146
  *
147
147
  * @param {AttributionOpts} opts
@@ -149,7 +149,7 @@ export function buildAttribution(opts = {}) {
149
149
  */
150
150
  export function renderAttribution(opts = {}) {
151
151
  const meta = buildAttribution(opts)
152
- const lines = ['<!-- gitissues-meta']
152
+ const lines = ['<!-- tissues-meta']
153
153
 
154
154
  for (const [key, value] of Object.entries(meta)) {
155
155
  if (Array.isArray(value)) {
@@ -165,7 +165,7 @@ export function renderAttribution(opts = {}) {
165
165
  }
166
166
 
167
167
  /**
168
- * Parse a `<!-- gitissues-meta ... -->` attribution block from an issue body.
168
+ * Parse a `<!-- tissues-meta ... -->` attribution block from an issue body.
169
169
  *
170
170
  * Returns the parsed key/value pairs as a plain object, or `null` if no
171
171
  * attribution block is present in `issueBody`.
@@ -180,7 +180,7 @@ export function parseAttribution(issueBody) {
180
180
  if (!issueBody) return null
181
181
 
182
182
  // Match the comment block (non-greedy, handle CRLF)
183
- const match = issueBody.match(/<!--\s*gitissues-meta\s*([\s\S]*?)-->/m)
183
+ const match = issueBody.match(/<!--\s*tissues-meta\s*([\s\S]*?)-->/m)
184
184
  if (!match) return null
185
185
 
186
186
  const block = match[1]
package/src/lib/config.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import Conf from 'conf'
2
2
 
3
3
  // Conf handles OS-appropriate storage path + creates dir automatically
4
- // macOS: ~/Library/Preferences/gitissues-nodejs/config.json
5
- // Linux: ~/.config/gitissues-nodejs/config.json
6
- export const store = new Conf({ projectName: 'gitissues' })
4
+ // macOS: ~/Library/Preferences/tissues-nodejs/config.json
5
+ // Linux: ~/.config/tissues-nodejs/config.json
6
+ export const store = new Conf({ projectName: 'tissues' })
7
7
 
8
8
  export function getConfig() {
9
9
  return store.store
package/src/lib/db.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
- * SQLite state database for ghissue CLI.
2
+ * SQLite state database for tissues CLI.
3
3
  *
4
4
  * Stores fingerprints (deduplication), idempotency keys, circuit breaker
5
5
  * state, and rate-limit event log. Uses better-sqlite3 (synchronous API).
6
6
  *
7
- * Database path: .gitissues/data/gitissues.db (relative to repo root).
7
+ * Database path: .tissues/data/tissues.db (relative to repo root).
8
8
  * Created automatically on first use. Users can .gitignore the data dir
9
9
  * for personal-only state, or commit it for shared team dedup history.
10
10
  */
@@ -14,7 +14,7 @@ import path from 'path'
14
14
  import fs from 'fs'
15
15
 
16
16
  // ---------------------------------------------------------------------------
17
- // Path resolution — repo-local .gitissues/data/gitissues.db
17
+ // Path resolution — repo-local .tissues/data/tissues.db
18
18
  // ---------------------------------------------------------------------------
19
19
 
20
20
  /**
@@ -35,11 +35,11 @@ function findRepoRootForDb(startDir) {
35
35
  function getDbPath() {
36
36
  const repoRoot = findRepoRootForDb()
37
37
  if (repoRoot) {
38
- return path.join(repoRoot, '.gitissues', 'data', 'gitissues.db')
38
+ return path.join(repoRoot, '.tissues', 'data', 'tissues.db')
39
39
  }
40
40
  // Fallback: user home config dir (outside a git repo)
41
41
  const home = process.env.HOME || process.env.USERPROFILE || ''
42
- return path.join(home, '.config', 'gitissues', 'gitissues.db')
42
+ return path.join(home, '.config', 'tissues', 'tissues.db')
43
43
  }
44
44
 
45
45
  const DB_PATH = getDbPath()
@@ -32,7 +32,7 @@ const BUILT_IN_DEFAULTS = {
32
32
 
33
33
  // Templates
34
34
  templates: {
35
- dir: '.gitissues/templates', // relative to repo root, or absolute
35
+ dir: '.tissues/templates', // relative to repo root, or absolute
36
36
  default: 'default', // default template name
37
37
  },
38
38
 
@@ -54,7 +54,7 @@ const BUILT_IN_DEFAULTS = {
54
54
  // Env var prefix
55
55
  // ---------------------------------------------------------------------------
56
56
 
57
- const ENV_PREFIX = 'GITISSUES_'
57
+ const ENV_PREFIX = 'TISSUES_'
58
58
 
59
59
  // ---------------------------------------------------------------------------
60
60
  // Helpers
@@ -114,15 +114,15 @@ function readJsonFile(filePath) {
114
114
  * @returns {string}
115
115
  */
116
116
  function userConfigPath() {
117
- return path.join(os.homedir(), '.config', 'gitissues', 'config.json')
117
+ return path.join(os.homedir(), '.config', 'tissues', 'config.json')
118
118
  }
119
119
 
120
120
  /**
121
- * Convert a flat `GITISSUES_SECTION_KEY=value` environment variable map into
121
+ * Convert a flat `TISSUES_SECTION_KEY=value` environment variable map into
122
122
  * a nested object matching the config shape.
123
123
  *
124
124
  * Variable names are lowercased and split on `_` to build the path:
125
- * GITISSUES_SAFETY_MAX_PER_HOUR=20 → { safety: { maxPerHour: 20 } }
125
+ * TISSUES_SAFETY_MAX_PER_HOUR=20 → { safety: { maxPerHour: 20 } }
126
126
  *
127
127
  * Simple camelCase reconstruction: after stripping the prefix and splitting on
128
128
  * `_`, the first segment is the section; the remaining segments are joined in
@@ -198,9 +198,9 @@ export function findRepoRoot(startDir) {
198
198
  /**
199
199
  * Load merged configuration from all sources in ascending priority order:
200
200
  * 1. Built-in defaults (lowest)
201
- * 2. User-level config (~/.config/gitissues/config.json)
202
- * 3. Repo-level config (<repoRoot>/.gitissues/config.json)
203
- * 4. Environment vars (GITISSUES_*)
201
+ * 2. User-level config (~/.config/tissues/config.json)
202
+ * 3. Repo-level config (<repoRoot>/.tissues/config.json)
203
+ * 4. Environment vars (TISSUES_*)
204
204
  * 5. CLI flags (passed as `cliOverrides`, highest)
205
205
  *
206
206
  * @param {string} [repoRoot] - path to the repo root; auto-detected if omitted
@@ -219,7 +219,7 @@ export function loadConfig(repoRoot, cliOverrides) {
219
219
 
220
220
  // 3. Repo-level config
221
221
  if (root) {
222
- const repoCfg = readJsonFile(path.join(root, '.gitissues', 'config.json'))
222
+ const repoCfg = readJsonFile(path.join(root, '.tissues', 'config.json'))
223
223
  if (repoCfg) merged = deepMerge(merged, repoCfg)
224
224
  }
225
225
 
package/src/lib/safety.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Circuit breaker and rate limiter for ghissue CLI.
2
+ * Circuit breaker and rate limiter for tissues CLI.
3
3
  *
4
4
  * Prevents runaway issue creation loops by:
5
5
  * - Rate limiting per agent (hourly + burst window)
@@ -86,10 +86,10 @@ function readTemplatesFromDir(dir, source) {
86
86
  */
87
87
  function resolveTemplateDir(source, repoRoot, cfg) {
88
88
  if (source === 'user') {
89
- return path.join(os.homedir(), '.config', 'gitissues', 'templates')
89
+ return path.join(os.homedir(), '.config', 'tissues', 'templates')
90
90
  }
91
91
  // repo source
92
- const templateDir = cfg.templates?.dir ?? '.gitissues/templates'
92
+ const templateDir = cfg.templates?.dir ?? '.tissues/templates'
93
93
  if (path.isAbsolute(templateDir)) return templateDir
94
94
  if (repoRoot) return path.join(repoRoot, templateDir)
95
95
  return path.resolve(templateDir)
File without changes