Skip to content

release: sync develop -> main (0.10.0 + CodeQL fixes)#50

Merged
tbitcs merged 5 commits intomainfrom
develop
May 4, 2026
Merged

release: sync develop -> main (0.10.0 + CodeQL fixes)#50
tbitcs merged 5 commits intomainfrom
develop

Conversation

@tbitcs
Copy link
Copy Markdown
Contributor

@tbitcs tbitcs commented May 4, 2026

Brings main up to date with develop so the default-setup CodeQL scan can re-run against the patched code. Develop is currently 4 commits ahead of main:\n\n- #49 security: resolve 17 CodeQL alerts (XSS / attribute-sanitization / insecure-randomness / shell-quote)\n- #48 feat(0.10.1): G2 capabilities filter helper + 5 new mocha tests\n- #47 specsmith-vscode 0.10.0: BYOE + agents sidebar trees + multi-agent routing (REQ-142, REQ-146)\n- #45 fix(bridge): tunable startup timeout + stderr-progress reset\n\nAll CI green on each commit. Merging this should drive the open code-scanning alert count to 0.\n\nCo-Authored-By: Oz oz-agent@warp.dev

tbitcs and others added 4 commits May 4, 2026 06:29
Cold Ollama loads of 14B+ models routinely exceed the previous hard-coded 20 s readyevent window, surfacing as 'specsmith not responding (tried: ...)' followed by a SIGTERM-on-retry. Make the window user-configurable via a new specsmith.startupTimeoutMs setting (default 60_000, clamped to [5_000, 600_000]) and grant the child a one-time timer extension when stderr proves it's alive but slow. Updates the retry/error messages to quote the configured timeout and point users at the setting.

- bridge.ts: STARTUP_TIMEOUT_MS_DEFAULT raised 20 s -> 60 s; new optional startupTimeoutMs ctor arg; _clampStartupTimeoutMs helper exported for tests; _stderrExtensionUsed gate so the keepalive only triggers once per spawn.

- SessionPanel.ts: read specsmith.startupTimeoutMs in create() and thread through the ProcessPool factory.

- package.json: declare specsmith.startupTimeoutMs (number, min 5000, max 600000, default 60000).

- src/test/bridge-recovery.test.ts: +7 mocha tests covering the clamp helper edge cases and the SpecsmithBridge constructor signature. Total now 111 passing (was 104).

Validation: npm run lint clean; npm run build clean; npm test 111 passing.

