akili-specs 2.1.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/.claude/commands/akili-archive.md +145 -0
- package/.claude/commands/akili-audit.md +97 -0
- package/.claude/commands/akili-constitution.md +413 -0
- package/.claude/commands/akili-execute.md +240 -0
- package/.claude/commands/akili-propose.md +167 -0
- package/.claude/commands/akili-seo.md +277 -0
- package/.claude/commands/akili-specify.md +320 -0
- package/.claude/commands/akili-test.md +141 -0
- package/.claude/commands/akili-validate.md +176 -0
- package/.claude/skills/angular-developer/SKILL.md +130 -0
- package/.claude/skills/angular-developer/references/angular-animations.md +160 -0
- package/.claude/skills/angular-developer/references/angular-aria.md +410 -0
- package/.claude/skills/angular-developer/references/cli.md +86 -0
- package/.claude/skills/angular-developer/references/component-harnesses.md +59 -0
- package/.claude/skills/angular-developer/references/component-styling.md +91 -0
- package/.claude/skills/angular-developer/references/components.md +117 -0
- package/.claude/skills/angular-developer/references/creating-services.md +97 -0
- package/.claude/skills/angular-developer/references/data-resolvers.md +69 -0
- package/.claude/skills/angular-developer/references/define-routes.md +67 -0
- package/.claude/skills/angular-developer/references/defining-providers.md +72 -0
- package/.claude/skills/angular-developer/references/di-fundamentals.md +120 -0
- package/.claude/skills/angular-developer/references/e2e-testing.md +66 -0
- package/.claude/skills/angular-developer/references/effects.md +83 -0
- package/.claude/skills/angular-developer/references/hierarchical-injectors.md +43 -0
- package/.claude/skills/angular-developer/references/host-elements.md +80 -0
- package/.claude/skills/angular-developer/references/injection-context.md +63 -0
- package/.claude/skills/angular-developer/references/inputs.md +101 -0
- package/.claude/skills/angular-developer/references/linked-signal.md +59 -0
- package/.claude/skills/angular-developer/references/loading-strategies.md +61 -0
- package/.claude/skills/angular-developer/references/mcp.md +106 -0
- package/.claude/skills/angular-developer/references/migrations.md +30 -0
- package/.claude/skills/angular-developer/references/navigate-to-routes.md +69 -0
- package/.claude/skills/angular-developer/references/outputs.md +86 -0
- package/.claude/skills/angular-developer/references/reactive-forms.md +122 -0
- package/.claude/skills/angular-developer/references/rendering-strategies.md +44 -0
- package/.claude/skills/angular-developer/references/resource.md +74 -0
- package/.claude/skills/angular-developer/references/route-animations.md +56 -0
- package/.claude/skills/angular-developer/references/route-guards.md +52 -0
- package/.claude/skills/angular-developer/references/router-lifecycle.md +45 -0
- package/.claude/skills/angular-developer/references/router-testing.md +87 -0
- package/.claude/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
- package/.claude/skills/angular-developer/references/signal-forms.md +897 -0
- package/.claude/skills/angular-developer/references/signals-overview.md +94 -0
- package/.claude/skills/angular-developer/references/tailwind-css.md +69 -0
- package/.claude/skills/angular-developer/references/template-driven-forms.md +114 -0
- package/.claude/skills/angular-developer/references/testing-fundamentals.md +66 -0
- package/.claude/skills/api-design-principles/SKILL.md +528 -0
- package/.claude/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/.claude/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/.claude/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/.claude/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/.claude/skills/aws-serverless/SKILL.md +323 -0
- package/.claude/skills/brainstorming/SKILL.md +96 -0
- package/.claude/skills/error-handling-patterns/SKILL.md +641 -0
- package/.claude/skills/frontend-design/LICENSE.txt +177 -0
- package/.claude/skills/frontend-design/SKILL.md +272 -0
- package/.claude/skills/gsap-core/SKILL.md +254 -0
- package/.claude/skills/gsap-frameworks/SKILL.md +153 -0
- package/.claude/skills/gsap-performance/SKILL.md +79 -0
- package/.claude/skills/gsap-plugins/SKILL.md +426 -0
- package/.claude/skills/gsap-react/SKILL.md +136 -0
- package/.claude/skills/gsap-scrolltrigger/SKILL.md +296 -0
- package/.claude/skills/gsap-timeline/SKILL.md +107 -0
- package/.claude/skills/gsap-utils/SKILL.md +284 -0
- package/.claude/skills/judgment-day/SKILL.md +52 -0
- package/.claude/skills/nestjs-expert/SKILL.md +552 -0
- package/.claude/skills/product-manager-toolkit/SKILL.md +351 -0
- package/.claude/skills/product-manager-toolkit/references/prd_templates.md +317 -0
- package/.claude/skills/product-manager-toolkit/scripts/customer_interview_analyzer.py +441 -0
- package/.claude/skills/product-manager-toolkit/scripts/rice_prioritizer.py +296 -0
- package/.claude/skills/react-doctor/AGENTS.md +15 -0
- package/.claude/skills/react-doctor/SKILL.md +19 -0
- package/.claude/skills/seo-audit/SKILL.md +497 -0
- package/.claude/skills/seo-audit/evals/evals.json +136 -0
- package/.claude/skills/seo-audit/references/ai-writing-detection.md +200 -0
- package/.claude/skills/seo-audit/references/international-seo.md +230 -0
- package/.claude/skills/shadcn-ui/SKILL.md +1677 -0
- package/.claude/skills/shadcn-ui/references/learn.md +145 -0
- package/.claude/skills/shadcn-ui/references/official-ui-reference.md +1725 -0
- package/.claude/skills/shadcn-ui/references/reference.md +586 -0
- package/.claude/skills/shadcn-ui/references/ui-reference.md +1578 -0
- package/.claude/skills/stitch-design/README.md +50 -0
- package/.claude/skills/stitch-design/SKILL.md +84 -0
- package/.claude/skills/stitch-design/examples/DESIGN.md +22 -0
- package/.claude/skills/stitch-design/examples/enhanced-prompt.md +28 -0
- package/.claude/skills/stitch-design/references/design-mappings.md +45 -0
- package/.claude/skills/stitch-design/references/prompt-keywords.md +114 -0
- package/.claude/skills/stitch-design/references/tool-schemas.md +76 -0
- package/.claude/skills/stitch-design/workflows/edit-design.md +44 -0
- package/.claude/skills/stitch-design/workflows/generate-design-md.md +63 -0
- package/.claude/skills/stitch-design/workflows/text-to-design.md +47 -0
- package/.claude/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/.claude/skills/systematic-debugging/SKILL.md +296 -0
- package/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/.claude/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/.claude/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/.claude/skills/systematic-debugging/find-polluter.sh +63 -0
- package/.claude/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/.claude/skills/systematic-debugging/test-academic.md +14 -0
- package/.claude/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/.claude/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/.claude/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/.claude/skills/tailwind-design-system/SKILL.md +874 -0
- package/.claude/skills/ui-ux-pro-max/SKILL.md +377 -0
- package/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.claude/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.claude/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.claude/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.claude/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.claude/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.claude/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.claude/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.claude/skills/vercel-react-best-practices/AGENTS.md +2934 -0
- package/.claude/skills/vercel-react-best-practices/SKILL.md +136 -0
- package/.claude/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.claude/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/.claude/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/.claude/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/.claude/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
- package/.claude/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/.claude/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/.claude/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.claude/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.claude/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/.claude/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.claude/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.claude/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/.claude/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/.claude/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.claude/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.claude/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.claude/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.claude/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/.claude/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.claude/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/.claude/templates/implementer.md +36 -0
- package/.claude/templates/leader.md +77 -0
- package/.claude/templates/reviewer.md +53 -0
- package/.mcp.json.example +12 -0
- package/CHANGELOG.md +243 -0
- package/LICENSE +21 -0
- package/README.md +795 -0
- package/assets/jc-fox-mark.svg +10 -0
- package/assets/jc-methodology-badge.png +0 -0
- package/bin/akili.js +574 -0
- package/docs/README.md +48 -0
- package/docs/cli.md +187 -0
- package/docs/commands/README.md +43 -0
- package/docs/commands/akili-archive.md +65 -0
- package/docs/commands/akili-constitution.md +91 -0
- package/docs/commands/akili-execute.md +93 -0
- package/docs/commands/akili-propose.md +65 -0
- package/docs/commands/akili-seo.md +75 -0
- package/docs/commands/akili-specify.md +69 -0
- package/docs/commands/akili-test.md +65 -0
- package/docs/commands/akili-validate.md +64 -0
- package/docs/flow.md +255 -0
- package/docs/model-routing.md +133 -0
- package/docs/openspec-comparison.md +42 -0
- package/docs/plans/2026-05-26-multi-agent-sdd-orchestration-design.md +105 -0
- package/docs/release-checklist.md +91 -0
- package/docs/skills/README.md +42 -0
- package/docs/skills/angular-developer.md +23 -0
- package/docs/skills/api-design-principles.md +22 -0
- package/docs/skills/aws-serverless.md +22 -0
- package/docs/skills/brainstorming.md +21 -0
- package/docs/skills/error-handling-patterns.md +22 -0
- package/docs/skills/frontend-design.md +23 -0
- package/docs/skills/gsap-core.md +21 -0
- package/docs/skills/gsap-frameworks.md +20 -0
- package/docs/skills/gsap-performance.md +21 -0
- package/docs/skills/gsap-plugins.md +20 -0
- package/docs/skills/gsap-react.md +22 -0
- package/docs/skills/gsap-scrolltrigger.md +21 -0
- package/docs/skills/gsap-timeline.md +20 -0
- package/docs/skills/gsap-utils.md +21 -0
- package/docs/skills/nestjs-expert.md +23 -0
- package/docs/skills/product-manager-toolkit.md +22 -0
- package/docs/skills/react-doctor.md +27 -0
- package/docs/skills/seo-audit.md +27 -0
- package/docs/skills/shadcn-ui.md +22 -0
- package/docs/skills/stitch-design.md +21 -0
- package/docs/skills/systematic-debugging.md +27 -0
- package/docs/skills/tailwind-design-system.md +23 -0
- package/docs/skills/ui-ux-pro-max.md +25 -0
- package/docs/skills/vercel-react-best-practices.md +22 -0
- package/package.json +50 -0
- package/scripts/gsc_verify.py +162 -0
- package/scripts/parse_tests.js +112 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# `ui-ux-pro-max`
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Provides broad UI/UX design intelligence, including styles, palettes, font pairings, accessibility, animation, layout, typography, dashboards, landing pages, charts, and stack-specific guidance.
|
|
6
|
+
|
|
7
|
+
## Use When
|
|
8
|
+
|
|
9
|
+
- Designing or reviewing UI/UX work.
|
|
10
|
+
- Creating a product experience baseline.
|
|
11
|
+
- Choosing visual direction, palettes, typography, layout, or responsive behavior.
|
|
12
|
+
- Auditing accessibility and interaction quality.
|
|
13
|
+
- Implementing dashboards, admin panels, SaaS pages, portfolios, e-commerce, mobile apps, or charts.
|
|
14
|
+
|
|
15
|
+
## Best Paired Commands
|
|
16
|
+
|
|
17
|
+
- `/akili-constitution` for the UX/UI design baseline.
|
|
18
|
+
- `/akili-specify` for UI requirements and design.
|
|
19
|
+
- `/akili-execute` for implementation guidance.
|
|
20
|
+
- `/akili-test` for UX checks.
|
|
21
|
+
- `/akili-validate` for UI conformance.
|
|
22
|
+
|
|
23
|
+
## Source
|
|
24
|
+
|
|
25
|
+
- `../../.claude/skills/ui-ux-pro-max/SKILL.md`
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# `vercel-react-best-practices`
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Guides React and Next.js performance, rendering, bundle, async, server/client, and architecture best practices based on Vercel engineering guidance.
|
|
6
|
+
|
|
7
|
+
## Use When
|
|
8
|
+
|
|
9
|
+
- Writing, reviewing, or refactoring React or Next.js code.
|
|
10
|
+
- Planning data fetching, server/client boundaries, Suspense, transitions, or bundle optimization.
|
|
11
|
+
- Diagnosing rerenders, hydration issues, performance regressions, or async patterns.
|
|
12
|
+
|
|
13
|
+
## Best Paired Commands
|
|
14
|
+
|
|
15
|
+
- `/akili-specify` for React/Next.js design decisions.
|
|
16
|
+
- `/akili-execute` for implementation.
|
|
17
|
+
- `/akili-test` for performance-sensitive verification.
|
|
18
|
+
- `/akili-validate` for conformance review.
|
|
19
|
+
|
|
20
|
+
## Source
|
|
21
|
+
|
|
22
|
+
- `../../.claude/skills/vercel-react-best-practices/SKILL.md`
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "akili-specs",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Portable AKILI-SPECS methodology commands and skills for AI-assisted development.",
|
|
5
|
+
"homepage": "https://github.com/JuankCadavid/akili-specs#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/JuankCadavid/akili-specs.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/JuankCadavid/akili-specs/issues"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"akili": "bin/akili.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
".claude/commands",
|
|
18
|
+
".claude/skills",
|
|
19
|
+
".claude/templates",
|
|
20
|
+
".mcp.json.example",
|
|
21
|
+
"assets",
|
|
22
|
+
"bin",
|
|
23
|
+
"CHANGELOG.md",
|
|
24
|
+
"docs",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"README.md",
|
|
27
|
+
"scripts/gsc_verify.py",
|
|
28
|
+
"scripts/parse_tests.js"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"pack:dry-run": "npm pack --dry-run",
|
|
32
|
+
"release:major": "node scripts/release.js major",
|
|
33
|
+
"release:minor": "node scripts/release.js minor",
|
|
34
|
+
"release:patch": "node scripts/release.js patch",
|
|
35
|
+
"release:status": "node scripts/release-status.js",
|
|
36
|
+
"verify:cli": "node bin/akili.js list"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"sdd",
|
|
40
|
+
"spec-driven-development",
|
|
41
|
+
"claude",
|
|
42
|
+
"opencode",
|
|
43
|
+
"ai-coding",
|
|
44
|
+
"methodology"
|
|
45
|
+
],
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18.0.0"
|
|
48
|
+
},
|
|
49
|
+
"license": "MIT"
|
|
50
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Verify a Google service account as an owner on Google Search Console
|
|
4
|
+
Domain properties via DNS TXT records.
|
|
5
|
+
|
|
6
|
+
The `gsc` MCP (@mikusnuz/gsc-mcp) does NOT expose Site Verification
|
|
7
|
+
endpoints — only Search Console. This helper covers the verification
|
|
8
|
+
half: token generation + verify call.
|
|
9
|
+
|
|
10
|
+
After verification succeeds, use the `gsc` MCP `sites_add` tool to add
|
|
11
|
+
the property to Search Console for the service account.
|
|
12
|
+
|
|
13
|
+
Setup:
|
|
14
|
+
pip install google-auth google-api-python-client
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
GSC_KEY_PATH=/abs/path/to/service-account.json \
|
|
18
|
+
python3 gsc_verify.py get <domain> [<domain> ...]
|
|
19
|
+
|
|
20
|
+
GSC_KEY_PATH=/abs/path/to/service-account.json \
|
|
21
|
+
python3 gsc_verify.py verify <domain> [<domain> ...]
|
|
22
|
+
|
|
23
|
+
Or pass the key path explicitly:
|
|
24
|
+
python3 gsc_verify.py --key /abs/path/to/key.json get example.com
|
|
25
|
+
|
|
26
|
+
Workflow:
|
|
27
|
+
1. Run with `get` to obtain a DNS TXT verification token per domain.
|
|
28
|
+
2. Add the TXT record to each domain's DNS (host: @, value: the token).
|
|
29
|
+
3. Wait for DNS propagation (a few minutes to an hour).
|
|
30
|
+
4. Run with `verify` to trigger the verification on Google's side.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import argparse
|
|
34
|
+
import os
|
|
35
|
+
import subprocess
|
|
36
|
+
import sys
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
from google.oauth2 import service_account
|
|
41
|
+
from googleapiclient.discovery import build
|
|
42
|
+
from googleapiclient.errors import HttpError
|
|
43
|
+
except ImportError:
|
|
44
|
+
print("ERROR: missing dependencies. Install with:", file=sys.stderr)
|
|
45
|
+
print(" pip install google-auth google-api-python-client", file=sys.stderr)
|
|
46
|
+
sys.exit(1)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
SCOPES = ["https://www.googleapis.com/auth/siteverification"]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def make_client(key_path: str):
|
|
53
|
+
if not Path(key_path).exists():
|
|
54
|
+
print(f"ERROR: key file not found at: {key_path}", file=sys.stderr)
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
creds = service_account.Credentials.from_service_account_file(
|
|
57
|
+
key_path, scopes=SCOPES
|
|
58
|
+
)
|
|
59
|
+
return build("siteVerification", "v1", credentials=creds, cache_discovery=False)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_token(sv, domain: str) -> str:
|
|
63
|
+
body = {
|
|
64
|
+
"site": {"type": "INET_DOMAIN", "identifier": domain},
|
|
65
|
+
"verificationMethod": "DNS_TXT",
|
|
66
|
+
}
|
|
67
|
+
return sv.webResource().getToken(body=body).execute()["token"]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def check_dns(domain: str, token: str):
|
|
71
|
+
"""Best-effort check that the TXT record is visible via dig."""
|
|
72
|
+
try:
|
|
73
|
+
out = subprocess.check_output(
|
|
74
|
+
["dig", "+short", "TXT", domain], stderr=subprocess.DEVNULL, text=True
|
|
75
|
+
)
|
|
76
|
+
return token in out
|
|
77
|
+
except Exception:
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def verify_domain(sv, domain: str):
|
|
82
|
+
body = {"site": {"type": "INET_DOMAIN", "identifier": domain}}
|
|
83
|
+
return sv.webResource().insert(verificationMethod="DNS_TXT", body=body).execute()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def cmd_get(sv, domains):
|
|
87
|
+
print("\n=== DNS TXT records to add ===\n")
|
|
88
|
+
print("For each domain, log into your DNS provider and add a TXT record")
|
|
89
|
+
print("at the root (host = '@' or blank) with the value shown.\n")
|
|
90
|
+
for d in domains:
|
|
91
|
+
try:
|
|
92
|
+
token = get_token(sv, d)
|
|
93
|
+
print(f"--- {d} ---")
|
|
94
|
+
print(f" Type: TXT")
|
|
95
|
+
print(f" Host: @ (root of {d})")
|
|
96
|
+
print(f" Value: {token}\n")
|
|
97
|
+
except HttpError as e:
|
|
98
|
+
print(f"--- {d} ---")
|
|
99
|
+
print(f" ERROR getting token: {e}\n")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def cmd_verify(sv, domains):
|
|
103
|
+
print("\n=== Verifying domains ===\n")
|
|
104
|
+
successes, failures = [], []
|
|
105
|
+
for d in domains:
|
|
106
|
+
try:
|
|
107
|
+
token = get_token(sv, d)
|
|
108
|
+
except HttpError as e:
|
|
109
|
+
print(f"[{d}] ERROR fetching token: {e}")
|
|
110
|
+
failures.append(d)
|
|
111
|
+
continue
|
|
112
|
+
|
|
113
|
+
dns_ok = check_dns(d, token)
|
|
114
|
+
if dns_ok is False:
|
|
115
|
+
print(f"[{d}] WARNING: TXT record not visible yet via dig. Trying anyway...")
|
|
116
|
+
elif dns_ok is True:
|
|
117
|
+
print(f"[{d}] TXT record visible in DNS")
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
verify_domain(sv, d)
|
|
121
|
+
print(f"[{d}] VERIFIED — service account is now an owner.")
|
|
122
|
+
successes.append(d)
|
|
123
|
+
except HttpError as e:
|
|
124
|
+
print(f"[{d}] FAILED to verify: {e}")
|
|
125
|
+
failures.append(d)
|
|
126
|
+
print()
|
|
127
|
+
|
|
128
|
+
print(f"\nDone. Success: {len(successes)} | Failed: {len(failures)}")
|
|
129
|
+
if failures:
|
|
130
|
+
print("Failed domains:", ", ".join(failures))
|
|
131
|
+
print("Tip: DNS can take a few minutes to propagate. Try again later.")
|
|
132
|
+
return 0 if not failures else 1
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def main():
|
|
136
|
+
parser = argparse.ArgumentParser(
|
|
137
|
+
description="Verify a service account as owner on GSC domain properties."
|
|
138
|
+
)
|
|
139
|
+
parser.add_argument(
|
|
140
|
+
"--key",
|
|
141
|
+
default=os.environ.get("GSC_KEY_PATH"),
|
|
142
|
+
help="Path to the Google service account JSON key. "
|
|
143
|
+
"Defaults to $GSC_KEY_PATH.",
|
|
144
|
+
)
|
|
145
|
+
parser.add_argument("action", choices=["get", "verify"])
|
|
146
|
+
parser.add_argument("domains", nargs="+", help="One or more apex domains.")
|
|
147
|
+
args = parser.parse_args()
|
|
148
|
+
|
|
149
|
+
if not args.key:
|
|
150
|
+
parser.error(
|
|
151
|
+
"missing service account key: pass --key /abs/path.json or set $GSC_KEY_PATH"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
sv = make_client(args.key)
|
|
155
|
+
if args.action == "get":
|
|
156
|
+
cmd_get(sv, args.domains)
|
|
157
|
+
return 0
|
|
158
|
+
return cmd_verify(sv, args.domains)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if __name__ == "__main__":
|
|
162
|
+
sys.exit(main())
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
function printHelp() {
|
|
7
|
+
console.log(`AKILI Test Report Parser
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
node parse_tests.js <input-results.json> [output-report.md]
|
|
11
|
+
|
|
12
|
+
Arguments:
|
|
13
|
+
input-results.json JSON output file generated by Jest/Vitest (using --json option)
|
|
14
|
+
output-report.md Optional path to write/append the markdown report (defaults to stdout)
|
|
15
|
+
`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function parseTestJson(inputPath) {
|
|
19
|
+
if (!fs.existsSync(inputPath)) {
|
|
20
|
+
console.error(`ERROR: Input file not found: ${inputPath}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let data;
|
|
25
|
+
try {
|
|
26
|
+
const raw = fs.readFileSync(inputPath, "utf8");
|
|
27
|
+
data = JSON.parse(raw);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.error(`ERROR: Failed to parse JSON: ${e.message}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// extract overall metrics
|
|
34
|
+
const total = data.numTotalTests || 0;
|
|
35
|
+
const passed = data.numPassedTests || 0;
|
|
36
|
+
const failed = data.numFailedTests || 0;
|
|
37
|
+
const pending = data.numPendingTests || 0;
|
|
38
|
+
const suites = data.numTotalTestSuites || 0;
|
|
39
|
+
|
|
40
|
+
let markdown = `## Test Summary
|
|
41
|
+
|
|
42
|
+
- **Total Test Suites:** ${suites}
|
|
43
|
+
- **Total Test Cases:** ${total}
|
|
44
|
+
- **Passed:** ${passed}
|
|
45
|
+
- **Failed:** ${failed}
|
|
46
|
+
- **Skipped/Pending:** ${pending}
|
|
47
|
+
|
|
48
|
+
### Detailed Traceability Matrix
|
|
49
|
+
|
|
50
|
+
| Test Suite / File | Test Case | Status | Duration | Notes / Failure Messages |
|
|
51
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
const results = data.testResults || [];
|
|
55
|
+
for (const suite of results) {
|
|
56
|
+
const relativeSuitePath = path.relative(process.cwd(), suite.name || "unknown");
|
|
57
|
+
const assertions = suite.assertionResults || [];
|
|
58
|
+
|
|
59
|
+
if (assertions.length === 0 && suite.message) {
|
|
60
|
+
// Suite-level failure or initialization failure
|
|
61
|
+
markdown += `| \`${relativeSuitePath}\` | *Suite Failure* | 🔴 **FAILED** | - | \`${suite.message.replace(/\r?\n/g, " ").substring(0, 100)}...\` |\n`;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (const test of assertions) {
|
|
66
|
+
const fullTitle = [...(test.ancestorTitles || []), test.title].join(" > ");
|
|
67
|
+
let statusIndicator = "⚪ **PENDING**";
|
|
68
|
+
if (test.status === "passed") {
|
|
69
|
+
statusIndicator = "🟢 **PASSED**";
|
|
70
|
+
} else if (test.status === "failed") {
|
|
71
|
+
statusIndicator = "🔴 **FAILED**";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const duration = test.duration ? `${test.duration}ms` : "-";
|
|
75
|
+
let failureNotes = "-";
|
|
76
|
+
if (test.failureMessages && test.failureMessages.length > 0) {
|
|
77
|
+
// Strip ANSI escape codes and clean up message
|
|
78
|
+
failureNotes = test.failureMessages[0]
|
|
79
|
+
.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "")
|
|
80
|
+
.replace(/\r?\n/g, " ")
|
|
81
|
+
.substring(0, 120);
|
|
82
|
+
failureNotes = `\`${failureNotes}...\``;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
markdown += `| \`${relativeSuitePath}\` | ${fullTitle} | ${statusIndicator} | ${duration} | ${failureNotes} |\n`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return markdown;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function main() {
|
|
93
|
+
const args = process.argv.slice(2);
|
|
94
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
95
|
+
printHelp();
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const inputPath = args[0];
|
|
100
|
+
const outputPath = args[1];
|
|
101
|
+
|
|
102
|
+
const parsedMarkdown = parseTestJson(inputPath);
|
|
103
|
+
|
|
104
|
+
if (outputPath) {
|
|
105
|
+
fs.writeFileSync(outputPath, parsedMarkdown, "utf8");
|
|
106
|
+
console.log(`Successfully generated markdown report at: ${outputPath}`);
|
|
107
|
+
} else {
|
|
108
|
+
console.log(parsedMarkdown);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
main();
|