@rse/ase 0.0.61 → 0.0.62

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.
@@ -20,6 +20,15 @@ const parseColorMode = (name) => (value) => {
20
20
  throw new InvalidArgumentError(`${name} must be "none", "ansi16", or "ansi256"`);
21
21
  return value;
22
22
  };
23
+ /* scan a CSI escape sequence starting at line[i] (where line[i]===ESC and
24
+ line[i+1]==="["); return the index just past the terminating letter, or
25
+ -1 if the sequence is unterminated within the line */
26
+ const scanAnsiSeq = (line, i) => {
27
+ let j = i + 2;
28
+ while (j < line.length && !/[A-Za-z]/.test(line[j]))
29
+ j++;
30
+ return j < line.length ? j + 1 : -1;
31
+ };
23
32
  /* truncate a single rendered line to a maximum visible column,
24
33
  preserving ANSI escape sequences (CSI ...m) and appending an ANSI
25
34
  reset sequence if any styling was active at the truncation point */
@@ -33,20 +42,15 @@ const truncateAnsiLine = (line, budget) => {
33
42
  while (i < line.length) {
34
43
  const ch = line[i];
35
44
  if (ch === "\x1b" && line[i + 1] === "[") {
36
- let j = i + 2;
37
- while (j < line.length && !/[A-Za-z]/.test(line[j]))
38
- j++;
39
- if (j < line.length) {
40
- const seq = line.slice(i, j + 1);
45
+ const j = scanAnsiSeq(line, i);
46
+ if (j >= 0) {
47
+ const seq = line.slice(i, j);
41
48
  out += seq;
42
49
  if (seq.endsWith("m")) {
43
50
  const body = seq.slice(2, -1);
44
- if (body === "" || body === "0")
45
- styled = false;
46
- else
47
- styled = true;
51
+ styled = !(body === "" || body === "0");
48
52
  }
49
- i = j + 1;
53
+ i = j;
50
54
  continue;
51
55
  }
52
56
  i++;
@@ -70,11 +74,9 @@ const visibleWidth = (line) => {
70
74
  while (i < line.length) {
71
75
  const ch = line[i];
72
76
  if (ch === "\x1b" && line[i + 1] === "[") {
73
- let j = i + 2;
74
- while (j < line.length && !/[A-Za-z]/.test(line[j]))
75
- j++;
76
- if (j < line.length) {
77
- i = j + 1;
77
+ const j = scanAnsiSeq(line, i);
78
+ if (j >= 0) {
79
+ i = j;
78
80
  continue;
79
81
  }
80
82
  i++;
@@ -87,39 +89,30 @@ const visibleWidth = (line) => {
87
89
  };
88
90
  /* reusable functionality: Mermaid diagram rendering as Unicode/ASCII art */
89
91
  export class Diagram {
90
- /* detect terminal column width */
91
- static detectTermWidth() {
92
- let width = 0;
92
+ static detectTermDimension(envVar, stdoutProp) {
93
+ let value = 0;
93
94
  /* attempt 1: query environment variable */
94
- if (process.env.ASE_TERM_WIDTH !== undefined) {
95
- const cols = Number.parseInt(process.env.ASE_TERM_WIDTH, 10);
96
- if (Number.isFinite(cols) && cols > 0)
97
- width = cols;
95
+ const env = process.env[envVar];
96
+ if (env !== undefined) {
97
+ const n = Number.parseInt(env, 10);
98
+ if (Number.isFinite(n) && n > 0)
99
+ value = n;
98
100
  }
99
101
  /* attempt 2: query stdout */
100
- if (width === 0 && process.stdout.isTTY) {
101
- const cols = process.stdout.columns;
102
- if (typeof cols === "number" && cols > 0)
103
- width = cols;
102
+ if (value === 0 && process.stdout.isTTY) {
103
+ const n = process.stdout[stdoutProp];
104
+ if (typeof n === "number" && n > 0)
105
+ value = n;
104
106
  }
105
- return width;
107
+ return value;
108
+ }
109
+ /* detect terminal column width */
110
+ static detectTermWidth() {
111
+ return Diagram.detectTermDimension("ASE_TERM_WIDTH", "columns");
106
112
  }
107
113
  /* detect terminal row height */
108
114
  static detectTermHeight() {
109
- let height = 0;
110
- /* attempt 1: query environment variable */
111
- if (process.env.ASE_TERM_HEIGHT !== undefined) {
112
- const rows = Number.parseInt(process.env.ASE_TERM_HEIGHT, 10);
113
- if (Number.isFinite(rows) && rows > 0)
114
- height = rows;
115
- }
116
- /* attempt 2: query stdout */
117
- if (height === 0 && process.stdout.isTTY) {
118
- const rows = process.stdout.rows;
119
- if (typeof rows === "number" && rows > 0)
120
- height = rows;
121
- }
122
- return height;
115
+ return Diagram.detectTermDimension("ASE_TERM_HEIGHT", "rows");
123
116
  }
124
117
  /* detect terminal color capability */
125
118
  static detectColorMode() {
@@ -51,14 +51,14 @@ export default class PersonaMCP {
51
51
  "If `session` is provided, the operation is scoped to that session, " +
52
52
  "otherwise it operates on the strongest/closest scope (user/project cascade). " +
53
53
  "Allowed styles: \"writer\" (decorative, eloquent, explaining), " +
54
- "\"engineer\" (brief, factual, accurate), " +
54
+ "\"engineer\" (concise, factual, accurate), " +
55
55
  "\"telegrapher\" (very brief, factual, abbreviating), " +
56
56
  "\"caveman\" (ultra brief, rough, stuttering).",
57
57
  inputSchema: {
58
58
  style: z.enum(Persona.styles).optional()
59
59
  .describe("persona style to set; if omitted, the current persona style is returned"),
60
60
  session: z.string().optional()
61
- .describe("session identifier (allowed characters: A-Z, a-z, 0-9, '-'); " +
61
+ .describe("session identifier (allowed characters: A-Z, a-z, 0-9, '.', '_', '-'); " +
62
62
  "if omitted, the operation is not scoped to a specific session")
63
63
  }
64
64
  }, async (args) => {
@@ -346,10 +346,10 @@ export default class StatuslineCommand {
346
346
  emit(`${prefix("◔", "context")}${bar} ${pct}%`);
347
347
  },
348
348
  C: () => {
349
- const context = Math.floor(data.context_window?.used_percentage ?? 0);
349
+ const pct = Math.floor(data.context_window?.used_percentage ?? 0);
350
350
  const tokensCur = (data.context_window?.total_input_tokens ?? 0) +
351
351
  (data.context_window?.total_output_tokens ?? 0);
352
- const tokensLim = context > 0 && tokensCur > 0 ? Math.round(tokensCur * 100 / context) : 0;
352
+ const tokensLim = pct > 0 && tokensCur > 0 ? Math.round(tokensCur * 100 / pct) : 0;
353
353
  if (tokensLim > 0)
354
354
  emit(`${prefix("◆", "tokens")}${c.bold(formatTokens(tokensCur) + "/" + formatTokens(tokensLim))}`);
355
355
  },
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "homepage": "http://github.com/rse/ase",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "http://github.com/rse/ase/issues" },
9
- "version": "0.0.61",
9
+ "version": "0.0.62",
10
10
  "license": "GPL-3.0-only",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.0.61",
3
+ "version": "0.0.62",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.0.61",
3
+ "version": "0.0.62",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -269,6 +269,7 @@ Workflow
269
269
 
270
270
  <template>
271
271
  ● **WHAT**: [...]
272
+
272
273
  ○ **WHY**: [...]
273
274
  </template>
274
275
 
@@ -279,6 +280,11 @@ Workflow
279
280
  text with Markdown based on the following <template/>:
280
281
  <template>"`<words/>`"</template>.
281
282
 
283
+ For all code references, always use a relative filename and
284
+ append the related single 1-based line number N as `:N` or the
285
+ related 1-based line number range as `:N-M` to the end of the
286
+ filename.
287
+
282
288
  4. Create the change set.
283
289
  For this, set <change-set></change-set> (set changes to empty).
284
290
 
@@ -6,7 +6,7 @@
6
6
  "homepage": "http://github.com/rse/ase",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "http://github.com/rse/ase/issues" },
9
- "version": "0.0.61",
9
+ "version": "0.0.62",
10
10
  "license": "GPL-3.0-only",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -51,4 +51,4 @@ Proofread an entire documentation directory automatically:
51
51
 
52
52
  ## SEE ALSO
53
53
 
54
- `ase-code-lint`, `ase-meta-changes`.
54
+ `ase-code-lint`, `ase-meta-changelog`.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: ase-meta-changes
2
+ name: ase-meta-changelog
3
3
  argument-hint: "[--help|-h]"
4
4
  description: >
5
5
  Update changes entries in CHANGELOG.md files
@@ -17,7 +17,7 @@ allowed-tools:
17
17
  @${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
18
18
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
19
19
 
20
- <skill name="ase-meta-changes">
20
+ <skill name="ase-meta-changelog">
21
21
  Update ChangeLog Entries
22
22
  </skill>
23
23
 
@@ -1,16 +1,16 @@
1
1
 
2
2
  ## NAME
3
3
 
4
- `ase-meta-changes` - Update ChangeLog Entries
4
+ `ase-meta-changelog` - Update ChangeLog Entries
5
5
 
6
6
  ## SYNOPSIS
7
7
 
8
- `ase-meta-changes`
8
+ `ase-meta-changelog`
9
9
  [`--help`|`-h`]
10
10
 
11
11
  ## DESCRIPTION
12
12
 
13
- The `ase-meta-changes` skill helps to *complete*, *consolidate*, and
13
+ The `ase-meta-changelog` skill helps to *complete*, *consolidate*, and
14
14
  *sort* the entries of the most recent section of a `CHANGELOG.md`
15
15
  file, based on the underlying *Git* commits and the currently staged
16
16
  changes in the Git *index*.
@@ -25,7 +25,7 @@ date in the section header is also updated to the current date.
25
25
  Update the most recent ChangeLog section:
26
26
 
27
27
  ```text
28
- ❯ /ase-meta-changes
28
+ ❯ /ase-meta-changelog
29
29
  ```
30
30
 
31
31
  ## SEE ALSO
@@ -28,4 +28,4 @@ Craft a commit message for the currently staged changes:
28
28
 
29
29
  ## SEE ALSO
30
30
 
31
- `ase-meta-changes`.
31
+ `ase-meta-changelog`.
@@ -78,4 +78,4 @@ Summarize the staged changes and append a blast-radius map:
78
78
 
79
79
  ## SEE ALSO
80
80
 
81
- `ase-meta-commit`, `ase-meta-changes`, `ase-arch-analyze`.
81
+ `ase-meta-commit`, `ase-meta-changelog`, `ase-arch-analyze`.