Commit Graph

7 Commits

Author SHA1 Message Date
Tom Boucher
79002a00cb chore(#518): rename npm package + bin to @opengsd/gsd-core (#519)
* chore: rename npm package + bin to @opengsd/gsd-core (functional)

- package.json: name @opengsd/get-shit-done-redux → @opengsd/gsd-core,
  bin key get-shit-done-redux → gsd-core, repository/homepage/bugs URLs
- package-lock.json: regenerated (npm install --package-lock-only)
- tests/**, scripts/**, bin/**, .github/**, agents/**, commands/**,
  get-shit-done/bin/**, get-shit-done/workflows/**:
  applied the 4-rule replacement (scoped npm ref, GitHub repo path,
  bin/clone invocations) per #505 single-source refactor

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: sweep live references to @opengsd/gsd-core

Update all live documentation (README.md + translations, docs/**,
CONTRIBUTING.md, VERSIONING.md, SECURITY.md, CONTEXT.md,
docs/CANARY.md) to reflect the renamed package and repository.

Rules applied:
- @opengsd/get-shit-done-redux → @opengsd/gsd-core (scoped npm name)
- open-gsd/get-shit-done-redux → open-gsd/gsd-core (GitHub repo)
- GSD-redux/get-shit-done-redux → open-gsd/gsd-core (stale badge org)
- bare bin/clone refs → gsd-core

CHANGELOG.md, docs/adr/**, docs/RELEASE-*.md, docs/research/**,
and .changeset/** are preserved byte-identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: add negative lookbehind to slash-command regex in bug-2954 test

The extractSlashReferences regex matched /gsd-core inside npm package
URLs (@opengsd/gsd-core), producing a false /gsd:core command reference.
Adding a negative lookbehind (?<![a-z]) excludes matches preceded by a
letter, so only standalone /gsd-<cmd> and /gsd:<cmd> tokens are found.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(#518): add changeset for package rename

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(#518): update package-identity expectations to the renamed coordinates

The rebase regenerated the seam to @opengsd/gsd-core (bin gsd-core, repo
open-gsd/gsd-core). The #498 seam tests assert deriveIdentity against the REAL
package.json, so their expected literals must follow the rename. The drift-lint
unit test is left as-is — its SEAM is a self-consistent fixture and its
stale-literal detection cases would shift if altered; the live-repo scan in it
already passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:25:02 -04:00
Tom Boucher
b8c33647d8 refactor(tests): retire output-grep & source-grep via typed surfaces (finish #2974) (#462)
* refactor(#455): implement typed surfaces to retire grep tests

Production surfaces added:
- hooks/managed-hooks-registry.cjs: new CJS module exporting MANAGED_HOOKS
  as a typed array; gsd-check-update-worker.js now requires it instead of
  declaring an inline array
- bin/install.js: elevate inline gsdHooks to module-level GSD_UNINSTALL_HOOKS,
  export it alongside runtimeMap/allRuntimes (already exported)
- scripts/build-hooks.js: export HOOKS_TO_COPY; guard build() behind
  require.main===module so tests can require the file without triggering a build
- get-shit-done/bin/lib/init.cjs: add --json mode to agent-skills command,
  emitting typed IR { agent_type, block, skills_count } for test assertions
- get-shit-done/bin/gsd-tools.cjs: wire --json flag for agent-skills dispatch

Category-B source-grep migrations:
- tests/managed-hooks.test.cjs: require MANAGED_HOOKS from registry, drop fs.readFileSync+regex
- tests/orphaned-hooks.test.cjs: require MANAGED_HOOKS+HOOKS_TO_COPY as typed exports
- tests/hooks-opt-in.test.cjs: replace gsdHooks regex-parse with GSD_UNINSTALL_HOOKS import
- tests/install-minimal-hooks.test.cjs: replace gsdHooks regex-parse with GSD_UNINSTALL_HOOKS
- tests/copilot-install.test.cjs: replace src.includes() checks with typed
  assertions on runtimeMap, allRuntimes, parseRuntimeInput, buildRuntimePromptText
- tests/agent-skills.test.cjs: migrate to --json typed IR assertions

pending-migration-to-typed-ir token cleared (87 of 87 files):
- 78 files already had source-text-is-the-product; removed duplicate token
- 5 files already used typed assertions; reclassified or annotated
- 4 files required individual reclassification to source-text-is-the-product
  or architectural-invariant

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(#455): update workflow-guard test to typed GSD_UNINSTALL_HOOKS import; isolate HOME in runtime-launcher (D) test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(#455): guard install.js main() behind require.main===module so the typed export is require-safe

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(#455): document --json typed surfaces for agent-skills, progress, validate context

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(#455): add changeset fragment for new --json surfaces

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(#455): complete grep migration for files flagged by lint-tests

The branch commit 4e630d99 stripped `allow-test-rule: pending-migration-to-typed-ir`
from ~80 test files without replacing their assertions or adding the correct
exemption annotation. The files were NOT source-grep tests — they read .md
workflow/agent/command/reference files (source-text-is-the-product) or hook
source files for structural invariants (structural-regression-guard). No
assertion logic was changed; only the correct allow-test-rule annotation was
added to each file per CONTRIBUTING.md exception matrix.

73 files: `source-text-is-the-product` — workflow/agent/command/reference .md
7 files:  `structural-regression-guard` — hook .js / bin/install.js structural checks

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 11:39:52 -04:00
Tom Boucher
334a64168e chore(npm): rebrand packages to @opengsd scope (#127)
* chore(npm): rebrand packages to @opengsd scope

Rename:
- get-shit-done-redux → @opengsd/get-shit-done-redux
- @gsd-redux/sdk → @opengsd/gsd-sdk

Add publishConfig.access=public for first-time scoped publish.
CLI binary names (get-shit-done-redux, gsd-sdk, gsd-tools) unchanged.

Sweeps install commands, npx invocations, CI publish/version-check
workflows, tests, docs, READMEs (all translations), and the
PACKAGE_NAME constant in check-latest-version.

Bumps qs 6.15.1 → 6.15.2 to clear a moderate advisory surfaced by
the audit-clean test (GHSA-q8mj-m7cp-5q26).

Closes #126

* chore: pin 2.0.0 release + remove canary workflow

- Bump both packages 1.50.0-canary.0 → 2.0.0 for first @opengsd publish
- Remove .github/workflows/canary.yml and canary dist-tag handling in
  release.yml / release-sdk.yml
- Drop canary section from VERSIONING.md

Refs #126

* chore: address review findings + harden tarball-smoke timeout

- .changeset/opengsd-org-rename.md: match project's custom
  parse.cjs frontmatter (type: Changed / pr: 127); the scoped
  @changesets/cli keys were silently rejected.
- CONTEXT.md: drop two canary-stream policy lines and a dangling
  DEFECT.CANARY-VERSION-LEAK.cross-ref now that canary.yml is gone.
- tests/release-tarball-smoke.install.test.cjs: pass
  timeout: 600_000 for npm pack + global install; the 3-minute
  runNpm default was timing out on slower Docker hosts (cartographer).

Refs #126

* fix(sdk): add missing type/runtime devDependencies for build

prepublishOnly invokes tsc which couldn't resolve @types/node,
@types/ws, or synckit. They had been hoisted from root but were
not declared in sdk/'s own package.json — first publish from a
clean SDK tree failed.

Refs #126

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): use npm pack stdout instead of glob to find tarball

`npm pack --silent` for a scoped package (@opengsd/get-shit-done-redux)
produces `opengsd-get-shit-done-redux-*.tgz`, not `get-shit-done-redux-*.tgz`.
Capture the filename from stdout instead of a hardcoded glob so the step
works regardless of package name format.

Fixes smoke (ubuntu-latest, 22, false) CI failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: treat workflow-file changes as test-skip eligible

`.github/workflows/install-smoke.yml` (and other workflow files)
were in neither `test.yml` paths nor `test-skip.yml` paths-ignore,
so neither workflow ran on a workflow-only commit — leaving the
required test-skip check perpetually missing.

Refs #126

* chore: reset version to 1.0.0 for first @opengsd publish

Nothing has been published yet under the @opengsd scope, so the
inaugural release uses 1.0.0 rather than 2.0.0. The "major bump"
in the changeset reflects the breaking install-command change for
users migrating from the prior unscoped `get-shit-done-redux`, not
a numeric continuation from a 1.x line under the new identity.

Refs #126

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 16:22:41 -04:00
Tom Boucher
dff176bfd2 chore: rebrand to GSD-redux/get-shit-done-redux
Mirror of code, issues, and PRs from the upstream gsd-build/get-shit-done,
which appears compromised or abandoned (maintainer unreachable since
2026-04-01; $GSD token linked to rug-pull).

- Adds rebrand notice block at top of English README
- Removes $GSD token badge and @gsd_foundation X badge (keeps Discord)
- Renames npm packages: get-shit-done-cc -> get-shit-done-redux,
  @gsd-build/sdk -> @gsd-redux/sdk
- Updates all repo URLs across docs, workflows, package.json, bin/
- Updates ci@gsd-build -> ci@gsd-redux in workflow git identities
- Leaves CHANGELOG and .changeset/* alone (historical, time-stamped)
2026-05-22 08:27:07 -04:00
Tom Boucher
918f987a19 feat(#2982): extend no-source-grep lint to catch var-binding readFileSync.includes() (#2985)
* feat(#2982): extend no-source-grep lint to catch var-binding readFileSync.includes()

The base lint (scripts/lint-no-source-grep.cjs) only catches
readFileSync(...).<text-method>() chained directly. The much more
common var-binding form escapes it:

  const src = fs.readFileSync(p, 'utf8');
  // 50 lines later
  if (src.includes('foo')) {}        // ← still grep, lint missed it

Scan of the test suite found ~141 files using this pattern.

Implementation built TDD per #2982 with structured-IR assertions:

  scripts/lint-no-source-grep-extras.cjs
    - detectVarBindingViolations(src) — pure detector, two passes:
      pass 1 collects vars bound from readFileSync, pass 2 finds any
      <var>.<includes|startsWith|endsWith|match|search>( on those vars.
    - detectWrappedAssertOkMatch(src) — flags
      assert.ok(<expr>.match(...)) which escapes the assert.match rule.
    - VIOLATION enum exposes stable codes for tests to assert on.

  scripts/lint-no-source-grep.cjs
    - Wires the new detectors into the existing per-file check; one
      additional violation row per file with the first 3 sample tokens.

  tests/bug-2982-lint-var-binding.test.cjs
    - 13 tests, all assertions on typed VIOLATION enum / structured
      records. Covers all 5 text-match methods, multi-var, no-bind,
      string literal (must NOT trigger), wrapped assert.ok(.match),
      and assert.match (must NOT double-flag).

Migration backlog (#2974 expanded scope):

  - 42 files annotated `// allow-test-rule: source-text-is-the-product`
    (legitimate — they read .md/.json/.yml files whose deployed text
    IS the product)
  - 3 files annotated `// allow-test-rule: pending-migration-to-typed-ir [#2974]`
    (read .cjs/.js source — clear migration debt)
  - 95 files annotated `pending-migration-to-typed-ir [#2974]` with
    `Per-file review may reclassify as source-text-is-the-product
    during migration` (mixed — manual review under #2974)

After this lands the lint reports 0 violations on main; new
violations in PRs surface immediately.

Closes #2982
Refs #2974

* test(#2982): fix truncated test name per CR

The label ended with a bare '(' from a copy-paste mishap. Now reads
'does NOT flag .matchAll(...) — matchAll is not match, so
assert.ok(.matchAll(...)) is not flagged'.

* chore(#2982): add changeset fragment for PR #2985

* chore(#2982): add changeset fragment for PR #2985
2026-05-01 19:50:10 -04:00
Berkay Karaman
d85a42c7ad fix(install): guard writeSettings against null settingsPath for cline runtime (#2035)
* fix(install): guard writeSettings against null settingsPath for cline runtime

Cline returns settingsPath: null from install() because it uses .clinerules
instead of settings.json. The finishInstall() guard was missing !isCline,
causing a crash with ERR_INVALID_ARG_TYPE when installing with the cline runtime.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* test(cline): add regression tests for ERR_INVALID_ARG_TYPE null settingsPath guard

Adds two regression tests to tests/cline-install.test.cjs for gsd-build/get-shit-done#2044:
- Assert install(false, 'cline') does not throw ERR_INVALID_ARG_TYPE
- Assert settings.json is not written for cline runtime

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* test(cline): fix regression tests to directly call finishInstall with null settingsPath

The previous regression tests called install() which returns early for cline
before reaching finishInstall(), so the crash was never exercised. Fix by:
- Exporting finishInstall from bin/install.js
- Calling finishInstall(null, null, ..., 'cline') directly so the null
  settingsPath guard is actually tested

Tests now fail (ERR_INVALID_ARG_TYPE) without the fix and pass with it.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:58:16 -04:00
Tom Boucher
aa3e9cfaf4 feat(install): add Cline as a first-class runtime (#1991) (#2032)
Cline was documented as a supported runtime but was absent from
bin/install.js. This adds full Cline support:

- Registers --cline CLI flag and adds 'cline' to --all list
- Adds getDirName/getConfigDirFromHome/getGlobalDir entries (CLINE_CONFIG_DIR env var respected)
- Adds convertClaudeToCliineMarkdown() and convertClaudeAgentToClineAgent()
- Wires Cline into copyWithPathReplacement(), install(), writeManifest(), finishInstall()
- Local install writes to project root (like Claude Code), not .cline/ subdirectory
- Generates .clinerules at install root with GSD integration rules
- Installs get-shit-done engine and agents with path/brand replacement
- Adds Cline as option 4 in interactive menu (13-runtime menu, All = 14)
- Updates banner description to include Cline
- Exports convertClaudeToCliineMarkdown and convertClaudeAgentToClineAgent for testing
- Adds tests/cline-install.test.cjs with 17 regression tests
- Updates multi-runtime-select, copilot-install, kilo-install tests for new option numbers

Fixes #1991

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 11:47:22 -04:00