instar 1.3.561 → 1.3.562
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +3 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/messaging/slack/sanitize.d.ts +17 -0
- package/dist/messaging/slack/sanitize.d.ts.map +1 -1
- package/dist/messaging/slack/sanitize.js +23 -0
- package/dist/messaging/slack/sanitize.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/upgrades/1.3.562.md +46 -0
- package/upgrades/eli16/slack-updates-channel-slug.md +16 -0
- package/upgrades/side-effects/slack-updates-channel-slug.md +46 -0
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Prevents prompt injection, path traversal, and SSRF attacks
|
|
5
5
|
* by validating and cleaning user-controlled fields before use.
|
|
6
|
+
*
|
|
7
|
+
* CONTRACT-EVIDENCE: EXEMPT — pure string-validation/slug helpers; this module
|
|
8
|
+
* makes NO Slack API calls and touches no API-contract surface. The added
|
|
9
|
+
* slugifyChannelName is covered by tests/unit/slack-channel-slug.test.ts.
|
|
6
10
|
*/
|
|
7
11
|
/**
|
|
8
12
|
* Sanitize a Slack display name for safe injection into session context.
|
|
@@ -21,6 +25,19 @@ export declare function validateChannelId(id: string): boolean;
|
|
|
21
25
|
* Must be lowercase alphanumeric with hyphens/underscores, max 80 chars.
|
|
22
26
|
*/
|
|
23
27
|
export declare function validateChannelName(name: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Slugify an arbitrary string into a valid Slack channel name.
|
|
30
|
+
*
|
|
31
|
+
* Slack channel names must be lowercase and may only contain [a-z0-9-_]
|
|
32
|
+
* (see {@link validateChannelName}). A workspace-derived name like
|
|
33
|
+
* "SageMind Live Test" contains spaces and uppercase, which `createChannel`
|
|
34
|
+
* rejects via validate-and-throw. This produces a guaranteed-valid slug:
|
|
35
|
+
* lowercase, non-[a-z0-9] runs collapsed to a single hyphen, leading/trailing
|
|
36
|
+
* hyphens trimmed, and clamped to Slack's 80-char limit.
|
|
37
|
+
*
|
|
38
|
+
* Mirrors the session-channel slug logic in SlackAdapter.
|
|
39
|
+
*/
|
|
40
|
+
export declare function slugifyChannelName(name: string): string;
|
|
24
41
|
/**
|
|
25
42
|
* Validate that a URL hostname belongs to *.slack.com.
|
|
26
43
|
* Used to prevent SSRF via manipulated upload URLs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/messaging/slack/sanitize.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/messaging/slack/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD"}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Prevents prompt injection, path traversal, and SSRF attacks
|
|
5
5
|
* by validating and cleaning user-controlled fields before use.
|
|
6
|
+
*
|
|
7
|
+
* CONTRACT-EVIDENCE: EXEMPT — pure string-validation/slug helpers; this module
|
|
8
|
+
* makes NO Slack API calls and touches no API-contract surface. The added
|
|
9
|
+
* slugifyChannelName is covered by tests/unit/slack-channel-slug.test.ts.
|
|
6
10
|
*/
|
|
7
11
|
const CHANNEL_ID_PATTERN = /^[CDG][A-Z0-9]{8,12}$/;
|
|
8
12
|
const CHANNEL_NAME_PATTERN = /^[a-z0-9][a-z0-9\-_]{0,79}$/;
|
|
@@ -36,6 +40,25 @@ export function validateChannelId(id) {
|
|
|
36
40
|
export function validateChannelName(name) {
|
|
37
41
|
return CHANNEL_NAME_PATTERN.test(name);
|
|
38
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Slugify an arbitrary string into a valid Slack channel name.
|
|
45
|
+
*
|
|
46
|
+
* Slack channel names must be lowercase and may only contain [a-z0-9-_]
|
|
47
|
+
* (see {@link validateChannelName}). A workspace-derived name like
|
|
48
|
+
* "SageMind Live Test" contains spaces and uppercase, which `createChannel`
|
|
49
|
+
* rejects via validate-and-throw. This produces a guaranteed-valid slug:
|
|
50
|
+
* lowercase, non-[a-z0-9] runs collapsed to a single hyphen, leading/trailing
|
|
51
|
+
* hyphens trimmed, and clamped to Slack's 80-char limit.
|
|
52
|
+
*
|
|
53
|
+
* Mirrors the session-channel slug logic in SlackAdapter.
|
|
54
|
+
*/
|
|
55
|
+
export function slugifyChannelName(name) {
|
|
56
|
+
return name
|
|
57
|
+
.toLowerCase()
|
|
58
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
59
|
+
.replace(/^-+|-+$/g, '')
|
|
60
|
+
.slice(0, 80);
|
|
61
|
+
}
|
|
39
62
|
/**
|
|
40
63
|
* Validate that a URL hostname belongs to *.slack.com.
|
|
41
64
|
* Used to prevent SSRF via manipulated upload URLs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../src/messaging/slack/sanitize.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../src/messaging/slack/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AACnD,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAC3D,4CAA4C;AAC5C,MAAM,aAAa,GAAG,kBAAkB,CAAC;AACzC,MAAM,eAAe,GAAG,UAAU,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,OAAO,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-14T11:06:11.902Z",
|
|
5
|
+
"instarVersion": "1.3.562",
|
|
6
6
|
"entryCount": 201,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The boot helpers that auto-create the Slack "Updates" and "Attention" channels
|
|
9
|
+
(`ensureSlackUpdatesChannel` / `ensureSlackAttentionChannel` in
|
|
10
|
+
`src/commands/server.ts`) passed a raw, workspace-derived name straight into
|
|
11
|
+
`SlackAdapter.createChannel`. When the workspace name contained spaces or
|
|
12
|
+
uppercase (e.g. "SageMind Live Test"), that produced an invalid Slack channel
|
|
13
|
+
name like `SageMind Live Test-sys-updates`, which `createChannel` rejects via
|
|
14
|
+
`validateChannelName` — so the channel never got created and the boot logged
|
|
15
|
+
`Failed to create Slack Updates channel: Invalid channel name`.
|
|
16
|
+
|
|
17
|
+
Both callers now slugify the name first through a new shared
|
|
18
|
+
`slugifyChannelName` helper in `src/messaging/slack/sanitize.ts` (lowercase,
|
|
19
|
+
collapse non-`[a-z0-9]` runs to a single hyphen, trim edge hyphens, clamp to
|
|
20
|
+
Slack's 80-char limit) — mirroring the per-session channel slug logic the
|
|
21
|
+
adapter already used on its `-sess-` path. The `createChannel` /
|
|
22
|
+
`validateChannelName` contract other callers rely on is untouched.
|
|
23
|
+
|
|
24
|
+
## What to Tell Your User
|
|
25
|
+
|
|
26
|
+
If your Slack workspace name has spaces or capital letters and your agent failed
|
|
27
|
+
to create its Updates or Attention channel (an "Invalid channel name" error on
|
|
28
|
+
startup), that's now fixed — the channel name is cleaned into a valid Slack
|
|
29
|
+
slug before creation. Workspaces whose name was already lowercase-and-dashes see
|
|
30
|
+
no change at all.
|
|
31
|
+
|
|
32
|
+
## Summary of New Capabilities
|
|
33
|
+
|
|
34
|
+
- New `slugifyChannelName(name)` helper in the Slack sanitize module — a single
|
|
35
|
+
source of truth for turning an arbitrary name into a valid Slack channel name.
|
|
36
|
+
- The Slack Updates and Attention boot channels now create reliably regardless
|
|
37
|
+
of workspace-name casing or spaces.
|
|
38
|
+
|
|
39
|
+
## Evidence
|
|
40
|
+
|
|
41
|
+
- `tests/unit/slack-channel-slug.test.ts` — the exact failing name
|
|
42
|
+
("SageMind Live Test-sys-updates") now slugifies to a name `validateChannelName`
|
|
43
|
+
accepts; covers lowercasing, space-collapse, punctuation stripping, edge-hyphen
|
|
44
|
+
trim, already-valid passthrough, 80-char clamp, and a regression assertion that
|
|
45
|
+
the raw un-slugified name is rejected.
|
|
46
|
+
- `npx tsc --noEmit` clean; 9/9 new unit tests green.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Why the Slack Updates channel failed to create (and now doesn't)
|
|
2
|
+
|
|
3
|
+
## The one-sentence version
|
|
4
|
+
When your Slack workspace had a space or a capital letter in its name (like "SageMind Live Test"), the agent tried to make a Slack channel literally named "SageMind Live Test-sys-updates" — but Slack only allows lowercase, no-spaces channel names, so the creation crashed every time. Now the name is cleaned up first.
|
|
5
|
+
|
|
6
|
+
## Picture it
|
|
7
|
+
Imagine a mailroom that will only accept package labels written in lowercase with dashes instead of spaces. The agent was handing it a label that said "SageMind Live Test-sys-updates" — capital letters, spaces and all — and the mailroom kept rejecting it. The fix is a tiny label-printer that rewrites the label as "sagemind-live-test-sys-updates" before handing it over.
|
|
8
|
+
|
|
9
|
+
## What changed, precisely
|
|
10
|
+
- The two callers that auto-create the Slack "Updates" and "Attention" channels were passing a raw, workspace-derived name straight into channel creation.
|
|
11
|
+
- That raw name kept its spaces and capitals, which Slack rejects — so the channel never got made and you saw "Invalid channel name".
|
|
12
|
+
- Now both callers run the name through a small slugifier first (lowercase it, turn anything that isn't a-z/0-9 into a single dash, trim stray dashes, cap at Slack's 80-char limit) — exactly the same cleanup the per-session Slack channels already used.
|
|
13
|
+
|
|
14
|
+
## Why this is safe
|
|
15
|
+
- It only changes how the name is *built* before creation; it does not touch the channel-creation rule that other code relies on (that rule still rejects bad names — it just never sees one now).
|
|
16
|
+
- A name that was already valid passes through unchanged.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Side-Effects Review — Slack Updates/Attention channel name slugify
|
|
2
|
+
|
|
3
|
+
## Change summary
|
|
4
|
+
Caller-side fix in `src/commands/server.ts`: the `ensureSlackUpdatesChannel` and
|
|
5
|
+
`ensureSlackAttentionChannel` boot helpers now slugify the workspace-derived
|
|
6
|
+
channel name before calling `SlackAdapter.createChannel`, via a new shared
|
|
7
|
+
`slugifyChannelName` helper in `src/messaging/slack/sanitize.ts`. Mirrors the
|
|
8
|
+
existing per-session channel slug logic in `SlackAdapter` (`-sess-` path).
|
|
9
|
+
|
|
10
|
+
## Tier
|
|
11
|
+
Tier 1 — small, low-risk, single-machine Slack-adapter boot-path bugfix. No
|
|
12
|
+
converged spec required.
|
|
13
|
+
|
|
14
|
+
## Files touched
|
|
15
|
+
- `src/messaging/slack/sanitize.ts` — adds exported `slugifyChannelName(name)`.
|
|
16
|
+
- `src/commands/server.ts` — imports the helper; wraps both `-sys-updates` and
|
|
17
|
+
`-sys-attention` channel names with it before `createChannel`.
|
|
18
|
+
- `tests/unit/slack-channel-slug.test.ts` — new focused unit test.
|
|
19
|
+
|
|
20
|
+
## Behavioral side-effects
|
|
21
|
+
- **Channel names on FRESH creation**: a workspace name containing spaces or
|
|
22
|
+
uppercase now yields a slugified channel (e.g. "SageMind Live Test" →
|
|
23
|
+
`sagemind-live-test-sys-updates`) instead of a hard failure. For workspaces
|
|
24
|
+
whose name was already slug-clean (lowercase, no spaces), the produced name is
|
|
25
|
+
byte-identical to before — no change.
|
|
26
|
+
- **No change to `createChannel` / `validateChannelName`**: the validate-and-throw
|
|
27
|
+
behavior other callers depend on is untouched; the fix only ensures these two
|
|
28
|
+
callers never hand it an invalid name.
|
|
29
|
+
- **Idempotent at the state layer**: both helpers early-return when their
|
|
30
|
+
`slack-*-channel` state key is already set, so this only affects the one-time
|
|
31
|
+
creation path; existing installs that already created a channel are unaffected.
|
|
32
|
+
|
|
33
|
+
## Migration parity
|
|
34
|
+
- No agent-installed file changed (no `.claude/settings.json` hooks, no
|
|
35
|
+
`.instar/config.json` defaults, no CLAUDE.md template, no hook scripts, no
|
|
36
|
+
built-in skills). This is server-side runtime code shipped in the normal
|
|
37
|
+
build — existing agents receive it on their next update with no migration.
|
|
38
|
+
|
|
39
|
+
## Rollback
|
|
40
|
+
- Revert the squash commit. The change is self-contained (one helper + two call
|
|
41
|
+
sites + one test); no data migration, no state schema change, nothing to undo.
|
|
42
|
+
|
|
43
|
+
## Blast radius
|
|
44
|
+
- Limited to the Slack adapter boot path. Telegram / WhatsApp / iMessage and all
|
|
45
|
+
non-Slack code paths are untouched. Dark-gate config line-map unchanged (no
|
|
46
|
+
ConfigDefaults edit).
|