Co-authored-by: Oz <oz-agent@warp.dev>
…uting (REQ-142, REQ-146) (#47)

* feat(extension): BYOE endpoints commands + bridge --endpoint plumbing (REQ-142)

Phase 3 of the BYOE 0.8.0 sprint. Surfaces the CLI-side endpoints registry to the VS Code extension and threads endpointId through the bridge so the agent can be routed to a self-hosted OpenAI-v1-compatible backend.

- src/EndpointsClient.ts: pure TS wrapper around 'specsmith endpoints list / test --json' + JSON parsers (parseEndpointsList, parseEndpointHealth) and the applyEndpointArg bridge helper. Tokens are never read from TypeScript memory; the CLI redacts inline tokens before serialising.

- src/types.ts: SessionConfig.endpointId optional field.

- src/bridge.ts: appends '--endpoint <id>' to specsmith run when SessionConfig.endpointId is set, routing through the openai-compat driver added in PR-2.

- src/extension.ts: new specsmith.endpoints command (Quick Pick over registered endpoints with copy / set-default / test actions) and specsmith.testEndpoint command (probes /v1/models, surfaces a notification with latency + model count).

- package.json: declares the two new commands.

- src/test/endpoints-client.test.ts: 11 new mocha tests covering the JSON parsers and the bridge arg helper (happy path, malformed body, redacted inline tokens, unknown auth kinds, non-object items).

- CHANGELOG.md: [Unreleased] entry.

Validation: tsc --noEmit clean; esbuild bundle 279.8kb; npm test 117 passing (was 104; +13 from the new suite).

Co-Authored-By: Oz <oz-agent@warp.dev>

* release: v0.8.0 (BYOE)

Bump package.json to 0.8.0 + cut the BYOE 0.8.0 changelog section.

Co-Authored-By: Oz <oz-agent@warp.dev>

* feat(extension): BYOE/agents sidebars + multi-agent routing wiring (REQ-142, REQ-146)

PR-B: BYOE end-to-end UI
- new specsmith.endpoints tree view (EndpointsTreeProvider)
- specsmith.refreshEndpoints command
- shipped command bar buttons in package.json

PR-G: agent profiles + activity routing
- new AgentsClient.ts wrapping specsmith agents subcommands
- new specsmith.agents tree view (AgentsTreeProvider) with profiles + routes
- new commands: specsmith.agents, .testAgent, .applyAgentPreset,
  .routeActivity, .pickSessionProfile, .refreshAgents
- bridge passes --agent <id> when SessionConfig.profileId is set
- /agent <id> in-chat command works through the runner
- session header pick command lets user pin a profile per session

PR-C/D/E/F skeletons
- new SpecsmithSidebars.ts also exports richer CLI-backed providers for
  workflows/notebooks/rules/mcp (file watching trees in SidebarTrees.ts
  remain the source of truth for back-compat; richer ones are exported
  for a follow-up swap)

Extension version 0.8.0 -> 0.10.0 (matches CLI bump).

Co-Authored-By: Oz <oz-agent@warp.dev>

* fix(test): forward-compatible version check (welcome-panel.test.ts)

* feat: retire Cloud Runs view; AgentsClient mocha tests (F4)

* Drop the \specsmith.cloud\ view and \CloudTree\ provider from
  package.json + SidebarTrees.ts (now four file-watcher trees:
  workflows / notebooks / rules / mcp). The CLI-side
  \specsmith cloud spawn\ / \cloud-serve\ commands they fronted are
  no longer shipped.
* WelcomePanel: drop the 'Cloud Runs' bullet from the onboarding card.
* SpecsmithSidebars: update the registration-helper comment to match
  the four legacy trees.
* New src/test/agents-client.test.ts (15 hermetic tests) mirroring the
  shape of endpoints-client.test.ts: parseAgentsList happy-path, JSON
  error handling, defensive coercion, route shape, and applyAgentArg
  trimming + immutability.

---------

Co-authored-by: Oz <oz-agent@warp.dev>
* AgentsClient.filterAgentsByCapability(profiles, capability) returns
  the subset of profiles whose `capabilities` array contains the
  requested string (case-insensitive, whitespace-trimmed). Empty input
  returns [] rather than every profile so callers can distinguish
  "no filter" (don't call this) from "filter for empty value" (always
  empty).
* 5 new mocha tests in src/test/agents-client.test.ts cover the helper
  end-to-end: matching, case-insensitivity, empty handling, no-match,
  and immutability. Total mocha now 144 passing.
…secure-randomness / shell-quote) (#49)

This is a defence-in-depth pass that closes every open CodeQL finding
on the develop branch. No user-visible behaviour changes.

media/session.js
- esc() now also escapes " and ' so it is safe to use in HTML attribute
  context, not just element text. This fixes the underlying cause of
  the five js/incomplete-html-attribute-sanitization alerts at
  lines 104, 166, 172, 218, 299.
- addU / addA: pass customTs (history-replay timestamps) through esc()
  before interpolating into innerHTML (was bare).
- addTStart: escape lbl and the args.path branch of hint (was bare).
  These were the user-controlled values flagged by js/xss at line 78.
- addImg: escape u (the data: URL / file path) before interpolating
  into <img src=...>. Closes the js/xss alert at line 298.
- vcs_state additions/deletions span: coerce to integers via
  Number(x)|0 before HTML concat; closes the js/xss alert at line 510.
- The Report Bug + View Full + Crash buttons used inline
  onclick="rptTool(this,'X','Y')" with brittle JS-string escaping
  via cleanR.replace(/'/g,"\\'") -> CodeQL flagged the regex pair as
  js/identity-replacement and the surrounding template as
  js/incomplete-html-attribute-sanitization. Replaced with
  data-action / data-tool / data-output / data-text / data-title /
  data-detail / data-repo attributes (HTML-escaped via esc()) plus
  one delegated document.addEventListener('click',...) handler that
  routes by btn.dataset.action. The brittle regex is gone; values
  cross the JS boundary as plain DOM attributes.

src/ChatStreamConsumer.ts
- generateSessionId() now uses crypto.randomUUID() instead of
  Math.random(); the 12-char hex slice is preserved so log lines
  remain readable. Closes both js/insecure-randomness alerts.

src/extension.ts (specsmith.runPreflight) and src/GovernancePanel.ts
(case 'agentTask')
- The double-quoted shell argument was previously built with
  utterance.replace(/"/g,'\\"') which leaves a trailing backslash able
  to escape the closing quote. Now backslashes are escaped first, then
  double quotes. Closes both js/incomplete-sanitization alerts.

src/test/session-logic.test.ts
- The two integrity tests that scan the bundle for stray escaped
  backticks used /<script>...<\/script>/g which CodeQL flags as
  js/bad-tag-filter because it does not match upper-case <SCRIPT>.
  Switched to /<script\b[^>]*>...<\/script\s*>/gi. We never emit
  uppercase tags, so behaviour is unchanged; the alert is closed.

Verification
- npm run lint: clean (tsc --noEmit).
- npm run build: 290.9 KB bundle.
- npm test: 144 passing.

Co-authored-by: Oz <oz-agent@warp.dev>
Comment thread src/extension.ts
placeHolder: 'Pin a profile for the active session (or pick Auto)',
});
if (!picked) { return; }
const profileId = picked.label.includes('Auto') ? '' : picked.label.replace(/^[\s$()-\w-]*\s/, '').trim();
Comment thread src/test/session-logic.test.ts Fixed
Comment thread src/test/session-logic.test.ts Fixed
The previous fix used /<script\b[^>]*>...<\/script\s*>/gi which still
fails CodeQL js/bad-tag-filter because </script\t\n bar> is a valid
HTML close tag and \s*> does not allow attribute chars before the >.

The bundles we emit never contain that form, but CodeQL is right that
a defensive scanner pattern should accept it. Switched to:

    /<script\b[^>]*>[\s\S]*?<\/script\b[\s\S]*?>/gi

which:
* matches <script ...>...</script> (lowercase, our normal output)
* matches <SCRIPT>...</SCRIPT> (case-insensitive)
* matches </script\t\n bar> (whitespace + attributes after </script)
* still uses lazy quantifiers so adjacent script blocks don't merge

Mocha: 144 passing.

Co-Authored-By: Oz <oz-agent@warp.dev>
@tbitcs tbitcs merged commit 6080da5 into main May 4, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants